diff --git a/block_pool.go b/block_pool.go index f65d9d576..334db9c1b 100644 --- a/block_pool.go +++ b/block_pool.go @@ -309,9 +309,13 @@ out: } } + // TODO figure out whether we were catching up + // If caught up and just a new block has been propagated: + // sm.eth.EventMux().Post(NewBlockEvent{block}) + // otherwise process and don't emit anything var err error for i, block := range blocks { - err = self.eth.StateManager().Process(block, false) + err = self.eth.StateManager().Process(block) if err != nil { poollogger.Infoln(err) poollogger.Debugf("Block #%v failed (%x...)\n", block.Number, block.Hash()[0:4]) diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go index 9e9a3e356..b78d49cae 100644 --- a/cmd/ethereum/main.go +++ b/cmd/ethereum/main.go @@ -98,6 +98,8 @@ func main() { // Leave the Println. This needs clean output for piping fmt.Printf("%s\n", block.State().Dump()) + fmt.Println(block) + os.Exit(0) } diff --git a/ethchain/block.go b/ethchain/block.go index e4a1aaf24..b31d68e4d 100644 --- a/ethchain/block.go +++ b/ethchain/block.go @@ -5,7 +5,6 @@ import ( "fmt" "math/big" "sort" - _ "strconv" "time" "github.com/ethereum/go-ethereum/ethcrypto" @@ -240,15 +239,19 @@ func (block *Block) SetUncles(uncles []*Block) { block.UncleSha = ethcrypto.Sha3(ethutil.Encode(block.rlpUncles())) } -func (self *Block) SetReceipts(receipts []*Receipt, txs []*Transaction) { +func (self *Block) SetReceipts(receipts Receipts) { self.receipts = receipts - self.setTransactions(txs) + self.SetReceiptHash(receipts) } -func (block *Block) setTransactions(txs []*Transaction) { - block.transactions = txs +func (self *Block) SetTransactions(txs Transactions) { + self.setTransactions(txs) + self.SetTransactionHash(txs) +} - block.LogsBloom = CreateBloom(txs) +func (block *Block) setTransactions(txs Transactions) { + block.transactions = txs + block.LogsBloom = CreateBloom(block) } func (self *Block) SetTransactionHash(transactions Transactions) { @@ -424,22 +427,7 @@ func (self *Block) Size() ethutil.StorageSize { return ethutil.StorageSize(len(self.RlpEncode())) } -/* -func DeriveReceiptHash(receipts Receipts) (sha []byte) { - trie := ethtrie.New(ethutil.Config.Db, "") - for i, receipt := range receipts { - trie.Update(string(ethutil.NewValue(i).Encode()), string(ethutil.NewValue(receipt.RlpData()).Encode())) - } - - switch trie.Root.(type) { - case string: - sha = []byte(trie.Root.(string)) - case []byte: - sha = trie.Root.([]byte) - default: - panic(fmt.Sprintf("invalid root type %T", trie.Root)) - } - - return sha +// Implement RlpEncodable +func (self *Block) RlpData() interface{} { + return self.Value().Val } -*/ diff --git a/ethchain/bloom9.go b/ethchain/bloom9.go index 742610169..508644b62 100644 --- a/ethchain/bloom9.go +++ b/ethchain/bloom9.go @@ -6,9 +6,10 @@ import ( "github.com/ethereum/go-ethereum/vm" ) -func CreateBloom(txs Transactions) []byte { +func CreateBloom(block *Block) []byte { bin := new(big.Int) - for _, tx := range txs { + bin.Or(bin, bloom9(block.Coinbase)) + for _, tx := range block.Transactions() { bin.Or(bin, LogsBloom(tx.logs)) } @@ -36,9 +37,7 @@ func bloom9(b []byte) *big.Int { r := new(big.Int) for _, i := range []int{0, 2, 4} { t := big.NewInt(1) - - //r |= 1 << (uint64(b[i+1]) + 256*(uint64(b[i])&1)) - r.Or(r, t.Rsh(t, uint(b[i+1])+256*(uint(b[i])&1))) + r.Or(r, t.Lsh(t, uint(b[i+1])+256*(uint(b[i])&1))) } return r diff --git a/ethchain/chain_manager.go b/ethchain/chain_manager.go index 970b93ca3..46990bb22 100644 --- a/ethchain/chain_manager.go +++ b/ethchain/chain_manager.go @@ -87,8 +87,6 @@ func (bc *ChainManager) Reset() { bc.genesisBlock.state.Trie.Sync() // Prepare the genesis block bc.Add(bc.genesisBlock) - //fk := append([]byte("bloom"), bc.genesisBlock.Hash()...) - //bc.Ethereum.Db().Put(fk, make([]byte, 255)) bc.CurrentBlock = bc.genesisBlock bc.SetTotalDifficulty(ethutil.Big("0")) diff --git a/ethchain/filter.go b/ethchain/filter.go index cf31766c4..55d7072e2 100644 --- a/ethchain/filter.go +++ b/ethchain/filter.go @@ -170,12 +170,6 @@ func (self *Filter) FilterMessages(msgs []*ethstate.Message) []*ethstate.Message } func (self *Filter) bloomFilter(block *Block) bool { - //fk := append([]byte("bloom"), block.Hash()...) - //bin, err := self.eth.Db().Get(fk) - //if err != nil { - // fmt.Println(err) - //} - // TODO update to the new bloom filter bloom := NewBloomFilter(nil) diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go index 774933e48..e45d44752 100644 --- a/ethchain/state_manager.go +++ b/ethchain/state_manager.go @@ -101,7 +101,7 @@ func (self *StateManager) Stop() { func (self *StateManager) updateThread() { for ev := range self.events.Chan() { for _, block := range ev.(Blocks) { - err := self.Process(block, false) + err := self.Process(block) if err != nil { statelogger.Infoln(err) statelogger.Debugf("Block #%v failed (%x...)\n", block.Number, block.Hash()[0:4]) @@ -206,7 +206,7 @@ done: return receipts, handled, unhandled, erroneous, err } -func (sm *StateManager) Process(block *Block, dontReact bool) (err error) { +func (sm *StateManager) Process(block *Block) (err error) { // Processing a blocks may never happen simultaneously sm.mutex.Lock() defer sm.mutex.Unlock() @@ -281,18 +281,9 @@ func (sm *StateManager) Process(block *Block, dontReact bool) (err error) { sm.transState = state.Copy() - // Create a bloom bin for this block - //filter := sm.createBloomFilter(state) - // Persist the data - //fk := append([]byte("bloom"), block.Hash()...) - //sm.eth.Db().Put(fk, filter.Bin()) - statelogger.Infof("Imported block #%d (%x...)\n", block.Number, block.Hash()[0:4]) - if dontReact == false { - sm.eth.EventMux().Post(NewBlockEvent{block}) - state.Manifest().Reset() - } + state.Manifest().Reset() sm.eth.TxPool().RemoveSet(block.Transactions()) } else { diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 4e95e55ba..809e5ad6a 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -231,7 +231,7 @@ func (self *StateTransition) TransitionState() (err error) { msg.Output = ret } else { // Add default LOG. Default = big(sender.addr) + 1 - addr := ethutil.BigD(sender.Address()) + addr := ethutil.BigD(receiver.Address()) tx.addLog(vm.Log{sender.Address(), [][]byte{addr.Add(addr, ethutil.Big1).Bytes()}, nil}) } } diff --git a/ethminer/miner.go b/ethminer/miner.go index 685aa45ae..24af7fbcb 100644 --- a/ethminer/miner.go +++ b/ethminer/miner.go @@ -85,11 +85,7 @@ func (miner *Miner) listener() { for { select { - case event, isopen := <-miner.events.Chan(): - if !isopen { - return - } - + case event := <-miner.events.Chan(): switch event := event.(type) { case ethchain.NewBlockEvent: miner.stopMining() @@ -114,16 +110,13 @@ func (miner *Miner) listener() { } } miner.txs = newtxs - - // Setup a fresh state to mine on - //miner.block = miner.ethereum.ChainManager().NewBlock(miner.coinbase, miner.txs) - } else { if bytes.Compare(block.PrevHash, miner.ethereum.ChainManager().CurrentBlock.PrevHash) == 0 { logger.Infoln("Adding uncle block") miner.uncles = append(miner.uncles, block) } } + miner.startMining() case ethchain.TxEvent: if event.Type == ethchain.TxPre { @@ -141,6 +134,8 @@ func (miner *Miner) listener() { // Apply new transactions miner.txs = append(miner.txs, event.Tx) } + + miner.startMining() } } @@ -159,8 +154,12 @@ func (miner *Miner) startMining() { } func (miner *Miner) stopMining() { - close(miner.powQuitChan) - <-miner.powDone + println("stop mining") + _, isopen := <-miner.powQuitChan + if isopen { + close(miner.powQuitChan) + } + //<-miner.powDone } func (self *Miner) mineNewBlock() { @@ -187,10 +186,9 @@ func (self *Miner) mineNewBlock() { } self.ethereum.TxPool().RemoveSet(erroneous) self.txs = append(txs, unhandledTxs...) - self.block.SetReceiptHash(receipts) - // Set the transactions to the block so the new SHA3 can be calculated - self.block.SetReceipts(receipts, txs) + self.block.SetReceipts(receipts) + self.block.SetTransactions(txs) // Accumulate the rewards included for this block stateManager.AccumelateRewards(self.block.State(), self.block, parent) @@ -203,7 +201,7 @@ func (self *Miner) mineNewBlock() { nonce := self.pow.Search(self.block, self.powQuitChan) if nonce != nil { self.block.Nonce = nonce - err := self.ethereum.StateManager().Process(self.block, false) + err := self.ethereum.StateManager().Process(self.block) if err != nil { logger.Infoln(err) } else { @@ -212,7 +210,10 @@ func (self *Miner) mineNewBlock() { logger.Infoln(self.block) // Gather the new batch of transactions currently in the tx pool self.txs = self.ethereum.TxPool().CurrentTransactions() + self.ethereum.EventMux().Post(ethchain.NewBlockEvent{self.block}) } + + // Continue mining on the next block + self.startMining() } - self.powDone <- struct{}{} } diff --git a/ethtrie/trie.go b/ethtrie/trie.go index 9bbe111d2..6db25db05 100644 --- a/ethtrie/trie.go +++ b/ethtrie/trie.go @@ -168,7 +168,24 @@ func New(db ethutil.Database, Root interface{}) *Trie { r := copyRoot(Root) p := copyRoot(Root) - return &Trie{cache: NewCache(db), Root: r, prevRoot: p} + trie := &Trie{cache: NewCache(db), Root: r, prevRoot: p} + trie.setRoot(Root) + + return trie +} + +func (self *Trie) setRoot(root interface{}) { + switch t := root.(type) { + case string: + if t == "" { + root = ethcrypto.Sha3([]byte("")) + } + self.Root = root + case []byte: + self.Root = root + default: + self.Root = self.cache.PutValue(root, true) + } } /* @@ -182,14 +199,7 @@ func (t *Trie) Update(key, value string) { k := CompactHexDecode(key) root := t.UpdateState(t.Root, k, value) - switch root.(type) { - case string: - t.Root = root - case []byte: - t.Root = root - default: - t.Root = t.cache.PutValue(root, true) - } + t.setRoot(root) } func (t *Trie) Get(key string) string { @@ -209,14 +219,7 @@ func (t *Trie) Delete(key string) { k := CompactHexDecode(key) root := t.deleteState(t.Root, k) - switch root.(type) { - case string: - t.Root = root - case []byte: - t.Root = root - default: - t.Root = t.cache.PutValue(root, true) - } + t.setRoot(root) } func (self *Trie) GetRoot() []byte {