From 56f777b2fc77275bc636562b66a08b19afe2ec56 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 5 Feb 2015 03:16:16 +0100 Subject: cmd/ethereum, cmd/mist, core, eth, javascript, xeth: fixes for new p2p API --- core/block_processor.go | 1 - core/helper_test.go | 8 -------- 2 files changed, 9 deletions(-) (limited to 'core') diff --git a/core/block_processor.go b/core/block_processor.go index 6db3c25f5..e6d4a1cda 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -34,7 +34,6 @@ type EthManager interface { IsListening() bool Peers() []*p2p.Peer KeyManager() *crypto.KeyManager - ClientIdentity() p2p.ClientIdentity Db() ethutil.Database EventMux() *event.TypeMux } diff --git a/core/helper_test.go b/core/helper_test.go index 7b41b86f1..473576e3f 100644 --- a/core/helper_test.go +++ b/core/helper_test.go @@ -9,7 +9,6 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/p2p" ) // Implement our EthTest Manager @@ -54,13 +53,6 @@ func (tm *TestManager) TxPool() *TxPool { func (tm *TestManager) EventMux() *event.TypeMux { return tm.eventMux } -func (tm *TestManager) Broadcast(msgType p2p.Msg, data []interface{}) { - fmt.Println("Broadcast not implemented") -} - -func (tm *TestManager) ClientIdentity() p2p.ClientIdentity { - return nil -} func (tm *TestManager) KeyManager() *crypto.KeyManager { return nil } -- cgit v1.2.3 From da2fae0e437f9467a943acfe0571a8a24e8e76fd Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 9 Feb 2015 16:20:34 +0100 Subject: Basic structure miner --- core/block_processor.go | 10 +++++----- core/chain_manager.go | 11 ++++++++++- 2 files changed, 15 insertions(+), 6 deletions(-) (limited to 'core') diff --git a/core/block_processor.go b/core/block_processor.go index d6755e7f7..8c4e53813 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -7,7 +7,6 @@ import ( "sync" "time" - "github.com/ethereum/c-ethash/go-ethash" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethutil" @@ -15,7 +14,7 @@ import ( "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/pow" - _ "github.com/ethereum/go-ethereum/pow/ezp" + "github.com/ethereum/go-ethereum/pow/ezp" "github.com/ethereum/go-ethereum/state" "gopkg.in/fatih/set.v0" ) @@ -65,9 +64,10 @@ type BlockProcessor struct { func NewBlockProcessor(db ethutil.Database, txpool *TxPool, chainManager *ChainManager, eventMux *event.TypeMux) *BlockProcessor { sm := &BlockProcessor{ - db: db, - mem: make(map[string]*big.Int), - Pow: ðash.Ethash{}, + db: db, + mem: make(map[string]*big.Int), + //Pow: ðash.Ethash{}, + Pow: ezp.New(), bc: chainManager, eventMux: eventMux, txpool: txpool, diff --git a/core/chain_manager.go b/core/chain_manager.go index 0847980ca..308e958fe 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -16,6 +16,11 @@ import ( var chainlogger = logger.NewLogger("CHAIN") +type ChainEvent struct { + Block *types.Block + Td *big.Int +} + type StateQuery interface { GetAccount(addr []byte) *state.StateObject } @@ -175,6 +180,9 @@ func (bc *ChainManager) NewBlock(coinbase []byte) *types.Block { ethutil.BigPow(2, 32), nil, "") + block.SetUncles(nil) + block.SetTransactions(nil) + block.SetReceipts(nil) parent := bc.currentBlock if parent != nil { @@ -385,8 +393,9 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { self.setTotalDifficulty(td) self.insert(block) self.transState = state.New(cblock.Root(), self.db) //state.New(cblock.Trie().Copy()) - } + self.eventMux.Post(ChainEvent{block, td}) + } } self.mu.Unlock() -- cgit v1.2.3 From 3f6baa45a7fb1ae5fd7966d2763a2a776a65eb96 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 11 Feb 2015 23:46:45 +0100 Subject: Documented methods & removed old manifest --- core/block_processor.go | 43 ++++++++++++++----------------------------- 1 file changed, 14 insertions(+), 29 deletions(-) (limited to 'core') diff --git a/core/block_processor.go b/core/block_processor.go index 0eb3f8920..c360273da 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -143,6 +143,9 @@ func (self *BlockProcessor) ApplyTransactions(coinbase *state.StateObject, state return receipts, handled, unhandled, erroneous, err } +// Process block will attempt to process the given block's transactions and applies them +// on top of the block's parent state (given it exists) and will return wether it was +// successful or not. func (sm *BlockProcessor) Process(block *types.Block) (td *big.Int, err error) { // Processing a blocks may never happen simultaneously sm.mutex.Lock() @@ -158,14 +161,14 @@ func (sm *BlockProcessor) Process(block *types.Block) (td *big.Int, err error) { } parent := sm.bc.GetBlock(header.ParentHash) - return sm.ProcessWithParent(block, parent) + return sm.processWithParent(block, parent) } -func (sm *BlockProcessor) ProcessWithParent(block, parent *types.Block) (td *big.Int, err error) { +func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (td *big.Int, err error) { sm.lastAttemptedBlock = block + // Create a new state based on the parent's root (e.g., create copy) state := state.New(parent.Root(), sm.db) - //state := state.New(parent.Trie().Copy()) // Block validation if err = sm.ValidateBlock(block, parent); err != nil { @@ -179,18 +182,23 @@ func (sm *BlockProcessor) ProcessWithParent(block, parent *types.Block) (td *big header := block.Header() + // Validate the received block's bloom with the one derived from the generated receipts. + // For valid blocks this should always validate to true. rbloom := types.CreateBloom(receipts) if bytes.Compare(rbloom, header.Bloom) != 0 { err = fmt.Errorf("unable to replicate block's bloom=%x", rbloom) return } + // The transactions Trie's root (R = (Tr [[H1, T1], [H2, T2], ... [Hn, Tn]])) + // can be used by light clients to make sure they've received the correct Txs txSha := types.DeriveSha(block.Transactions()) if bytes.Compare(txSha, header.TxHash) != 0 { err = fmt.Errorf("validating transaction root. received=%x got=%x", header.TxHash, txSha) return } + // Tre receipt Trie's root (R = (Tr [[H1, R1], ... [Hn, R1]])) receiptSha := types.DeriveSha(receipts) if bytes.Compare(receiptSha, header.ReceiptHash) != 0 { fmt.Println("receipts", receipts) @@ -198,12 +206,14 @@ func (sm *BlockProcessor) ProcessWithParent(block, parent *types.Block) (td *big return } + // Accumulate static rewards; block reward, uncle's and uncle inclusion. if err = sm.AccumulateRewards(state, block, parent); err != nil { return } + // Commit state objects/accounts to a temporary trie (does not save) + // used to calculate the state root. state.Update(ethutil.Big0) - if !bytes.Equal(header.Root, state.Root()) { err = fmt.Errorf("invalid merkle root. received=%x got=%x", header.Root, state.Root()) return @@ -213,10 +223,6 @@ func (sm *BlockProcessor) ProcessWithParent(block, parent *types.Block) (td *big td = CalculateTD(block, parent) // Sync the current block's state to the database state.Sync() - // Set the block hashes for the current messages - state.Manifest().SetHash(block.Hash()) - // Reset the manifest XXX We need this? - state.Manifest().Reset() // Remove transactions from the pool sm.txpool.RemoveSet(block.Transactions()) @@ -296,27 +302,6 @@ func (sm *BlockProcessor) AccumulateRewards(statedb *state.StateDB, block, paren return nil } -func (sm *BlockProcessor) GetMessages(block *types.Block) (messages []*state.Message, err error) { - if !sm.bc.HasBlock(block.Header().ParentHash) { - return nil, ParentError(block.Header().ParentHash) - } - - sm.lastAttemptedBlock = block - - var ( - parent = sm.bc.GetBlock(block.Header().ParentHash) - //state = state.New(parent.Trie().Copy()) - state = state.New(parent.Root(), sm.db) - ) - - defer state.Reset() - - sm.TransitionState(state, parent, block) - sm.AccumulateRewards(state, block, parent) - - return state.Manifest().Messages, nil -} - func (sm *BlockProcessor) GetLogs(block *types.Block) (logs state.Logs, err error) { if !sm.bc.HasBlock(block.Header().ParentHash) { return nil, ParentError(block.Header().ParentHash) -- cgit v1.2.3 From bde3ff16ad98cb4ab0befc899f7f0584d21ff9a4 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 13 Feb 2015 16:02:37 +0100 Subject: merge --- core/block_processor.go | 13 ------------- core/manager.go | 1 - 2 files changed, 14 deletions(-) (limited to 'core') diff --git a/core/block_processor.go b/core/block_processor.go index 8f5ee52b7..c360273da 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -23,19 +23,6 @@ type PendingBlockEvent struct { var statelogger = logger.NewLogger("BLOCK") -type EthManager interface { - BlockProcessor() *BlockProcessor - ChainManager() *ChainManager - TxPool() *TxPool - PeerCount() int - IsMining() bool - IsListening() bool - Peers() []*p2p.Peer - KeyManager() *crypto.KeyManager - Db() ethutil.Database - EventMux() *event.TypeMux -} - type BlockProcessor struct { db ethutil.Database // Mutex for locking the block processor. Blocks can only be handled one at a time diff --git a/core/manager.go b/core/manager.go index 4671573b1..f960fc5f0 100644 --- a/core/manager.go +++ b/core/manager.go @@ -16,7 +16,6 @@ type EthManager interface { IsListening() bool Peers() []*p2p.Peer KeyManager() *crypto.KeyManager - ClientIdentity() p2p.ClientIdentity Db() ethutil.Database EventMux() *event.TypeMux } -- cgit v1.2.3 From ce239333d529898edd8333637fd75c565e80a9ff Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 13 Feb 2015 18:15:23 +0100 Subject: Update balance label when mining --- core/types/block.go | 2 ++ 1 file changed, 2 insertions(+) (limited to 'core') diff --git a/core/types/block.go b/core/types/block.go index a334c512e..562a21239 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -6,6 +6,7 @@ import ( "math/big" "sort" "time" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/rlp" @@ -175,6 +176,7 @@ func (self *Block) RlpDataForStorage() interface{} { // Header accessors (add as you need them) func (self *Block) Number() *big.Int { return self.header.Number } func (self *Block) NumberU64() uint64 { return self.header.Number.Uint64() } +func (self *Block) Nonce() []byte { return self.header.Nonce } func (self *Block) Bloom() []byte { return self.header.Bloom } func (self *Block) Coinbase() []byte { return self.header.Coinbase } func (self *Block) Time() int64 { return int64(self.header.Time) } -- cgit v1.2.3 From 32c7ebc51dcb31f21efe1b9c75f2b86cd216f510 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 14 Feb 2015 16:52:14 +0100 Subject: Fixed mining & limited hash power --- core/types/block.go | 3 ++- core/types/receipt.go | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'core') diff --git a/core/types/block.go b/core/types/block.go index 562a21239..fa28f5cc7 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -209,6 +209,7 @@ func (self *Block) ParentHash() []byte { func (self *Block) String() string { return fmt.Sprintf(`BLOCK(%x): Size: %v TD: %v { +NoNonce: %x Header: [ %v @@ -218,7 +219,7 @@ Transactions: Uncles: %v } -`, self.header.Hash(), self.Size(), self.Td, self.header, self.transactions, self.uncles) +`, self.header.Hash(), self.Size(), self.Td, self.header.HashNoNonce(), self.header, self.transactions, self.uncles) } func (self *Header) String() string { diff --git a/core/types/receipt.go b/core/types/receipt.go index bac64e41d..49e68e233 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -17,7 +17,7 @@ type Receipt struct { } func NewReceipt(root []byte, cumalativeGasUsed *big.Int) *Receipt { - return &Receipt{PostState: ethutil.CopyBytes(root), CumulativeGasUsed: cumalativeGasUsed} + return &Receipt{PostState: ethutil.CopyBytes(root), CumulativeGasUsed: new(big.Int).Set(cumalativeGasUsed)} } func NewRecieptFromValue(val *ethutil.Value) *Receipt { -- cgit v1.2.3 From b143dad596f4230d74dadd3c5060020bd50ef7f3 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 15 Feb 2015 02:09:57 +0100 Subject: Reference pointer to block instead of pointer to function --- core/chain_manager.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'core') diff --git a/core/chain_manager.go b/core/chain_manager.go index 308e958fe..54f1ced8c 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -168,7 +168,7 @@ func (bc *ChainManager) NewBlock(coinbase []byte) *types.Block { var root []byte parentHash := ZeroHash256 - if bc.CurrentBlock != nil { + if bc.currentBlock != nil { root = bc.currentBlock.Header().Root parentHash = bc.lastBlockHash } -- cgit v1.2.3 From 2c3a014f03390628d329167109f90a30e3c4e4c3 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 15 Feb 2015 16:16:27 +0100 Subject: Resolved some bugs in the miner * TODO nonce error sometimes persists * Fixed mining on wrong blocks * Fixed state error & receipt fail --- core/chain_manager.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'core') diff --git a/core/chain_manager.go b/core/chain_manager.go index 54f1ced8c..922d2a8d8 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -392,7 +392,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { self.setTotalDifficulty(td) self.insert(block) - self.transState = state.New(cblock.Root(), self.db) //state.New(cblock.Trie().Copy()) + self.transState = state.New(cblock.Root(), self.db) self.eventMux.Post(ChainEvent{block, td}) } -- cgit v1.2.3 From d2a4bc4d7389f4b442a19fc03d0d664c19f931e2 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 16 Feb 2015 12:03:27 +0100 Subject: Removed reference to lastBlockNumber & LastBlockNumber --- core/chain_manager.go | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) (limited to 'core') diff --git a/core/chain_manager.go b/core/chain_manager.go index 922d2a8d8..c28e901c6 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -78,11 +78,10 @@ type ChainManager struct { eventMux *event.TypeMux genesisBlock *types.Block // Last known total difficulty - mu sync.RWMutex - td *big.Int - lastBlockNumber uint64 - currentBlock *types.Block - lastBlockHash []byte + mu sync.RWMutex + td *big.Int + currentBlock *types.Block + lastBlockHash []byte transState *state.StateDB } @@ -94,13 +93,6 @@ func (self *ChainManager) Td() *big.Int { return self.td } -func (self *ChainManager) LastBlockNumber() uint64 { - self.mu.RLock() - defer self.mu.RUnlock() - - return self.lastBlockNumber -} - func (self *ChainManager) LastBlockHash() []byte { self.mu.RLock() defer self.mu.RUnlock() @@ -149,7 +141,6 @@ func (bc *ChainManager) setLastBlock() { rlp.Decode(bytes.NewReader(data), &block) bc.currentBlock = &block bc.lastBlockHash = block.Hash() - bc.lastBlockNumber = block.Header().Number.Uint64() // Set the last know difficulty (might be 0x0 as initial value, Genesis) bc.td = ethutil.BigD(bc.db.LastKnownTD()) @@ -157,7 +148,7 @@ func (bc *ChainManager) setLastBlock() { bc.Reset() } - chainlogger.Infof("Last block (#%d) %x TD=%v\n", bc.lastBlockNumber, bc.currentBlock.Hash(), bc.td) + chainlogger.Infof("Last block (#%v) %x TD=%v\n", bc.currentBlock.Number(), bc.currentBlock.Hash(), bc.td) } // Block creation & chain handling @@ -234,8 +225,6 @@ func (bc *ChainManager) insert(block *types.Block) { } func (bc *ChainManager) write(block *types.Block) { - bc.writeBlockInfo(block) - encodedBlock := ethutil.Encode(block.RlpDataForStorage()) bc.db.Put(block.Hash(), encodedBlock) } @@ -354,11 +343,6 @@ func (self *ChainManager) CalcTotalDiff(block *types.Block) (*big.Int, error) { return td, nil } -// Unexported method for writing extra non-essential block info to the db -func (bc *ChainManager) writeBlockInfo(block *types.Block) { - bc.lastBlockNumber++ -} - func (bc *ChainManager) Stop() { if bc.CurrentBlock != nil { chainlogger.Infoln("Stopped") -- cgit v1.2.3 From 8135752a32837748e6d4a986912131736b1a0aa0 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 17 Feb 2015 12:24:51 +0100 Subject: "centralised" mining to backend. Closes #323 --- core/filter.go | 4 ++-- core/manager.go | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'core') diff --git a/core/filter.go b/core/filter.go index b93fcc8a5..234fa3316 100644 --- a/core/filter.go +++ b/core/filter.go @@ -25,7 +25,7 @@ type FilterOptions struct { // Filtering interface type Filter struct { - eth EthManager + eth Backend earliest int64 latest int64 skip int @@ -40,7 +40,7 @@ type Filter struct { // Create a new filter which uses a bloom filter on blocks to figure out whether a particular block // is interesting or not. -func NewFilter(eth EthManager) *Filter { +func NewFilter(eth Backend) *Filter { return &Filter{eth: eth} } diff --git a/core/manager.go b/core/manager.go index f960fc5f0..bb039d063 100644 --- a/core/manager.go +++ b/core/manager.go @@ -7,12 +7,11 @@ import ( "github.com/ethereum/go-ethereum/p2p" ) -type EthManager interface { +type Backend interface { BlockProcessor() *BlockProcessor ChainManager() *ChainManager TxPool() *TxPool PeerCount() int - IsMining() bool IsListening() bool Peers() []*p2p.Peer KeyManager() *crypto.KeyManager -- cgit v1.2.3 From 567428fb3489d639cd7fdcd50e4362be52745ec4 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 17 Feb 2015 16:12:55 +0100 Subject: Filter and mutex locks added --- core/chain_manager.go | 13 ++++++++++++- core/filter.go | 23 +++++++++++++++++------ 2 files changed, 29 insertions(+), 7 deletions(-) (limited to 'core') diff --git a/core/chain_manager.go b/core/chain_manager.go index c28e901c6..025615676 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -79,6 +79,7 @@ type ChainManager struct { genesisBlock *types.Block // Last known total difficulty mu sync.RWMutex + tsmu sync.RWMutex td *big.Int currentBlock *types.Block lastBlockHash []byte @@ -131,9 +132,19 @@ func (self *ChainManager) State() *state.StateDB { } func (self *ChainManager) TransState() *state.StateDB { + self.tsmu.RLock() + defer self.tsmu.RUnlock() + //tmp := self.transState + return self.transState } +func (self *ChainManager) setTransState(statedb *state.StateDB) { + self.tsmu.Lock() + defer self.tsmu.Unlock() + self.transState = statedb +} + func (bc *ChainManager) setLastBlock() { data, _ := bc.db.Get([]byte("LastBlock")) if len(data) != 0 { @@ -376,7 +387,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { self.setTotalDifficulty(td) self.insert(block) - self.transState = state.New(cblock.Root(), self.db) + self.setTransState(state.New(cblock.Root(), self.db)) self.eventMux.Post(ChainEvent{block, td}) } diff --git a/core/filter.go b/core/filter.go index 234fa3316..88f12a67c 100644 --- a/core/filter.go +++ b/core/filter.go @@ -16,7 +16,7 @@ type FilterOptions struct { Earliest int64 Latest int64 - Address []byte + Address [][]byte Topics [][]byte Skip int @@ -29,7 +29,7 @@ type Filter struct { earliest int64 latest int64 skip int - address []byte + address [][]byte max int topics [][]byte @@ -65,7 +65,7 @@ func (self *Filter) SetLatestBlock(latest int64) { self.latest = latest } -func (self *Filter) SetAddress(addr []byte) { +func (self *Filter) SetAddress(addr [][]byte) { self.address = addr } @@ -145,7 +145,8 @@ func (self *Filter) FilterLogs(logs state.Logs) state.Logs { // Filter the logs for interesting stuff Logs: for _, log := range logs { - if !bytes.Equal(self.address, log.Address()) { + if !includes(self.address, log.Address()) { + //if !bytes.Equal(self.address, log.Address()) { continue } @@ -163,8 +164,18 @@ Logs: } func (self *Filter) bloomFilter(block *types.Block) bool { - if len(self.address) > 0 && !types.BloomLookup(block.Bloom(), self.address) { - return false + if len(self.address) > 0 { + var included bool + for _, addr := range self.address { + if types.BloomLookup(block.Bloom(), addr) { + included = true + break + } + } + + if !included { + return false + } } for _, topic := range self.topics { -- cgit v1.2.3 From 7fc9b5b3f9ca0111cc4bc1b2a6b4bb2eccd3e048 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 17 Feb 2015 22:20:47 +0100 Subject: Changed to ChainEvent and fixed a nil pointer in transact --- core/chain_manager.go | 2 -- 1 file changed, 2 deletions(-) (limited to 'core') diff --git a/core/chain_manager.go b/core/chain_manager.go index 025615676..22d54be03 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -393,8 +393,6 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { } } self.mu.Unlock() - - self.eventMux.Post(NewBlockEvent{block}) } return nil -- cgit v1.2.3 From 655e94259765b02454df93205a30a271103de5a0 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 18 Feb 2015 13:14:21 +0100 Subject: Added GetBlock GetUncle with OOB guard --- core/block_processor.go | 6 +++++- core/block_processor_test.go | 34 ++++++++++++++++++++++++++++++++++ core/chain_manager.go | 16 ++++++++-------- core/types/block.go | 12 ++++++++++++ 4 files changed, 59 insertions(+), 9 deletions(-) create mode 100644 core/block_processor_test.go (limited to 'core') diff --git a/core/block_processor.go b/core/block_processor.go index 893c586dd..b4449100f 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -250,7 +250,11 @@ func (sm *BlockProcessor) ValidateBlock(block, parent *types.Block) error { } if block.Time() > time.Now().Unix() { - return fmt.Errorf("block time is in the future") + return BlockFutureErr + } + + if new(big.Int).Sub(block.Number(), parent.Number()).Cmp(big.NewInt(1)) != 0 { + return BlockNumberErr } // Verify the nonce of the block. Return an error if it's not valid diff --git a/core/block_processor_test.go b/core/block_processor_test.go new file mode 100644 index 000000000..35aeaa714 --- /dev/null +++ b/core/block_processor_test.go @@ -0,0 +1,34 @@ +package core + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/event" +) + +func proc() (*BlockProcessor, *ChainManager) { + db, _ := ethdb.NewMemDatabase() + var mux event.TypeMux + + chainMan := NewChainManager(db, &mux) + return NewBlockProcessor(db, nil, chainMan, &mux), chainMan +} + +func TestNumber(t *testing.T) { + bp, chain := proc() + block1 := chain.NewBlock(nil) + block1.Header().Number = big.NewInt(3) + + err := bp.ValidateBlock(block1, chain.Genesis()) + if err != BlockNumberErr { + t.Errorf("expected block number error") + } + + block1 = chain.NewBlock(nil) + err = bp.ValidateBlock(block1, chain.Genesis()) + if err == BlockNumberErr { + t.Errorf("didn't expect block number error") + } +} diff --git a/core/chain_manager.go b/core/chain_manager.go index 22d54be03..286282064 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -87,6 +87,14 @@ type ChainManager struct { transState *state.StateDB } +func NewChainManager(db ethutil.Database, mux *event.TypeMux) *ChainManager { + bc := &ChainManager{db: db, genesisBlock: GenesisBlock(db), eventMux: mux} + bc.setLastBlock() + bc.transState = bc.State().Copy() + + return bc +} + func (self *ChainManager) Td() *big.Int { self.mu.RLock() defer self.mu.RUnlock() @@ -108,14 +116,6 @@ func (self *ChainManager) CurrentBlock() *types.Block { return self.currentBlock } -func NewChainManager(db ethutil.Database, mux *event.TypeMux) *ChainManager { - bc := &ChainManager{db: db, genesisBlock: GenesisBlock(db), eventMux: mux} - bc.setLastBlock() - bc.transState = bc.State().Copy() - - return bc -} - func (self *ChainManager) Status() (td *big.Int, currentBlock []byte, genesisBlock []byte) { self.mu.RLock() defer self.mu.RUnlock() diff --git a/core/types/block.go b/core/types/block.go index fa28f5cc7..d57de1311 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -185,6 +185,18 @@ func (self *Block) GasUsed() *big.Int { return self.header.GasUsed } func (self *Block) Root() []byte { return self.header.Root } func (self *Block) SetRoot(root []byte) { self.header.Root = root } func (self *Block) Size() ethutil.StorageSize { return ethutil.StorageSize(len(ethutil.Encode(self))) } +func (self *Block) GetTransaction(i int) *Transaction { + if len(self.transactions) > i { + return self.transactions[i] + } + return nil +} +func (self *Block) GetUncle(i int) *Header { + if len(self.uncles) > i { + return self.uncles[i] + } + return nil +} // Implement pow.Block func (self *Block) Difficulty() *big.Int { return self.header.Difficulty } -- cgit v1.2.3 From ee9df32dba5091069cbdad8d00dc15738d676d5b Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 18 Feb 2015 16:08:51 +0100 Subject: Added errors --- core/error.go | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'core') diff --git a/core/error.go b/core/error.go index 11d8c1653..6af48ac2d 100644 --- a/core/error.go +++ b/core/error.go @@ -1,10 +1,16 @@ package core import ( + "errors" "fmt" "math/big" ) +var ( + BlockNumberErr = errors.New("block number invalid") + BlockFutureErr = errors.New("block time is in the future") +) + // Parent error. In case a parent is unknown this error will be thrown // by the block manager type ParentErr struct { -- cgit v1.2.3 From fa4cbad315609e41d88c59ecbce7c6c6169fc57a Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 19 Feb 2015 22:33:22 +0100 Subject: Optimisations and fixed a couple of DDOS issues in the miner --- core/block_processor.go | 25 ++++++++++++++----------- core/chain_manager.go | 25 ++++++++++++++++++++----- core/error.go | 17 ----------------- core/events.go | 3 +++ core/state_transition.go | 3 ++- core/transaction_pool.go | 33 ++++++++++++++++++++++++--------- 6 files changed, 63 insertions(+), 43 deletions(-) (limited to 'core') diff --git a/core/block_processor.go b/core/block_processor.go index b4449100f..a9795385f 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -73,24 +73,27 @@ func (sm *BlockProcessor) TransitionState(statedb *state.StateDB, parent, block return receipts, nil } -func (self *BlockProcessor) ApplyTransaction(coinbase *state.StateObject, state *state.StateDB, block *types.Block, tx *types.Transaction, usedGas *big.Int, transientProcess bool) (*types.Receipt, *big.Int, error) { +func (self *BlockProcessor) ApplyTransaction(coinbase *state.StateObject, statedb *state.StateDB, block *types.Block, tx *types.Transaction, usedGas *big.Int, transientProcess bool) (*types.Receipt, *big.Int, error) { // If we are mining this block and validating we want to set the logs back to 0 - state.EmptyLogs() + statedb.EmptyLogs() txGas := new(big.Int).Set(tx.Gas()) - cb := state.GetStateObject(coinbase.Address()) - st := NewStateTransition(NewEnv(state, self.bc, tx, block), tx, cb) + cb := statedb.GetStateObject(coinbase.Address()) + st := NewStateTransition(NewEnv(statedb, self.bc, tx, block), tx, cb) _, err := st.TransitionState() + if err != nil && (IsNonceErr(err) || state.IsGasLimitErr(err)) { + return nil, nil, err + } txGas.Sub(txGas, st.gas) // Update the state with pending changes - state.Update(txGas) + statedb.Update(txGas) cumulative := new(big.Int).Set(usedGas.Add(usedGas, txGas)) - receipt := types.NewReceipt(state.Root(), cumulative) - receipt.SetLogs(state.Logs()) + receipt := types.NewReceipt(statedb.Root(), cumulative) + receipt.SetLogs(statedb.Logs()) receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) chainlogger.Debugln(receipt) @@ -99,12 +102,12 @@ func (self *BlockProcessor) ApplyTransaction(coinbase *state.StateObject, state go self.eventMux.Post(TxPostEvent{tx}) } - go self.eventMux.Post(state.Logs()) + go self.eventMux.Post(statedb.Logs()) return receipt, txGas, err } -func (self *BlockProcessor) ApplyTransactions(coinbase *state.StateObject, state *state.StateDB, block *types.Block, txs types.Transactions, transientProcess bool) (types.Receipts, types.Transactions, types.Transactions, types.Transactions, error) { +func (self *BlockProcessor) ApplyTransactions(coinbase *state.StateObject, statedb *state.StateDB, block *types.Block, txs types.Transactions, transientProcess bool) (types.Receipts, types.Transactions, types.Transactions, types.Transactions, error) { var ( receipts types.Receipts handled, unhandled types.Transactions @@ -115,12 +118,12 @@ func (self *BlockProcessor) ApplyTransactions(coinbase *state.StateObject, state ) for _, tx := range txs { - receipt, txGas, err := self.ApplyTransaction(coinbase, state, block, tx, totalUsedGas, transientProcess) + receipt, txGas, err := self.ApplyTransaction(coinbase, statedb, block, tx, totalUsedGas, transientProcess) if err != nil { switch { case IsNonceErr(err): return nil, nil, nil, nil, err - case IsGasLimitErr(err): + case state.IsGasLimitErr(err): return nil, nil, nil, nil, err default: statelogger.Infoln(err) diff --git a/core/chain_manager.go b/core/chain_manager.go index 286282064..003781791 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -134,14 +134,11 @@ func (self *ChainManager) State() *state.StateDB { func (self *ChainManager) TransState() *state.StateDB { self.tsmu.RLock() defer self.tsmu.RUnlock() - //tmp := self.transState return self.transState } func (self *ChainManager) setTransState(statedb *state.StateDB) { - self.tsmu.Lock() - defer self.tsmu.Unlock() self.transState = statedb } @@ -361,6 +358,9 @@ func (bc *ChainManager) Stop() { } func (self *ChainManager) InsertChain(chain types.Blocks) error { + self.tsmu.Lock() + defer self.tsmu.Unlock() + for _, block := range chain { td, err := self.processor.Process(block) if err != nil { @@ -376,6 +376,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { } block.Td = td + var chain, split bool self.mu.Lock() { self.write(block) @@ -383,16 +384,26 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { if td.Cmp(self.td) > 0 { if block.Header().Number.Cmp(new(big.Int).Add(cblock.Header().Number, ethutil.Big1)) < 0 { chainlogger.Infof("Split detected. New head #%v (%x) TD=%v, was #%v (%x) TD=%v\n", block.Header().Number, block.Hash()[:4], td, cblock.Header().Number, cblock.Hash()[:4], self.td) + split = true } self.setTotalDifficulty(td) self.insert(block) - self.setTransState(state.New(cblock.Root(), self.db)) - self.eventMux.Post(ChainEvent{block, td}) + chain = true } } self.mu.Unlock() + + if chain { + //self.setTransState(state.New(block.Root(), self.db)) + self.eventMux.Post(ChainEvent{block, td}) + } + + if split { + self.setTransState(state.New(block.Root(), self.db)) + self.eventMux.Post(ChainSplitEvent{block}) + } } return nil @@ -402,3 +413,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { func (self *ChainManager) GetAccount(addr []byte) *state.StateObject { return self.State().GetAccount(addr) } + +func (self *ChainManager) TransMut() *sync.RWMutex { + return &self.tsmu +} diff --git a/core/error.go b/core/error.go index 6af48ac2d..e86bacb2d 100644 --- a/core/error.go +++ b/core/error.go @@ -68,23 +68,6 @@ func IsValidationErr(err error) bool { return ok } -type GasLimitErr struct { - Message string - Is, Max *big.Int -} - -func IsGasLimitErr(err error) bool { - _, ok := err.(*GasLimitErr) - - return ok -} -func (err *GasLimitErr) Error() string { - return err.Message -} -func GasLimitError(is, max *big.Int) *GasLimitErr { - return &GasLimitErr{Message: fmt.Sprintf("GasLimit error. Max %s, transaction would take it to %s", max, is), Is: is, Max: max} -} - type NonceErr struct { Message string Is, Exp uint64 diff --git a/core/events.go b/core/events.go index fe106da49..4cbbc609c 100644 --- a/core/events.go +++ b/core/events.go @@ -13,3 +13,6 @@ type NewBlockEvent struct{ Block *types.Block } // NewMinedBlockEvent is posted when a block has been imported. type NewMinedBlockEvent struct{ Block *types.Block } + +// ChainSplit is posted when a new head is detected +type ChainSplitEvent struct{ Block *types.Block } diff --git a/core/state_transition.go b/core/state_transition.go index 33dd45f02..e82be647d 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -166,7 +166,8 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) { defer self.RefundGas() // Increment the nonce for the next transaction - sender.Nonce += 1 + self.state.SetNonce(sender.Address(), sender.Nonce+1) + //sender.Nonce += 1 // Transaction gas if err = self.UseGas(vm.GasTx); err != nil { diff --git a/core/transaction_pool.go b/core/transaction_pool.go index 7a901fcae..894b6c440 100644 --- a/core/transaction_pool.go +++ b/core/transaction_pool.go @@ -3,6 +3,7 @@ package core import ( "errors" "fmt" + "sync" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethutil" @@ -35,6 +36,7 @@ type TxProcessor interface { // guarantee a non blocking pool we use a queue channel which can be // independently read without needing access to the actual pool. type TxPool struct { + mu sync.RWMutex // Queueing channel for reading and writing incoming // transactions to queueChan chan *types.Transaction @@ -97,7 +99,7 @@ func (self *TxPool) addTx(tx *types.Transaction) { self.txs[string(tx.Hash())] = tx } -func (self *TxPool) Add(tx *types.Transaction) error { +func (self *TxPool) add(tx *types.Transaction) error { if self.txs[string(tx.Hash())] != nil { return fmt.Errorf("Known transaction (%x)", tx.Hash()[0:4]) } @@ -128,17 +130,28 @@ func (self *TxPool) Size() int { return len(self.txs) } +func (self *TxPool) Add(tx *types.Transaction) error { + self.mu.Lock() + defer self.mu.Unlock() + return self.add(tx) +} func (self *TxPool) AddTransactions(txs []*types.Transaction) { + self.mu.Lock() + defer self.mu.Unlock() + for _, tx := range txs { - if err := self.Add(tx); err != nil { - txplogger.Infoln(err) + if err := self.add(tx); err != nil { + txplogger.Debugln(err) } else { - txplogger.Infof("tx %x\n", tx.Hash()[0:4]) + txplogger.Debugf("tx %x\n", tx.Hash()[0:4]) } } } func (self *TxPool) GetTransactions() (txs types.Transactions) { + self.mu.RLock() + defer self.mu.RUnlock() + txs = make(types.Transactions, self.Size()) i := 0 for _, tx := range self.txs { @@ -150,30 +163,32 @@ func (self *TxPool) GetTransactions() (txs types.Transactions) { } func (pool *TxPool) RemoveInvalid(query StateQuery) { + pool.mu.Lock() + var removedTxs types.Transactions for _, tx := range pool.txs { sender := query.GetAccount(tx.From()) err := pool.ValidateTransaction(tx) - fmt.Println(err, sender.Nonce, tx.Nonce()) if err != nil || sender.Nonce >= tx.Nonce() { removedTxs = append(removedTxs, tx) } } + pool.mu.Unlock() pool.RemoveSet(removedTxs) } func (self *TxPool) RemoveSet(txs types.Transactions) { + self.mu.Lock() + defer self.mu.Unlock() + for _, tx := range txs { delete(self.txs, string(tx.Hash())) } } -func (pool *TxPool) Flush() []*types.Transaction { - txList := pool.GetTransactions() +func (pool *TxPool) Flush() { pool.txs = make(map[string]*types.Transaction) - - return txList } func (pool *TxPool) Start() { -- cgit v1.2.3 From d8ac267f4128117c3fb9736a40f3dbc327582e32 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 20 Feb 2015 14:01:30 +0100 Subject: dirty tracking for state objects fixed --- core/block_processor.go | 7 ++----- core/chain_manager.go | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'core') diff --git a/core/block_processor.go b/core/block_processor.go index a9795385f..bfd9d4560 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -296,16 +296,13 @@ func (sm *BlockProcessor) AccumulateRewards(statedb *state.StateDB, block, paren r := new(big.Int) r.Mul(BlockReward, big.NewInt(15)).Div(r, big.NewInt(16)) - uncleAccount := statedb.GetAccount(uncle.Coinbase) - uncleAccount.AddAmount(r) + statedb.AddBalance(uncle.Coinbase, r) reward.Add(reward, new(big.Int).Div(BlockReward, big.NewInt(32))) } // Get the account associated with the coinbase - account := statedb.GetAccount(block.Header().Coinbase) - // Reward amount of ether to the coinbase address - account.AddAmount(reward) + statedb.AddBalance(block.Header().Coinbase, reward) return nil } diff --git a/core/chain_manager.go b/core/chain_manager.go index 003781791..dd0dd3cbe 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -397,7 +397,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { if chain { //self.setTransState(state.New(block.Root(), self.db)) - self.eventMux.Post(ChainEvent{block, td}) + //self.eventMux.Post(ChainEvent{block, td}) } if split { -- cgit v1.2.3 From ea9a549bbdc8377bca73f1417f2dc4a18396a382 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 20 Feb 2015 14:19:34 +0100 Subject: Removed exported fields from state object and added proper set/getters --- core/state_transition.go | 8 ++++---- core/transaction_pool.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'core') diff --git a/core/state_transition.go b/core/state_transition.go index e82be647d..36ffa23d9 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -138,8 +138,8 @@ func (self *StateTransition) preCheck() (err error) { ) // Make sure this transaction's nonce is correct - if sender.Nonce != msg.Nonce() { - return NonceError(msg.Nonce(), sender.Nonce) + if sender.Nonce() != msg.Nonce() { + return NonceError(msg.Nonce(), sender.Nonce()) } // Pre-pay gas / Buy gas of the coinbase account @@ -166,7 +166,7 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) { defer self.RefundGas() // Increment the nonce for the next transaction - self.state.SetNonce(sender.Address(), sender.Nonce+1) + self.state.SetNonce(sender.Address(), sender.Nonce()+1) //sender.Nonce += 1 // Transaction gas @@ -242,7 +242,7 @@ func MakeContract(msg Message, state *state.StateDB) *state.StateObject { addr := AddressFromMessage(msg) contract := state.GetOrNewStateObject(addr) - contract.InitCode = msg.Data() + contract.SetInitCode(msg.Data()) return contract } diff --git a/core/transaction_pool.go b/core/transaction_pool.go index 894b6c440..050cff3d8 100644 --- a/core/transaction_pool.go +++ b/core/transaction_pool.go @@ -169,7 +169,7 @@ func (pool *TxPool) RemoveInvalid(query StateQuery) { for _, tx := range pool.txs { sender := query.GetAccount(tx.From()) err := pool.ValidateTransaction(tx) - if err != nil || sender.Nonce >= tx.Nonce() { + if err != nil || sender.Nonce() >= tx.Nonce() { removedTxs = append(removedTxs, tx) } } -- cgit v1.2.3 From 66d5559866f37a79a7b5aeccd03dfe1b4401542b Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 20 Feb 2015 16:59:08 +0100 Subject: Fixed chain event issue --- core/chain_manager.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'core') diff --git a/core/chain_manager.go b/core/chain_manager.go index 47cad825d..600dc3db5 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -396,9 +396,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { self.mu.Unlock() if chain { - fmt.Println("POST START") - self.eventMux.Post(ChainEvent{block, td}) - fmt.Println("POST END") + go self.eventMux.Post(ChainEvent{block, td}) } if split { -- cgit v1.2.3 From cc43ab9a810125239636143a91609389b19b49c7 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 20 Feb 2015 18:05:46 +0100 Subject: Minor updates for release --- core/chain_manager.go | 3 ++- core/genesis.go | 44 +++++++++++++++++++++++++++++++------------- 2 files changed, 33 insertions(+), 14 deletions(-) (limited to 'core') diff --git a/core/chain_manager.go b/core/chain_manager.go index 600dc3db5..9ef091c3c 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -268,6 +268,7 @@ func (self *ChainManager) GetBlockHashesFromHash(hash []byte, max uint64) (chain break } } + fmt.Printf("get hash %x (%d)\n", hash, len(chain)) return } @@ -396,7 +397,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { self.mu.Unlock() if chain { - go self.eventMux.Post(ChainEvent{block, td}) + self.eventMux.Post(ChainEvent{block, td}) } if split { diff --git a/core/genesis.go b/core/genesis.go index c870ce61e..75b4fc100 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -1,7 +1,10 @@ package core import ( + "encoding/json" + "fmt" "math/big" + "os" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" @@ -31,24 +34,39 @@ func GenesisBlock(db ethutil.Database) *types.Block { genesis.SetTransactions(types.Transactions{}) genesis.SetReceipts(types.Receipts{}) + var accounts map[string]struct{ Balance string } + err := json.Unmarshal(genesisData, &accounts) + if err != nil { + fmt.Println("enable to decode genesis json data:", err) + os.Exit(1) + } + statedb := state.New(genesis.Root(), db) - for _, addr := range []string{ - "dbdbdb2cbd23b783741e8d7fcf51e459b497e4a6", - "e4157b34ea9615cfbde6b4fda419828124b70c78", - "b9c015918bdaba24b4ff057a92a3873d6eb201be", - "6c386a4b26f73c802f34673f7248bb118f97424a", - "cd2a3d9f938e13cd947ec05abc7fe734df8dd826", - "2ef47100e0787b915105fd5e3f4ff6752079d5cb", - "e6716f9544a56c530d868e4bfbacb172315bdead", - "1a26338f0d905e295fccb71fa9ea849ffa12aaf4", - } { + for addr, account := range accounts { codedAddr := ethutil.Hex2Bytes(addr) - account := statedb.GetAccount(codedAddr) - account.SetBalance(ethutil.Big("1606938044258990275541962092341162602522202993782792835301376")) //ethutil.BigPow(2, 200) - statedb.UpdateStateObject(account) + accountState := statedb.GetAccount(codedAddr) + accountState.SetBalance(ethutil.Big(account.Balance)) + statedb.UpdateStateObject(accountState) } statedb.Sync() genesis.Header().Root = statedb.Root() + fmt.Printf("+++ genesis +++\nRoot: %x\nHash: %x\n", genesis.Header().Root, genesis.Hash()) + return genesis } + +var genesisData = []byte(`{ + "dbdbdb2cbd23b783741e8d7fcf51e459b497e4a6": {"balance": "1606938044258990275541962092341162602522202993782792835301376"}, + "e4157b34ea9615cfbde6b4fda419828124b70c78": {"balance": "1606938044258990275541962092341162602522202993782792835301376"}, + "b9c015918bdaba24b4ff057a92a3873d6eb201be": {"balance": "1606938044258990275541962092341162602522202993782792835301376"}, + "6c386a4b26f73c802f34673f7248bb118f97424a": {"balance": "1606938044258990275541962092341162602522202993782792835301376"}, + "cd2a3d9f938e13cd947ec05abc7fe734df8dd826": {"balance": "1606938044258990275541962092341162602522202993782792835301376"}, + "2ef47100e0787b915105fd5e3f4ff6752079d5cb": {"balance": "1606938044258990275541962092341162602522202993782792835301376"}, + "e6716f9544a56c530d868e4bfbacb172315bdead": {"balance": "1606938044258990275541962092341162602522202993782792835301376"}, + "1a26338f0d905e295fccb71fa9ea849ffa12aaf4": {"balance": "1606938044258990275541962092341162602522202993782792835301376"}, + "b0afc46d9ce366d06ab4952ca27db1d9557ae9fd": {"balance": "154162184000000000000000"}, + "f6b1e9dc460d4d62cc22ec5f987d726929c0f9f0": {"balance": "102774789000000000000000"}, + "cc45122d8b7fa0b1eaa6b29e0fb561422a9239d0": {"balance": "51387394000000000000000"}, + "b7576e9d314df41ec5506494293afb1bd5d3f65d": {"balance": "69423399000000000000000"} +}`) -- cgit v1.2.3 From 483d96a89d68023360d211ab329400f4b960fe48 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 22 Feb 2015 13:12:01 +0100 Subject: Added eth_logs & fixed issue with manual log filtering * Implemented `eth_logs` * Fixed issue with `filter.Find()` where logs were appended to an incorrect, non-returned slice resulting in no logs found --- core/block_processor.go | 16 ++++++---------- core/filter.go | 5 ++--- 2 files changed, 8 insertions(+), 13 deletions(-) (limited to 'core') diff --git a/core/block_processor.go b/core/block_processor.go index bfd9d4560..fd591a29d 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -60,12 +60,12 @@ func NewBlockProcessor(db ethutil.Database, txpool *TxPool, chainManager *ChainM return sm } -func (sm *BlockProcessor) TransitionState(statedb *state.StateDB, parent, block *types.Block) (receipts types.Receipts, err error) { +func (sm *BlockProcessor) TransitionState(statedb *state.StateDB, parent, block *types.Block, transientProcess bool) (receipts types.Receipts, err error) { coinbase := statedb.GetOrNewStateObject(block.Header().Coinbase) coinbase.SetGasPool(CalcGasLimit(parent, block)) // Process the transactions on to parent state - receipts, _, _, _, err = sm.ApplyTransactions(coinbase, statedb, block, block.Transactions(), false) + receipts, _, _, _, err = sm.ApplyTransactions(coinbase, statedb, block, block.Transactions(), transientProcess) if err != nil { return nil, err } @@ -100,10 +100,9 @@ func (self *BlockProcessor) ApplyTransaction(coinbase *state.StateObject, stated // Notify all subscribers if !transientProcess { go self.eventMux.Post(TxPostEvent{tx}) + go self.eventMux.Post(statedb.Logs()) } - go self.eventMux.Post(statedb.Logs()) - return receipt, txGas, err } @@ -179,7 +178,7 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (td *big return } - receipts, err := sm.TransitionState(state, parent, block) + receipts, err := sm.TransitionState(state, parent, block, false) if err != nil { return } @@ -316,13 +315,10 @@ func (sm *BlockProcessor) GetLogs(block *types.Block) (logs state.Logs, err erro var ( parent = sm.bc.GetBlock(block.Header().ParentHash) - //state = state.New(parent.Trie().Copy()) - state = state.New(parent.Root(), sm.db) + state = state.New(parent.Root(), sm.db) ) - defer state.Reset() - - sm.TransitionState(state, parent, block) + sm.TransitionState(state, parent, block, true) sm.AccumulateRewards(state, block, parent) return state.Logs(), nil diff --git a/core/filter.go b/core/filter.go index 88f12a67c..cdf7b282d 100644 --- a/core/filter.go +++ b/core/filter.go @@ -111,14 +111,14 @@ func (self *Filter) Find() state.Logs { // current parameters if self.bloomFilter(block) { // Get the logs of the block - logs, err := self.eth.BlockProcessor().GetLogs(block) + unfiltered, err := self.eth.BlockProcessor().GetLogs(block) if err != nil { chainlogger.Warnln("err: filter get logs ", err) break } - logs = append(logs, self.FilterLogs(logs)...) + logs = append(logs, self.FilterLogs(unfiltered)...) } block = self.eth.ChainManager().GetBlock(block.ParentHash()) @@ -146,7 +146,6 @@ func (self *Filter) FilterLogs(logs state.Logs) state.Logs { Logs: for _, log := range logs { if !includes(self.address, log.Address()) { - //if !bytes.Equal(self.address, log.Address()) { continue } -- cgit v1.2.3