From ba295ec6feb8288bb1e0cacca4ed2c3c5515d133 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Thu, 21 May 2015 08:50:01 -0700 Subject: [PATCH 01/14] Log locally mined blocks, after they are 5-deep in the chain This helps determine which blocks are unlikely to end up as uncles * Store the 5 most recent locally mined block numbers * On every imported block, check if the 5-deep block num is in that store * Also confirm that the block is signed with miner's coinbase Why not just check the coinbase? This log is useful if you're running multiple miners and want to know if *this* miner is performing well. --- miner/worker.go | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/miner/worker.go b/miner/worker.go index 5e4ff7510f..5b4af64cb4 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -38,6 +38,13 @@ type Agent interface { GetHashRate() int64 } +const MINING_LOG_AT_DEPTH = 5 + +type UInt64RingBuffer struct { + ints []uint64 //array of all integers in buffer + next int //where is the next insertion? assert 0 <= next < len(ints) +} + // environment is the workers current environment and holds // all of the current state information type environment struct { @@ -54,6 +61,7 @@ type environment struct { lowGasTransactors *set.Set ownedAccounts *set.Set lowGasTxs types.Transactions + localMinedBlocks *UInt64RingBuffer // the most recent block numbers that were mined locally (used to check block inclusion) } // env returns a new environment for the current cycle @@ -209,6 +217,18 @@ out: events.Unsubscribe() } +func newLocalMinedBlock(blockNumber uint64, prevMinedBlocks *UInt64RingBuffer) (minedBlocks *UInt64RingBuffer) { + if prevMinedBlocks == nil { + minedBlocks = &UInt64RingBuffer{next: 0, ints: make([]uint64, MINING_LOG_AT_DEPTH)} + } else { + minedBlocks = prevMinedBlocks + } + + minedBlocks.ints[minedBlocks.next] = blockNumber + minedBlocks.next = (minedBlocks.next + 1) % len(minedBlocks.ints) + return minedBlocks +} + func (self *worker) wait() { for { for block := range self.recv { @@ -232,6 +252,8 @@ func (self *worker) wait() { glog.V(logger.Info).Infof("🔨 Mined %sblock #%v (%x)", stale, block.Number(), block.Hash().Bytes()[:4]) + self.current.localMinedBlocks = newLocalMinedBlock(block.Number().Uint64(), self.current.localMinedBlocks) + jsonlogger.LogJson(&logger.EthMinerNewBlock{ BlockHash: block.Hash().Hex(), BlockNumber: block.Number(), @@ -286,6 +308,9 @@ func (self *worker) makeCurrent() { current.ignoredTransactors = set.New() current.lowGasTransactors = set.New() current.ownedAccounts = accountAddressesSet(accounts) + if self.current != nil { + current.localMinedBlocks = self.current.localMinedBlocks + } parent := self.chain.GetBlock(current.block.ParentHash()) current.coinbase.SetGasPool(core.CalcGasLimit(parent)) @@ -304,6 +329,38 @@ func (w *worker) setGasPrice(p *big.Int) { w.mux.Post(core.GasPriceChanged{w.gasPrice}) } +func (self *worker) isBlockLocallyMined(deepBlockNum uint64) bool { + //Did this instance mine a block at {deepBlockNum} ? + var isLocal = false + for idx, blockNum := range self.current.localMinedBlocks.ints { + if deepBlockNum == blockNum { + isLocal = true + self.current.localMinedBlocks.ints[idx] = 0 //prevent showing duplicate logs + break + } + } + //Short-circuit on false, because the previous and following tests must both be true + if !isLocal { + return false + } + + //Does the block at {deepBlockNum} send earnings to my coinbase? + var block = self.chain.GetBlockByNumber(deepBlockNum) + return block.Header().Coinbase == self.coinbase +} + +func (self *worker) logLocalMinedBlocks(previous *environment) { + if previous != nil && self.current.localMinedBlocks != nil { + nextBlockNum := self.current.block.Number().Uint64() + for checkBlockNum := previous.block.Number().Uint64(); checkBlockNum < nextBlockNum; checkBlockNum++ { + inspectBlockNum := checkBlockNum - MINING_LOG_AT_DEPTH + if self.isBlockLocallyMined(inspectBlockNum) { + glog.V(logger.Info).Infof("🔨 🔗 Mined %d blocks back: block #%v", MINING_LOG_AT_DEPTH, inspectBlockNum) + } + } + } +} + func (self *worker) commitNewWork() { self.mu.Lock() defer self.mu.Unlock() @@ -312,6 +369,7 @@ func (self *worker) commitNewWork() { self.currentMu.Lock() defer self.currentMu.Unlock() + previous := self.current self.makeCurrent() current := self.current @@ -347,6 +405,7 @@ func (self *worker) commitNewWork() { // We only care about logging if we're actually mining if atomic.LoadInt32(&self.mining) == 1 { glog.V(logger.Info).Infof("commit new work on block %v with %d txs & %d uncles\n", current.block.Number(), current.tcount, len(uncles)) + self.logLocalMinedBlocks(previous) } for _, hash := range badUncles { From 8a7fb5fd342ee9d4c2e8609d4c008f12c5956a41 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Sat, 23 May 2015 12:00:18 -0700 Subject: [PATCH 02/14] do not export constant for when to log a deep block you mined --- miner/worker.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/miner/worker.go b/miner/worker.go index 5b4af64cb4..937e98e438 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -38,7 +38,7 @@ type Agent interface { GetHashRate() int64 } -const MINING_LOG_AT_DEPTH = 5 +const miningLogAtDepth = 5 type UInt64RingBuffer struct { ints []uint64 //array of all integers in buffer @@ -219,7 +219,7 @@ out: func newLocalMinedBlock(blockNumber uint64, prevMinedBlocks *UInt64RingBuffer) (minedBlocks *UInt64RingBuffer) { if prevMinedBlocks == nil { - minedBlocks = &UInt64RingBuffer{next: 0, ints: make([]uint64, MINING_LOG_AT_DEPTH)} + minedBlocks = &UInt64RingBuffer{next: 0, ints: make([]uint64, miningLogAtDepth)} } else { minedBlocks = prevMinedBlocks } @@ -353,9 +353,9 @@ func (self *worker) logLocalMinedBlocks(previous *environment) { if previous != nil && self.current.localMinedBlocks != nil { nextBlockNum := self.current.block.Number().Uint64() for checkBlockNum := previous.block.Number().Uint64(); checkBlockNum < nextBlockNum; checkBlockNum++ { - inspectBlockNum := checkBlockNum - MINING_LOG_AT_DEPTH + inspectBlockNum := checkBlockNum - miningLogAtDepth if self.isBlockLocallyMined(inspectBlockNum) { - glog.V(logger.Info).Infof("🔨 🔗 Mined %d blocks back: block #%v", MINING_LOG_AT_DEPTH, inspectBlockNum) + glog.V(logger.Info).Infof("🔨 🔗 Mined %d blocks back: block #%v", miningLogAtDepth, inspectBlockNum) } } } From f1ce5877badf5624a5fc5214dc18086b930c8d38 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Sat, 23 May 2015 12:04:00 -0700 Subject: [PATCH 03/14] do not export ring buffer struct --- miner/worker.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/miner/worker.go b/miner/worker.go index 937e98e438..6f618d632d 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -40,7 +40,7 @@ type Agent interface { const miningLogAtDepth = 5 -type UInt64RingBuffer struct { +type uint64RingBuffer struct { ints []uint64 //array of all integers in buffer next int //where is the next insertion? assert 0 <= next < len(ints) } @@ -61,7 +61,7 @@ type environment struct { lowGasTransactors *set.Set ownedAccounts *set.Set lowGasTxs types.Transactions - localMinedBlocks *UInt64RingBuffer // the most recent block numbers that were mined locally (used to check block inclusion) + localMinedBlocks *uint64RingBuffer // the most recent block numbers that were mined locally (used to check block inclusion) } // env returns a new environment for the current cycle @@ -217,9 +217,9 @@ out: events.Unsubscribe() } -func newLocalMinedBlock(blockNumber uint64, prevMinedBlocks *UInt64RingBuffer) (minedBlocks *UInt64RingBuffer) { +func newLocalMinedBlock(blockNumber uint64, prevMinedBlocks *uint64RingBuffer) (minedBlocks *uint64RingBuffer) { if prevMinedBlocks == nil { - minedBlocks = &UInt64RingBuffer{next: 0, ints: make([]uint64, miningLogAtDepth)} + minedBlocks = &uint64RingBuffer{next: 0, ints: make([]uint64, miningLogAtDepth)} } else { minedBlocks = prevMinedBlocks } From 9253fc337e4f36029f90f31b1b4e116d0a77ae05 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 27 May 2015 00:52:02 +0200 Subject: [PATCH 04/14] cmd/geth: exit the console cleanly when interrupted This fix applies mostly to unsupported terminals that do not trigger the special interrupt handling in liner. Supported terminals were covered because liner.Prompt returns an error if Ctrl-C is pressed. --- cmd/geth/js.go | 68 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 22 deletions(-) diff --git a/cmd/geth/js.go b/cmd/geth/js.go index 0fb234d455..706bc6554f 100644 --- a/cmd/geth/js.go +++ b/cmd/geth/js.go @@ -22,6 +22,7 @@ import ( "fmt" "math/big" "os" + "os/signal" "path/filepath" "strings" @@ -47,7 +48,8 @@ type dumbterm struct{ r *bufio.Reader } func (r dumbterm) Prompt(p string) (string, error) { fmt.Print(p) - return r.r.ReadString('\n') + line, err := r.r.ReadString('\n') + return strings.TrimSuffix(line, "\n"), err } func (r dumbterm) PasswordPrompt(p string) (string, error) { @@ -182,30 +184,52 @@ func (self *jsre) exec(filename string) error { } func (self *jsre) interactive() { - for { - input, err := self.Prompt(self.ps1) - if err != nil { - break - } - if input == "" { - continue - } - str += input + "\n" - self.setIndent() - if indentCount <= 0 { - if input == "exit" { - break + // Read input lines. + prompt := make(chan string) + inputln := make(chan string) + go func() { + defer close(inputln) + for { + line, err := self.Prompt(<-prompt) + if err != nil { + return + } + inputln <- line + } + }() + // Wait for Ctrl-C, too. + sig := make(chan os.Signal, 1) + signal.Notify(sig, os.Interrupt) + + defer func() { + if self.atexit != nil { + self.atexit() + } + self.re.Stop(false) + }() + for { + prompt <- self.ps1 + select { + case <-sig: + fmt.Println("caught interrupt, exiting") + return + case input, ok := <-inputln: + if !ok || indentCount <= 0 && input == "exit" { + return + } + if input == "" { + continue + } + str += input + "\n" + self.setIndent() + if indentCount <= 0 { + hist := str[:len(str)-1] + self.AppendHistory(hist) + self.parseInput(str) + str = "" } - hist := str[:len(str)-1] - self.AppendHistory(hist) - self.parseInput(str) - str = "" } } - if self.atexit != nil { - self.atexit() - } - self.re.Stop(false) } func (self *jsre) withHistory(op func(*os.File)) { From 6019f1bb0a0744ffa52bf1ab93309c1a6dd9063c Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 26 May 2015 18:54:56 -0700 Subject: [PATCH 05/14] deep-mining-log: only track non-stale blocks if you track stale blocks, then you quickly overflow your ring buffer in the local network case where you're mining every block and generating a lot of stales. --- miner/worker.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/miner/worker.go b/miner/worker.go index 6f618d632d..fac2e65683 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -248,12 +248,12 @@ func (self *worker) wait() { canonBlock := self.chain.GetBlockByNumber(block.NumberU64()) if canonBlock != nil && canonBlock.Hash() != block.Hash() { stale = "stale-" + } else { + self.current.localMinedBlocks = newLocalMinedBlock(block.Number().Uint64(), self.current.localMinedBlocks) } glog.V(logger.Info).Infof("🔨 Mined %sblock #%v (%x)", stale, block.Number(), block.Hash().Bytes()[:4]) - self.current.localMinedBlocks = newLocalMinedBlock(block.Number().Uint64(), self.current.localMinedBlocks) - jsonlogger.LogJson(&logger.EthMinerNewBlock{ BlockHash: block.Hash().Hex(), BlockNumber: block.Number(), From de12183d3824c25763e8996c14f8b5a52832fad6 Mon Sep 17 00:00:00 2001 From: Jason Carver Date: Tue, 26 May 2015 18:55:52 -0700 Subject: [PATCH 06/14] deep-mining-log: need ring buffer to be one bigger for all-blocks-mined case --- miner/worker.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/miner/worker.go b/miner/worker.go index fac2e65683..12ed656268 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -219,7 +219,7 @@ out: func newLocalMinedBlock(blockNumber uint64, prevMinedBlocks *uint64RingBuffer) (minedBlocks *uint64RingBuffer) { if prevMinedBlocks == nil { - minedBlocks = &uint64RingBuffer{next: 0, ints: make([]uint64, miningLogAtDepth)} + minedBlocks = &uint64RingBuffer{next: 0, ints: make([]uint64, miningLogAtDepth + 1)} } else { minedBlocks = prevMinedBlocks } From 14955bd4542e422daad5c6b39cfe07cdcb86b230 Mon Sep 17 00:00:00 2001 From: Gustav Simonsson Date: Wed, 27 May 2015 13:01:06 +0200 Subject: [PATCH 07/14] Revert "core: block.gasLimit - parent.gasLimit <= parent.gasLimit / GasLimitBoundDivisor" This reverts commit be2b0501b5832c0b49f07cdf2db597cc34450199. --- core/block_processor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/block_processor.go b/core/block_processor.go index e808c03da0..0377824079 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -302,7 +302,7 @@ func (sm *BlockProcessor) ValidateHeader(block, parent *types.Header, checkPow b a := new(big.Int).Sub(block.GasLimit, parent.GasLimit) a.Abs(a) b := new(big.Int).Div(parent.GasLimit, params.GasLimitBoundDivisor) - if !(a.Cmp(b) <= 0) || (block.GasLimit.Cmp(params.MinGasLimit) == -1) { + if !(a.Cmp(b) < 0) || (block.GasLimit.Cmp(params.MinGasLimit) == -1) { return fmt.Errorf("GasLimit check failed for block %v (%v > %v)", block.GasLimit, a, b) } From bf5f0b1d0cf9207c8958646f6ac16ffbaf89d7fa Mon Sep 17 00:00:00 2001 From: Gustav Simonsson Date: Wed, 27 May 2015 13:30:24 +0200 Subject: [PATCH 08/14] Update ValidateHeader comments --- core/block_processor.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/core/block_processor.go b/core/block_processor.go index 0377824079..e064cdd802 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -285,9 +285,8 @@ func (self *BlockProcessor) GetBlockReceipts(bhash common.Hash) (receipts types. } -// Validates the current block. Returns an error if the block was invalid, -// an uncle or anything that isn't on the current block chain. -// Validation validates easy over difficult (dagger takes longer time = difficult) +// See YP section 4.3.4. "Block Header Validity" +// Validates a block. Returns an error if the block is invalid. func (sm *BlockProcessor) ValidateHeader(block, parent *types.Header, checkPow bool) error { if big.NewInt(int64(len(block.Extra))).Cmp(params.MaximumExtraDataSize) == 1 { return fmt.Errorf("Block extra data too long (%d)", len(block.Extra)) @@ -298,7 +297,6 @@ func (sm *BlockProcessor) ValidateHeader(block, parent *types.Header, checkPow b return fmt.Errorf("Difficulty check failed for block %v, %v", block.Difficulty, expd) } - // block.gasLimit - parent.gasLimit <= parent.gasLimit / GasLimitBoundDivisor a := new(big.Int).Sub(block.GasLimit, parent.GasLimit) a.Abs(a) b := new(big.Int).Div(parent.GasLimit, params.GasLimitBoundDivisor) From 12650e16d3aa453a65417a79d79af5ce98cc4b01 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 27 May 2015 13:08:06 +0200 Subject: [PATCH 09/14] core, miner: fixed miner time issue and removed future blocks * Miner should no longer generate blocks with a time stamp less or equal than it's parent. * Future blocks are no longer processed and queued directly. Closes #1118 --- core/block_processor.go | 3 +-- miner/worker.go | 7 ++++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/block_processor.go b/core/block_processor.go index 0377824079..454c40e27a 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -306,8 +306,7 @@ func (sm *BlockProcessor) ValidateHeader(block, parent *types.Header, checkPow b return fmt.Errorf("GasLimit check failed for block %v (%v > %v)", block.GasLimit, a, b) } - // Allow future blocks up to 10 seconds - if int64(block.Time) > time.Now().Unix()+4 { + if int64(block.Time) > time.Now().Unix() { return BlockFutureErr } diff --git a/miner/worker.go b/miner/worker.go index 12ed656268..182b993981 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -287,8 +287,10 @@ func (self *worker) push() { func (self *worker) makeCurrent() { block := self.chain.NewBlock(self.coinbase) - if block.Time() == self.chain.CurrentBlock().Time() { - block.Header().Time++ + parent := self.chain.GetBlock(block.ParentHash()) + + if block.Time() <= parent.Time() { + block.Header().Time = parent.Header().Time + 1 } block.Header().Extra = self.extra @@ -312,7 +314,6 @@ func (self *worker) makeCurrent() { current.localMinedBlocks = self.current.localMinedBlocks } - parent := self.chain.GetBlock(current.block.ParentHash()) current.coinbase.SetGasPool(core.CalcGasLimit(parent)) self.current = current From 912ae80350c72a9cbefe60969fc9c88b1db302f3 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 27 May 2015 13:16:36 +0200 Subject: [PATCH 10/14] miner: Added 5 blocks wait in prep for #1067 --- miner/worker.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/miner/worker.go b/miner/worker.go index 182b993981..bc69551696 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -219,7 +219,7 @@ out: func newLocalMinedBlock(blockNumber uint64, prevMinedBlocks *uint64RingBuffer) (minedBlocks *uint64RingBuffer) { if prevMinedBlocks == nil { - minedBlocks = &uint64RingBuffer{next: 0, ints: make([]uint64, miningLogAtDepth + 1)} + minedBlocks = &uint64RingBuffer{next: 0, ints: make([]uint64, miningLogAtDepth+1)} } else { minedBlocks = prevMinedBlocks } @@ -244,15 +244,16 @@ func (self *worker) wait() { } self.mux.Post(core.NewMinedBlockEvent{block}) - var stale string + var stale, confirm string canonBlock := self.chain.GetBlockByNumber(block.NumberU64()) if canonBlock != nil && canonBlock.Hash() != block.Hash() { - stale = "stale-" + stale = "stale " } else { + confirm = "Wait 5 blocks for confirmation" self.current.localMinedBlocks = newLocalMinedBlock(block.Number().Uint64(), self.current.localMinedBlocks) } - glog.V(logger.Info).Infof("🔨 Mined %sblock #%v (%x)", stale, block.Number(), block.Hash().Bytes()[:4]) + glog.V(logger.Info).Infof("🔨 Mined %sblock (#%v / %x). %s", stale, block.Number(), block.Hash().Bytes()[:4], confirm) jsonlogger.LogJson(&logger.EthMinerNewBlock{ BlockHash: block.Hash().Hex(), From 3f91ee4ff824b38b7775f4e9f51a4160f5edc19d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Wed, 27 May 2015 16:46:46 +0300 Subject: [PATCH 11/14] cmd/geth: expand admin.progress() to something meaningful --- cmd/geth/admin.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/geth/admin.go b/cmd/geth/admin.go index 8f9a009d74..f0be444c68 100644 --- a/cmd/geth/admin.go +++ b/cmd/geth/admin.go @@ -262,8 +262,8 @@ func (js *jsre) setHead(call otto.FunctionCall) otto.Value { } func (js *jsre) downloadProgress(call otto.FunctionCall) otto.Value { - current, max := js.ethereum.Downloader().Stats() - v, _ := call.Otto.ToValue(fmt.Sprintf("%d/%d", current, max)) + pending, cached := js.ethereum.Downloader().Stats() + v, _ := call.Otto.ToValue(map[string]interface{}{"pending": pending, "cached": cached}) return v } From 759571681604e95b876a03e274c9588529ab204e Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 27 May 2015 17:01:28 +0200 Subject: [PATCH 12/14] core: adjust gas calculation --- core/chain_manager.go | 1 + 1 file changed, 1 insertion(+) diff --git a/core/chain_manager.go b/core/chain_manager.go index ec479db25c..ee73145c10 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -69,6 +69,7 @@ func CalcGasLimit(parent *types.Block) *big.Int { gl := new(big.Int).Sub(parent.GasLimit(), decay) gl = gl.Add(gl, contrib) + gl = gl.Add(gl, big.NewInt(1)) gl = common.BigMax(gl, params.MinGasLimit) if gl.Cmp(params.GenesisGasLimit) < 0 { From 5235e01b8dac36a847723fc83cfd5ff65c903215 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Wed, 27 May 2015 18:58:51 +0300 Subject: [PATCH 13/14] eth: hard disconnect if a peer is flaky --- eth/handler.go | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/eth/handler.go b/eth/handler.go index 777a9c7c0e..8092a5f714 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -93,14 +93,22 @@ func NewProtocolManager(protocolVersion, networkId int, mux *event.TypeMux, txpo } func (pm *ProtocolManager) removePeer(id string) { - // Unregister the peer from the downloader - pm.downloader.UnregisterPeer(id) + // Short circuit if the peer was already removed + peer := pm.peers.Peer(id) + if peer == nil { + return + } + glog.V(logger.Debug).Infoln("Removing peer", id) - // Remove the peer from the Ethereum peer set too - glog.V(logger.Detail).Infoln("Removing peer", id) + // Unregister the peer from the downloader and Ethereum peer set + pm.downloader.UnregisterPeer(id) if err := pm.peers.Unregister(id); err != nil { glog.V(logger.Error).Infoln("Removal failed:", err) } + // Hard disconnect at the networking layer + if peer != nil { + peer.Peer.Disconnect(p2p.DiscUselessPeer) + } } func (pm *ProtocolManager) Start() { From 020006a8ede0463346ad3d4ae318d299eee63fb1 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 27 May 2015 18:03:16 +0200 Subject: [PATCH 14/14] common, ethdb: removed caching and LastTD --- common/db.go | 1 - ethdb/database.go | 64 +++++------------------------------------------ 2 files changed, 6 insertions(+), 59 deletions(-) diff --git a/common/db.go b/common/db.go index ae13c75573..c12a2cfb03 100644 --- a/common/db.go +++ b/common/db.go @@ -5,7 +5,6 @@ type Database interface { Put(key []byte, value []byte) Get(key []byte) ([]byte, error) Delete(key []byte) error - LastKnownTD() []byte Close() Flush() error } diff --git a/ethdb/database.go b/ethdb/database.go index 9bf09467b4..019645cedd 100644 --- a/ethdb/database.go +++ b/ethdb/database.go @@ -1,8 +1,6 @@ package ethdb import ( - "sync" - "github.com/ethereum/go-ethereum/compression/rle" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" @@ -15,14 +13,10 @@ import ( var OpenFileLimit = 64 type LDBDatabase struct { + // filename for reporting fn string - - mu sync.Mutex + // LevelDB instance db *leveldb.DB - - queue map[string][]byte - - quit chan struct{} } // NewLDBDatabase returns a LevelDB wrapped object. LDBDatabase does not persist data by @@ -40,85 +34,39 @@ func NewLDBDatabase(file string) (*LDBDatabase, error) { return nil, err } database := &LDBDatabase{ - fn: file, - db: db, - quit: make(chan struct{}), + fn: file, + db: db, } - database.makeQueue() return database, nil } -func (self *LDBDatabase) makeQueue() { - self.queue = make(map[string][]byte) -} - // Put puts the given key / value to the queue func (self *LDBDatabase) Put(key []byte, value []byte) { - self.mu.Lock() - defer self.mu.Unlock() - - self.queue[string(key)] = value + self.db.Put(key, rle.Compress(value), nil) } // Get returns the given key if it's present. func (self *LDBDatabase) Get(key []byte) ([]byte, error) { - self.mu.Lock() - defer self.mu.Unlock() - - // Check queue first - if dat, ok := self.queue[string(key)]; ok { - return dat, nil - } - dat, err := self.db.Get(key, nil) if err != nil { return nil, err } - return rle.Decompress(dat) } // Delete deletes the key from the queue and database func (self *LDBDatabase) Delete(key []byte) error { - self.mu.Lock() - defer self.mu.Unlock() - - // make sure it's not in the queue - delete(self.queue, string(key)) - return self.db.Delete(key, nil) } -func (self *LDBDatabase) LastKnownTD() []byte { - data, _ := self.Get([]byte("LTD")) - - if len(data) == 0 { - data = []byte{0x0} - } - - return data -} - func (self *LDBDatabase) NewIterator() iterator.Iterator { return self.db.NewIterator(nil, nil) } // Flush flushes out the queue to leveldb func (self *LDBDatabase) Flush() error { - self.mu.Lock() - defer self.mu.Unlock() - - batch := new(leveldb.Batch) - - for key, value := range self.queue { - batch.Put([]byte(key), rle.Compress(value)) - } - self.makeQueue() // reset the queue - - glog.V(logger.Detail).Infoln("Flush database: ", self.fn) - - return self.db.Write(batch, nil) + return nil } func (self *LDBDatabase) Close() {