From 73123bf257934e95e08311d4af9b3382f3dcdb39 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 4 Dec 2014 15:35:21 +0100 Subject: Only set TD if it's actually higher --- core/chain_manager.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'core') diff --git a/core/chain_manager.go b/core/chain_manager.go index 7acd171ec..7d4aeaab6 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -267,7 +267,10 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { } self.add(block) - self.SetTotalDifficulty(td) + if td.Cmp(self.TD) > 0 { + self.SetTotalDifficulty(td) + } + self.eventMux.Post(NewBlockEvent{block}) self.eventMux.Post(messages) } -- cgit From a5b27bbc10d6a145152fc2629043c46ef4a9ca71 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 4 Dec 2014 16:44:43 +0100 Subject: Improved and simplified wallet functions and behaviour --- core/block_manager.go | 10 ++++++---- core/transaction_pool.go | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'core') diff --git a/core/block_manager.go b/core/block_manager.go index c2ffc7ae0..b648166ec 100644 --- a/core/block_manager.go +++ b/core/block_manager.go @@ -123,7 +123,7 @@ func (sm *BlockManager) TransitionState(statedb *state.StateDB, parent, block *t coinbase.SetGasPool(block.CalcGasLimit(parent)) // Process the transactions on to current block - receipts, _, _, _, err = sm.ProcessTransactions(coinbase, statedb, block, parent, block.Transactions()) + receipts, _, _, _, err = sm.ApplyTransactions(coinbase, statedb, block, block.Transactions(), false) if err != nil { return nil, err } @@ -131,7 +131,7 @@ func (sm *BlockManager) TransitionState(statedb *state.StateDB, parent, block *t return receipts, nil } -func (self *BlockManager) ProcessTransactions(coinbase *state.StateObject, state *state.StateDB, block, parent *types.Block, txs types.Transactions) (types.Receipts, types.Transactions, types.Transactions, types.Transactions, error) { +func (self *BlockManager) ApplyTransactions(coinbase *state.StateObject, state *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 @@ -180,7 +180,9 @@ done: receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) // Notify all subscribers - go self.eth.EventMux().Post(TxPostEvent{tx}) + if !transientProcess { + go self.eth.EventMux().Post(TxPostEvent{tx}) + } receipts = append(receipts, receipt) handled = append(handled, tx) @@ -378,7 +380,7 @@ func (sm *BlockManager) AccumelateRewards(statedb *state.StateDB, block, parent account.AddAmount(reward) statedb.Manifest().AddMessage(&state.Message{ - To: block.Coinbase, From: block.Coinbase, + To: block.Coinbase, Input: nil, Origin: nil, Block: block.Hash(), Timestamp: block.Time, Coinbase: block.Coinbase, Number: block.Number, diff --git a/core/transaction_pool.go b/core/transaction_pool.go index abacb14f1..c48d3d8a4 100644 --- a/core/transaction_pool.go +++ b/core/transaction_pool.go @@ -164,7 +164,7 @@ func (self *TxPool) Add(tx *types.Transaction) error { txplogger.Debugf("(t) %x => %x (%v) %x\n", tx.Sender()[:4], tmp, tx.Value, tx.Hash()) // Notify the subscribers - self.Ethereum.EventMux().Post(TxPreEvent{tx}) + go self.Ethereum.EventMux().Post(TxPreEvent{tx}) return nil } -- cgit From 8dbca75d85553f2d9451ee563a919850f05ea1dd Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 4 Dec 2014 23:54:07 +0100 Subject: Skip mining on transactions that don't meet the min accepted gas price --- core/block_manager.go | 28 ++++++++++++---------------- core/transaction_pool.go | 8 ++++---- 2 files changed, 16 insertions(+), 20 deletions(-) (limited to 'core') diff --git a/core/block_manager.go b/core/block_manager.go index b648166ec..909f26a1b 100644 --- a/core/block_manager.go +++ b/core/block_manager.go @@ -231,7 +231,7 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I return } - _, err = sm.TransitionState(state, parent, block) + receipts, err := sm.TransitionState(state, parent, block) if err != nil { return } @@ -242,26 +242,22 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I return } - /* - receiptSha := types.DeriveSha(receipts) - if bytes.Compare(receiptSha, block.ReceiptSha) != 0 { - err = fmt.Errorf("validating receipt root. received=%x got=%x", block.ReceiptSha, receiptSha) - return - } - */ + receiptSha := types.DeriveSha(receipts) + if bytes.Compare(receiptSha, block.ReceiptSha) != 0 { + err = fmt.Errorf("validating receipt root. received=%x got=%x", block.ReceiptSha, receiptSha) + return + } if err = sm.AccumelateRewards(state, block, parent); err != nil { return } - /* - //block.receipts = receipts // although this isn't necessary it be in the future - rbloom := types.CreateBloom(receipts) - if bytes.Compare(rbloom, block.LogsBloom) != 0 { - err = fmt.Errorf("unable to replicate block's bloom=%x", rbloom) - return - } - */ + //block.receipts = receipts // although this isn't necessary it be in the future + rbloom := types.CreateBloom(receipts) + if bytes.Compare(rbloom, block.LogsBloom) != 0 { + err = fmt.Errorf("unable to replicate block's bloom=%x", rbloom) + return + } state.Update(ethutil.Big0) diff --git a/core/transaction_pool.go b/core/transaction_pool.go index c48d3d8a4..1d1f478e4 100644 --- a/core/transaction_pool.go +++ b/core/transaction_pool.go @@ -115,10 +115,6 @@ func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error { return fmt.Errorf("tx.v != (28 || 27)") } - if tx.GasPrice.Cmp(MinGasPrice) < 0 { - return fmt.Errorf("Gas price to low. Require %v > Got %v", MinGasPrice, tx.GasPrice) - } - // Get the sender sender := pool.Ethereum.BlockManager().CurrentState().GetAccount(tx.Sender()) @@ -169,6 +165,10 @@ func (self *TxPool) Add(tx *types.Transaction) error { return nil } +func (self *TxPool) Size() int { + return self.pool.Len() +} + func (pool *TxPool) CurrentTransactions() []*types.Transaction { pool.mutex.Lock() defer pool.mutex.Unlock() -- cgit From d80f8bda940a8ae8f6dab1502a46054c06cee5cc Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 5 Dec 2014 12:32:47 +0100 Subject: Fixed issue in VM where LOG didn't pop anything of the stack --- core/block_manager.go | 13 ++++++------- core/types/bloom9.go | 12 +++++------- core/types/receipt.go | 13 +++++++++++++ 3 files changed, 24 insertions(+), 14 deletions(-) (limited to 'core') diff --git a/core/block_manager.go b/core/block_manager.go index 909f26a1b..4c1cea35a 100644 --- a/core/block_manager.go +++ b/core/block_manager.go @@ -236,6 +236,12 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I return } + rbloom := types.CreateBloom(receipts) + if bytes.Compare(rbloom, block.LogsBloom) != 0 { + err = fmt.Errorf("unable to replicate block's bloom=%x", rbloom) + return + } + txSha := types.DeriveSha(block.Transactions()) if bytes.Compare(txSha, block.TxSha) != 0 { err = fmt.Errorf("validating transaction root. received=%x got=%x", block.TxSha, txSha) @@ -252,13 +258,6 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I return } - //block.receipts = receipts // although this isn't necessary it be in the future - rbloom := types.CreateBloom(receipts) - if bytes.Compare(rbloom, block.LogsBloom) != 0 { - err = fmt.Errorf("unable to replicate block's bloom=%x", rbloom) - return - } - state.Update(ethutil.Big0) if !block.State().Cmp(state) { diff --git a/core/types/bloom9.go b/core/types/bloom9.go index d04656b0d..c1841e553 100644 --- a/core/types/bloom9.go +++ b/core/types/bloom9.go @@ -20,18 +20,16 @@ func CreateBloom(receipts Receipts) []byte { func LogsBloom(logs state.Logs) *big.Int { bin := new(big.Int) for _, log := range logs { - data := [][]byte{log.Address()} - for _, topic := range log.Topics() { - data = append(data, topic) + data := make([][]byte, len(log.Topics())+1) + data[0] = log.Address() + + for i, topic := range log.Topics() { + data[i+1] = topic } for _, b := range data { bin.Or(bin, ethutil.BigD(bloom9(crypto.Sha3(b)).Bytes())) } - - //if log.Data != nil { - // data = append(data, log.Data) - //} } return bin diff --git a/core/types/receipt.go b/core/types/receipt.go index 25fa8fb07..bac64e41d 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -64,5 +64,18 @@ func (self *Receipt) String() string { type Receipts []*Receipt +func (self Receipts) RlpData() interface{} { + data := make([]interface{}, len(self)) + for i, receipt := range self { + data[i] = receipt.RlpData() + } + + return data +} + +func (self Receipts) RlpEncode() []byte { + return ethutil.Encode(self.RlpData()) +} + func (self Receipts) Len() int { return len(self) } func (self Receipts) GetRlp(i int) []byte { return ethutil.Rlp(self[i]) } -- cgit From 9925916851c00323336e213fc18c83da5fceee94 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 5 Dec 2014 16:26:39 +0100 Subject: upped proto version and modified block pool --- core/chain_manager.go | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'core') diff --git a/core/chain_manager.go b/core/chain_manager.go index 7d4aeaab6..150139def 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -125,7 +125,8 @@ func (bc *ChainManager) Reset() { bc.genesisBlock.Trie().Sync() // Prepare the genesis block - bc.add(bc.genesisBlock) + bc.write(bc.genesisBlock) + bc.insert(bc.genesisBlock) bc.CurrentBlock = bc.genesisBlock bc.SetTotalDifficulty(ethutil.Big("0")) @@ -134,18 +135,18 @@ func (bc *ChainManager) Reset() { bc.TD = ethutil.BigD(ethutil.Config.Db.LastKnownTD()) } -// Add a block to the chain and record addition information -func (bc *ChainManager) add(block *types.Block) { - bc.writeBlockInfo(block) - +func (bc *ChainManager) insert(block *types.Block) { + encodedBlock := block.RlpEncode() + ethutil.Config.Db.Put([]byte("LastBlock"), encodedBlock) bc.CurrentBlock = block bc.LastBlockHash = block.Hash() +} + +func (bc *ChainManager) write(block *types.Block) { + bc.writeBlockInfo(block) encodedBlock := block.RlpEncode() ethutil.Config.Db.Put(block.Hash(), encodedBlock) - ethutil.Config.Db.Put([]byte("LastBlock"), encodedBlock) - - //chainlogger.Infof("Imported block #%d (%x...)\n", block.Number, block.Hash()[0:4]) } // Accessors @@ -266,9 +267,14 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { return err } - self.add(block) + self.write(block) if td.Cmp(self.TD) > 0 { + if block.Number.Cmp(new(big.Int).Add(self.CurrentBlock.Number, ethutil.Big1)) < 0 { + chainlogger.Infof("Split detected. New head #%v (%x), was #%v (%x)\n", block.Number, block.Hash()[:4], self.CurrentBlock.Number, self.CurrentBlock.Hash()[:4]) + } + self.SetTotalDifficulty(td) + self.insert(block) } self.eventMux.Post(NewBlockEvent{block}) -- cgit From acf4b5753fd473f048176a12c42e1b8209035b57 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 9 Dec 2014 20:27:57 +0100 Subject: Core changes * Code = '' if gas < len(D) * 5 * Sha3 gas 10 + 10 * len(D), rounding up 32 bytes * Sha256 gas 50 + 50 * len(D), rounding up 32 bytes * Ripmed gas 50 + 50 * len(D), rounding up 32 bytes * Accounts and value transfers no longer reverted --- core/execution.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'core') diff --git a/core/execution.go b/core/execution.go index 9f9d9a5d9..5176f7351 100644 --- a/core/execution.go +++ b/core/execution.go @@ -34,8 +34,14 @@ func (self *Execution) Call(codeAddr []byte, caller vm.ClosureRef) ([]byte, erro func (self *Execution) exec(code, caddr []byte, caller vm.ClosureRef) (ret []byte, err error) { env := self.vm.Env() - chainlogger.Debugf("pre state %x\n", env.State().Root()) + + from, to := env.State().GetStateObject(caller.Address()), env.State().GetOrNewStateObject(self.address) + // Skipping transfer is used on testing for the initial call + if !self.SkipTransfer { + err = env.Transfer(from, to, self.value) + } + snapshot := env.State().Copy() defer func() { if vm.IsDepthErr(err) || vm.IsOOGErr(err) { @@ -44,12 +50,6 @@ func (self *Execution) exec(code, caddr []byte, caller vm.ClosureRef) (ret []byt chainlogger.Debugf("post state %x\n", env.State().Root()) }() - from, to := env.State().GetStateObject(caller.Address()), env.State().GetOrNewStateObject(self.address) - // Skipping transfer is used on testing for the initial call - if !self.SkipTransfer { - err = env.Transfer(from, to, self.value) - } - if err != nil { caller.ReturnGas(self.Gas, self.price) @@ -59,7 +59,7 @@ func (self *Execution) exec(code, caddr []byte, caller vm.ClosureRef) (ret []byt // Pre-compiled contracts (address.go) 1, 2 & 3. naddr := ethutil.BigD(caddr).Uint64() if p := vm.Precompiled[naddr]; p != nil { - if self.Gas.Cmp(p.Gas) >= 0 { + if self.Gas.Cmp(p.Gas(len(self.input))) >= 0 { ret = p.Call(self.input) self.vm.Printf("NATIVE_FUNC(%x) => %x", naddr, ret) self.vm.Endl() -- cgit From 3308491c92ea819826f7606e7a38224e3d2f214a Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 10 Dec 2014 00:09:32 +0100 Subject: Removed tests because they've become obsolete --- core/chain_manager_test.go | 115 --------------------------------------------- 1 file changed, 115 deletions(-) (limited to 'core') diff --git a/core/chain_manager_test.go b/core/chain_manager_test.go index ab43c511d..9a8bc9592 100644 --- a/core/chain_manager_test.go +++ b/core/chain_manager_test.go @@ -1,116 +1 @@ package core - -import ( - "fmt" - "math/big" - "testing" - "time" - - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/ethutil" - "github.com/ethereum/go-ethereum/state" -) - -var TD *big.Int - -func init() { - ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "") - ethutil.Config.Db, _ = ethdb.NewMemDatabase() -} - -type fakeproc struct { -} - -func (self fakeproc) ProcessWithParent(a, b *types.Block) (*big.Int, state.Messages, error) { - TD = new(big.Int).Add(TD, big.NewInt(1)) - return TD, nil, nil -} - -func makechain(cman *ChainManager, max int) *BlockChain { - blocks := make(types.Blocks, max) - for i := 0; i < max; i++ { - addr := ethutil.LeftPadBytes([]byte{byte(i)}, 20) - block := cman.NewBlock(addr) - if i != 0 { - cman.CurrentBlock = blocks[i-1] - } - blocks[i] = block - } - return NewChain(blocks) -} - -func TestLongerFork(t *testing.T) { - cman := NewChainManager() - cman.SetProcessor(fakeproc{}) - - TD = big.NewInt(1) - chainA := makechain(cman, 5) - - TD = big.NewInt(1) - chainB := makechain(cman, 10) - - td, err := cman.TestChain(chainA) - if err != nil { - t.Error("unable to create new TD from chainA:", err) - } - cman.TD = td - - _, err = cman.TestChain(chainB) - if err != nil { - t.Error("expected chainB not to give errors:", err) - } -} - -func TestEqualFork(t *testing.T) { - cman := NewChainManager() - cman.SetProcessor(fakeproc{}) - - TD = big.NewInt(1) - chainA := makechain(cman, 5) - - TD = big.NewInt(2) - chainB := makechain(cman, 5) - - td, err := cman.TestChain(chainA) - if err != nil { - t.Error("unable to create new TD from chainA:", err) - } - cman.TD = td - - _, err = cman.TestChain(chainB) - if err != nil { - t.Error("expected chainB not to give errors:", err) - } -} - -func TestBrokenChain(t *testing.T) { - cman := NewChainManager() - cman.SetProcessor(fakeproc{}) - - TD = big.NewInt(1) - chain := makechain(cman, 5) - chain.Remove(chain.Front()) - - _, err := cman.TestChain(chain) - if err == nil { - t.Error("expected broken chain to return error") - } -} - -func BenchmarkChainTesting(b *testing.B) { - const chainlen = 1000 - - ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "") - ethutil.Config.Db, _ = ethdb.NewMemDatabase() - - cman := NewChainManager() - cman.SetProcessor(fakeproc{}) - - TD = big.NewInt(1) - chain := makechain(cman, chainlen) - - stime := time.Now() - cman.TestChain(chain) - fmt.Println(chainlen, "took", time.Since(stime)) -} -- cgit From 1b98cbbfa4f587107fa15fccde7d22102ea4b1c0 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 10 Dec 2014 16:45:16 +0100 Subject: Moved pow --- core/block_manager.go | 8 +++-- core/dagger.go | 85 --------------------------------------------------- core/simple_pow.go | 1 + core/types/block.go | 3 ++ 4 files changed, 9 insertions(+), 88 deletions(-) create mode 100644 core/simple_pow.go (limited to 'core') diff --git a/core/block_manager.go b/core/block_manager.go index 4c1cea35a..6f952f9f8 100644 --- a/core/block_manager.go +++ b/core/block_manager.go @@ -14,6 +14,8 @@ import ( "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/pow" + "github.com/ethereum/go-ethereum/pow/ezp" "github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/wire" ) @@ -55,7 +57,7 @@ type BlockManager struct { // non-persistent key/value memory storage mem map[string]*big.Int // Proof of work used for validating - Pow PoW + Pow pow.PoW // The ethereum manager interface eth EthManager // The managed states @@ -78,7 +80,7 @@ type BlockManager struct { func NewBlockManager(ethereum EthManager) *BlockManager { sm := &BlockManager{ mem: make(map[string]*big.Int), - Pow: &EasyPow{}, + Pow: ezp.New(), eth: ethereum, bc: ethereum.ChainManager(), } @@ -327,7 +329,7 @@ func (sm *BlockManager) ValidateBlock(block, parent *types.Block) error { */ // Verify the nonce of the block. Return an error if it's not valid - if !sm.Pow.Verify(block.HashNoNonce(), block.Difficulty, block.Nonce) { + if !sm.Pow.Verify(block /*block.HashNoNonce(), block.Difficulty, block.Nonce*/) { return ValidationError("Block's nonce is invalid (= %v)", ethutil.Bytes2Hex(block.Nonce)) } diff --git a/core/dagger.go b/core/dagger.go index 8a042b34f..3039d8995 100644 --- a/core/dagger.go +++ b/core/dagger.go @@ -6,8 +6,6 @@ import ( "math/rand" "time" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/logger" "github.com/obscuren/sha3" @@ -15,89 +13,6 @@ import ( var powlogger = logger.NewLogger("POW") -type PoW interface { - Search(block *types.Block, stop <-chan struct{}) []byte - Verify(hash []byte, diff *big.Int, nonce []byte) bool - GetHashrate() int64 - Turbo(bool) -} - -type EasyPow struct { - hash *big.Int - HashRate int64 - turbo bool -} - -func (pow *EasyPow) GetHashrate() int64 { - return pow.HashRate -} - -func (pow *EasyPow) Turbo(on bool) { - pow.turbo = on -} - -func (pow *EasyPow) Search(block *types.Block, stop <-chan struct{}) []byte { - r := rand.New(rand.NewSource(time.Now().UnixNano())) - hash := block.HashNoNonce() - diff := block.Difficulty - i := int64(0) - start := time.Now().UnixNano() - t := time.Now() - - for { - select { - case <-stop: - powlogger.Infoln("Breaking from mining") - pow.HashRate = 0 - return nil - default: - i++ - - if time.Since(t) > (1 * time.Second) { - elapsed := time.Now().UnixNano() - start - hashes := ((float64(1e9) / float64(elapsed)) * float64(i)) / 1000 - pow.HashRate = int64(hashes) - powlogger.Infoln("Hashing @", pow.HashRate, "khash") - - t = time.Now() - } - - sha := crypto.Sha3(big.NewInt(r.Int63()).Bytes()) - if pow.Verify(hash, diff, sha) { - return sha - } - } - - if !pow.turbo { - time.Sleep(20 * time.Microsecond) - } - } - - return nil -} - -func (pow *EasyPow) Verify(hash []byte, diff *big.Int, nonce []byte) bool { - sha := sha3.NewKeccak256() - - d := append(hash, nonce...) - sha.Write(d) - - verification := new(big.Int).Div(ethutil.BigPow(2, 256), diff) - res := ethutil.U256(ethutil.BigD(sha.Sum(nil))) - - /* - fmt.Printf("hash w/o nonce %x\n", hash) - fmt.Printf("2**256 / %v = %v\n", diff, verification) - fmt.Printf("%v <= %v\n", res, verification) - fmt.Printf("vlen: %d rlen: %d\n", len(verification.Bytes()), len(res.Bytes())) - */ - - return res.Cmp(verification) <= 0 -} - -func (pow *EasyPow) SetHash(hash *big.Int) { -} - type Dagger struct { hash *big.Int xn *big.Int diff --git a/core/simple_pow.go b/core/simple_pow.go new file mode 100644 index 000000000..9a8bc9592 --- /dev/null +++ b/core/simple_pow.go @@ -0,0 +1 @@ +package core diff --git a/core/types/block.go b/core/types/block.go index 55ce1fb9b..0108bd586 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -411,3 +411,6 @@ func (self *Block) Size() ethutil.StorageSize { func (self *Block) RlpData() interface{} { return self.Value().Val } + +// Implement pow.Block +func (self *Block) N() []byte { return self.Nonce } -- cgit From af6afbaa56efa15abe6a03665c6674b0e2f591c8 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 10 Dec 2014 16:48:39 +0100 Subject: Removed start/stop methods --- core/block_manager.go | 22 ---------------------- 1 file changed, 22 deletions(-) (limited to 'core') diff --git a/core/block_manager.go b/core/block_manager.go index 6f952f9f8..80b2542b5 100644 --- a/core/block_manager.go +++ b/core/block_manager.go @@ -90,14 +90,6 @@ func NewBlockManager(ethereum EthManager) *BlockManager { return sm } -func (self *BlockManager) Start() { - statelogger.Debugln("Starting block manager") -} - -func (self *BlockManager) Stop() { - statelogger.Debugln("Stopping state manager") -} - func (sm *BlockManager) CurrentState() *state.StateDB { return sm.eth.ChainManager().CurrentBlock.State() } @@ -106,20 +98,6 @@ func (sm *BlockManager) TransState() *state.StateDB { return sm.transState } -func (sm *BlockManager) MiningState() *state.StateDB { - return sm.miningState -} - -func (sm *BlockManager) NewMiningState() *state.StateDB { - sm.miningState = sm.eth.ChainManager().CurrentBlock.State().Copy() - - return sm.miningState -} - -func (sm *BlockManager) ChainManager() *ChainManager { - return sm.bc -} - func (sm *BlockManager) TransitionState(statedb *state.StateDB, parent, block *types.Block) (receipts types.Receipts, err error) { coinbase := statedb.GetOrNewStateObject(block.Coinbase) coinbase.SetGasPool(block.CalcGasLimit(parent)) -- cgit From 5553e5aaed5c3f4e303b7d6671d2c92a45aa487e Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 10 Dec 2014 19:59:12 +0100 Subject: states moved to chain --- core/block_manager.go | 10 ---------- core/chain_manager.go | 13 +++++++++++++ core/transaction_pool.go | 2 +- 3 files changed, 14 insertions(+), 11 deletions(-) (limited to 'core') diff --git a/core/block_manager.go b/core/block_manager.go index 80b2542b5..7227c6f95 100644 --- a/core/block_manager.go +++ b/core/block_manager.go @@ -84,20 +84,10 @@ func NewBlockManager(ethereum EthManager) *BlockManager { eth: ethereum, bc: ethereum.ChainManager(), } - sm.transState = ethereum.ChainManager().CurrentBlock.State().Copy() - sm.miningState = ethereum.ChainManager().CurrentBlock.State().Copy() return sm } -func (sm *BlockManager) CurrentState() *state.StateDB { - return sm.eth.ChainManager().CurrentBlock.State() -} - -func (sm *BlockManager) TransState() *state.StateDB { - return sm.transState -} - func (sm *BlockManager) TransitionState(statedb *state.StateDB, parent, block *types.Block) (receipts types.Receipts, err error) { coinbase := statedb.GetOrNewStateObject(block.Coinbase) coinbase.SetGasPool(block.CalcGasLimit(parent)) diff --git a/core/chain_manager.go b/core/chain_manager.go index 150139def..0322edaa5 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -8,6 +8,7 @@ import ( "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/state" ) var chainlogger = logger.NewLogger("CHAIN") @@ -55,6 +56,8 @@ type ChainManager struct { CurrentBlock *types.Block LastBlockHash []byte + + transState *state.StateDB } func NewChainManager(mux *event.TypeMux) *ChainManager { @@ -64,6 +67,8 @@ func NewChainManager(mux *event.TypeMux) *ChainManager { bc.setLastBlock() + bc.transState = bc.State().Copy() + return bc } @@ -71,6 +76,14 @@ func (self *ChainManager) SetProcessor(proc types.BlockProcessor) { self.processor = proc } +func (self *ChainManager) State() *state.StateDB { + return self.CurrentBlock.State() +} + +func (self *ChainManager) TransState() *state.StateDB { + return self.transState +} + func (bc *ChainManager) setLastBlock() { data, _ := ethutil.Config.Db.Get([]byte("LastBlock")) if len(data) != 0 { diff --git a/core/transaction_pool.go b/core/transaction_pool.go index 1d1f478e4..7166d35e8 100644 --- a/core/transaction_pool.go +++ b/core/transaction_pool.go @@ -116,7 +116,7 @@ func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error { } // Get the sender - sender := pool.Ethereum.BlockManager().CurrentState().GetAccount(tx.Sender()) + sender := pool.Ethereum.ChainManager().State().GetAccount(tx.Sender()) totAmount := new(big.Int).Set(tx.Value) // Make sure there's enough in the sender's account. Having insufficient -- cgit From 2b5fcb464262a7bdd766861b513b2a23706f8b13 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 10 Dec 2014 20:26:55 +0100 Subject: moved interfaces --- core/block_manager.go | 23 ++++++++--------------- core/chain_manager.go | 2 ++ 2 files changed, 10 insertions(+), 15 deletions(-) (limited to 'core') diff --git a/core/block_manager.go b/core/block_manager.go index 7227c6f95..f6c73bc2c 100644 --- a/core/block_manager.go +++ b/core/block_manager.go @@ -60,14 +60,6 @@ type BlockManager struct { Pow pow.PoW // The ethereum manager interface eth EthManager - // The managed states - // Transiently state. The trans state isn't ever saved, validated and - // it could be used for setting account nonces without effecting - // the main states. - transState *state.StateDB - // Mining state. The mining state is used purely and solely by the mining - // operation. - miningState *state.StateDB // The last attempted block is mainly used for debugging purposes // This does not have to be a valid block and will be set during @@ -75,14 +67,17 @@ type BlockManager struct { lastAttemptedBlock *types.Block events event.Subscription + + eventMux *event.TypeMux } func NewBlockManager(ethereum EthManager) *BlockManager { sm := &BlockManager{ - mem: make(map[string]*big.Int), - Pow: ezp.New(), - eth: ethereum, - bc: ethereum.ChainManager(), + mem: make(map[string]*big.Int), + Pow: ezp.New(), + eth: ethereum, + bc: ethereum.ChainManager(), + eventMux: ethereum.EventMux(), } return sm @@ -151,7 +146,7 @@ done: // Notify all subscribers if !transientProcess { - go self.eth.EventMux().Post(TxPostEvent{tx}) + go self.eventMux.Post(TxPostEvent{tx}) } receipts = append(receipts, receipt) @@ -245,8 +240,6 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I chainlogger.Infof("Processed block #%d (%x...)\n", block.Number, block.Hash()[0:4]) - sm.transState = state.Copy() - sm.eth.TxPool().RemoveSet(block.Transactions()) return td, messages, nil diff --git a/core/chain_manager.go b/core/chain_manager.go index 0322edaa5..edf50e715 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -288,6 +288,8 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { self.SetTotalDifficulty(td) self.insert(block) + self.transState = self.State().Copy() + //sm.eth.TxPool().RemoveSet(block.Transactions()) } self.eventMux.Post(NewBlockEvent{block}) -- cgit From 0d57ca486a4db9f2488df5f6be47eb9b09df2004 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 12 Dec 2014 11:34:27 +0100 Subject: Squashed commit of the following: commit 779f25d36c770fcc0bdf135c8baf13be9b0a77b9 Author: CJentzsch Date: Thu Dec 11 22:59:56 2014 +0100 first random test commit 68175386c0606a824686606e992c2544775ef6c9 Author: CJentzsch Date: Thu Dec 11 21:34:50 2014 +0100 update gas prices commit ad322fbb58e87ee5175cfaf4b8f9650675660e08 Author: CJentzsch Date: Mon Dec 8 06:01:17 2014 +0100 Log as array commit f989f42618ffdaeb004c2c99007189b4739c8fad Author: CJentzsch Date: Fri Dec 5 15:12:12 2014 +0100 state log tests commit 4bc65d1129efa36eae3c83fa8f11bb7df9bcaea5 Author: CJentzsch Date: Thu Dec 4 18:18:49 2014 +0100 add calldataload, codecopy, extcodecopy tests commit 12cfae18e3e5250cca9af0932bd4178cf190b794 Author: CJentzsch Date: Thu Dec 4 15:57:56 2014 +0100 add calldataload test commit 086caf37011478ec847c7a9071f057832ad3be3e Author: CJentzsch Date: Wed Dec 3 08:31:03 2014 +0100 protocol update (CALLCODE <-> RETURN), topics in log are arrays not sets commit e6c92673b9cee6146a89e0eb28894620fe5ac035 Author: CJentzsch Date: Mon Dec 1 21:14:08 2014 +0100 update state tests with logs commit 4089b809fb9b5daea24ab88ad3e3e3947b3ff6d7 Author: CJentzsch Date: Mon Dec 1 18:19:40 2014 +0100 update gas costs commit cfdca6227716b66bd64b64c6aab864fde69336d3 Merge: 2e5175e f59f89d Author: Christoph Jentzsch Date: Mon Dec 1 18:04:51 2014 +0100 Merge pull request #42 from negedzuregal/fix vmTest fix commit f59f89d876c0e44d88b3daa4f0d26e6764ccbe0b Author: alon muroch Date: Mon Dec 1 16:18:12 2014 +0100 vmEnvironmentalInfoTest CALLDATACOPY, CODECOPY, EXTCODECOPY fix commit 68da13fe3e2efe85898e8a4ffeb99e2a8f8c103d Author: alon muroch Date: Mon Dec 1 11:10:57 2014 +0100 vmArithmeticTest exp fix commit 2e5175e818d817cda4607f9e731632393e2eb93e Author: ethers Date: Sun Nov 30 19:55:51 2014 +0100 add vmLogTest commit b5b9408e641031ded31a87792c4ec613c8afabbf Author: Heiko Heiko Date: Sun Nov 30 16:27:27 2014 +0100 updated genesis to new header w/o min_gas_price commit 8e69fbfa98d95116734f2349f6d90fbd479b694a Author: ethers Date: Fri Nov 21 17:42:05 2014 -0800 add special tests commit 90f4f942e68f38e833a727214d5810be3f8f6cf5 Author: ethers Date: Thu Nov 20 19:01:09 2014 -0800 typo commit c5e5228e0d47ec237ef6a28e696dda47a4a3a85e Author: Christoph Jentzsch Date: Thu Nov 20 17:04:06 2014 +0100 Removed log,post,out,gas,callcreates if exception occured commit 9c0232a2b995bd608f5f541e6f607d373797641d Author: Christoph Jentzsch Date: Wed Nov 19 18:19:05 2014 +0100 MakeMoney test commit 3ba0007e868e9cfc802443d6f5d42ba35a4209cb Author: Christoph Jentzsch Date: Wed Nov 19 16:23:04 2014 +0100 Added log sections in all vmtests + log tests commit d84be4fe07bb240c1ae56f63580e0e4655611e62 Merge: c8497ab 76d2542 Author: Christoph Jentzsch Date: Wed Nov 19 10:00:24 2014 +0100 Merge remote-tracking branch 'origin/develop' into develop commit c8497ab25724bb6aed40fcd0462f3789380848a1 Author: Christoph Jentzsch Date: Wed Nov 19 10:00:02 2014 +0100 new push32 test and renaming commit 76d25420e153e18c667aa4991dcacf12e8f4fb5c Author: ethers Date: Mon Nov 17 18:59:30 2014 -0800 adding test commit 0be275e757744de496a80525ad8aa153def89fd3 Merge: 1d42d1d d90868c Author: Christoph Jentzsch Date: Mon Nov 17 22:47:34 2014 +0100 Merge remote-tracking branch 'origin/develop' into develop commit 1d42d1d7c620fb3e6d0e284697d5041226567af9 Author: Christoph Jentzsch Date: Mon Nov 17 22:46:51 2014 +0100 fix ecrecover2 commit d90868c3070624bc38668a0f3ceef3e3806d9f00 Merge: 1f38c8c 6dbcf6b Author: Christoph Jentzsch Date: Mon Nov 17 20:26:59 2014 +0100 Merge pull request #39 from wanderer/develop added test for max call depth on creation commit 6dbcf6b0d6bb68ceaa743e18a52ac815f495d408 Author: wanderer Date: Mon Nov 17 14:06:43 2014 -0500 spelling fix commit 6fc07a7f81408308e56db105afcad191f81c43bc Author: wanderer Date: Sat Nov 15 21:39:16 2014 -0500 added test for max call depth on creation commit 1f38c8c0a2e306fa95e8332c03a02e72fe26f9be Merge: 279b284 cd85ca1 Author: martin becze Date: Fri Nov 14 20:10:21 2014 -0500 Merge pull request #38 from wanderer/develop updated test 'jeff' in trietest.json commit cd85ca17edd314b3744c46573f1d5093e9be2db3 Author: martin becze Date: Fri Nov 14 19:59:34 2014 -0500 Update trietest.json commit 279b284c0d03737360ae36ce2c0da06d70e91c2c Merge: 89675a7 6cae937 Author: martin becze Date: Fri Nov 14 17:43:49 2014 -0500 Merge pull request #37 from wanderer/develop Update trietest.json commit 6cae937e5eee1c904b636440653b6157359c0963 Author: martin becze Date: Fri Nov 14 17:20:03 2014 -0500 Update trietest.json 'emptyValues' should have the same root as 'puppy' commit 89675a71537e6a386f97a9190db40276b388d692 Merge: f1de1cc 32f0c47 Author: Christoph Jentzsch Date: Thu Nov 13 23:17:49 2014 +0100 Merge remote-tracking branch 'origin/develop' into develop commit f1de1cc97a556adad8a4a864267150c39bef4d85 Author: Christoph Jentzsch Date: Thu Nov 13 23:17:13 2014 +0100 Fix CallRecursiveBomb2 commit 32f0c47c6801974c210c3b93792105a9183f9e7b Merge: ab50e76 3da90d0 Author: martin becze Date: Thu Nov 13 15:26:49 2014 -0500 Merge pull request #36 from wanderer/develop converted back to arrary format commit ab50e766521ca31febe21677909a665043937488 Merge: d06b792 78f1e4a Author: Christoph Jentzsch Date: Thu Nov 13 07:52:35 2014 +0100 Merge pull request #35 from ethers/delOld rename tests since they are valid opcodes that exist commit 3da90d01f6f9e79190ebcd3a6513f481eacbbae2 Author: wanderer Date: Wed Nov 12 22:22:47 2014 -0500 converted back to arrary format commit 78f1e4a9452566f5645a7f5ade6aad79901d5f98 Author: ethers Date: Wed Nov 12 19:11:06 2014 -0800 rename tests since they are valid opcodes that exist commit d06b792cd0c80d48aa206dd9126b515e4fb1d606 Author: Christoph Jentzsch Date: Wed Nov 12 07:00:17 2014 +0100 minor change in CallSha256_1_nonzeroValue test commit d434ecdcc37af4bb53058a43884df8085c5efe73 Author: Christoph Jentzsch Date: Wed Nov 12 06:56:31 2014 +0100 Added CallSha256_1_nonzeroValue test commit 2c06f34cc00e6c41dc0c68d3e99825731e0603ab Author: Christoph Jentzsch Date: Tue Nov 11 18:10:26 2014 +0100 Store return value of call to precompiled contracts commit 4b0c3b29ae5b8807d7d244340a625c6144320df0 Author: Christoph Jentzsch Date: Tue Nov 11 17:51:14 2014 +0100 Fix gas cost for OOG calls commit 63bcca7604dce4f912776f4e2e9954ceca02dfcf Author: Heiko Heiko Date: Tue Nov 11 08:59:19 2014 +0100 fix: genesis test commit 6e0310c1ea7b0f8af7a337df93b3b83591a6e647 Merge: 30c266c 2927763 Author: Christoph Jentzsch Date: Tue Nov 11 08:34:36 2014 +0100 Merge remote-tracking branch 'origin/develop' into develop commit 30c266caff8c253438e542a81501a313c3c06eaf Author: Christoph Jentzsch Date: Tue Nov 11 08:33:59 2014 +0100 jump to position outside code stops execution commit 2927763d68df91c16a4a463a3fbb91a2e67e22e9 Author: ethers Date: Mon Nov 10 14:10:22 2014 -0800 RandomTests were removed commit a0fa91b2b82c2a4b97e08d7e9b32abc1188d0ce0 Merge: 6092484 fcba866 Author: Christoph Jentzsch Date: Mon Nov 10 22:22:05 2014 +0100 Merge branch 'develop' of https://github.com/ethereum/tests into develop commit 60924843f07f394c8e95782ab52d56ef27d5e642 Author: Christoph Jentzsch Date: Mon Nov 10 22:21:37 2014 +0100 Unintended Exceptions work like OOG commit fcba86672193d6bd19ab2104432348eff3f353f2 Author: ethers Date: Thu Nov 6 14:19:59 2014 -0800 add StateTests commit a441074ba4b057e2918735f7427841b92aa3c16e Author: Christoph Jentzsch Date: Thu Nov 6 17:54:36 2014 +0100 Updated precompiled contracts test commit 0afa72c82be2f4996d1662dfbf9e019c5267c6b1 Author: Christoph Jentzsch Date: Thu Nov 6 15:27:45 2014 +0100 Added precompiledContracts tests commit 6be83dd5a185048cfdb8ec29659f14abaeab0c42 Author: Christoph Jentzsch Date: Thu Nov 6 13:31:34 2014 +0100 Update gas cost for PoC7 commit c18b8ab2d3462e813b731e525afc9ea414d8d136 Merge: 66c2e1f 9a93258 Author: Christoph Jentzsch Date: Thu Nov 6 09:19:53 2014 +0100 Merge remote-tracking branch 'origin/develop' into develop commit 66c2e1f642a7b37d9f3631e4573100b0cdc36cef Author: Christoph Jentzsch Date: Thu Nov 6 09:19:22 2014 +0100 Updated SIGNEXTEND tests commit 9a9325822e756dafce8d7418bd4fda63acf84d2d Author: ethers Date: Wed Nov 5 16:20:26 2014 -0800 part of 9b4e768 - Delete vmNamecoin.json commit e229374f467452bf82fd0cc86b18f224dabfadfa Merge: 189527e 9b4e768 Author: Christoph Jentzsch Date: Wed Nov 5 20:59:49 2014 +0100 Merge remote-tracking branch 'origin/develop' into develop commit 189527e563a6e7a39654a9544a2b0d873be7176f Author: Christoph Jentzsch Date: Wed Nov 5 20:59:20 2014 +0100 added dynamic jump out of code commit 9b4e7689951e50c7de3bd945784b92242ed8fd63 Author: Christoph Jentzsch Date: Wed Nov 5 20:41:54 2014 +0100 Delete vmNamecoin.json commit 4669b5694b9dc7bdf9e6f527323dff612b65634d Merge: a567fed aaba185 Author: Christoph Jentzsch Date: Wed Nov 5 15:00:12 2014 +0100 Merge remote-tracking branch 'origin/develop' into develop commit a567fedaa7f8ff8904bd90447fc4b68685bf2af9 Author: Christoph Jentzsch Date: Wed Nov 5 14:59:08 2014 +0100 added state systemOperationsTest commit aaba185ceb0e4c37151134f3e1ded9714d6b7685 Merge: 79d7cbf fa782ae Author: ethers Date: Tue Nov 4 12:15:40 2014 -0800 Merge pull request #32 from ethers/indexjs updates needed per restructure commit fa782aed93934eb51347d08facea838bb4262b1b Author: ethers Date: Tue Nov 4 11:28:56 2014 -0800 updates needed per restructure commit 79d7cbfc4a9cf3d70ae01dea8ee76c770af33211 Merge: 9120274 1c1ba8d Author: Christoph Jentzsch Date: Tue Nov 4 13:32:11 2014 +0100 Merge remote-tracking branch 'origin/develop' into develop commit 9120274a46d696cda6d595b2ec5acc2947eb2b46 Author: Christoph Jentzsch Date: Tue Nov 4 13:31:27 2014 +0100 Update tests to latest protocol changes (PoC7) commit 1c1ba8d161817b391ea296391ad3ede3e71c0aa1 Merge: 014d370 3aebe53 Author: Christoph Jentzsch Date: Tue Nov 4 13:30:52 2014 +0100 Merge pull request #31 from CJentzsch/develop Restructered tests in folders in accordance to test suites commit 3aebe532e536eb6f6766ccac456c07023ab822e1 Author: Christoph Jentzsch Date: Mon Nov 3 13:58:21 2014 +0100 Updated vmNamecoin.json to new sstore prices commit 8a0be21839cf8bb7d3d80a2b61c8433b5d3a8bfd Author: Christoph Jentzsch Date: Mon Nov 3 13:53:00 2014 +0100 Added example state test commit 83643addbc3d50c6a79611a5d8700aad5fb1df16 Author: Christoph Jentzsch Date: Mon Nov 3 13:36:25 2014 +0100 removed systemoperationstests commit 3930ca3a9a377107d5792b3e7202f79c688f1a67 Author: Christoph Jentzsch Date: Mon Nov 3 13:22:15 2014 +0100 Restructered tests in folders in accordance to test suites commit 014d370b5d5d0a807cc31a2fc3a8c5313ccd7ea4 Author: Christoph Jentzsch Date: Wed Oct 29 21:23:56 2014 +0100 New SIGNEXTEND tets commit 155d449be206f5276f689770006ecbbb203dd6ad Author: Christoph Jentzsch Date: Wed Oct 29 20:59:05 2014 +0100 New tests for BNOT and SIGNEXTEND commit c9eae764b8921a5d6c929b8544cb9acdb920453c Author: Christoph Jentzsch Date: Tue Oct 28 12:58:27 2014 +0100 Update SSTORE gas cost and BNOT instead of NEG commit ad2a75ac58ddcb06316f68d0fdaa8e80828a990c Author: Christoph Jentzsch Date: Thu Oct 23 16:05:49 2014 +0200 Added new recursive bombs commit 834c52af6406b9af429104408ca7bcbc525efe5c Author: Christoph Jentzsch Date: Thu Oct 23 12:01:05 2014 +0200 Changing gas cost to zero at stackunderflow commit c73a8a89d23cbdaf80875667437d57c3ee32f08a Author: Jeffrey Wilcke Date: Wed Oct 22 13:04:45 2014 +0200 Reverted back to original value. commit b9a8c924227996ef281d44ccfcc72c7618027f91 Author: martin becze Date: Tue Oct 21 17:02:52 2014 -0400 fix spelling error commit b48ae74af441c00cdce487416be448b0df3d4323 Author: Christoph Jentzsch Date: Tue Oct 21 17:26:26 2014 +0200 Added failing random tests commit bee0a4100c69cabfa361e36831ec0f64187188f3 Merge: 5050d20 b315da6 Author: Christoph Jentzsch Date: Tue Oct 21 17:15:05 2014 +0200 Merge remote-tracking branch 'origin/master' into develop commit 5050d20b4d0321e3e4ea2f118781c7bb96a3d7b5 Merge: 7516685 ba35362 Author: Christoph Jentzsch Date: Mon Oct 20 20:18:20 2014 +0200 Merge pull request #26 from wanderer/develop Add a package.json for node.js commit ba35362876caa03b11c7ce777d959b99accbcfb0 Author: wanderer Date: Sun Oct 19 23:59:47 2014 -0400 turned tests into a node module commit 751668571e390e6bceb515d082222aa31b5e5b14 Author: ethers Date: Thu Oct 16 17:08:20 2014 -0700 json was invalid and missing quotes commit 0e687cee479acfd82861e13d2022ad430fc78d78 Author: Jeffrey Wilcke Date: Thu Oct 16 17:13:24 2014 +0200 Update vmEnvironmentalInfoTest.json commit 78a78e2e6cffb9357f2281070d83bf869ab8b2f4 Author: Christoph Jentzsch Date: Wed Oct 15 14:19:11 2014 +0200 updated genesis_hash commit b315da618b55b581ba8e87f83b2ab5175841392e Merge: 7a7e198 0a76a3a Author: Christoph Jentzsch Date: Tue Oct 14 10:33:26 2014 +0200 Merge pull request #23 from ethers/fix22 numbers should be strings #22 commit 0a76a3a312951e852509e2b378b2b5b3f87135b0 Author: ethers Date: Mon Oct 13 14:45:30 2014 -0700 numbers should be strings #22 commit 1f67385f130422588f92341fe82c2435b160fe84 Author: Christoph Jentzsch Date: Sat Oct 11 13:18:00 2014 +0200 Added some MUL tests commit 7a7e198395f776d0a95d252ddc3b30492b9d3cff Author: Christoph Jentzsch Date: Sat Oct 11 13:11:59 2014 +0200 Added some MUL tests commit 46eb6283ae6c147f7efa910dadc18a504b6725ed Author: Christoph Jentzsch Date: Sat Oct 11 12:18:13 2014 +0200 tested new opcodes (JUMPDEST,CALLCODE) and created test for CALL/CREATE depth commit 8d38d62d1053ed7552211105e26b2e248a3db747 Author: Nick Savers Date: Fri Oct 10 18:09:41 2014 +0200 INVALID stops the operation and doesn't cost gas commit ed6eba7c8ebc0cbb65ccd45b047823f9acc1471b Author: Christoph Jentzsch Date: Wed Oct 8 19:08:48 2014 +0200 Update + ABA recursive bomb which needs maximum recursion limit of 1024 commit 2d72050db1c67d9d6912ce6ade80dbe5685749ff Author: Christoph Jentzsch Date: Wed Oct 8 14:37:18 2014 +0200 Applied recent protocol changes (PoC7) to existin tests commit dfe66cab3fb533003ddaec7250d8fffbf3fbad65 Merge: 4513623 1a67a96 Author: Christoph Jentzsch Date: Wed Oct 8 11:05:51 2014 +0200 Merge remote-tracking branch 'origin/develop' Conflicts: genesishashestest.json commit 1a67a96cff2fba02e57a82d65007cec99dcc313c Merge: a4f5f45 ffd6bc9 Author: vbuterin Date: Tue Oct 7 15:10:23 2014 +0100 Merge pull request #18 from CJentzsch/develop CallToNameRegistratorOutOfGas balance correction commit ffd6bc97adfbc83b6e0c50cdf072fd58f94ace69 Merge: a4f5f45 9779d67 Author: Christoph Jentzsch Date: Tue Oct 7 15:47:34 2014 +0200 Merge remote-tracking branch 'origin/develop' into develop commit 9779d67b8cdf4e99818a5eeadbc3aebd7527b1a9 Author: Christoph Jentzsch Date: Tue Oct 7 15:45:53 2014 +0200 CallToNameRegistratorOutOfGas balance correction Even if execution fails, the value gets transferred. commit a4f5f45228b6f3ebf8ea77c47515149a3df2bc24 Merge: 49a9f47 b6d7cba Author: vbuterin Date: Tue Oct 7 14:13:12 2014 +0100 Merge pull request #17 from CJentzsch/develop Added A calls B calls A contracts commit b6d7cba49914362297c0fcac48d868ffe3bdf06a Merge: 865cb40 49a9f47 Author: Christoph Jentzsch Date: Tue Oct 7 15:02:51 2014 +0200 Merge remote-tracking branch 'upstream/develop' into develop commit 865cb4083d33de2a9115ee39c73aea56b0c34fe8 Author: Christoph Jentzsch Date: Tue Oct 7 15:02:36 2014 +0200 Added A calls B calls A contracts commit 49a9f47aec2dbd6e321298947929b3d0b5abc280 Merge: 3b0ec43 94a493b Author: Jeffrey Wilcke Date: Tue Oct 7 10:56:17 2014 +0200 Merge pull request #16 from CJentzsch/develop corrected amount of used gas for CallToNameRegistratorOutOfGas commit 94a493b0d94163e3de96e1c4bb389ef745756f30 Merge: 72853c4 3b0ec43 Author: Christoph Jentzsch Date: Tue Oct 7 10:51:32 2014 +0200 Merge remote-tracking branch 'upstream/develop' into develop commit 72853c4382fa1b51e384223da34427d3579fe48a Author: Christoph Jentzsch Date: Tue Oct 7 10:51:07 2014 +0200 corrected amount of used gas for CallToNameRegistratorOutOfGas commit 3b0ec436e4c6808f98f1bc5bb5c66b4d2be4b4be Merge: aec3252 222068b Author: vbuterin Date: Tue Oct 7 05:52:43 2014 +0100 Merge pull request #15 from CJentzsch/develop corrected tests and different style for storage commit 222068b9bac6c386e499cb6b0fc2af562fcd309e Merge: c169653 aec3252 Author: Christoph Jentzsch Date: Mon Oct 6 21:17:28 2014 +0200 Merge remote-tracking branch 'upstream/develop' into develop commit c1696531a646309b2b286abb7552eb05f1278cd1 Author: Christoph Jentzsch Date: Mon Oct 6 21:17:09 2014 +0200 corrected tests and different style for storage commit aec3252b8e9f6d37b5cf3dbe0c1678e08929d291 Merge: 25f9fd5 e17a909 Author: vbuterin Date: Mon Oct 6 09:39:46 2014 +0100 Merge pull request #14 from CJentzsch/develop corrected gas limit in vmSystemOperationsTest commit e17a909f70af18fbfc0216c061a663e8778e7d5c Merge: 33fcab5 25f9fd5 Author: Christoph Jentzsch Date: Mon Oct 6 10:31:51 2014 +0200 Merge remote-tracking branch 'upstream/develop' into develop commit 33fcab57273731f449e9504d15c5d22cbe773e2a Author: Christoph Jentzsch Date: Mon Oct 6 10:30:04 2014 +0200 Bug fix, corrected gasLimit in vmSystemOperationsTest commit 25f9fd542a4ab27a5a66668a72b84d4bf7c292e6 Author: Vitalik Buterin Date: Sat Oct 4 15:47:00 2014 -0400 one more vm test commit 2d561a5373faf392e51f8c579c936549db2966d3 Author: Vitalik Buterin Date: Sat Oct 4 15:15:37 2014 -0400 separated out vmtests commit b0c48fa8d69ae02e01931a5675fc58ff9e84aba3 Merge: cb8261a 6cae166 Author: vbuterin Date: Sat Oct 4 17:18:02 2014 +0100 Merge pull request #13 from CJentzsch/develop Added comprehensive EVM test suite. All commands are tested. commit 6cae166f6f1e3f4eaaef6a9036c597b6064b263a Author: Christoph Jentzsch Date: Wed Oct 1 15:34:23 2014 +0200 Delete tmp.json commit 4ff906fbc271ee3aee3eb5db135e591eb187793a Author: Christoph Jentzsch Date: Wed Oct 1 14:06:32 2014 +0200 corrected CALLSTATELESS tests commit 5b3fee6806a69545e572725add73c297e9473eee Author: Christoph Jentzsch Date: Mon Sep 29 13:08:44 2014 +0200 Completed vm tests. Added ADDMOD, MULMOD, POST, CALLSTATELESS commit 9cdd2180833d98cf967929e07cab6638c2e933d0 Author: Christoph Jentzsch Date: Sat Sep 27 21:48:09 2014 +0200 Added IOandFlowOperation-, PushDupSwap- and SystemOperations- tests. Removed empty storage from adresses. commit 28ed968b46590bd8f3e5bb25606e8f83e0ee9b9e Author: Christoph Jentzsch Date: Tue Sep 23 15:49:22 2014 +0200 Added blockInfoTest commit ffbd5a35b597d2908fa0fa37d9b2aeaf30aee155 Author: Christoph Jentzsch Date: Tue Sep 23 15:37:52 2014 +0200 Added environmentalInfo- and sha3- test commit 54c14f1ff3f7ec66d755181be32a13e0404110d9 Author: Christoph Jentzsch Date: Mon Sep 22 13:06:57 2014 +0200 Added bitwise logic operation test commit d0af113aab3991fecbde29933f4a77884fafdf60 Author: Christoph Jentzsch Date: Sat Sep 20 01:42:51 2014 +0200 Added vm arithmetic test commit cb8261a78b56197e421bce5ac2afb7147f5acb45 Author: Jeffrey Wilcke Date: Fri Sep 19 13:15:44 2014 +0200 Update genesishashestest.json commit 4513623da1110e74a236abf0357ad00ff7a38126 Author: Maran Date: Tue Jul 22 12:24:46 2014 +0200 Update keyaddrtest to be valid JSON commit e8cb5c221d4763c8c26ac73f99609b64a595f4b3 Author: Vitalik Buterin Date: Mon Jul 21 23:30:33 2014 -0400 Added next/prev trie test commit 98823c04b30ef0be478c69a11edc3f9f6dff567e Author: Vitalik Buterin Date: Mon Jul 14 02:51:31 2014 -0400 Replaced with deterministic test commit 357eb21e4d5d9d6713ba7c63a76bd597a57d6a0e Author: Vitalik Buterin Date: Sun Jul 13 16:12:56 2014 -0400 Added my own random and namecoin tests (pyethereum) commit 00cd0cce8f0fc0ca8aa2c8ca424954d4932672f2 Author: Gav Wood Date: Sat Jul 12 21:20:04 2014 +0200 Output hex strings. commit ddfa3af45da9d5d81da38745ae23ee93ce390c2b Author: Gav Wood Date: Thu Jul 10 11:28:35 2014 +0100 Everything a string. commit d659f469a9ddcdd144a332da64b826908b0f7872 Author: Gav Wood Date: Thu Jul 10 10:16:25 2014 +0100 Code fixes. commit 5e83ea82283f042df384d7ff20183ba51760d893 Author: Gav Wood Date: Sun Jul 6 16:17:12 2014 +0200 Prettier VM tests. commit a09aae0efe9a1cb94be3e0386532c532262956ec Author: Gav Wood Date: Sun Jul 6 15:46:01 2014 +0200 Fix VM tests. commit ec9a044a17779f0b3814bffa8c058b4091d6d13d Merge: 4bb6461 5e0123f Author: Jeffrey Wilcke Date: Fri Jul 4 15:56:52 2014 +0200 Merge pull request #10 from romanman/patch-1 Update vmtests.json commit 5e0123fbe1573dcf8157995f3ef2f7ce625235a4 Author: romanman Date: Fri Jul 4 10:23:04 2014 +0100 Update vmtests.json commit 2b6da2f5f21b60ebca44a5866888b00f736f92b2 Author: romanman Date: Thu Jul 3 17:45:04 2014 +0100 Update vmtests.json arith testcase updated commit 4bb646117d0034fb459c07e6955b1c9cca802fa9 Merge: bba3898 a33b309 Author: Gav Wood Date: Wed Jul 2 19:43:22 2014 +0200 Merge branch 'develop' of github.com:/ethereum/tests into develop commit bba38980bdfa6ba6fddf0419479ad2405a3cb079 Author: Gav Wood Date: Wed Jul 2 19:43:06 2014 +0200 New tests. commit a33b309d99b36c4c57083d5e77422c3f2bba4bbe Author: Vitalik Buterin Date: Wed Jul 2 10:14:05 2014 -0400 Testing submodules commit 50318217ca875d23147eddfa7cc0326242db90bf Author: Vitalik Buterin Date: Wed Jul 2 10:10:46 2014 -0400 Testing submodules commit 57fa655522fc9696adcc7a6a25b64afd569b0758 Author: Vitalik Buterin Date: Wed Jul 2 10:09:08 2014 -0400 Testing submodules commit ea0eb0a8c82521322bd0359d1c42fc013c433d2e Author: Gav Wood Date: Tue Jul 1 15:19:34 2014 +0200 Latest genesis block. commit 25bb76b69c90ebd44a271d7c180a4a4b86845018 Author: Jeffrey Wilcke Date: Mon Jun 30 13:25:04 2014 +0200 Reset commit 74c6d8424e7d91ccd592c179794bc74e63c0d8c0 Author: Jeffrey Wilcke Date: Mon Jun 30 12:10:06 2014 +0200 Updated wrong test commit 9ea3a60291f2ca68a54198d53e4c40fffb09f6b3 Author: Jeffrey Wilcke Date: Sat Jun 28 18:48:28 2014 +0200 Fixed roots commit 5fc3ac0e925cdfe95632024f574fb945558491b8 Author: Gav Wood Date: Sat Jun 28 18:40:06 2014 +0200 Simple hex test. commit edd3a00c2a8d78867d8bb1557697455729a03027 Author: Gav Wood Date: Sat Jun 28 18:22:18 2014 +0200 Additional test for jeff. Now use the 0x... notation. commit 5021e0dd83bdb8b23ca3dcc72293c6737e8165a8 Author: Gav Wood Date: Fri Jun 27 21:35:26 2014 +0200 VM test framework updated. commit c818d132022c228c5b04ab82871f5971049b0c6d Author: Gav Wood Date: Fri Jun 27 18:18:24 2014 +0200 Removed arrays from Trie tests JSON as per conformance guide and changed vocabulary to match other tests. VM test updates. commit 714770ffb3bb037e2daeaa37a6f4f4066387abe3 Author: Gav Wood Date: Wed Jun 11 11:32:42 2014 +0100 Added Gav's new address. commit 9345bc13d40e6d288c37b650ace1db0c41a89d84 Merge: a2257f3 78576dd Author: Gav Wood Date: Fri May 30 17:50:38 2014 +0200 Merge branch 'master' of github.com:ethereum/tests into develop commit a2257f3471dd4b472bc156be4575ea0f26a8a046 Author: Gav Wood Date: Fri May 30 17:50:18 2014 +0200 VM tests. commit 78576dd3d3d4bf46af19d703affdd42f221e49c9 Author: Heiko Heiko Date: Fri May 30 17:19:09 2014 +0200 changes based on new account structure nonce, balance, storage, code commit 125839e84833ec25e0fdd4fbd545772ba706fe6b Merge: 42e14ec 356a329 Author: Jeffrey Wilcke Date: Thu May 22 09:58:45 2014 +0200 Merge pull request #5 from bkirwi/master Fix invalid JSON (removed trailing comma) and add test names commit 356a3296bc7eeac8b1b65aa843b5856cd786c4cf Author: Ben Kirwin Date: Thu May 22 00:20:48 2014 -0400 Add some arbitrary test names This should now conform to the format specified in the README. commit 42e14ec54fa57c2373625d21e5b47f597c748bf5 Author: Chen Houwu Date: Wed May 21 23:27:40 2014 +0800 revert to correct data commit 4300197a748de29cc5c93fd77f13cae029dad49e Author: Chen Houwu Date: Wed May 21 22:42:23 2014 +0800 fix: wrong sha3 hash because of the wrong rlp hex commit a0d01b1a0b59555e38ea694ff864f2aa25a0d953 Author: Chen Houwu Date: Wed May 21 22:29:53 2014 +0800 fix: wrong rlp hex commit 6bc2fc74054a418e7cfca9cf9144237a5e4fa65f Merge: 66bc366 c31a93c Author: Jeffrey Wilcke Date: Wed May 21 14:11:37 2014 +0200 Merge pull request #4 from ethers/master fix file name that seems to have been a typo commit c31a93c27a9048df92fcf53a2201c6e3737a40fd Author: ethers Date: Tue May 20 15:42:39 2014 -0700 fix file name that seems to have been a typo commit 66bc3665c17e1eec309e5a40b2a9c74273fb639a Author: Heiko Heiko Date: Tue May 20 17:36:35 2014 +0200 fix: represent integers as strings commit ede5499da624d95db1cad63939be56f7bdaa6389 Author: Heiko Heiko Date: Tue May 20 17:21:09 2014 +0200 add: current initial alloc and genesis hashes commit 5131429abbe6d2636064e17b45c99827a904c345 Author: Ben Kirwin Date: Mon May 19 11:18:31 2014 -0400 Delete a comma This should now be parseable as JSON. commit f44a85933110dd3ef362090f512678e99ae80256 Author: Chen Houwu Date: Sun May 18 15:04:42 2014 +0800 add: case when value is long, ensure it's not get rlp encoded as node commit e1ae4ad4495dd13fba6346274971a8871cb32607 Author: Gav Wood Date: Mon May 12 14:40:47 2014 +0100 PoC-5 VM tests. commit 2b6c136dda0d55a0ebd228bff029d97411c9cec6 Author: Vitalik Buterin Date: Sun May 11 21:42:41 2014 -0400 Moved txt to json commit cbccbf977ca7bde15a661a4b453ea062e62ac856 Merge: edbb8d4 45a0974 Author: Vitalik Buterin Date: Thu May 8 21:54:48 2014 -0400 New commit commit edbb8d407ecfbcbb6504659cbd9bdabdb93369e3 Author: Vitalik Buterin Date: Tue May 6 16:53:43 2014 -0400 Removed unneeded test, added new tests commit 45a0974f6f32511119e40a27042fdd571fe47a16 Merge: 15dd8fd 5fd2a98 Author: Gav Wood Date: Sun Apr 27 12:53:47 2014 +0100 Merge pull request #3 from autolycus/develop Fixed formatting and added test cases commit 5fd2a98fcb4f6a648160204d1b20b0f980d55b9d Author: Carl Allendorph Date: Sat Apr 19 13:26:14 2014 -0700 Added some new test cases for the rlp encoding. commit 4ba150954ef8ac72416a35f06fdad9c6d7ed461d Author: Carl Allendorph Date: Sat Apr 19 12:48:42 2014 -0700 Converted spaces to tabs to be compliant with the coding standards defined in cpp-ethereum commit 15dd8fd794a0dc305ef7696d0c2a68e032bc9759 Author: Gav Wood Date: Fri Feb 28 12:54:47 2014 +0000 RLP tests and Trie updates. commit 33f80fef211c2d51162c1856e50448be3d90c214 Author: Gav Wood Date: Fri Feb 28 11:39:35 2014 +0000 Hex encode tests done. commit e1f5e12abb38f8cedb4a589b1347fb01c3da902a Author: Gav Wood Date: Fri Feb 28 11:22:49 2014 +0000 Fix RLP tests. commit f87ce15ad201a6d97e2654e5dc5a3181873d1719 Author: Gav Wood Date: Thu Feb 27 13:28:11 2014 +0000 Fix empty string. commit c006ed4ffd7d00124dbcb44d4e7ca05d6d9ddc12 Author: Gav Wood Date: Mon Feb 24 10:24:39 2014 +0000 Tests fix. commit 510ff563639e71224306d9af0e50a28a9d624b8f Author: Gav Wood Date: Fri Feb 21 18:54:08 2014 +0000 Updated the tests. commit a0ec84383218ea80b4c0b99e09710fae182a2379 Author: Gav Wood Date: Fri Feb 21 18:49:24 2014 +0000 Moved over to new format, but RLP tests still need updating. commit 660cd26f31b3979149950c1fdea995b85a774c1c Author: Gav Wood Date: Fri Feb 21 18:35:51 2014 +0000 More docs. commit 6ad14c1a157e707fd15c87816e8ad872f69790db Author: Gav Wood Date: Fri Feb 21 18:33:39 2014 +0000 Added VM test suite. Added TODO. Renamed old files. commit f91ad7b3857ec9157e7df7f315d942afb7594da0 Author: Vitalik Buterin Date: Wed Jan 8 11:26:58 2014 -0500 update trie algorithm commit 6da295446203889ac5a4a365b397bb45766c9ad8 Merge: cc42246 131c610 Author: Vitalik Buterin Date: Wed Jan 8 08:15:38 2014 -0500 merge commit cc4224675f1f70242f91ee7d2d1295bed6f0dc01 Author: Vitalik Buterin Date: Tue Jan 7 14:35:26 2014 -0500 Updated trie test commit 131c610da66203f708391485aa42fc7a81f01ef7 Merge: 121632b 7613302 Author: vbuterin Date: Wed Jan 1 06:40:54 2014 -0800 Merge pull request #1 from obscuren/master Update trietest.txt commit 7613302b491b3f6406b1ea3c8292adf6d41860d0 Author: obscuren Date: Wed Jan 1 15:25:21 2014 +0100 Update trietest.txt New proposed explanatory format commit 121632bedd1c84a0af847b923aa4b803556722c0 Author: Vitalik Buterin Date: Wed Jan 1 08:26:18 2014 -0500 Added obscure's tests commit ef6c5506c3fcdecf779184ad81d92db9315c2488 Author: Vitalik Buterin Date: Tue Dec 31 19:04:48 2013 -0500 Fixed tests a bit commit 345e4bcfefb45a66a09b1761570405a03c67b9d2 Merge: 2c81698 e4bbea4 Author: Vitalik Buterin Date: Tue Dec 31 15:52:46 2013 -0500 Merge branch 'master' of github.com:ethereum/tests commit 2c81698f31e7e579335a2ab8706f96397a68f018 Author: Vitalik Buterin Date: Mon Dec 30 21:09:40 2013 -0500 Added first three tests commit e4bbea400f7df275faf47ea643256d68495b35aa Author: vbuterin Date: Mon Dec 30 18:09:03 2013 -0800 Initial commit --- core/execution.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'core') diff --git a/core/execution.go b/core/execution.go index 5176f7351..a464abc66 100644 --- a/core/execution.go +++ b/core/execution.go @@ -32,7 +32,7 @@ func (self *Execution) Call(codeAddr []byte, caller vm.ClosureRef) ([]byte, erro return self.exec(code, codeAddr, caller) } -func (self *Execution) exec(code, caddr []byte, caller vm.ClosureRef) (ret []byte, err error) { +func (self *Execution) exec(code, contextAddr []byte, caller vm.ClosureRef) (ret []byte, err error) { env := self.vm.Env() chainlogger.Debugf("pre state %x\n", env.State().Root()) @@ -57,7 +57,7 @@ func (self *Execution) exec(code, caddr []byte, caller vm.ClosureRef) (ret []byt } else { self.object = to // Pre-compiled contracts (address.go) 1, 2 & 3. - naddr := ethutil.BigD(caddr).Uint64() + naddr := ethutil.BigD(contextAddr).Uint64() if p := vm.Precompiled[naddr]; p != nil { if self.Gas.Cmp(p.Gas(len(self.input))) >= 0 { ret = p.Call(self.input) -- cgit From b1c58b76a9588a90db5a773a997bb70265c378d3 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 17 Dec 2014 12:57:35 +0100 Subject: moved err check --- core/chain_manager.go | 11 ++++++++++- core/chain_manager_test.go | 18 ++++++++++++++++++ core/execution.go | 32 ++++++++++++++++---------------- 3 files changed, 44 insertions(+), 17 deletions(-) (limited to 'core') diff --git a/core/chain_manager.go b/core/chain_manager.go index edf50e715..3e48579b9 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -148,6 +148,16 @@ func (bc *ChainManager) Reset() { bc.TD = ethutil.BigD(ethutil.Config.Db.LastKnownTD()) } +func (self *ChainManager) Export() []byte { + chainlogger.Infoln("exporting", self.CurrentBlock.Number, "blocks") + + blocks := make(types.Blocks, int(self.CurrentBlock.Number.Int64())+1) + for block := self.CurrentBlock; block != nil; block = self.GetBlock(block.PrevHash) { + blocks[block.Number.Int64()] = block + } + return ethutil.Encode(blocks) +} + func (bc *ChainManager) insert(block *types.Block) { encodedBlock := block.RlpEncode() ethutil.Config.Db.Put([]byte("LastBlock"), encodedBlock) @@ -181,7 +191,6 @@ func (self *ChainManager) GetChainHashesFromHash(hash []byte, max uint64) (chain // XXX Could be optimised by using a different database which only holds hashes (i.e., linked list) for i := uint64(0); i < max; i++ { - chain = append(chain, block.Hash()) if block.Number.Cmp(ethutil.Big0) <= 0 { diff --git a/core/chain_manager_test.go b/core/chain_manager_test.go index 9a8bc9592..a84e3ff3b 100644 --- a/core/chain_manager_test.go +++ b/core/chain_manager_test.go @@ -1 +1,19 @@ package core + +import ( + "fmt" + "path" + "testing" + + "github.com/ethereum/go-ethereum/ethutil" +) + +func TestChainInsertions(t *testing.T) { + c1, err := ethutil.ReadAllFile(path.Join("..", "_data", "chain1")) + if err != nil { + fmt.Println(err) + t.FailNow() + } + data1, _ := ethutil.Decode([]byte(c1), 0) + fmt.Println(data1) +} diff --git a/core/execution.go b/core/execution.go index a464abc66..58d46c509 100644 --- a/core/execution.go +++ b/core/execution.go @@ -40,6 +40,12 @@ func (self *Execution) exec(code, contextAddr []byte, caller vm.ClosureRef) (ret // Skipping transfer is used on testing for the initial call if !self.SkipTransfer { err = env.Transfer(from, to, self.value) + if err != nil { + caller.ReturnGas(self.Gas, self.price) + + err = fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, from.Balance) + return + } } snapshot := env.State().Copy() @@ -50,23 +56,17 @@ func (self *Execution) exec(code, contextAddr []byte, caller vm.ClosureRef) (ret chainlogger.Debugf("post state %x\n", env.State().Root()) }() - if err != nil { - caller.ReturnGas(self.Gas, self.price) - - err = fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, from.Balance) - } else { - self.object = to - // Pre-compiled contracts (address.go) 1, 2 & 3. - naddr := ethutil.BigD(contextAddr).Uint64() - if p := vm.Precompiled[naddr]; p != nil { - if self.Gas.Cmp(p.Gas(len(self.input))) >= 0 { - ret = p.Call(self.input) - self.vm.Printf("NATIVE_FUNC(%x) => %x", naddr, ret) - self.vm.Endl() - } - } else { - ret, err = self.vm.Run(to, caller, code, self.value, self.Gas, self.price, self.input) + self.object = to + // Pre-compiled contracts (address.go) 1, 2 & 3. + naddr := ethutil.BigD(contextAddr).Uint64() + if p := vm.Precompiled[naddr]; p != nil { + if self.Gas.Cmp(p.Gas(len(self.input))) >= 0 { + ret = p.Call(self.input) + self.vm.Printf("NATIVE_FUNC(%x) => %x", naddr, ret) + self.vm.Endl() } + } else { + ret, err = self.vm.Run(to, caller, code, self.value, self.Gas, self.price, self.input) } return -- cgit From 4dbdcaecb117d7e1fcaf0869f5d4602312552991 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 17 Dec 2014 23:58:52 +0100 Subject: Moved pre-compiled, moved depth check * Depth check has been moved to the execution * Pre compiled execution has been moved to the VM * PrecompiledAddress has been renamed to PrecompiledAccount --- core/execution.go | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) (limited to 'core') diff --git a/core/execution.go b/core/execution.go index 58d46c509..827e1ee0e 100644 --- a/core/execution.go +++ b/core/execution.go @@ -4,7 +4,6 @@ import ( "fmt" "math/big" - "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/vm" ) @@ -36,6 +35,11 @@ func (self *Execution) exec(code, contextAddr []byte, caller vm.ClosureRef) (ret env := self.vm.Env() chainlogger.Debugf("pre state %x\n", env.State().Root()) + if self.vm.Env().Depth() == vm.MaxCallDepth { + // Consume all gas (by not returning it) and return a depth error + return nil, vm.DepthError{} + } + from, to := env.State().GetStateObject(caller.Address()), env.State().GetOrNewStateObject(self.address) // Skipping transfer is used on testing for the initial call if !self.SkipTransfer { @@ -50,24 +54,14 @@ func (self *Execution) exec(code, contextAddr []byte, caller vm.ClosureRef) (ret snapshot := env.State().Copy() defer func() { - if vm.IsDepthErr(err) || vm.IsOOGErr(err) { + if /*vm.IsDepthErr(err) ||*/ vm.IsOOGErr(err) { env.State().Set(snapshot) } chainlogger.Debugf("post state %x\n", env.State().Root()) }() self.object = to - // Pre-compiled contracts (address.go) 1, 2 & 3. - naddr := ethutil.BigD(contextAddr).Uint64() - if p := vm.Precompiled[naddr]; p != nil { - if self.Gas.Cmp(p.Gas(len(self.input))) >= 0 { - ret = p.Call(self.input) - self.vm.Printf("NATIVE_FUNC(%x) => %x", naddr, ret) - self.vm.Endl() - } - } else { - ret, err = self.vm.Run(to, caller, code, self.value, self.Gas, self.price, self.input) - } + ret, err = self.vm.Run(to, caller, code, self.value, self.Gas, self.price, self.input) return } -- cgit From 590aace88dce9922d40fca71e87905383a71d12b Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 18 Dec 2014 12:18:19 +0100 Subject: Removed ethereum as dependency --- core/block_manager.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'core') diff --git a/core/block_manager.go b/core/block_manager.go index f6c73bc2c..98c6d006d 100644 --- a/core/block_manager.go +++ b/core/block_manager.go @@ -58,8 +58,8 @@ type BlockManager struct { mem map[string]*big.Int // Proof of work used for validating Pow pow.PoW - // The ethereum manager interface - eth EthManager + + txpool *TxPool // The last attempted block is mainly used for debugging purposes // This does not have to be a valid block and will be set during @@ -71,13 +71,13 @@ type BlockManager struct { eventMux *event.TypeMux } -func NewBlockManager(ethereum EthManager) *BlockManager { +func NewBlockManager(txpool *TxPool, chainManager *ChainManager, eventMux *event.TypeMux) *BlockManager { sm := &BlockManager{ mem: make(map[string]*big.Int), Pow: ezp.New(), - eth: ethereum, - bc: ethereum.ChainManager(), - eventMux: ethereum.EventMux(), + bc: chainManager, + eventMux: eventMux, + txpool: txpool, } return sm @@ -240,7 +240,7 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I chainlogger.Infof("Processed block #%d (%x...)\n", block.Number, block.Hash()[0:4]) - sm.eth.TxPool().RemoveSet(block.Transactions()) + sm.txpool.RemoveSet(block.Transactions()) return td, messages, nil } else { -- cgit From 49e0267fe76cfd13eaf3e5e26caa637b93dbdd29 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 18 Dec 2014 13:12:54 +0100 Subject: Locks, refactor, tests * Added additional chain tests * Added proper mutex' on chain * Removed ethereum dependencies --- core/block_manager.go | 6 +-- core/chain_manager.go | 113 ++++++++++++++++++++++++++++++--------------- core/chain_manager_test.go | 66 ++++++++++++++++++++++++-- core/filter.go | 4 +- core/filter_test.go | 6 --- core/transaction_pool.go | 26 +++++++---- core/types/block.go | 2 +- core/types/common.go | 5 ++ 8 files changed, 165 insertions(+), 63 deletions(-) (limited to 'core') diff --git a/core/block_manager.go b/core/block_manager.go index 98c6d006d..794c87f52 100644 --- a/core/block_manager.go +++ b/core/block_manager.go @@ -256,12 +256,12 @@ func (sm *BlockManager) CalculateTD(block *types.Block) (*big.Int, bool) { // TD(genesis_block) = 0 and TD(B) = TD(B.parent) + sum(u.difficulty for u in B.uncles) + B.difficulty td := new(big.Int) - td = td.Add(sm.bc.TD, uncleDiff) + td = td.Add(sm.bc.Td(), uncleDiff) td = td.Add(td, block.Difficulty) // The new TD will only be accepted if the new difficulty is // is greater than the previous. - if td.Cmp(sm.bc.TD) > 0 { + if td.Cmp(sm.bc.Td()) > 0 { return td, true } @@ -279,7 +279,7 @@ func (sm *BlockManager) ValidateBlock(block, parent *types.Block) error { diff := block.Time - parent.Time if diff < 0 { - return ValidationError("Block timestamp less then prev block %v (%v - %v)", diff, block.Time, sm.bc.CurrentBlock.Time) + return ValidationError("Block timestamp less then prev block %v (%v - %v)", diff, block.Time, sm.bc.CurrentBlock().Time) } /* XXX diff --git a/core/chain_manager.go b/core/chain_manager.go index 3e48579b9..c81552b5d 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -3,6 +3,7 @@ package core import ( "fmt" "math/big" + "sync" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethutil" @@ -50,14 +51,34 @@ type ChainManager struct { eventMux *event.TypeMux genesisBlock *types.Block // Last known total difficulty - TD *big.Int + mu sync.RWMutex + td *big.Int + lastBlockNumber uint64 + currentBlock *types.Block + lastBlockHash []byte - LastBlockNumber uint64 + transState *state.StateDB +} - CurrentBlock *types.Block - LastBlockHash []byte +func (self *ChainManager) Td() *big.Int { + self.mu.RLock() + defer self.mu.RUnlock() - transState *state.StateDB + return self.td +} + +func (self *ChainManager) LastBlockNumber() uint64 { + self.mu.RLock() + defer self.mu.RUnlock() + + return self.lastBlockNumber +} + +func (self *ChainManager) CurrentBlock() *types.Block { + self.mu.RLock() + defer self.mu.RUnlock() + + return self.currentBlock } func NewChainManager(mux *event.TypeMux) *ChainManager { @@ -77,7 +98,7 @@ func (self *ChainManager) SetProcessor(proc types.BlockProcessor) { } func (self *ChainManager) State() *state.StateDB { - return self.CurrentBlock.State() + return self.CurrentBlock().State() } func (self *ChainManager) TransState() *state.StateDB { @@ -91,27 +112,30 @@ func (bc *ChainManager) setLastBlock() { AddTestNetFunds(bc.genesisBlock) block := types.NewBlockFromBytes(data) - bc.CurrentBlock = block - bc.LastBlockHash = block.Hash() - bc.LastBlockNumber = block.Number.Uint64() + bc.currentBlock = block + bc.lastBlockHash = block.Hash() + bc.lastBlockNumber = block.Number.Uint64() // Set the last know difficulty (might be 0x0 as initial value, Genesis) - bc.TD = ethutil.BigD(ethutil.Config.Db.LastKnownTD()) + bc.td = ethutil.BigD(ethutil.Config.Db.LastKnownTD()) } else { bc.Reset() } - chainlogger.Infof("Last block (#%d) %x\n", bc.LastBlockNumber, bc.CurrentBlock.Hash()) + chainlogger.Infof("Last block (#%d) %x\n", bc.lastBlockNumber, bc.currentBlock.Hash()) } // Block creation & chain handling func (bc *ChainManager) NewBlock(coinbase []byte) *types.Block { + bc.mu.RLock() + defer bc.mu.RUnlock() + var root interface{} hash := ZeroHash256 if bc.CurrentBlock != nil { - root = bc.CurrentBlock.Root() - hash = bc.LastBlockHash + root = bc.currentBlock.Root() + hash = bc.lastBlockHash } block := types.CreateBlock( @@ -122,11 +146,11 @@ func (bc *ChainManager) NewBlock(coinbase []byte) *types.Block { nil, "") - parent := bc.CurrentBlock + parent := bc.currentBlock if parent != nil { block.Difficulty = CalcDifficulty(block, parent) - block.Number = new(big.Int).Add(bc.CurrentBlock.Number, ethutil.Big1) - block.GasLimit = block.CalcGasLimit(bc.CurrentBlock) + block.Number = new(big.Int).Add(bc.currentBlock.Number, ethutil.Big1) + block.GasLimit = block.CalcGasLimit(bc.currentBlock) } @@ -134,35 +158,42 @@ func (bc *ChainManager) NewBlock(coinbase []byte) *types.Block { } func (bc *ChainManager) Reset() { + bc.mu.Lock() + defer bc.mu.Unlock() + AddTestNetFunds(bc.genesisBlock) bc.genesisBlock.Trie().Sync() // Prepare the genesis block bc.write(bc.genesisBlock) bc.insert(bc.genesisBlock) - bc.CurrentBlock = bc.genesisBlock + bc.currentBlock = bc.genesisBlock - bc.SetTotalDifficulty(ethutil.Big("0")) + bc.setTotalDifficulty(ethutil.Big("0")) // Set the last know difficulty (might be 0x0 as initial value, Genesis) - bc.TD = ethutil.BigD(ethutil.Config.Db.LastKnownTD()) + bc.td = ethutil.BigD(ethutil.Config.Db.LastKnownTD()) } func (self *ChainManager) Export() []byte { - chainlogger.Infoln("exporting", self.CurrentBlock.Number, "blocks") + self.mu.RLock() + defer self.mu.RUnlock() + + chainlogger.Infof("exporting %v blocks...\n", self.currentBlock.Number) - blocks := make(types.Blocks, int(self.CurrentBlock.Number.Int64())+1) - for block := self.CurrentBlock; block != nil; block = self.GetBlock(block.PrevHash) { + blocks := make([]*types.Block, int(self.currentBlock.Number.Int64())+1) + for block := self.currentBlock; block != nil; block = self.GetBlock(block.PrevHash) { blocks[block.Number.Int64()] = block } + return ethutil.Encode(blocks) } func (bc *ChainManager) insert(block *types.Block) { encodedBlock := block.RlpEncode() ethutil.Config.Db.Put([]byte("LastBlock"), encodedBlock) - bc.CurrentBlock = block - bc.LastBlockHash = block.Hash() + bc.currentBlock = block + bc.lastBlockHash = block.Hash() } func (bc *ChainManager) write(block *types.Block) { @@ -213,7 +244,10 @@ func (self *ChainManager) GetBlock(hash []byte) *types.Block { } func (self *ChainManager) GetBlockByNumber(num uint64) *types.Block { - block := self.CurrentBlock + self.mu.RLock() + defer self.mu.RUnlock() + + block := self.currentBlock for ; block != nil; block = self.GetBlock(block.PrevHash) { if block.Number.Uint64() == num { break @@ -227,9 +261,9 @@ func (self *ChainManager) GetBlockByNumber(num uint64) *types.Block { return block } -func (bc *ChainManager) SetTotalDifficulty(td *big.Int) { +func (bc *ChainManager) setTotalDifficulty(td *big.Int) { ethutil.Config.Db.Put([]byte("LTD"), td.Bytes()) - bc.TD = td + bc.td = td } func (self *ChainManager) CalcTotalDiff(block *types.Block) (*big.Int, error) { @@ -262,8 +296,8 @@ func (bc *ChainManager) BlockInfo(block *types.Block) types.BlockInfo { // Unexported method for writing extra non-essential block info to the db func (bc *ChainManager) writeBlockInfo(block *types.Block) { - bc.LastBlockNumber++ - bi := types.BlockInfo{Number: bc.LastBlockNumber, Hash: block.Hash(), Parent: block.PrevHash, TD: bc.TD} + bc.lastBlockNumber++ + bi := types.BlockInfo{Number: bc.lastBlockNumber, Hash: block.Hash(), Parent: block.PrevHash, TD: bc.td} // For now we use the block hash with the words "info" appended as key ethutil.Config.Db.Put(append(block.Hash(), []byte("Info")...), bi.RlpEncode()) @@ -289,17 +323,22 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error { return err } - self.write(block) - if td.Cmp(self.TD) > 0 { - if block.Number.Cmp(new(big.Int).Add(self.CurrentBlock.Number, ethutil.Big1)) < 0 { - chainlogger.Infof("Split detected. New head #%v (%x), was #%v (%x)\n", block.Number, block.Hash()[:4], self.CurrentBlock.Number, self.CurrentBlock.Hash()[:4]) + self.mu.Lock() + { + + self.write(block) + if td.Cmp(self.td) > 0 { + if block.Number.Cmp(new(big.Int).Add(self.currentBlock.Number, ethutil.Big1)) < 0 { + chainlogger.Infof("Split detected. New head #%v (%x), was #%v (%x)\n", block.Number, block.Hash()[:4], self.currentBlock.Number, self.currentBlock.Hash()[:4]) + } + + self.setTotalDifficulty(td) + self.insert(block) + self.transState = self.currentBlock.State().Copy() } - self.SetTotalDifficulty(td) - self.insert(block) - self.transState = self.State().Copy() - //sm.eth.TxPool().RemoveSet(block.Transactions()) } + self.mu.Unlock() self.eventMux.Post(NewBlockEvent{block}) self.eventMux.Post(messages) diff --git a/core/chain_manager_test.go b/core/chain_manager_test.go index a84e3ff3b..52be8b0ea 100644 --- a/core/chain_manager_test.go +++ b/core/chain_manager_test.go @@ -3,17 +3,75 @@ package core import ( "fmt" "path" + "runtime" "testing" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethutil" + "github.com/ethereum/go-ethereum/event" + //logpkg "github.com/ethereum/go-ethereum/logger" ) -func TestChainInsertions(t *testing.T) { - c1, err := ethutil.ReadAllFile(path.Join("..", "_data", "chain1")) +//var Logger logpkg.LogSystem +//var Log = logpkg.NewLogger("TEST") + +func init() { + runtime.GOMAXPROCS(runtime.NumCPU()) + //Logger = logpkg.NewStdLogSystem(os.Stdout, log.LstdFlags, logpkg.InfoLevel) + //logpkg.AddLogSystem(Logger) + + ethutil.ReadConfig("/tmp/ethtest", "/tmp/ethtest", "ETH") + + db, err := ethdb.NewMemDatabase() + if err != nil { + panic("Could not create mem-db, failing") + } + ethutil.Config.Db = db +} + +func loadChain(fn string, t *testing.T) types.Blocks { + c1, err := ethutil.ReadAllFile(path.Join("..", "_data", fn)) if err != nil { fmt.Println(err) t.FailNow() } - data1, _ := ethutil.Decode([]byte(c1), 0) - fmt.Println(data1) + value := ethutil.NewValueFromBytes([]byte(c1)) + blocks := make(types.Blocks, value.Len()) + it := value.NewIterator() + for it.Next() { + blocks[it.Idx()] = types.NewBlockFromRlpValue(it.Value()) + } + + return blocks +} + +func insertChain(done chan bool, chainMan *ChainManager, chain types.Blocks, t *testing.T) { + err := chainMan.InsertChain(chain) + if err != nil { + fmt.Println(err) + t.FailNow() + } + done <- true +} + +func TestChainInsertions(t *testing.T) { + chain1 := loadChain("chain1", t) + chain2 := loadChain("chain2", t) + var eventMux event.TypeMux + chainMan := NewChainManager(&eventMux) + txPool := NewTxPool(chainMan, nil, &eventMux) + blockMan := NewBlockManager(txPool, chainMan, &eventMux) + chainMan.SetProcessor(blockMan) + + const max = 2 + done := make(chan bool, max) + + go insertChain(done, chainMan, chain1, t) + go insertChain(done, chainMan, chain2, t) + + for i := 0; i < max; i++ { + <-done + } + fmt.Println(chainMan.CurrentBlock()) } diff --git a/core/filter.go b/core/filter.go index fe3665bf3..fb992782d 100644 --- a/core/filter.go +++ b/core/filter.go @@ -78,11 +78,11 @@ func (self *Filter) SetSkip(skip int) { func (self *Filter) Find() []*state.Message { var earliestBlockNo uint64 = uint64(self.earliest) if self.earliest == -1 { - earliestBlockNo = self.eth.ChainManager().CurrentBlock.Number.Uint64() + earliestBlockNo = self.eth.ChainManager().CurrentBlock().Number.Uint64() } var latestBlockNo uint64 = uint64(self.latest) if self.latest == -1 { - latestBlockNo = self.eth.ChainManager().CurrentBlock.Number.Uint64() + latestBlockNo = self.eth.ChainManager().CurrentBlock().Number.Uint64() } var ( diff --git a/core/filter_test.go b/core/filter_test.go index d53b835b7..9a8bc9592 100644 --- a/core/filter_test.go +++ b/core/filter_test.go @@ -1,7 +1 @@ package core - -// import "testing" - -// func TestFilter(t *testing.T) { -// NewFilter(NewTestManager()) -// } diff --git a/core/transaction_pool.go b/core/transaction_pool.go index 7166d35e8..36b0beb28 100644 --- a/core/transaction_pool.go +++ b/core/transaction_pool.go @@ -8,6 +8,7 @@ import ( "sync" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/wire" @@ -61,7 +62,6 @@ type TxProcessor interface { // pool is being drained or synced for whatever reason the transactions // will simple queue up and handled when the mutex is freed. type TxPool struct { - Ethereum EthManager // The mutex for accessing the Tx pool. mutex sync.Mutex // Queueing channel for reading and writing incoming @@ -75,14 +75,20 @@ type TxPool struct { SecondaryProcessor TxProcessor subscribers []chan TxMsg + + broadcaster types.Broadcaster + chainManager *ChainManager + eventMux *event.TypeMux } -func NewTxPool(ethereum EthManager) *TxPool { +func NewTxPool(chainManager *ChainManager, broadcaster types.Broadcaster, eventMux *event.TypeMux) *TxPool { return &TxPool{ - pool: list.New(), - queueChan: make(chan *types.Transaction, txPoolQueueSize), - quit: make(chan bool), - Ethereum: ethereum, + pool: list.New(), + queueChan: make(chan *types.Transaction, txPoolQueueSize), + quit: make(chan bool), + chainManager: chainManager, + eventMux: eventMux, + broadcaster: broadcaster, } } @@ -94,13 +100,13 @@ func (pool *TxPool) addTransaction(tx *types.Transaction) { pool.pool.PushBack(tx) // Broadcast the transaction to the rest of the peers - pool.Ethereum.Broadcast(wire.MsgTxTy, []interface{}{tx.RlpData()}) + pool.broadcaster.Broadcast(wire.MsgTxTy, []interface{}{tx.RlpData()}) } func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error { // Get the last block so we can retrieve the sender and receiver from // the merkle trie - block := pool.Ethereum.ChainManager().CurrentBlock + block := pool.chainManager.CurrentBlock // Something has gone horribly wrong if this happens if block == nil { return fmt.Errorf("No last block on the block chain") @@ -116,7 +122,7 @@ func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error { } // Get the sender - sender := pool.Ethereum.ChainManager().State().GetAccount(tx.Sender()) + sender := pool.chainManager.State().GetAccount(tx.Sender()) totAmount := new(big.Int).Set(tx.Value) // Make sure there's enough in the sender's account. Having insufficient @@ -160,7 +166,7 @@ func (self *TxPool) Add(tx *types.Transaction) error { txplogger.Debugf("(t) %x => %x (%v) %x\n", tx.Sender()[:4], tmp, tx.Value, tx.Hash()) // Notify the subscribers - go self.Ethereum.EventMux().Post(TxPreEvent{tx}) + go self.eventMux.Post(TxPreEvent{tx}) return nil } diff --git a/core/types/block.go b/core/types/block.go index 0108bd586..2d889f35f 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -409,7 +409,7 @@ func (self *Block) Size() ethutil.StorageSize { // Implement RlpEncodable func (self *Block) RlpData() interface{} { - return self.Value().Val + return []interface{}{self.header(), self.transactions, self.rlpUncles()} } // Implement pow.Block diff --git a/core/types/common.go b/core/types/common.go index ba88b77e1..89cb5f498 100644 --- a/core/types/common.go +++ b/core/types/common.go @@ -4,8 +4,13 @@ import ( "math/big" "github.com/ethereum/go-ethereum/state" + "github.com/ethereum/go-ethereum/wire" ) type BlockProcessor interface { Process(*Block) (*big.Int, state.Messages, error) } + +type Broadcaster interface { + Broadcast(wire.MsgType, []interface{}) +} -- cgit From 2d09e67713757e2a80eb614562c97f962af36cf7 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 18 Dec 2014 13:17:24 +0100 Subject: Updated to new methods --- core/chain_manager.go | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'core') diff --git a/core/chain_manager.go b/core/chain_manager.go index c81552b5d..794ae0011 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -74,6 +74,13 @@ func (self *ChainManager) LastBlockNumber() uint64 { return self.lastBlockNumber } +func (self *ChainManager) LastBlockHash() []byte { + self.mu.RLock() + defer self.mu.RUnlock() + + return self.lastBlockHash +} + func (self *ChainManager) CurrentBlock() *types.Block { self.mu.RLock() defer self.mu.RUnlock() -- cgit From db494170dc819b1eb0d267b6e1ab36c6cfb63569 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 18 Dec 2014 15:18:13 +0100 Subject: Created generic message (easy for testing) --- core/block_manager.go | 4 +- core/state_transition.go | 98 +++++++++++++++++++++++++++++++---------------- core/transaction_pool.go | 17 ++++---- core/types/transaction.go | 88 +++++++++++++++++++++++++++--------------- core/vm_env.go | 10 ++--- 5 files changed, 137 insertions(+), 80 deletions(-) (limited to 'core') diff --git a/core/block_manager.go b/core/block_manager.go index 794c87f52..aa845a007 100644 --- a/core/block_manager.go +++ b/core/block_manager.go @@ -111,7 +111,7 @@ done: // If we are mining this block and validating we want to set the logs back to 0 state.EmptyLogs() - txGas := new(big.Int).Set(tx.Gas) + txGas := new(big.Int).Set(tx.Gas()) cb := state.GetStateObject(coinbase.Address()) st := NewStateTransition(cb, tx, state, block) @@ -134,7 +134,7 @@ done: } txGas.Sub(txGas, st.gas) - cumulativeSum.Add(cumulativeSum, new(big.Int).Mul(txGas, tx.GasPrice)) + cumulativeSum.Add(cumulativeSum, new(big.Int).Mul(txGas, tx.GasPrice())) // Update the state with pending changes state.Update(txGas) diff --git a/core/state_transition.go b/core/state_transition.go index 820ba66e6..a6b654842 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -5,6 +5,8 @@ import ( "math/big" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/vm" ) @@ -27,7 +29,7 @@ import ( */ type StateTransition struct { coinbase, receiver []byte - tx *types.Transaction + msg Message gas, gasPrice *big.Int value *big.Int data []byte @@ -35,10 +37,42 @@ type StateTransition struct { block *types.Block cb, rec, sen *state.StateObject + + Env vm.Environment +} + +type Message interface { + Hash() []byte + + CreatesContract() bool + + From() []byte + To() []byte + + GasValue() *big.Int + GasPrice() *big.Int + Gas() *big.Int + Value() *big.Int + + Nonce() uint64 + Data() []byte } -func NewStateTransition(coinbase *state.StateObject, tx *types.Transaction, state *state.StateDB, block *types.Block) *StateTransition { - return &StateTransition{coinbase.Address(), tx.Recipient, tx, new(big.Int), new(big.Int).Set(tx.GasPrice), tx.Value, tx.Data, state, block, coinbase, nil, nil} +func AddressFromMessage(msg Message) []byte { + // Generate a new address + return crypto.Sha3(ethutil.NewValue([]interface{}{msg.From(), msg.Nonce()}).Encode())[12:] +} + +func NewStateTransition(coinbase *state.StateObject, msg Message, state *state.StateDB, block *types.Block) *StateTransition { + return &StateTransition{coinbase.Address(), msg.To(), msg, new(big.Int), new(big.Int).Set(msg.GasPrice()), msg.Value(), msg.Data(), state, block, coinbase, nil, nil, nil} +} + +func (self *StateTransition) VmEnv() vm.Environment { + if self.Env == nil { + self.Env = NewEnv(self.state, self.msg, self.block) + } + + return self.Env } func (self *StateTransition) Coinbase() *state.StateObject { @@ -49,17 +83,17 @@ func (self *StateTransition) Coinbase() *state.StateObject { self.cb = self.state.GetOrNewStateObject(self.coinbase) return self.cb } -func (self *StateTransition) Sender() *state.StateObject { +func (self *StateTransition) From() *state.StateObject { if self.sen != nil { return self.sen } - self.sen = self.state.GetOrNewStateObject(self.tx.Sender()) + self.sen = self.state.GetOrNewStateObject(self.msg.From()) return self.sen } -func (self *StateTransition) Receiver() *state.StateObject { - if self.tx != nil && self.tx.CreatesContract() { +func (self *StateTransition) To() *state.StateObject { + if self.msg != nil && self.msg.CreatesContract() { return nil } @@ -67,7 +101,7 @@ func (self *StateTransition) Receiver() *state.StateObject { return self.rec } - self.rec = self.state.GetOrNewStateObject(self.tx.Recipient) + self.rec = self.state.GetOrNewStateObject(self.msg.To()) return self.rec } @@ -87,41 +121,41 @@ func (self *StateTransition) AddGas(amount *big.Int) { func (self *StateTransition) BuyGas() error { var err error - sender := self.Sender() - if sender.Balance().Cmp(self.tx.GasValue()) < 0 { - return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", self.tx.GasValue(), sender.Balance()) + sender := self.From() + if sender.Balance().Cmp(self.msg.GasValue()) < 0 { + return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", self.msg.GasValue(), sender.Balance()) } coinbase := self.Coinbase() - err = coinbase.BuyGas(self.tx.Gas, self.tx.GasPrice) + err = coinbase.BuyGas(self.msg.Gas(), self.msg.GasPrice()) if err != nil { return err } - self.AddGas(self.tx.Gas) - sender.SubAmount(self.tx.GasValue()) + self.AddGas(self.msg.Gas()) + sender.SubAmount(self.msg.GasValue()) return nil } func (self *StateTransition) RefundGas() { - coinbase, sender := self.Coinbase(), self.Sender() - coinbase.RefundGas(self.gas, self.tx.GasPrice) + coinbase, sender := self.Coinbase(), self.From() + coinbase.RefundGas(self.gas, self.msg.GasPrice()) // Return remaining gas - remaining := new(big.Int).Mul(self.gas, self.tx.GasPrice) + remaining := new(big.Int).Mul(self.gas, self.msg.GasPrice()) sender.AddAmount(remaining) } func (self *StateTransition) preCheck() (err error) { var ( - tx = self.tx - sender = self.Sender() + msg = self.msg + sender = self.From() ) // Make sure this transaction's nonce is correct - if sender.Nonce != tx.Nonce { - return NonceError(tx.Nonce, sender.Nonce) + if sender.Nonce != msg.Nonce() { + return NonceError(msg.Nonce(), sender.Nonce) } // Pre-pay gas / Buy gas of the coinbase account @@ -133,7 +167,7 @@ func (self *StateTransition) preCheck() (err error) { } func (self *StateTransition) TransitionState() (err error) { - statelogger.Debugf("(~) %x\n", self.tx.Hash()) + statelogger.Debugf("(~) %x\n", self.msg.Hash()) // XXX Transactions after this point are considered valid. if err = self.preCheck(); err != nil { @@ -141,8 +175,8 @@ func (self *StateTransition) TransitionState() (err error) { } var ( - tx = self.tx - sender = self.Sender() + msg = self.msg + sender = self.From() ) defer self.RefundGas() @@ -169,15 +203,15 @@ func (self *StateTransition) TransitionState() (err error) { } var ret []byte - vmenv := NewEnv(self.state, self.tx, self.block) + vmenv := self.VmEnv() var ref vm.ClosureRef - if tx.CreatesContract() { - self.rec = MakeContract(tx, self.state) + if msg.CreatesContract() { + self.rec = MakeContract(msg, self.state) - ret, err, ref = vmenv.Create(sender, self.rec.Address(), self.tx.Data, self.gas, self.gasPrice, self.value) + ret, err, ref = vmenv.Create(sender, self.rec.Address(), self.msg.Data(), self.gas, self.gasPrice, self.value) ref.SetCode(ret) } else { - ret, err = vmenv.Call(self.Sender(), self.Receiver().Address(), self.tx.Data, self.gas, self.gasPrice, self.value) + ret, err = vmenv.Call(self.From(), self.To().Address(), self.msg.Data(), self.gas, self.gasPrice, self.value) } if err != nil { statelogger.Debugln(err) @@ -187,11 +221,11 @@ func (self *StateTransition) TransitionState() (err error) { } // Converts an transaction in to a state object -func MakeContract(tx *types.Transaction, state *state.StateDB) *state.StateObject { - addr := tx.CreationAddress(state) +func MakeContract(msg Message, state *state.StateDB) *state.StateObject { + addr := AddressFromMessage(msg) contract := state.GetOrNewStateObject(addr) - contract.InitCode = tx.Data + contract.InitCode = msg.Data() return contract } diff --git a/core/transaction_pool.go b/core/transaction_pool.go index 36b0beb28..da91ec568 100644 --- a/core/transaction_pool.go +++ b/core/transaction_pool.go @@ -112,8 +112,8 @@ func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error { return fmt.Errorf("No last block on the block chain") } - if len(tx.Recipient) != 0 && len(tx.Recipient) != 20 { - return fmt.Errorf("Invalid recipient. len = %d", len(tx.Recipient)) + if len(tx.To()) != 0 && len(tx.To()) != 20 { + return fmt.Errorf("Invalid recipient. len = %d", len(tx.To())) } v, _, _ := tx.Curve() @@ -124,15 +124,15 @@ func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error { // Get the sender sender := pool.chainManager.State().GetAccount(tx.Sender()) - totAmount := new(big.Int).Set(tx.Value) + totAmount := new(big.Int).Set(tx.Value()) // Make sure there's enough in the sender's account. Having insufficient // funds won't invalidate this transaction but simple ignores it. if sender.Balance().Cmp(totAmount) < 0 { - return fmt.Errorf("Insufficient amount in sender's (%x) account", tx.Sender()) + return fmt.Errorf("Insufficient amount in sender's (%x) account", tx.From()) } if tx.IsContract() { - if tx.GasPrice.Cmp(big.NewInt(minGasPrice)) < 0 { + if tx.GasPrice().Cmp(big.NewInt(minGasPrice)) < 0 { return fmt.Errorf("Gasprice too low, %s given should be at least %d.", tx.GasPrice, minGasPrice) } } @@ -160,10 +160,7 @@ func (self *TxPool) Add(tx *types.Transaction) error { self.addTransaction(tx) - tmp := make([]byte, 4) - copy(tmp, tx.Recipient) - - txplogger.Debugf("(t) %x => %x (%v) %x\n", tx.Sender()[:4], tmp, tx.Value, tx.Hash()) + txplogger.Debugf("(t) %x => %x (%v) %x\n", tx.From()[:4], tx.To()[:4], tx.Value, tx.Hash()) // Notify the subscribers go self.eventMux.Post(TxPreEvent{tx}) @@ -200,7 +197,7 @@ func (pool *TxPool) RemoveInvalid(state *state.StateDB) { tx := e.Value.(*types.Transaction) sender := state.GetAccount(tx.Sender()) err := pool.ValidateTransaction(tx) - if err != nil || sender.Nonce >= tx.Nonce { + if err != nil || sender.Nonce >= tx.Nonce() { pool.pool.Remove(e) } } diff --git a/core/types/transaction.go b/core/types/transaction.go index 63edef756..4b75d3abd 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -6,7 +6,6 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethutil" - "github.com/ethereum/go-ethereum/state" "github.com/obscuren/secp256k1-go" ) @@ -18,12 +17,12 @@ func IsContractAddr(addr []byte) bool { } type Transaction struct { - Nonce uint64 - Recipient []byte - Value *big.Int - Gas *big.Int - GasPrice *big.Int - Data []byte + nonce uint64 + recipient []byte + value *big.Int + gas *big.Int + gasPrice *big.Int + data []byte v byte r, s []byte @@ -32,11 +31,11 @@ type Transaction struct { } func NewContractCreationTx(value, gas, gasPrice *big.Int, script []byte) *Transaction { - return &Transaction{Recipient: nil, Value: value, Gas: gas, GasPrice: gasPrice, Data: script, contractCreation: true} + return &Transaction{recipient: nil, value: value, gas: gas, gasPrice: gasPrice, data: script, contractCreation: true} } func NewTransactionMessage(to []byte, value, gas, gasPrice *big.Int, data []byte) *Transaction { - return &Transaction{Recipient: to, Value: value, GasPrice: gasPrice, Gas: gas, Data: data, contractCreation: IsContractAddr(to)} + return &Transaction{recipient: to, value: value, gasPrice: gasPrice, gas: gas, data: data, contractCreation: IsContractAddr(to)} } func NewTransactionFromBytes(data []byte) *Transaction { @@ -54,20 +53,52 @@ func NewTransactionFromValue(val *ethutil.Value) *Transaction { } func (self *Transaction) GasValue() *big.Int { - return new(big.Int).Mul(self.Gas, self.GasPrice) + return new(big.Int).Mul(self.gas, self.gasPrice) } func (self *Transaction) TotalValue() *big.Int { v := self.GasValue() - return v.Add(v, self.Value) + return v.Add(v, self.value) } func (tx *Transaction) Hash() []byte { - data := []interface{}{tx.Nonce, tx.GasPrice, tx.Gas, tx.Recipient, tx.Value, tx.Data} + data := []interface{}{tx.Nonce, tx.gasPrice, tx.gas, tx.recipient, tx.Value, tx.Data} return crypto.Sha3(ethutil.NewValue(data).Encode()) } +func (self *Transaction) Data() []byte { + return self.data +} + +func (self *Transaction) Gas() *big.Int { + return self.gas +} + +func (self *Transaction) GasPrice() *big.Int { + return self.gasPrice +} + +func (self *Transaction) Value() *big.Int { + return self.value +} + +func (self *Transaction) Nonce() uint64 { + return self.nonce +} + +func (self *Transaction) SetNonce(nonce uint64) { + self.nonce = nonce +} + +func (self *Transaction) From() []byte { + return self.Sender() +} + +func (self *Transaction) To() []byte { + return self.recipient +} + func (tx *Transaction) CreatesContract() bool { return tx.contractCreation } @@ -77,11 +108,6 @@ func (tx *Transaction) IsContract() bool { return tx.CreatesContract() } -func (tx *Transaction) CreationAddress(state *state.StateDB) []byte { - // Generate a new address - return crypto.Sha3(ethutil.NewValue([]interface{}{tx.Sender(), tx.Nonce}).Encode())[12:] -} - func (tx *Transaction) Curve() (v byte, r []byte, s []byte) { v = tx.v r = ethutil.LeftPadBytes(tx.r, 32) @@ -136,7 +162,7 @@ func (tx *Transaction) Sign(privk []byte) error { } func (tx *Transaction) RlpData() interface{} { - data := []interface{}{tx.Nonce, tx.GasPrice, tx.Gas, tx.Recipient, tx.Value, tx.Data} + data := []interface{}{tx.Nonce, tx.GasPrice, tx.Gas, tx.recipient, tx.Value, tx.Data} // TODO Remove prefixing zero's @@ -156,18 +182,18 @@ func (tx *Transaction) RlpDecode(data []byte) { } func (tx *Transaction) RlpValueDecode(decoder *ethutil.Value) { - tx.Nonce = decoder.Get(0).Uint() - tx.GasPrice = decoder.Get(1).BigInt() - tx.Gas = decoder.Get(2).BigInt() - tx.Recipient = decoder.Get(3).Bytes() - tx.Value = decoder.Get(4).BigInt() - tx.Data = decoder.Get(5).Bytes() + tx.nonce = decoder.Get(0).Uint() + tx.gasPrice = decoder.Get(1).BigInt() + tx.gas = decoder.Get(2).BigInt() + tx.recipient = decoder.Get(3).Bytes() + tx.value = decoder.Get(4).BigInt() + tx.data = decoder.Get(5).Bytes() tx.v = byte(decoder.Get(6).Uint()) tx.r = decoder.Get(7).Bytes() tx.s = decoder.Get(8).Bytes() - if IsContractAddr(tx.Recipient) { + if IsContractAddr(tx.recipient) { tx.contractCreation = true } } @@ -188,12 +214,12 @@ func (tx *Transaction) String() string { S: 0x%x `, tx.Hash(), - len(tx.Recipient) == 0, + len(tx.recipient) == 0, tx.Sender(), - tx.Recipient, - tx.Nonce, - tx.GasPrice, - tx.Gas, + tx.recipient, + tx.nonce, + tx.gasPrice, + tx.gas, tx.Value, tx.Data, tx.v, @@ -221,5 +247,5 @@ func (s Transactions) GetRlp(i int) []byte { return ethutil.Rlp(s[i]) } type TxByNonce struct{ Transactions } func (s TxByNonce) Less(i, j int) bool { - return s.Transactions[i].Nonce < s.Transactions[j].Nonce + return s.Transactions[i].nonce < s.Transactions[j].nonce } diff --git a/core/vm_env.go b/core/vm_env.go index 9e1815188..0b6744972 100644 --- a/core/vm_env.go +++ b/core/vm_env.go @@ -11,26 +11,26 @@ import ( type VMEnv struct { state *state.StateDB block *types.Block - tx *types.Transaction + msg Message depth int } -func NewEnv(state *state.StateDB, tx *types.Transaction, block *types.Block) *VMEnv { +func NewEnv(state *state.StateDB, msg Message, block *types.Block) *VMEnv { return &VMEnv{ state: state, block: block, - tx: tx, + msg: msg, } } -func (self *VMEnv) Origin() []byte { return self.tx.Sender() } +func (self *VMEnv) Origin() []byte { return self.msg.From() } func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number } func (self *VMEnv) PrevHash() []byte { return self.block.PrevHash } func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase } func (self *VMEnv) Time() int64 { return self.block.Time } func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty } func (self *VMEnv) BlockHash() []byte { return self.block.Hash() } -func (self *VMEnv) Value() *big.Int { return self.tx.Value } +func (self *VMEnv) Value() *big.Int { return self.msg.Value() } func (self *VMEnv) State() *state.StateDB { return self.state } func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit } func (self *VMEnv) Depth() int { return self.depth } -- cgit From 5ad473d7581b92811c3a3e035274a82fc5568f57 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 18 Dec 2014 15:33:22 +0100 Subject: Moved methods to messages --- core/state_transition.go | 10 ++++++---- core/transaction_pool.go | 6 ------ core/types/transaction.go | 23 ++--------------------- 3 files changed, 8 insertions(+), 31 deletions(-) (limited to 'core') diff --git a/core/state_transition.go b/core/state_transition.go index a6b654842..61c9558e3 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -44,8 +44,6 @@ type StateTransition struct { type Message interface { Hash() []byte - CreatesContract() bool - From() []byte To() []byte @@ -63,6 +61,10 @@ func AddressFromMessage(msg Message) []byte { return crypto.Sha3(ethutil.NewValue([]interface{}{msg.From(), msg.Nonce()}).Encode())[12:] } +func MessageCreatesContract(msg Message) bool { + return len(msg.To()) == 0 +} + func NewStateTransition(coinbase *state.StateObject, msg Message, state *state.StateDB, block *types.Block) *StateTransition { return &StateTransition{coinbase.Address(), msg.To(), msg, new(big.Int), new(big.Int).Set(msg.GasPrice()), msg.Value(), msg.Data(), state, block, coinbase, nil, nil, nil} } @@ -93,7 +95,7 @@ func (self *StateTransition) From() *state.StateObject { return self.sen } func (self *StateTransition) To() *state.StateObject { - if self.msg != nil && self.msg.CreatesContract() { + if self.msg != nil && MessageCreatesContract(self.msg) { return nil } @@ -205,7 +207,7 @@ func (self *StateTransition) TransitionState() (err error) { var ret []byte vmenv := self.VmEnv() var ref vm.ClosureRef - if msg.CreatesContract() { + if MessageCreatesContract(msg) { self.rec = MakeContract(msg, self.state) ret, err, ref = vmenv.Create(sender, self.rec.Address(), self.msg.Data(), self.gas, self.gasPrice, self.value) diff --git a/core/transaction_pool.go b/core/transaction_pool.go index da91ec568..58c2255a4 100644 --- a/core/transaction_pool.go +++ b/core/transaction_pool.go @@ -131,12 +131,6 @@ func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error { return fmt.Errorf("Insufficient amount in sender's (%x) account", tx.From()) } - if tx.IsContract() { - if tx.GasPrice().Cmp(big.NewInt(minGasPrice)) < 0 { - return fmt.Errorf("Gasprice too low, %s given should be at least %d.", tx.GasPrice, minGasPrice) - } - } - // Increment the nonce making each tx valid only once to prevent replay // attacks diff --git a/core/types/transaction.go b/core/types/transaction.go index 4b75d3abd..21d455f2e 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -9,11 +9,8 @@ import ( "github.com/obscuren/secp256k1-go" ) -var ContractAddr = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - func IsContractAddr(addr []byte) bool { return len(addr) == 0 - //return bytes.Compare(addr, ContractAddr) == 0 } type Transaction struct { @@ -25,17 +22,14 @@ type Transaction struct { data []byte v byte r, s []byte - - // Indicates whether this tx is a contract creation transaction - contractCreation bool } func NewContractCreationTx(value, gas, gasPrice *big.Int, script []byte) *Transaction { - return &Transaction{recipient: nil, value: value, gas: gas, gasPrice: gasPrice, data: script, contractCreation: true} + return &Transaction{recipient: nil, value: value, gas: gas, gasPrice: gasPrice, data: script} } func NewTransactionMessage(to []byte, value, gas, gasPrice *big.Int, data []byte) *Transaction { - return &Transaction{recipient: to, value: value, gasPrice: gasPrice, gas: gas, data: data, contractCreation: IsContractAddr(to)} + return &Transaction{recipient: to, value: value, gasPrice: gasPrice, gas: gas, data: data} } func NewTransactionFromBytes(data []byte) *Transaction { @@ -99,15 +93,6 @@ func (self *Transaction) To() []byte { return self.recipient } -func (tx *Transaction) CreatesContract() bool { - return tx.contractCreation -} - -/* Deprecated */ -func (tx *Transaction) IsContract() bool { - return tx.CreatesContract() -} - func (tx *Transaction) Curve() (v byte, r []byte, s []byte) { v = tx.v r = ethutil.LeftPadBytes(tx.r, 32) @@ -192,10 +177,6 @@ func (tx *Transaction) RlpValueDecode(decoder *ethutil.Value) { tx.r = decoder.Get(7).Bytes() tx.s = decoder.Get(8).Bytes() - - if IsContractAddr(tx.recipient) { - tx.contractCreation = true - } } func (tx *Transaction) String() string { -- cgit From 198cc69357a0f25ae486a041786e1239c6f5ab0f Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 18 Dec 2014 21:58:26 +0100 Subject: Gas corrections and vm fixes --- core/block_manager.go | 2 +- core/state_transition.go | 73 ++++++++++++++++++++++++----------------------- core/types/transaction.go | 9 ------ 3 files changed, 38 insertions(+), 46 deletions(-) (limited to 'core') diff --git a/core/block_manager.go b/core/block_manager.go index aa845a007..8d319f84e 100644 --- a/core/block_manager.go +++ b/core/block_manager.go @@ -115,7 +115,7 @@ done: cb := state.GetStateObject(coinbase.Address()) st := NewStateTransition(cb, tx, state, block) - err = st.TransitionState() + _, err = st.TransitionState() if err != nil { switch { case IsNonceErr(err): diff --git a/core/state_transition.go b/core/state_transition.go index 61c9558e3..34d8cca74 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -31,6 +31,7 @@ type StateTransition struct { coinbase, receiver []byte msg Message gas, gasPrice *big.Int + initialGas *big.Int value *big.Int data []byte state *state.StateDB @@ -47,7 +48,6 @@ type Message interface { From() []byte To() []byte - GasValue() *big.Int GasPrice() *big.Int Gas() *big.Int Value() *big.Int @@ -65,8 +65,12 @@ func MessageCreatesContract(msg Message) bool { return len(msg.To()) == 0 } +func MessageGasValue(msg Message) *big.Int { + return new(big.Int).Mul(msg.Gas(), msg.GasPrice()) +} + func NewStateTransition(coinbase *state.StateObject, msg Message, state *state.StateDB, block *types.Block) *StateTransition { - return &StateTransition{coinbase.Address(), msg.To(), msg, new(big.Int), new(big.Int).Set(msg.GasPrice()), msg.Value(), msg.Data(), state, block, coinbase, nil, nil, nil} + return &StateTransition{coinbase.Address(), msg.To(), msg, new(big.Int), new(big.Int).Set(msg.GasPrice()), new(big.Int), msg.Value(), msg.Data(), state, block, coinbase, nil, nil, nil} } func (self *StateTransition) VmEnv() vm.Environment { @@ -78,33 +82,16 @@ func (self *StateTransition) VmEnv() vm.Environment { } func (self *StateTransition) Coinbase() *state.StateObject { - if self.cb != nil { - return self.cb - } - - self.cb = self.state.GetOrNewStateObject(self.coinbase) - return self.cb + return self.state.GetOrNewStateObject(self.coinbase) } func (self *StateTransition) From() *state.StateObject { - if self.sen != nil { - return self.sen - } - - self.sen = self.state.GetOrNewStateObject(self.msg.From()) - - return self.sen + return self.state.GetOrNewStateObject(self.msg.From()) } func (self *StateTransition) To() *state.StateObject { if self.msg != nil && MessageCreatesContract(self.msg) { return nil } - - if self.rec != nil { - return self.rec - } - - self.rec = self.state.GetOrNewStateObject(self.msg.To()) - return self.rec + return self.state.GetOrNewStateObject(self.msg.To()) } func (self *StateTransition) UseGas(amount *big.Int) error { @@ -124,8 +111,8 @@ func (self *StateTransition) BuyGas() error { var err error sender := self.From() - if sender.Balance().Cmp(self.msg.GasValue()) < 0 { - return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", self.msg.GasValue(), sender.Balance()) + if sender.Balance().Cmp(MessageGasValue(self.msg)) < 0 { + return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", MessageGasValue(self.msg), sender.Balance()) } coinbase := self.Coinbase() @@ -135,20 +122,12 @@ func (self *StateTransition) BuyGas() error { } self.AddGas(self.msg.Gas()) - sender.SubAmount(self.msg.GasValue()) + self.initialGas.Set(self.msg.Gas()) + sender.SubAmount(MessageGasValue(self.msg)) return nil } -func (self *StateTransition) RefundGas() { - coinbase, sender := self.Coinbase(), self.From() - coinbase.RefundGas(self.gas, self.msg.GasPrice()) - - // Return remaining gas - remaining := new(big.Int).Mul(self.gas, self.msg.GasPrice()) - sender.AddAmount(remaining) -} - func (self *StateTransition) preCheck() (err error) { var ( msg = self.msg @@ -168,7 +147,7 @@ func (self *StateTransition) preCheck() (err error) { return nil } -func (self *StateTransition) TransitionState() (err error) { +func (self *StateTransition) TransitionState() (ret []byte, err error) { statelogger.Debugf("(~) %x\n", self.msg.Hash()) // XXX Transactions after this point are considered valid. @@ -204,7 +183,6 @@ func (self *StateTransition) TransitionState() (err error) { return } - var ret []byte vmenv := self.VmEnv() var ref vm.ClosureRef if MessageCreatesContract(msg) { @@ -231,3 +209,26 @@ func MakeContract(msg Message, state *state.StateDB) *state.StateObject { return contract } + +func (self *StateTransition) RefundGas() { + coinbaseSub := new(big.Int).Set(self.gas) + uhalf := new(big.Int).Div(self.GasUsed(), ethutil.Big2) + for addr, refs := range self.state.Refunds() { + for _, ref := range refs { + coinbaseSub.Add(self.gas, ref) + refund := ethutil.BigMin(uhalf, ref) + self.state.AddBalance([]byte(addr), refund.Mul(refund, self.msg.GasPrice())) + } + } + + coinbase, sender := self.Coinbase(), self.From() + coinbase.RefundGas(coinbaseSub, self.msg.GasPrice()) + + // Return remaining gas + remaining := new(big.Int).Mul(self.gas, self.msg.GasPrice()) + sender.AddAmount(remaining) +} + +func (self *StateTransition) GasUsed() *big.Int { + return new(big.Int).Sub(self.initialGas, self.gas) +} diff --git a/core/types/transaction.go b/core/types/transaction.go index 21d455f2e..c64fb69f0 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -46,15 +46,6 @@ func NewTransactionFromValue(val *ethutil.Value) *Transaction { return tx } -func (self *Transaction) GasValue() *big.Int { - return new(big.Int).Mul(self.gas, self.gasPrice) -} - -func (self *Transaction) TotalValue() *big.Int { - v := self.GasValue() - return v.Add(v, self.value) -} - func (tx *Transaction) Hash() []byte { data := []interface{}{tx.Nonce, tx.gasPrice, tx.gas, tx.recipient, tx.Value, tx.Data} -- cgit From 332568379454dce6b1fb3c3e023a53d0c52cded0 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 18 Dec 2014 22:38:51 +0100 Subject: Fixed refund model --- core/state_transition.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'core') diff --git a/core/state_transition.go b/core/state_transition.go index 34d8cca74..9e81ddf28 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -213,12 +213,10 @@ func MakeContract(msg Message, state *state.StateDB) *state.StateObject { func (self *StateTransition) RefundGas() { coinbaseSub := new(big.Int).Set(self.gas) uhalf := new(big.Int).Div(self.GasUsed(), ethutil.Big2) - for addr, refs := range self.state.Refunds() { - for _, ref := range refs { - coinbaseSub.Add(self.gas, ref) - refund := ethutil.BigMin(uhalf, ref) - self.state.AddBalance([]byte(addr), refund.Mul(refund, self.msg.GasPrice())) - } + for addr, ref := range self.state.Refunds() { + refund := ethutil.BigMin(uhalf, ref) + coinbaseSub.Add(self.gas, refund) + self.state.AddBalance([]byte(addr), refund.Mul(refund, self.msg.GasPrice())) } coinbase, sender := self.Coinbase(), self.From() -- cgit From 59ef6e36931c980ba15babfb3680514635faebf6 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 19 Dec 2014 00:18:52 +0100 Subject: Cleaned up objects --- core/execution.go | 6 ++++-- core/vm_env.go | 4 +--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'core') diff --git a/core/execution.go b/core/execution.go index 827e1ee0e..cd98746c4 100644 --- a/core/execution.go +++ b/core/execution.go @@ -16,8 +16,10 @@ type Execution struct { SkipTransfer bool } -func NewExecution(vm vm.VirtualMachine, address, input []byte, gas, gasPrice, value *big.Int) *Execution { - return &Execution{vm: vm, address: address, input: input, Gas: gas, price: gasPrice, value: value} +func NewExecution(env vm.Environment, address, input []byte, gas, gasPrice, value *big.Int) *Execution { + evm := vm.New(env, vm.DebugVmTy) + + return &Execution{vm: evm, address: address, input: input, Gas: gas, price: gasPrice, value: value} } func (self *Execution) Addr() []byte { diff --git a/core/vm_env.go b/core/vm_env.go index 0b6744972..ad63ecf9c 100644 --- a/core/vm_env.go +++ b/core/vm_env.go @@ -43,9 +43,7 @@ func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error { } func (self *VMEnv) vm(addr, data []byte, gas, price, value *big.Int) *Execution { - evm := vm.New(self, vm.DebugVmTy) - - return NewExecution(evm, addr, data, gas, price, value) + return NewExecution(self, addr, data, gas, price, value) } func (self *VMEnv) Call(me vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) { -- cgit From 12671c82eadc367a43502109e5e0237e228da998 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 19 Dec 2014 00:23:00 +0100 Subject: Moved VM to execution --- core/execution.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'core') diff --git a/core/execution.go b/core/execution.go index cd98746c4..0b5e0558f 100644 --- a/core/execution.go +++ b/core/execution.go @@ -9,7 +9,7 @@ import ( ) type Execution struct { - vm vm.VirtualMachine + env vm.Environment address, input []byte Gas, price, value *big.Int object *state.StateObject @@ -17,9 +17,7 @@ type Execution struct { } func NewExecution(env vm.Environment, address, input []byte, gas, gasPrice, value *big.Int) *Execution { - evm := vm.New(env, vm.DebugVmTy) - - return &Execution{vm: evm, address: address, input: input, Gas: gas, price: gasPrice, value: value} + return &Execution{env: env, address: address, input: input, Gas: gas, price: gasPrice, value: value} } func (self *Execution) Addr() []byte { @@ -28,16 +26,18 @@ func (self *Execution) Addr() []byte { func (self *Execution) Call(codeAddr []byte, caller vm.ClosureRef) ([]byte, error) { // Retrieve the executing code - code := self.vm.Env().State().GetCode(codeAddr) + code := self.env.State().GetCode(codeAddr) return self.exec(code, codeAddr, caller) } func (self *Execution) exec(code, contextAddr []byte, caller vm.ClosureRef) (ret []byte, err error) { - env := self.vm.Env() + env := self.env + evm := vm.New(env, vm.DebugVmTy) + chainlogger.Debugf("pre state %x\n", env.State().Root()) - if self.vm.Env().Depth() == vm.MaxCallDepth { + if env.Depth() == vm.MaxCallDepth { // Consume all gas (by not returning it) and return a depth error return nil, vm.DepthError{} } @@ -56,21 +56,21 @@ func (self *Execution) exec(code, contextAddr []byte, caller vm.ClosureRef) (ret snapshot := env.State().Copy() defer func() { - if /*vm.IsDepthErr(err) ||*/ vm.IsOOGErr(err) { + if vm.IsOOGErr(err) { env.State().Set(snapshot) } chainlogger.Debugf("post state %x\n", env.State().Root()) }() self.object = to - ret, err = self.vm.Run(to, caller, code, self.value, self.Gas, self.price, self.input) + ret, err = evm.Run(to, caller, code, self.value, self.Gas, self.price, self.input) return } func (self *Execution) Create(caller vm.ClosureRef) (ret []byte, err error, account *state.StateObject) { ret, err = self.exec(self.input, nil, caller) - account = self.vm.Env().State().GetStateObject(self.address) + account = self.env.State().GetStateObject(self.address) return } -- cgit From 0e93b98533968f4a0033ec6214391f5ca647a956 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 19 Dec 2014 13:34:53 +0100 Subject: Transaction was generating incorrect hash because of var changes --- core/state_transition.go | 2 +- core/types/transaction.go | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) (limited to 'core') diff --git a/core/state_transition.go b/core/state_transition.go index 9e81ddf28..a54246eba 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -112,7 +112,7 @@ func (self *StateTransition) BuyGas() error { sender := self.From() if sender.Balance().Cmp(MessageGasValue(self.msg)) < 0 { - return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", MessageGasValue(self.msg), sender.Balance()) + return fmt.Errorf("insufficient ETH for gas (%x). Req %v, has %v", sender.Address()[:4], MessageGasValue(self.msg), sender.Balance()) } coinbase := self.Coinbase() diff --git a/core/types/transaction.go b/core/types/transaction.go index c64fb69f0..f6ad0774b 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -47,7 +47,7 @@ func NewTransactionFromValue(val *ethutil.Value) *Transaction { } func (tx *Transaction) Hash() []byte { - data := []interface{}{tx.Nonce, tx.gasPrice, tx.gas, tx.recipient, tx.Value, tx.Data} + data := []interface{}{tx.nonce, tx.gasPrice, tx.gas, tx.recipient, tx.value, tx.data} return crypto.Sha3(ethutil.NewValue(data).Encode()) } @@ -108,8 +108,8 @@ func (tx *Transaction) PublicKey() []byte { sig := append(r, s...) sig = append(sig, v-27) - pubkey := crypto.Ecrecover(append(hash, sig...)) - //pubkey, _ := secp256k1.RecoverPubkey(hash, sig) + //pubkey := crypto.Ecrecover(append(hash, sig...)) + pubkey, _ := secp256k1.RecoverPubkey(hash, sig) return pubkey } @@ -138,9 +138,7 @@ func (tx *Transaction) Sign(privk []byte) error { } func (tx *Transaction) RlpData() interface{} { - data := []interface{}{tx.Nonce, tx.GasPrice, tx.Gas, tx.recipient, tx.Value, tx.Data} - - // TODO Remove prefixing zero's + data := []interface{}{tx.nonce, tx.gasPrice, tx.gas, tx.recipient, tx.value, tx.data} return append(data, tx.v, new(big.Int).SetBytes(tx.r).Bytes(), new(big.Int).SetBytes(tx.s).Bytes()) } @@ -184,6 +182,7 @@ func (tx *Transaction) String() string { V: 0x%x R: 0x%x S: 0x%x + Hex: %x `, tx.Hash(), len(tx.recipient) == 0, @@ -192,11 +191,13 @@ func (tx *Transaction) String() string { tx.nonce, tx.gasPrice, tx.gas, - tx.Value, - tx.Data, + tx.value, + tx.data, tx.v, tx.r, - tx.s) + tx.s, + ethutil.Encode(tx), + ) } // Transaction slice type for basic sorting -- cgit From f5b8f3d41b533d51eb81e895ed9b6aa31d7aaaef Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 19 Dec 2014 13:59:49 +0100 Subject: Removed OOG check. Revert should always happen. --- core/block_manager.go | 2 +- core/execution.go | 4 +--- core/state_transition.go | 11 +++++++++-- 3 files changed, 11 insertions(+), 6 deletions(-) (limited to 'core') diff --git a/core/block_manager.go b/core/block_manager.go index 8d319f84e..20285f8f0 100644 --- a/core/block_manager.go +++ b/core/block_manager.go @@ -129,7 +129,6 @@ done: statelogger.Infoln(err) erroneous = append(erroneous, tx) err = nil - continue } } @@ -215,6 +214,7 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I receiptSha := types.DeriveSha(receipts) if bytes.Compare(receiptSha, block.ReceiptSha) != 0 { + chainlogger.Debugln(receipts) err = fmt.Errorf("validating receipt root. received=%x got=%x", block.ReceiptSha, receiptSha) return } diff --git a/core/execution.go b/core/execution.go index 0b5e0558f..44dbd3ace 100644 --- a/core/execution.go +++ b/core/execution.go @@ -56,9 +56,7 @@ func (self *Execution) exec(code, contextAddr []byte, caller vm.ClosureRef) (ret snapshot := env.State().Copy() defer func() { - if vm.IsOOGErr(err) { - env.State().Set(snapshot) - } + env.State().Set(snapshot) chainlogger.Debugf("post state %x\n", env.State().Root()) }() diff --git a/core/state_transition.go b/core/state_transition.go index a54246eba..a60f31e3e 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -189,12 +189,19 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) { self.rec = MakeContract(msg, self.state) ret, err, ref = vmenv.Create(sender, self.rec.Address(), self.msg.Data(), self.gas, self.gasPrice, self.value) - ref.SetCode(ret) + if err == nil { + dataGas := big.NewInt(int64(len(ret))) + dataGas.Mul(dataGas, vm.GasCreateByte) + if err = self.UseGas(dataGas); err == nil { + ref.SetCode(ret) + } + } } else { ret, err = vmenv.Call(self.From(), self.To().Address(), self.msg.Data(), self.gas, self.gasPrice, self.value) } + if err != nil { - statelogger.Debugln(err) + self.UseGas(self.gas) } return -- cgit From 1508a23a6fe3cc50f718bfd6c62caae056534c09 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 20 Dec 2014 02:21:13 +0100 Subject: Minor updates on gas and removed/refactored old code. --- core/block_manager.go | 4 +++- core/execution.go | 15 ++++++--------- core/state_transition.go | 21 ++++++++++----------- 3 files changed, 19 insertions(+), 21 deletions(-) (limited to 'core') diff --git a/core/block_manager.go b/core/block_manager.go index 20285f8f0..2567e39c4 100644 --- a/core/block_manager.go +++ b/core/block_manager.go @@ -142,6 +142,7 @@ done: receipt := types.NewReceipt(state.Root(), cumulative) receipt.SetLogs(state.Logs()) receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) + chainlogger.Debugln(receipt) // Notify all subscribers if !transientProcess { @@ -214,7 +215,8 @@ func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.I receiptSha := types.DeriveSha(receipts) if bytes.Compare(receiptSha, block.ReceiptSha) != 0 { - chainlogger.Debugln(receipts) + //chainlogger.Debugf("validating receipt root. received=%x got=%x", block.ReceiptSha, receiptSha) + fmt.Printf("%x\n", ethutil.Encode(receipts)) err = fmt.Errorf("validating receipt root. received=%x got=%x", block.ReceiptSha, receiptSha) return } diff --git a/core/execution.go b/core/execution.go index 44dbd3ace..b7eead0dd 100644 --- a/core/execution.go +++ b/core/execution.go @@ -3,6 +3,7 @@ package core import ( "fmt" "math/big" + "time" "github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/vm" @@ -12,7 +13,6 @@ type Execution struct { env vm.Environment address, input []byte Gas, price, value *big.Int - object *state.StateObject SkipTransfer bool } @@ -35,8 +35,6 @@ func (self *Execution) exec(code, contextAddr []byte, caller vm.ClosureRef) (ret env := self.env evm := vm.New(env, vm.DebugVmTy) - chainlogger.Debugf("pre state %x\n", env.State().Root()) - if env.Depth() == vm.MaxCallDepth { // Consume all gas (by not returning it) and return a depth error return nil, vm.DepthError{} @@ -55,13 +53,12 @@ func (self *Execution) exec(code, contextAddr []byte, caller vm.ClosureRef) (ret } snapshot := env.State().Copy() - defer func() { - env.State().Set(snapshot) - chainlogger.Debugf("post state %x\n", env.State().Root()) - }() - - self.object = to + start := time.Now() ret, err = evm.Run(to, caller, code, self.value, self.Gas, self.price, self.input) + if err != nil { + env.State().Set(snapshot) + } + chainlogger.Debugf("vm took %v\n", time.Since(start)) return } diff --git a/core/state_transition.go b/core/state_transition.go index a60f31e3e..7b7026c29 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -186,13 +186,13 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) { vmenv := self.VmEnv() var ref vm.ClosureRef if MessageCreatesContract(msg) { - self.rec = MakeContract(msg, self.state) - - ret, err, ref = vmenv.Create(sender, self.rec.Address(), self.msg.Data(), self.gas, self.gasPrice, self.value) + contract := MakeContract(msg, self.state) + ret, err, ref = vmenv.Create(sender, contract.Address(), self.msg.Data(), self.gas, self.gasPrice, self.value) if err == nil { dataGas := big.NewInt(int64(len(ret))) dataGas.Mul(dataGas, vm.GasCreateByte) if err = self.UseGas(dataGas); err == nil { + //self.state.SetCode(ref.Address(), ret) ref.SetCode(ret) } } @@ -218,20 +218,19 @@ func MakeContract(msg Message, state *state.StateDB) *state.StateObject { } func (self *StateTransition) RefundGas() { - coinbaseSub := new(big.Int).Set(self.gas) + coinbase, sender := self.Coinbase(), self.From() + // Return remaining gas + remaining := new(big.Int).Mul(self.gas, self.msg.GasPrice()) + sender.AddAmount(remaining) + uhalf := new(big.Int).Div(self.GasUsed(), ethutil.Big2) for addr, ref := range self.state.Refunds() { refund := ethutil.BigMin(uhalf, ref) - coinbaseSub.Add(self.gas, refund) + self.gas.Add(self.gas, refund) self.state.AddBalance([]byte(addr), refund.Mul(refund, self.msg.GasPrice())) } - coinbase, sender := self.Coinbase(), self.From() - coinbase.RefundGas(coinbaseSub, self.msg.GasPrice()) - - // Return remaining gas - remaining := new(big.Int).Mul(self.gas, self.msg.GasPrice()) - sender.AddAmount(remaining) + coinbase.RefundGas(self.gas, self.msg.GasPrice()) } func (self *StateTransition) GasUsed() *big.Int { -- cgit