github.1485827954.workers.dev/ethereum/go-ethereum@v1.14.3/core/state/state_test.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package state 18 19 import ( 20 "bytes" 21 "encoding/json" 22 "testing" 23 24 "github.com/ethereum/go-ethereum/common" 25 "github.com/ethereum/go-ethereum/core/rawdb" 26 "github.com/ethereum/go-ethereum/core/tracing" 27 "github.com/ethereum/go-ethereum/core/types" 28 "github.com/ethereum/go-ethereum/crypto" 29 "github.com/ethereum/go-ethereum/ethdb" 30 "github.com/ethereum/go-ethereum/triedb" 31 "github.com/holiman/uint256" 32 ) 33 34 type stateEnv struct { 35 db ethdb.Database 36 state *StateDB 37 } 38 39 func newStateEnv() *stateEnv { 40 db := rawdb.NewMemoryDatabase() 41 sdb, _ := New(types.EmptyRootHash, NewDatabase(db), nil) 42 return &stateEnv{db: db, state: sdb} 43 } 44 45 func TestDump(t *testing.T) { 46 db := rawdb.NewMemoryDatabase() 47 tdb := NewDatabaseWithConfig(db, &triedb.Config{Preimages: true}) 48 sdb, _ := New(types.EmptyRootHash, tdb, nil) 49 s := &stateEnv{db: db, state: sdb} 50 51 // generate a few entries 52 obj1 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x01})) 53 obj1.AddBalance(uint256.NewInt(22), tracing.BalanceChangeUnspecified) 54 obj2 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x01, 0x02})) 55 obj2.SetCode(crypto.Keccak256Hash([]byte{3, 3, 3, 3, 3, 3, 3}), []byte{3, 3, 3, 3, 3, 3, 3}) 56 obj3 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x02})) 57 obj3.SetBalance(uint256.NewInt(44), tracing.BalanceChangeUnspecified) 58 59 // write some of them to the trie 60 s.state.updateStateObject(obj1) 61 s.state.updateStateObject(obj2) 62 root, _ := s.state.Commit(0, false) 63 64 // check that DumpToCollector contains the state objects that are in trie 65 s.state, _ = New(root, tdb, nil) 66 got := string(s.state.Dump(nil)) 67 want := `{ 68 "root": "71edff0130dd2385947095001c73d9e28d862fc286fca2b922ca6f6f3cddfdd2", 69 "accounts": { 70 "0x0000000000000000000000000000000000000001": { 71 "balance": "22", 72 "nonce": 0, 73 "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", 74 "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", 75 "address": "0x0000000000000000000000000000000000000001", 76 "key": "0x1468288056310c82aa4c01a7e12a10f8111a0560e72b700555479031b86c357d" 77 }, 78 "0x0000000000000000000000000000000000000002": { 79 "balance": "44", 80 "nonce": 0, 81 "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", 82 "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", 83 "address": "0x0000000000000000000000000000000000000002", 84 "key": "0xd52688a8f926c816ca1e079067caba944f158e764817b83fc43594370ca9cf62" 85 }, 86 "0x0000000000000000000000000000000000000102": { 87 "balance": "0", 88 "nonce": 0, 89 "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", 90 "codeHash": "0x87874902497a5bb968da31a2998d8f22e949d1ef6214bcdedd8bae24cca4b9e3", 91 "code": "0x03030303030303", 92 "address": "0x0000000000000000000000000000000000000102", 93 "key": "0xa17eacbc25cda025e81db9c5c62868822c73ce097cee2a63e33a2e41268358a1" 94 } 95 } 96 }` 97 if got != want { 98 t.Errorf("DumpToCollector mismatch:\ngot: %s\nwant: %s\n", got, want) 99 } 100 } 101 102 func TestIterativeDump(t *testing.T) { 103 db := rawdb.NewMemoryDatabase() 104 tdb := NewDatabaseWithConfig(db, &triedb.Config{Preimages: true}) 105 sdb, _ := New(types.EmptyRootHash, tdb, nil) 106 s := &stateEnv{db: db, state: sdb} 107 108 // generate a few entries 109 obj1 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x01})) 110 obj1.AddBalance(uint256.NewInt(22), tracing.BalanceChangeUnspecified) 111 obj2 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x01, 0x02})) 112 obj2.SetCode(crypto.Keccak256Hash([]byte{3, 3, 3, 3, 3, 3, 3}), []byte{3, 3, 3, 3, 3, 3, 3}) 113 obj3 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x02})) 114 obj3.SetBalance(uint256.NewInt(44), tracing.BalanceChangeUnspecified) 115 obj4 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x00})) 116 obj4.AddBalance(uint256.NewInt(1337), tracing.BalanceChangeUnspecified) 117 118 // write some of them to the trie 119 s.state.updateStateObject(obj1) 120 s.state.updateStateObject(obj2) 121 root, _ := s.state.Commit(0, false) 122 s.state, _ = New(root, tdb, nil) 123 124 b := &bytes.Buffer{} 125 s.state.IterativeDump(nil, json.NewEncoder(b)) 126 // check that DumpToCollector contains the state objects that are in trie 127 got := b.String() 128 want := `{"root":"0xd5710ea8166b7b04bc2bfb129d7db12931cee82f75ca8e2d075b4884322bf3de"} 129 {"balance":"22","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","address":"0x0000000000000000000000000000000000000001","key":"0x1468288056310c82aa4c01a7e12a10f8111a0560e72b700555479031b86c357d"} 130 {"balance":"1337","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","address":"0x0000000000000000000000000000000000000000","key":"0x5380c7b7ae81a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312a"} 131 {"balance":"0","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0x87874902497a5bb968da31a2998d8f22e949d1ef6214bcdedd8bae24cca4b9e3","code":"0x03030303030303","address":"0x0000000000000000000000000000000000000102","key":"0xa17eacbc25cda025e81db9c5c62868822c73ce097cee2a63e33a2e41268358a1"} 132 {"balance":"44","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","address":"0x0000000000000000000000000000000000000002","key":"0xd52688a8f926c816ca1e079067caba944f158e764817b83fc43594370ca9cf62"} 133 ` 134 if got != want { 135 t.Errorf("DumpToCollector mismatch:\ngot: %s\nwant: %s\n", got, want) 136 } 137 } 138 139 func TestNull(t *testing.T) { 140 s := newStateEnv() 141 address := common.HexToAddress("0x823140710bf13990e4500136726d8b55") 142 s.state.CreateAccount(address) 143 //value := common.FromHex("0x823140710bf13990e4500136726d8b55") 144 var value common.Hash 145 146 s.state.SetState(address, common.Hash{}, value) 147 s.state.Commit(0, false) 148 149 if value := s.state.GetState(address, common.Hash{}); value != (common.Hash{}) { 150 t.Errorf("expected empty current value, got %x", value) 151 } 152 if value := s.state.GetCommittedState(address, common.Hash{}); value != (common.Hash{}) { 153 t.Errorf("expected empty committed value, got %x", value) 154 } 155 } 156 157 func TestSnapshot(t *testing.T) { 158 stateobjaddr := common.BytesToAddress([]byte("aa")) 159 var storageaddr common.Hash 160 data1 := common.BytesToHash([]byte{42}) 161 data2 := common.BytesToHash([]byte{43}) 162 s := newStateEnv() 163 164 // snapshot the genesis state 165 genesis := s.state.Snapshot() 166 167 // set initial state object value 168 s.state.SetState(stateobjaddr, storageaddr, data1) 169 snapshot := s.state.Snapshot() 170 171 // set a new state object value, revert it and ensure correct content 172 s.state.SetState(stateobjaddr, storageaddr, data2) 173 s.state.RevertToSnapshot(snapshot) 174 175 if v := s.state.GetState(stateobjaddr, storageaddr); v != data1 { 176 t.Errorf("wrong storage value %v, want %v", v, data1) 177 } 178 if v := s.state.GetCommittedState(stateobjaddr, storageaddr); v != (common.Hash{}) { 179 t.Errorf("wrong committed storage value %v, want %v", v, common.Hash{}) 180 } 181 182 // revert up to the genesis state and ensure correct content 183 s.state.RevertToSnapshot(genesis) 184 if v := s.state.GetState(stateobjaddr, storageaddr); v != (common.Hash{}) { 185 t.Errorf("wrong storage value %v, want %v", v, common.Hash{}) 186 } 187 if v := s.state.GetCommittedState(stateobjaddr, storageaddr); v != (common.Hash{}) { 188 t.Errorf("wrong committed storage value %v, want %v", v, common.Hash{}) 189 } 190 } 191 192 func TestSnapshotEmpty(t *testing.T) { 193 s := newStateEnv() 194 s.state.RevertToSnapshot(s.state.Snapshot()) 195 } 196 197 func TestCreateObjectRevert(t *testing.T) { 198 state, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil) 199 addr := common.BytesToAddress([]byte("so0")) 200 snap := state.Snapshot() 201 202 state.CreateAccount(addr) 203 so0 := state.getStateObject(addr) 204 so0.SetBalance(uint256.NewInt(42), tracing.BalanceChangeUnspecified) 205 so0.SetNonce(43) 206 so0.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e'}), []byte{'c', 'a', 'f', 'e'}) 207 state.setStateObject(so0) 208 209 state.RevertToSnapshot(snap) 210 if state.Exist(addr) { 211 t.Error("Unexpected account after revert") 212 } 213 }