github.com/ethereum/go-ethereum@v1.16.1/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/types" 27 "github.com/ethereum/go-ethereum/crypto" 28 "github.com/ethereum/go-ethereum/triedb" 29 "github.com/holiman/uint256" 30 ) 31 32 type stateEnv struct { 33 state *StateDB 34 } 35 36 func newStateEnv() *stateEnv { 37 sdb, _ := New(types.EmptyRootHash, NewDatabaseForTesting()) 38 return &stateEnv{state: sdb} 39 } 40 41 func TestDump(t *testing.T) { 42 db := rawdb.NewMemoryDatabase() 43 triedb := triedb.NewDatabase(db, &triedb.Config{Preimages: true}) 44 tdb := NewDatabase(triedb, nil) 45 sdb, _ := New(types.EmptyRootHash, tdb) 46 s := &stateEnv{state: sdb} 47 48 // generate a few entries 49 obj1 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x01})) 50 obj1.AddBalance(uint256.NewInt(22)) 51 obj2 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x01, 0x02})) 52 obj2.SetCode(crypto.Keccak256Hash([]byte{3, 3, 3, 3, 3, 3, 3}), []byte{3, 3, 3, 3, 3, 3, 3}) 53 obj3 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x02})) 54 obj3.SetBalance(uint256.NewInt(44)) 55 56 // write some of them to the trie 57 root, _ := s.state.Commit(0, false, false) 58 59 // check that DumpToCollector contains the state objects that are in trie 60 s.state, _ = New(root, tdb) 61 got := string(s.state.Dump(nil)) 62 want := `{ 63 "root": "71edff0130dd2385947095001c73d9e28d862fc286fca2b922ca6f6f3cddfdd2", 64 "accounts": { 65 "0x0000000000000000000000000000000000000001": { 66 "balance": "22", 67 "nonce": 0, 68 "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", 69 "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", 70 "address": "0x0000000000000000000000000000000000000001", 71 "key": "0x1468288056310c82aa4c01a7e12a10f8111a0560e72b700555479031b86c357d" 72 }, 73 "0x0000000000000000000000000000000000000002": { 74 "balance": "44", 75 "nonce": 0, 76 "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", 77 "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", 78 "address": "0x0000000000000000000000000000000000000002", 79 "key": "0xd52688a8f926c816ca1e079067caba944f158e764817b83fc43594370ca9cf62" 80 }, 81 "0x0000000000000000000000000000000000000102": { 82 "balance": "0", 83 "nonce": 0, 84 "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", 85 "codeHash": "0x87874902497a5bb968da31a2998d8f22e949d1ef6214bcdedd8bae24cca4b9e3", 86 "code": "0x03030303030303", 87 "address": "0x0000000000000000000000000000000000000102", 88 "key": "0xa17eacbc25cda025e81db9c5c62868822c73ce097cee2a63e33a2e41268358a1" 89 } 90 } 91 }` 92 if got != want { 93 t.Errorf("DumpToCollector mismatch:\ngot: %s\nwant: %s\n", got, want) 94 } 95 } 96 97 func TestIterativeDump(t *testing.T) { 98 db := rawdb.NewMemoryDatabase() 99 triedb := triedb.NewDatabase(db, &triedb.Config{Preimages: true}) 100 tdb := NewDatabase(triedb, nil) 101 sdb, _ := New(types.EmptyRootHash, tdb) 102 s := &stateEnv{state: sdb} 103 104 // generate a few entries 105 obj1 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x01})) 106 obj1.AddBalance(uint256.NewInt(22)) 107 obj2 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x01, 0x02})) 108 obj2.SetCode(crypto.Keccak256Hash([]byte{3, 3, 3, 3, 3, 3, 3}), []byte{3, 3, 3, 3, 3, 3, 3}) 109 obj3 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x02})) 110 obj3.SetBalance(uint256.NewInt(44)) 111 obj4 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x00})) 112 obj4.AddBalance(uint256.NewInt(1337)) 113 114 // write some of them to the trie 115 root, _ := s.state.Commit(0, false, false) 116 s.state, _ = New(root, tdb) 117 118 b := &bytes.Buffer{} 119 s.state.IterativeDump(nil, json.NewEncoder(b)) 120 // check that DumpToCollector contains the state objects that are in trie 121 got := b.String() 122 want := `{"root":"0xd5710ea8166b7b04bc2bfb129d7db12931cee82f75ca8e2d075b4884322bf3de"} 123 {"balance":"22","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","address":"0x0000000000000000000000000000000000000001","key":"0x1468288056310c82aa4c01a7e12a10f8111a0560e72b700555479031b86c357d"} 124 {"balance":"1337","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","address":"0x0000000000000000000000000000000000000000","key":"0x5380c7b7ae81a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312a"} 125 {"balance":"0","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0x87874902497a5bb968da31a2998d8f22e949d1ef6214bcdedd8bae24cca4b9e3","code":"0x03030303030303","address":"0x0000000000000000000000000000000000000102","key":"0xa17eacbc25cda025e81db9c5c62868822c73ce097cee2a63e33a2e41268358a1"} 126 {"balance":"44","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","address":"0x0000000000000000000000000000000000000002","key":"0xd52688a8f926c816ca1e079067caba944f158e764817b83fc43594370ca9cf62"} 127 ` 128 if got != want { 129 t.Errorf("DumpToCollector mismatch:\ngot: %s\nwant: %s\n", got, want) 130 } 131 } 132 133 func TestNull(t *testing.T) { 134 s := newStateEnv() 135 address := common.HexToAddress("0x823140710bf13990e4500136726d8b55") 136 s.state.CreateAccount(address) 137 //value := common.FromHex("0x823140710bf13990e4500136726d8b55") 138 var value common.Hash 139 140 s.state.SetState(address, common.Hash{}, value) 141 s.state.Commit(0, false, false) 142 143 if value := s.state.GetState(address, common.Hash{}); value != (common.Hash{}) { 144 t.Errorf("expected empty current value, got %x", value) 145 } 146 if value := s.state.GetCommittedState(address, common.Hash{}); value != (common.Hash{}) { 147 t.Errorf("expected empty committed value, got %x", value) 148 } 149 } 150 151 func TestSnapshot(t *testing.T) { 152 stateobjaddr := common.BytesToAddress([]byte("aa")) 153 var storageaddr common.Hash 154 data1 := common.BytesToHash([]byte{42}) 155 data2 := common.BytesToHash([]byte{43}) 156 s := newStateEnv() 157 158 // snapshot the genesis state 159 genesis := s.state.Snapshot() 160 161 // set initial state object value 162 s.state.SetState(stateobjaddr, storageaddr, data1) 163 snapshot := s.state.Snapshot() 164 165 // set a new state object value, revert it and ensure correct content 166 s.state.SetState(stateobjaddr, storageaddr, data2) 167 s.state.RevertToSnapshot(snapshot) 168 169 if v := s.state.GetState(stateobjaddr, storageaddr); v != data1 { 170 t.Errorf("wrong storage value %v, want %v", v, data1) 171 } 172 if v := s.state.GetCommittedState(stateobjaddr, storageaddr); v != (common.Hash{}) { 173 t.Errorf("wrong committed storage value %v, want %v", v, common.Hash{}) 174 } 175 176 // revert up to the genesis state and ensure correct content 177 s.state.RevertToSnapshot(genesis) 178 if v := s.state.GetState(stateobjaddr, storageaddr); v != (common.Hash{}) { 179 t.Errorf("wrong storage value %v, want %v", v, common.Hash{}) 180 } 181 if v := s.state.GetCommittedState(stateobjaddr, storageaddr); v != (common.Hash{}) { 182 t.Errorf("wrong committed storage value %v, want %v", v, common.Hash{}) 183 } 184 } 185 186 func TestSnapshotEmpty(t *testing.T) { 187 s := newStateEnv() 188 s.state.RevertToSnapshot(s.state.Snapshot()) 189 } 190 191 func TestCreateObjectRevert(t *testing.T) { 192 state, _ := New(types.EmptyRootHash, NewDatabaseForTesting()) 193 addr := common.BytesToAddress([]byte("so0")) 194 snap := state.Snapshot() 195 196 state.CreateAccount(addr) 197 so0 := state.getStateObject(addr) 198 so0.SetBalance(uint256.NewInt(42)) 199 so0.SetNonce(43) 200 so0.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e'}), []byte{'c', 'a', 'f', 'e'}) 201 state.setStateObject(so0) 202 203 state.RevertToSnapshot(snap) 204 if state.Exist(addr) { 205 t.Error("Unexpected account after revert") 206 } 207 }