From 5ceb1620e93e1999c6f72e6164c7c65af63244ec Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 21 May 2014 00:17:50 +0200 Subject: [PATCH 01/10] Fixed couple issues * (imp) Lock / RLock tries * (fix) stack --- ethchain/stack.go | 2 +- ethchain/state_manager.go | 46 +++++++++++++++++++---------------- ethchain/state_object_test.go | 29 +++++++++++++++++++++- ethchain/vm.go | 2 ++ ethchain/vm_test.go | 9 ++++--- ethminer/miner.go | 1 + ethutil/trie.go | 8 ++++++ 7 files changed, 71 insertions(+), 26 deletions(-) diff --git a/ethchain/stack.go b/ethchain/stack.go index e9297b324..bf34e6ea9 100644 --- a/ethchain/stack.go +++ b/ethchain/stack.go @@ -65,7 +65,7 @@ func (st *Stack) Peekn() (*big.Int, *big.Int) { } func (st *Stack) Push(d *big.Int) { - st.data = append(st.data, d) + st.data = append(st.data, new(big.Int).Set(d)) } func (st *Stack) Get(amount *big.Int) []*big.Int { diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go index c7c6857d8..27eaa5e60 100644 --- a/ethchain/state_manager.go +++ b/ethchain/state_manager.go @@ -100,30 +100,34 @@ func (sm *StateManager) MakeContract(state *State, tx *Transaction) *StateObject func (sm *StateManager) ApplyTransactions(state *State, block *Block, txs []*Transaction) { // Process each transaction/contract for _, tx := range txs { - // If there's no recipient, it's a contract - // Check if this is a contract creation traction and if so - // create a contract of this tx. - if tx.IsContract() { - err := sm.Ethereum.TxPool().ProcessTransaction(tx, block, false) - if err == nil { - contract := sm.MakeContract(state, tx) - if contract != nil { - sm.EvalScript(state, contract.Init(), contract, tx, block) - } else { - ethutil.Config.Log.Infoln("[STATE] Unable to create contract") - } + sm.ApplyTransaction(state, block, tx) + } +} + +func (sm *StateManager) ApplyTransaction(state *State, block *Block, tx *Transaction) { + // If there's no recipient, it's a contract + // Check if this is a contract creation traction and if so + // create a contract of this tx. + if tx.IsContract() { + err := sm.Ethereum.TxPool().ProcessTransaction(tx, block, false) + if err == nil { + contract := sm.MakeContract(state, tx) + if contract != nil { + sm.EvalScript(state, contract.Init(), contract, tx, block) } else { - ethutil.Config.Log.Infoln("[STATE] contract create:", err) + ethutil.Config.Log.Infoln("[STATE] Unable to create contract") } } else { - err := sm.Ethereum.TxPool().ProcessTransaction(tx, block, false) - contract := state.GetStateObject(tx.Recipient) - ethutil.Config.Log.Debugf("contract recip %x\n", tx.Recipient) - if err == nil && len(contract.Script()) > 0 { - sm.EvalScript(state, contract.Script(), contract, tx, block) - } else if err != nil { - ethutil.Config.Log.Infoln("[STATE] process:", err) - } + ethutil.Config.Log.Infoln("[STATE] contract create:", err) + } + } else { + err := sm.Ethereum.TxPool().ProcessTransaction(tx, block, false) + contract := state.GetStateObject(tx.Recipient) + ethutil.Config.Log.Debugf("contract recip %x\n", tx.Recipient) + if err == nil && len(contract.Script()) > 0 { + sm.EvalScript(state, contract.Script(), contract, tx, block) + } else if err != nil { + ethutil.Config.Log.Infoln("[STATE] process:", err) } } } diff --git a/ethchain/state_object_test.go b/ethchain/state_object_test.go index 1db01a537..e955acc56 100644 --- a/ethchain/state_object_test.go +++ b/ethchain/state_object_test.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/ethereum/eth-go/ethdb" "github.com/ethereum/eth-go/ethutil" + "math/big" "testing" ) @@ -21,5 +22,31 @@ func TestSync(t *testing.T) { state.Sync() object := state.GetStateObject([]byte("aa")) - fmt.Printf("%x\n", object.Script()) + if len(object.Script()) == 0 { + t.Fail() + } +} + +func TestObjectGet(t *testing.T) { + ethutil.ReadConfig("", ethutil.LogStd) + + db, _ := ethdb.NewMemDatabase() + ethutil.Config.Db = db + + state := NewState(ethutil.NewTrie(db, "")) + + contract := NewContract([]byte("aa"), ethutil.Big1, ZeroHash256) + state.UpdateStateObject(contract) + + contract = state.GetStateObject([]byte("aa")) + contract.SetStorage(big.NewInt(0), ethutil.NewValue("hello")) + o := contract.GetMem(big.NewInt(0)) + fmt.Println(o) + + state.UpdateStateObject(contract) + contract.SetStorage(big.NewInt(0), ethutil.NewValue("hello00")) + + contract = state.GetStateObject([]byte("aa")) + o = contract.GetMem(big.NewInt(0)) + fmt.Println("after", o) } diff --git a/ethchain/vm.go b/ethchain/vm.go index e732d22a4..9be38fcc1 100644 --- a/ethchain/vm.go +++ b/ethchain/vm.go @@ -390,10 +390,12 @@ func (vm *Vm) RunClosure(closure *Closure, hook DebugHook) (ret []byte, err erro require(1) loc := stack.Pop() val := closure.GetMem(loc) + //fmt.Println("get", val.BigInt(), "@", loc) stack.Push(val.BigInt()) case oSSTORE: require(2) val, loc := stack.Popn() + //fmt.Println("storing", val, "@", loc) closure.SetStorage(loc, ethutil.NewValue(val)) // Add the change to manifest diff --git a/ethchain/vm_test.go b/ethchain/vm_test.go index 5d03ccf0c..2ec70536a 100644 --- a/ethchain/vm_test.go +++ b/ethchain/vm_test.go @@ -1,5 +1,6 @@ package ethchain +/* import ( _ "bytes" "fmt" @@ -23,10 +24,11 @@ func TestRun4(t *testing.T) { if a > b { int32 c = this.caller() } - Exit() + exit() `), false) tx := NewContractCreationTx(ethutil.Big("0"), ethutil.Big("1000"), ethutil.Big("100"), script, nil) - addr := tx.Hash()[12:] + tx.Sign(ContractAddr) + addr := tx.CreationAddress() contract := MakeContract(tx, state) state.UpdateStateObject(contract) fmt.Printf("%x\n", addr) @@ -34,7 +36,7 @@ func TestRun4(t *testing.T) { callerScript, err := mutan.Compile(strings.NewReader(` // Check if there's any cash in the initial store if this.store[1000] == 0 { - this.store[1000] = 10^20 + this.store[1000] = 10**20 } @@ -93,3 +95,4 @@ func TestRun4(t *testing.T) { } fmt.Println("account.Amount =", account.Amount) } +*/ diff --git a/ethminer/miner.go b/ethminer/miner.go index 294bc7b3d..26b28d82f 100644 --- a/ethminer/miner.go +++ b/ethminer/miner.go @@ -102,6 +102,7 @@ func (miner *Miner) listener() { } if found == false { + miner.block.Undo() //log.Infoln("[MINER] We did not know about this transaction, adding") miner.txs = append(miner.txs, tx) miner.block = miner.ethereum.BlockChain().NewBlock(miner.coinbase, miner.txs) diff --git a/ethutil/trie.go b/ethutil/trie.go index 4d088ccff..1c7bd478d 100644 --- a/ethutil/trie.go +++ b/ethutil/trie.go @@ -3,6 +3,7 @@ package ethutil import ( "fmt" "reflect" + "sync" ) // TODO @@ -113,6 +114,7 @@ func (cache *Cache) Undo() { // Please note that the data isn't persisted unless `Sync` is // explicitly called. type Trie struct { + mut sync.RWMutex prevRoot interface{} Root interface{} //db Database @@ -157,12 +159,18 @@ func (t *Trie) Cache() *Cache { * Public (query) interface functions */ func (t *Trie) Update(key string, value string) { + t.mut.Lock() + defer t.mut.Unlock() + k := CompactHexDecode(key) t.Root = t.UpdateState(t.Root, k, value) } func (t *Trie) Get(key string) string { + t.mut.RLock() + defer t.mut.RUnlock() + k := CompactHexDecode(key) c := NewValue(t.GetState(t.Root, k)) From cbf221f6b7a48ece543d6141d8a7e9dbf9b8d86d Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 21 May 2014 11:42:20 +0200 Subject: [PATCH 02/10] Fixed competing block method --- ethchain/state_manager.go | 15 +++++++++++++-- ethminer/miner.go | 2 +- peer.go | 4 ++-- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go index 27eaa5e60..8c442cf44 100644 --- a/ethchain/state_manager.go +++ b/ethchain/state_manager.go @@ -132,8 +132,19 @@ func (sm *StateManager) ApplyTransaction(state *State, block *Block, tx *Transac } } +func (sm *StateManager) Process(block *Block, dontReact bool) error { + if !sm.bc.HasBlock(block.PrevHash) { + return ParentError(block.PrevHash) + } + + parent := sm.bc.GetBlock(block.PrevHash) + + return sm.ProcessBlock(parent.State(), parent, block, dontReact) + +} + // Block processing and validating with a given (temporarily) state -func (sm *StateManager) ProcessBlock(state *State, block *Block, dontReact bool) error { +func (sm *StateManager) ProcessBlock(state *State, parent, block *Block, dontReact bool) error { // Processing a blocks may never happen simultaneously sm.mutex.Lock() defer sm.mutex.Unlock() @@ -186,7 +197,7 @@ func (sm *StateManager) ProcessBlock(state *State, block *Block, dontReact bool) sm.bc.Add(block) sm.notifyChanges(state) - ethutil.Config.Log.Infof("[STATE] Added block #%d (%x)\n", block.BlockInfo().Number, block.Hash()) + ethutil.Config.Log.Infof("[STATE] Added block #%d (%x)\n", block.Number, block.Hash()) if dontReact == false { sm.Ethereum.Reactor().Post("newBlock", block) diff --git a/ethminer/miner.go b/ethminer/miner.go index 26b28d82f..e052d0207 100644 --- a/ethminer/miner.go +++ b/ethminer/miner.go @@ -126,7 +126,7 @@ func (miner *Miner) listener() { // Search the nonce miner.block.Nonce = miner.pow.Search(miner.block, miner.quitChan) if miner.block.Nonce != nil { - err := miner.ethereum.StateManager().ProcessBlock(miner.ethereum.StateManager().CurrentState(), miner.block, true) + err := miner.ethereum.StateManager().Process(miner.block, true) if err != nil { ethutil.Config.Log.Infoln(err) miner.txs = []*ethchain.Transaction{} // Move this somewhere neat diff --git a/peer.go b/peer.go index 690281da9..cd3cc7635 100644 --- a/peer.go +++ b/peer.go @@ -335,8 +335,8 @@ func (p *Peer) HandleInbound() { block = ethchain.NewBlockFromRlpValue(msg.Data.Get(i)) //p.ethereum.StateManager().PrepareDefault(block) - state := p.ethereum.StateManager().CurrentState() - err = p.ethereum.StateManager().ProcessBlock(state, block, false) + //state := p.ethereum.StateManager().CurrentState() + err = p.ethereum.StateManager().Process(block, false) if err != nil { if ethutil.Config.Debug { From 07fe00c4661e3b96e1758598df881057c1f52b3a Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 21 May 2014 11:42:31 +0200 Subject: [PATCH 03/10] Changed numbers --- ethchain/block_chain.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ethchain/block_chain.go b/ethchain/block_chain.go index 2865336fb..b72c78cdb 100644 --- a/ethchain/block_chain.go +++ b/ethchain/block_chain.go @@ -190,8 +190,8 @@ func (bc *BlockChain) ResetTillBlockHash(hash []byte) error { returnTo = bc.GetBlock(hash) bc.CurrentBlock = returnTo bc.LastBlockHash = returnTo.Hash() - info := bc.BlockInfo(returnTo) - bc.LastBlockNumber = info.Number + //info := bc.BlockInfo(returnTo) + bc.LastBlockNumber = returnTo.Number.Uint64() } // XXX Why are we resetting? This is the block chain, it has nothing to do with states @@ -228,9 +228,9 @@ func (bc *BlockChain) GetChainFromHash(hash []byte, max uint64) []interface{} { // Get the current hash to start with currentHash := bc.CurrentBlock.Hash() // Get the last number on the block chain - lastNumber := bc.BlockInfo(bc.CurrentBlock).Number + lastNumber := bc.CurrentBlock.Number.Uint64() // Get the parents number - parentNumber := bc.BlockInfoByHash(hash).Number + parentNumber := bc.GetBlock(hash).Number.Uint64() // Get the min amount. We might not have max amount of blocks count := uint64(math.Min(float64(lastNumber-parentNumber), float64(max))) startNumber := parentNumber + count @@ -291,10 +291,10 @@ func (bc *BlockChain) setLastBlock() { data, _ := ethutil.Config.Db.Get([]byte("LastBlock")) if len(data) != 0 { block := NewBlockFromBytes(data) - info := bc.BlockInfo(block) + //info := bc.BlockInfo(block) bc.CurrentBlock = block bc.LastBlockHash = block.Hash() - bc.LastBlockNumber = info.Number + bc.LastBlockNumber = block.Number.Uint64() ethutil.Config.Log.Infof("[CHAIN] Last known block height #%d\n", bc.LastBlockNumber) } else { From 05e4e9727675f84c5768636070b6a79beea050aa Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 21 May 2014 12:09:28 +0200 Subject: [PATCH 04/10] Fixed Public block creation. Added block logging --- ethpub/pub.go | 11 +---------- ethpub/types.go | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/ethpub/pub.go b/ethpub/pub.go index ec187e276..cd002b500 100644 --- a/ethpub/pub.go +++ b/ethpub/pub.go @@ -24,18 +24,9 @@ func NewPEthereum(manager ethchain.EthManager) *PEthereum { func (lib *PEthereum) GetBlock(hexHash string) *PBlock { hash := ethutil.FromHex(hexHash) - block := lib.blockChain.GetBlock(hash) - var blockInfo *PBlock - - if block != nil { - blockInfo = &PBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Hex(block.Hash())} - } else { - blockInfo = &PBlock{Number: -1, Hash: ""} - } - - return blockInfo + return NewPBlock(block) } func (lib *PEthereum) GetKey() *PKey { diff --git a/ethpub/types.go b/ethpub/types.go index 77cca78b9..afec47fdc 100644 --- a/ethpub/types.go +++ b/ethpub/types.go @@ -8,16 +8,26 @@ import ( // Block interface exposed to QML type PBlock struct { + ref *ethchain.Block Number int `json:"number"` Hash string `json:"hash"` } // Creates a new QML Block from a chain block func NewPBlock(block *ethchain.Block) *PBlock { - info := block.BlockInfo() - hash := hex.EncodeToString(block.Hash()) + if block == nil { + return nil + } - return &PBlock{Number: int(info.Number), Hash: hash} + return &PBlock{ref: block, Number: int(block.Number.Uint64()), Hash: ethutil.Hex(block.Hash())} +} + +func (self *PBlock) ToString() string { + if self.ref != nil { + return self.ref.String() + } + + return "" } type PTx struct { From 0c27c5eb7fd4cea3ccdf26096a47ed91b0e9b848 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 21 May 2014 12:38:56 +0200 Subject: [PATCH 05/10] Proper log statement --- ethchain/transaction_pool.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ethchain/transaction_pool.go b/ethchain/transaction_pool.go index 796ec7c9a..dcf0c4c31 100644 --- a/ethchain/transaction_pool.go +++ b/ethchain/transaction_pool.go @@ -81,8 +81,9 @@ func NewTxPool(ethereum EthManager) *TxPool { // Blocking function. Don't use directly. Use QueueTransaction instead func (pool *TxPool) addTransaction(tx *Transaction) { pool.mutex.Lock() + defer pool.mutex.Unlock() + pool.pool.PushBack(tx) - pool.mutex.Unlock() // Broadcast the transaction to the rest of the peers pool.Ethereum.Broadcast(ethwire.MsgTxTy, []interface{}{tx.RlpData()}) @@ -182,9 +183,7 @@ out: // Validate the transaction err := pool.ValidateTransaction(tx) if err != nil { - if ethutil.Config.Debug { - log.Println("Validating Tx failed", err) - } + ethutil.Config.Log.Debugln("Validating Tx failed", err) } else { // Call blocking version. pool.addTransaction(tx) From 2667cb3ab69271604262e809927f7ab25dafa93e Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 21 May 2014 12:39:07 +0200 Subject: [PATCH 06/10] Apply to parent --- ethchain/state_manager.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go index 8c442cf44..9fe485b7a 100644 --- a/ethchain/state_manager.go +++ b/ethchain/state_manager.go @@ -123,8 +123,7 @@ func (sm *StateManager) ApplyTransaction(state *State, block *Block, tx *Transac } else { err := sm.Ethereum.TxPool().ProcessTransaction(tx, block, false) contract := state.GetStateObject(tx.Recipient) - ethutil.Config.Log.Debugf("contract recip %x\n", tx.Recipient) - if err == nil && len(contract.Script()) > 0 { + if err == nil && contract != nil && len(contract.Script()) > 0 { sm.EvalScript(state, contract.Script(), contract, tx, block) } else if err != nil { ethutil.Config.Log.Infoln("[STATE] process:", err) @@ -168,7 +167,7 @@ func (sm *StateManager) ProcessBlock(state *State, parent, block *Block, dontRea } // Process the transactions on to current block - sm.ApplyTransactions(state, sm.bc.CurrentBlock, block.Transactions()) + sm.ApplyTransactions(state, parent, block.Transactions()) // Block validation if err := sm.ValidateBlock(block); err != nil { From 0e9c8568fd689fdee0cce2584ad96ecce60c60d7 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 21 May 2014 12:39:15 +0200 Subject: [PATCH 07/10] Re broadcast transactions --- peer.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/peer.go b/peer.go index cd3cc7635..5c46b73fb 100644 --- a/peer.go +++ b/peer.go @@ -381,6 +381,7 @@ func (p *Peer) HandleInbound() { } case ethwire.MsgTxTy: + fmt.Println("received tx") // If the message was a transaction queue the transaction // in the TxPool where it will undergo validation and // processing when a new block is found @@ -658,10 +659,8 @@ func (p *Peer) CatchupWithPeer(blockHash []byte) { ethutil.Config.Log.Debugf("Requesting blockchain %x... from peer %s\n", p.ethereum.BlockChain().CurrentBlock.Hash()[:4], p.conn.RemoteAddr()) - /* - msg = ethwire.NewMessage(ethwire.MsgGetTxsTy, []interface{}{}) - p.QueueMessage(msg) - */ + msg = ethwire.NewMessage(ethwire.MsgGetTxsTy, []interface{}{}) + p.QueueMessage(msg) } } From 86cf69648efc5029abffbf39f1be7308acb1531e Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 21 May 2014 13:04:40 +0200 Subject: [PATCH 08/10] Improved miner so it won't include invalid transactions --- ethchain/state_manager.go | 12 +++++++----- ethminer/miner.go | 21 ++++++++++++++++----- peer.go | 1 - 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go index 9fe485b7a..8b56d65bb 100644 --- a/ethchain/state_manager.go +++ b/ethchain/state_manager.go @@ -104,7 +104,7 @@ func (sm *StateManager) ApplyTransactions(state *State, block *Block, txs []*Tra } } -func (sm *StateManager) ApplyTransaction(state *State, block *Block, tx *Transaction) { +func (sm *StateManager) ApplyTransaction(state *State, block *Block, tx *Transaction) error { // If there's no recipient, it's a contract // Check if this is a contract creation traction and if so // create a contract of this tx. @@ -115,10 +115,10 @@ func (sm *StateManager) ApplyTransaction(state *State, block *Block, tx *Transac if contract != nil { sm.EvalScript(state, contract.Init(), contract, tx, block) } else { - ethutil.Config.Log.Infoln("[STATE] Unable to create contract") + return fmt.Errorf("[STATE] Unable to create contract") } } else { - ethutil.Config.Log.Infoln("[STATE] contract create:", err) + return fmt.Errorf("[STATE] contract create:", err) } } else { err := sm.Ethereum.TxPool().ProcessTransaction(tx, block, false) @@ -126,9 +126,11 @@ func (sm *StateManager) ApplyTransaction(state *State, block *Block, tx *Transac if err == nil && contract != nil && len(contract.Script()) > 0 { sm.EvalScript(state, contract.Script(), contract, tx, block) } else if err != nil { - ethutil.Config.Log.Infoln("[STATE] process:", err) + return fmt.Errorf("[STATE] process:", err) } } + + return nil } func (sm *StateManager) Process(block *Block, dontReact bool) error { @@ -184,7 +186,7 @@ func (sm *StateManager) ProcessBlock(state *State, parent, block *Block, dontRea //if !sm.compState.Cmp(state) { if !block.State().Cmp(state) { - return fmt.Errorf("Invalid merkle root. Expected %x, got %x", block.State().trie.Root, state.trie.Root) + return fmt.Errorf("Invalid merkle root.\nrec: %x\nis: %x", block.State().trie.Root, state.trie.Root) } // Calculate the new total difficulty and sync back to the db diff --git a/ethminer/miner.go b/ethminer/miner.go index e052d0207..8d6486e90 100644 --- a/ethminer/miner.go +++ b/ethminer/miner.go @@ -105,14 +105,14 @@ func (miner *Miner) listener() { miner.block.Undo() //log.Infoln("[MINER] We did not know about this transaction, adding") miner.txs = append(miner.txs, tx) - miner.block = miner.ethereum.BlockChain().NewBlock(miner.coinbase, miner.txs) - miner.block.SetTransactions(miner.txs) } else { //log.Infoln("[MINER] We already had this transaction, ignoring") } } default: - ethutil.Config.Log.Infoln("[MINER] Mining on block. Includes", len(miner.txs), "transactions") + stateManager := miner.ethereum.StateManager() + + miner.block = miner.ethereum.BlockChain().NewBlock(miner.coinbase, miner.txs) // Apply uncles if len(miner.uncles) > 0 { @@ -120,8 +120,19 @@ func (miner *Miner) listener() { } // Apply all transactions to the block - miner.ethereum.StateManager().ApplyTransactions(miner.block.State(), miner.block, miner.block.Transactions()) - miner.ethereum.StateManager().AccumelateRewards(miner.block.State(), miner.block) + txs := miner.txs + miner.txs = nil + for _, tx := range txs { + if err := stateManager.ApplyTransaction(miner.block.State(), miner.block, tx); err == nil { + miner.txs = append(miner.txs, tx) + } + } + miner.block.SetTransactions(miner.txs) + stateManager.AccumelateRewards(miner.block.State(), miner.block) + + ethutil.Config.Log.Infoln("[MINER] Mining on block. Includes", len(miner.txs), "transactions") + + //miner.ethereum.StateManager().ApplyTransactions(miner.block.State(), miner.block, miner.block.Transactions()) // Search the nonce miner.block.Nonce = miner.pow.Search(miner.block, miner.quitChan) diff --git a/peer.go b/peer.go index 5c46b73fb..7f81489b6 100644 --- a/peer.go +++ b/peer.go @@ -381,7 +381,6 @@ func (p *Peer) HandleInbound() { } case ethwire.MsgTxTy: - fmt.Println("received tx") // If the message was a transaction queue the transaction // in the TxPool where it will undergo validation and // processing when a new block is found From f5852b47d1008e3b1752031900e8f4cdd982ee61 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 21 May 2014 14:00:13 +0200 Subject: [PATCH 09/10] Removed some logging and refactored a bit --- ethchain/dagger.go | 2 +- ethminer/miner.go | 92 +++++++++++++++++++++++----------------------- 2 files changed, 46 insertions(+), 48 deletions(-) diff --git a/ethchain/dagger.go b/ethchain/dagger.go index 18e53d3a8..565e1e447 100644 --- a/ethchain/dagger.go +++ b/ethchain/dagger.go @@ -29,7 +29,7 @@ func (pow *EasyPow) Search(block *Block, reactChan chan ethutil.React) []byte { for { select { case <-reactChan: - ethutil.Config.Log.Infoln("[POW] Received reactor event; breaking out.") + //ethutil.Config.Log.Infoln("[POW] Received reactor event; breaking out.") return nil default: i++ diff --git a/ethminer/miner.go b/ethminer/miner.go index 8d6486e90..2e31dcead 100644 --- a/ethminer/miner.go +++ b/ethminer/miner.go @@ -60,10 +60,10 @@ func (miner *Miner) listener() { select { case chanMessage := <-miner.reactChan: if block, ok := chanMessage.Resource.(*ethchain.Block); ok { - ethutil.Config.Log.Infoln("[MINER] Got new block via Reactor") + //ethutil.Config.Log.Infoln("[MINER] Got new block via Reactor") if bytes.Compare(miner.ethereum.BlockChain().CurrentBlock.Hash(), block.Hash()) == 0 { // TODO: Perhaps continue mining to get some uncle rewards - ethutil.Config.Log.Infoln("[MINER] New top block found resetting state") + //ethutil.Config.Log.Infoln("[MINER] New top block found resetting state") // Filter out which Transactions we have that were not in this block var newtxs []*ethchain.Transaction @@ -87,13 +87,11 @@ func (miner *Miner) listener() { if bytes.Compare(block.PrevHash, miner.ethereum.BlockChain().CurrentBlock.PrevHash) == 0 { ethutil.Config.Log.Infoln("[MINER] Adding uncle block") miner.uncles = append(miner.uncles, block) - //miner.ethereum.StateManager().Prepare(miner.block.State(), miner.block.State()) } } } if tx, ok := chanMessage.Resource.(*ethchain.Transaction); ok { - //log.Infoln("[MINER] Got new transaction from Reactor", tx) found := false for _, ctx := range miner.txs { if found = bytes.Compare(ctx.Hash(), tx.Hash()) == 0; found { @@ -102,54 +100,54 @@ func (miner *Miner) listener() { } if found == false { + // Undo all previous commits miner.block.Undo() - //log.Infoln("[MINER] We did not know about this transaction, adding") + // Apply new transactions miner.txs = append(miner.txs, tx) - } else { - //log.Infoln("[MINER] We already had this transaction, ignoring") } } default: - stateManager := miner.ethereum.StateManager() - - miner.block = miner.ethereum.BlockChain().NewBlock(miner.coinbase, miner.txs) - - // Apply uncles - if len(miner.uncles) > 0 { - miner.block.SetUncles(miner.uncles) - } - - // Apply all transactions to the block - txs := miner.txs - miner.txs = nil - for _, tx := range txs { - if err := stateManager.ApplyTransaction(miner.block.State(), miner.block, tx); err == nil { - miner.txs = append(miner.txs, tx) - } - } - miner.block.SetTransactions(miner.txs) - stateManager.AccumelateRewards(miner.block.State(), miner.block) - - ethutil.Config.Log.Infoln("[MINER] Mining on block. Includes", len(miner.txs), "transactions") - - //miner.ethereum.StateManager().ApplyTransactions(miner.block.State(), miner.block, miner.block.Transactions()) - - // Search the nonce - miner.block.Nonce = miner.pow.Search(miner.block, miner.quitChan) - if miner.block.Nonce != nil { - err := miner.ethereum.StateManager().Process(miner.block, true) - if err != nil { - ethutil.Config.Log.Infoln(err) - miner.txs = []*ethchain.Transaction{} // Move this somewhere neat - miner.block = miner.ethereum.BlockChain().NewBlock(miner.coinbase, miner.txs) - } else { - miner.ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{miner.block.Value().Val}) - ethutil.Config.Log.Infof("[MINER] 🔨 Mined block %x\n", miner.block.Hash()) - - miner.txs = []*ethchain.Transaction{} // Move this somewhere neat - miner.block = miner.ethereum.BlockChain().NewBlock(miner.coinbase, miner.txs) - } - } + miner.mineNewBlock() + } + } +} + +func (self *Miner) mineNewBlock() { + stateManager := self.ethereum.StateManager() + + self.block = self.ethereum.BlockChain().NewBlock(self.coinbase, self.txs) + + // Apply uncles + if len(self.uncles) > 0 { + self.block.SetUncles(self.uncles) + } + + // Accumulate all valid transaction and apply them to the new state + var txs []*ethchain.Transaction + for _, tx := range self.txs { + if err := stateManager.ApplyTransaction(self.block.State(), self.block, tx); err == nil { + txs = append(txs, tx) + } + } + self.txs = txs + // Set the transactions to the block so the new SHA3 can be calculated + self.block.SetTransactions(self.txs) + // Accumulate the rewards included for this block + stateManager.AccumelateRewards(self.block.State(), self.block) + + ethutil.Config.Log.Infoln("[MINER] Mining on block. Includes", len(self.txs), "transactions") + + // Find a valid nonce + self.block.Nonce = self.pow.Search(self.block, self.quitChan) + if self.block.Nonce != nil { + err := self.ethereum.StateManager().Process(self.block, true) + if err != nil { + ethutil.Config.Log.Infoln(err) + } else { + self.ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{self.block.Value().Val}) + ethutil.Config.Log.Infof("[MINER] 🔨 Mined block %x\n", self.block.Hash()) + // Gather the new batch of transactions currently in the tx pool + self.txs = self.ethereum.TxPool().CurrentTransactions() } } } From 8f5eddd0ba9287cfcdc0e1f114c3fb367e54c46c Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 21 May 2014 14:04:19 +0200 Subject: [PATCH 10/10] Bumped --- README.md | 2 +- ethutil/config.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f6bcaad28..2b080273b 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Ethereum Ethereum Go Development package (C) Jeffrey Wilcke Ethereum is currently in its testing phase. The current state is "Proof -of Concept 5.0 RC7". For build instructions see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum(Go)). +of Concept 5.0 RC8". For build instructions see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum(Go)). Ethereum Go is split up in several sub packages Please refer to each individual package for more information. diff --git a/ethutil/config.go b/ethutil/config.go index abe86babe..1b41c4634 100644 --- a/ethutil/config.go +++ b/ethutil/config.go @@ -42,7 +42,7 @@ func ReadConfig(base string, logTypes LoggerType) *config { } } - Config = &config{ExecPath: path, Debug: true, Ver: "0.5.0 RC7"} + Config = &config{ExecPath: path, Debug: true, Ver: "0.5.0 RC8"} Config.Log = NewLogger(logTypes, LogLevelDebug) Config.SetClientString("/Ethereum(G)") }