diff options
author | obscuren <geffobscura@gmail.com> | 2015-04-16 07:14:27 +0800 |
---|---|---|
committer | obscuren <geffobscura@gmail.com> | 2015-04-16 07:28:24 +0800 |
commit | 3a51c3b584b16b408c3fbf87c4f9719fcfb1c52a (patch) | |
tree | b2d4a5e7fcc1da2fd5b1aa3c139ddc7594c8646c /core | |
parent | 97d2954e227049a089652d91e6fb0ea1c8115cc6 (diff) | |
parent | c4678ffd77a18a9d03c888fdf242c9e5915b9f5f (diff) | |
download | go-tangerine-3a51c3b584b16b408c3fbf87c4f9719fcfb1c52a.tar go-tangerine-3a51c3b584b16b408c3fbf87c4f9719fcfb1c52a.tar.gz go-tangerine-3a51c3b584b16b408c3fbf87c4f9719fcfb1c52a.tar.bz2 go-tangerine-3a51c3b584b16b408c3fbf87c4f9719fcfb1c52a.tar.lz go-tangerine-3a51c3b584b16b408c3fbf87c4f9719fcfb1c52a.tar.xz go-tangerine-3a51c3b584b16b408c3fbf87c4f9719fcfb1c52a.tar.zst go-tangerine-3a51c3b584b16b408c3fbf87c4f9719fcfb1c52a.zip |
Merge branch 'develop' into downloader-proto
Diffstat (limited to 'core')
-rw-r--r-- | core/block_processor.go | 6 | ||||
-rw-r--r-- | core/chain_manager.go | 44 | ||||
-rw-r--r-- | core/filter.go | 2 | ||||
-rw-r--r-- | core/state/managed_state.go | 20 | ||||
-rw-r--r-- | core/types/bloom9.go | 8 |
5 files changed, 69 insertions, 11 deletions
diff --git a/core/block_processor.go b/core/block_processor.go index 7aded346a..d5a29b258 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -18,6 +18,12 @@ import ( "gopkg.in/fatih/set.v0" ) +const ( + // must be bumped when consensus algorithm is changed, this forces the upgradedb + // command to be run (forces the blocks to be imported again using the new algorithm) + BlockChainVersion = 1 +) + var statelogger = logger.NewLogger("BLOCK") type BlockProcessor struct { diff --git a/core/chain_manager.go b/core/chain_manager.go index 5ad1dda83..7e792864a 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -284,11 +284,14 @@ func (self *ChainManager) Export(w io.Writer) error { defer self.mu.RUnlock() glog.V(logger.Info).Infof("exporting %v blocks...\n", self.currentBlock.Header().Number) - for block := self.currentBlock; block != nil; block = self.GetBlock(block.Header().ParentHash) { - if err := block.EncodeRLP(w); err != nil { + last := self.currentBlock.NumberU64() + + for nr := uint64(0); nr <= last; nr++ { + if err := self.GetBlockByNumber(nr).EncodeRLP(w); err != nil { return err } } + return nil } @@ -470,6 +473,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { } if IsParentErr(err) && self.futureBlocks.Has(block.ParentHash()) { + block.SetQueued(true) self.futureBlocks.Push(block) stats.queued++ continue @@ -486,21 +490,24 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { block.Td = td self.mu.Lock() - cblock := self.currentBlock { + cblock := self.currentBlock // Write block to database. Eventually we'll have to improve on this and throw away blocks that are // not in the canonical chain. self.write(block) // Compare the TD of the last known block in the canonical chain to make sure it's greater. // At this point it's possible that a different chain (fork) becomes the new canonical chain. if td.Cmp(self.td) > 0 { - if block.Header().Number.Cmp(new(big.Int).Add(cblock.Header().Number, common.Big1)) < 0 { + //if block.Header().Number.Cmp(new(big.Int).Add(cblock.Header().Number, common.Big1)) < 0 { + if block.Number().Cmp(cblock.Number()) <= 0 { chash := cblock.Hash() hash := block.Hash() if glog.V(logger.Info) { glog.Infof("Split detected. New head #%v (%x) TD=%v, was #%v (%x) TD=%v\n", block.Header().Number, hash[:4], td, cblock.Header().Number, chash[:4], self.td) } + // during split we merge two different chains and create the new canonical chain + self.merge(cblock, block) queue[i] = ChainSplitEvent{block, logs} queueEvent.splitCount++ @@ -549,6 +556,35 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { return nil } +// merge takes two blocks, an old chain and a new chain and will reconstruct the blocks and inserts them +// to be part of the new canonical chain. +func (self *ChainManager) merge(oldBlock, newBlock *types.Block) { + glog.V(logger.Debug).Infof("Applying diff to %x & %x\n", oldBlock.Hash().Bytes()[:4], newBlock.Hash().Bytes()[:4]) + + var oldChain, newChain types.Blocks + // First find the split (common ancestor) so we can perform an adequate merge + for { + oldBlock, newBlock = self.GetBlock(oldBlock.ParentHash()), self.GetBlock(newBlock.ParentHash()) + if oldBlock.Hash() == newBlock.Hash() { + break + } + oldChain = append(oldChain, oldBlock) + newChain = append(newChain, newBlock) + } + + // insert blocks + for _, block := range newChain { + self.insert(block) + } + + if glog.V(logger.Detail) { + for i, oldBlock := range oldChain { + glog.Infof("- %.10v = %x\n", oldBlock.Number(), oldBlock.Hash()) + glog.Infof("+ %.10v = %x\n", newChain[i].Number(), newChain[i].Hash()) + } + } +} + func (self *ChainManager) update() { events := self.eventMux.Subscribe(queueEvent{}) futureTimer := time.NewTicker(5 * time.Second) diff --git a/core/filter.go b/core/filter.go index dd15db27d..4508b35b3 100644 --- a/core/filter.go +++ b/core/filter.go @@ -153,7 +153,7 @@ func (self *Filter) bloomFilter(block *types.Block) bool { if len(self.address) > 0 { var included bool for _, addr := range self.address { - if types.BloomLookup(block.Bloom(), addr.Hash()) { + if types.BloomLookup(block.Bloom(), addr) { included = true break } diff --git a/core/state/managed_state.go b/core/state/managed_state.go index 9d2fc48e7..9e6be9980 100644 --- a/core/state/managed_state.go +++ b/core/state/managed_state.go @@ -37,7 +37,7 @@ func (ms *ManagedState) SetState(statedb *StateDB) { // RemoveNonce removed the nonce from the managed state and all future pending nonces func (ms *ManagedState) RemoveNonce(addr common.Address, n uint64) { - if ms.HasAccount(addr) { + if ms.hasAccount(addr) { ms.mu.Lock() defer ms.mu.Unlock() @@ -52,8 +52,8 @@ func (ms *ManagedState) RemoveNonce(addr common.Address, n uint64) { // NewNonce returns the new canonical nonce for the managed account func (ms *ManagedState) NewNonce(addr common.Address) uint64 { - ms.mu.RLock() - defer ms.mu.RUnlock() + ms.mu.Lock() + defer ms.mu.Unlock() account := ms.getAccount(addr) for i, nonce := range account.nonces { @@ -67,7 +67,10 @@ func (ms *ManagedState) NewNonce(addr common.Address) uint64 { // GetNonce returns the canonical nonce for the managed or unmanged account func (ms *ManagedState) GetNonce(addr common.Address) uint64 { - if ms.HasAccount(addr) { + ms.mu.RLock() + defer ms.mu.RUnlock() + + if ms.hasAccount(addr) { account := ms.getAccount(addr) return uint64(len(account.nonces)) + account.nstart } else { @@ -77,6 +80,9 @@ func (ms *ManagedState) GetNonce(addr common.Address) uint64 { // SetNonce sets the new canonical nonce for the managed state func (ms *ManagedState) SetNonce(addr common.Address, nonce uint64) { + ms.mu.Lock() + defer ms.mu.Unlock() + so := ms.GetOrNewStateObject(addr) so.SetNonce(nonce) @@ -85,6 +91,12 @@ func (ms *ManagedState) SetNonce(addr common.Address, nonce uint64) { // HasAccount returns whether the given address is managed or not func (ms *ManagedState) HasAccount(addr common.Address) bool { + ms.mu.RLock() + defer ms.mu.RUnlock() + return ms.hasAccount(addr) +} + +func (ms *ManagedState) hasAccount(addr common.Address) bool { _, ok := ms.accounts[addr.Str()] return ok } diff --git a/core/types/bloom9.go b/core/types/bloom9.go index 0d37cb19f..aa76a2e9d 100644 --- a/core/types/bloom9.go +++ b/core/types/bloom9.go @@ -8,6 +8,10 @@ import ( "github.com/ethereum/go-ethereum/crypto" ) +type bytesBacked interface { + Bytes() []byte +} + func CreateBloom(receipts Receipts) Bloom { bin := new(big.Int) for _, receipt := range receipts { @@ -51,9 +55,9 @@ func bloom9(b []byte) *big.Int { var Bloom9 = bloom9 -func BloomLookup(bin Bloom, topic common.Hash) bool { +func BloomLookup(bin Bloom, topic bytesBacked) bool { bloom := bin.Big() - cmp := bloom9(topic[:]) + cmp := bloom9(topic.Bytes()[:]) return bloom.And(bloom, cmp).Cmp(cmp) == 0 } |