github.com/jeffallen/go-ethereum@v1.1.4-0.20150910155051-571d3236c49c/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 "math/big" 22 "testing" 23 24 checker "gopkg.in/check.v1" 25 26 "github.com/ethereum/go-ethereum/common" 27 "github.com/ethereum/go-ethereum/ethdb" 28 ) 29 30 type StateSuite struct { 31 state *StateDB 32 } 33 34 var _ = checker.Suite(&StateSuite{}) 35 36 var toAddr = common.BytesToAddress 37 38 func (s *StateSuite) TestDump(c *checker.C) { 39 return 40 // generate a few entries 41 obj1 := s.state.GetOrNewStateObject(toAddr([]byte{0x01})) 42 obj1.AddBalance(big.NewInt(22)) 43 obj2 := s.state.GetOrNewStateObject(toAddr([]byte{0x01, 0x02})) 44 obj2.SetCode([]byte{3, 3, 3, 3, 3, 3, 3}) 45 obj3 := s.state.GetOrNewStateObject(toAddr([]byte{0x02})) 46 obj3.SetBalance(big.NewInt(44)) 47 48 // write some of them to the trie 49 s.state.UpdateStateObject(obj1) 50 s.state.UpdateStateObject(obj2) 51 52 // check that dump contains the state objects that are in trie 53 got := string(s.state.Dump()) 54 want := `{ 55 "root": "6e277ae8357d013e50f74eedb66a991f6922f93ae03714de58b3d0c5e9eee53f", 56 "accounts": { 57 "1468288056310c82aa4c01a7e12a10f8111a0560e72b700555479031b86c357d": { 58 "balance": "22", 59 "nonce": 0, 60 "root": "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", 61 "codeHash": "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", 62 "storage": {} 63 }, 64 "a17eacbc25cda025e81db9c5c62868822c73ce097cee2a63e33a2e41268358a1": { 65 "balance": "0", 66 "nonce": 0, 67 "root": "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", 68 "codeHash": "87874902497a5bb968da31a2998d8f22e949d1ef6214bcdedd8bae24cca4b9e3", 69 "storage": {} 70 } 71 } 72 }` 73 if got != want { 74 c.Errorf("dump mismatch:\ngot: %s\nwant: %s\n", got, want) 75 } 76 } 77 78 func (s *StateSuite) SetUpTest(c *checker.C) { 79 db, _ := ethdb.NewMemDatabase() 80 s.state = New(common.Hash{}, db) 81 } 82 83 func TestNull(t *testing.T) { 84 db, _ := ethdb.NewMemDatabase() 85 state := New(common.Hash{}, db) 86 87 address := common.HexToAddress("0x823140710bf13990e4500136726d8b55") 88 state.CreateAccount(address) 89 //value := common.FromHex("0x823140710bf13990e4500136726d8b55") 90 var value common.Hash 91 state.SetState(address, common.Hash{}, value) 92 state.SyncIntermediate() 93 state.Sync() 94 value = state.GetState(address, common.Hash{}) 95 if !common.EmptyHash(value) { 96 t.Errorf("expected empty hash. got %x", value) 97 } 98 } 99 100 func (s *StateSuite) TestSnapshot(c *checker.C) { 101 stateobjaddr := toAddr([]byte("aa")) 102 var storageaddr common.Hash 103 data1 := common.BytesToHash([]byte{42}) 104 data2 := common.BytesToHash([]byte{43}) 105 106 // set inital state object value 107 s.state.SetState(stateobjaddr, storageaddr, data1) 108 // get snapshot of current state 109 snapshot := s.state.Copy() 110 111 // set new state object value 112 s.state.SetState(stateobjaddr, storageaddr, data2) 113 // restore snapshot 114 s.state.Set(snapshot) 115 116 // get state storage value 117 res := s.state.GetState(stateobjaddr, storageaddr) 118 119 c.Assert(data1, checker.DeepEquals, res) 120 } 121 122 // use testing instead of checker because checker does not support 123 // printing/logging in tests (-check.vv does not work) 124 func TestSnapshot2(t *testing.T) { 125 db, _ := ethdb.NewMemDatabase() 126 state := New(common.Hash{}, db) 127 128 stateobjaddr0 := toAddr([]byte("so0")) 129 stateobjaddr1 := toAddr([]byte("so1")) 130 var storageaddr common.Hash 131 132 data0 := common.BytesToHash([]byte{17}) 133 data1 := common.BytesToHash([]byte{18}) 134 135 state.SetState(stateobjaddr0, storageaddr, data0) 136 state.SetState(stateobjaddr1, storageaddr, data1) 137 138 // db, trie are already non-empty values 139 so0 := state.GetStateObject(stateobjaddr0) 140 so0.balance = big.NewInt(42) 141 so0.nonce = 43 142 so0.gasPool = big.NewInt(44) 143 so0.code = []byte{'c', 'a', 'f', 'e'} 144 so0.codeHash = so0.CodeHash() 145 so0.remove = true 146 so0.deleted = false 147 so0.dirty = false 148 state.SetStateObject(so0) 149 150 // and one with deleted == true 151 so1 := state.GetStateObject(stateobjaddr1) 152 so1.balance = big.NewInt(52) 153 so1.nonce = 53 154 so1.gasPool = big.NewInt(54) 155 so1.code = []byte{'c', 'a', 'f', 'e', '2'} 156 so1.codeHash = so1.CodeHash() 157 so1.remove = true 158 so1.deleted = true 159 so1.dirty = true 160 state.SetStateObject(so1) 161 162 so1 = state.GetStateObject(stateobjaddr1) 163 if so1 != nil { 164 t.Fatalf("deleted object not nil when getting") 165 } 166 167 snapshot := state.Copy() 168 state.Set(snapshot) 169 170 so0Restored := state.GetStateObject(stateobjaddr0) 171 so1Restored := state.GetStateObject(stateobjaddr1) 172 // non-deleted is equal (restored) 173 compareStateObjects(so0Restored, so0, t) 174 // deleted should be nil, both before and after restore of state copy 175 if so1Restored != nil { 176 t.Fatalf("deleted object not nil after restoring snapshot") 177 } 178 } 179 180 func compareStateObjects(so0, so1 *StateObject, t *testing.T) { 181 if so0.address != so1.address { 182 t.Fatalf("Address mismatch: have %v, want %v", so0.address, so1.address) 183 } 184 if so0.balance.Cmp(so1.balance) != 0 { 185 t.Fatalf("Balance mismatch: have %v, want %v", so0.balance, so1.balance) 186 } 187 if so0.nonce != so1.nonce { 188 t.Fatalf("Nonce mismatch: have %v, want %v", so0.nonce, so1.nonce) 189 } 190 if !bytes.Equal(so0.codeHash, so1.codeHash) { 191 t.Fatalf("CodeHash mismatch: have %v, want %v", so0.codeHash, so1.codeHash) 192 } 193 if !bytes.Equal(so0.code, so1.code) { 194 t.Fatalf("Code mismatch: have %v, want %v", so0.code, so1.code) 195 } 196 if !bytes.Equal(so0.initCode, so1.initCode) { 197 t.Fatalf("InitCode mismatch: have %v, want %v", so0.initCode, so1.initCode) 198 } 199 200 for k, v := range so1.storage { 201 if so0.storage[k] != v { 202 t.Fatalf("Storage key %s mismatch: have %v, want %v", k, so0.storage[k], v) 203 } 204 } 205 for k, v := range so0.storage { 206 if so1.storage[k] != v { 207 t.Fatalf("Storage key %s mismatch: have %v, want none.", k, v) 208 } 209 } 210 211 if so0.gasPool.Cmp(so1.gasPool) != 0 { 212 t.Fatalf("GasPool mismatch: have %v, want %v", so0.gasPool, so1.gasPool) 213 } 214 if so0.remove != so1.remove { 215 t.Fatalf("Remove mismatch: have %v, want %v", so0.remove, so1.remove) 216 } 217 if so0.deleted != so1.deleted { 218 t.Fatalf("Deleted mismatch: have %v, want %v", so0.deleted, so1.deleted) 219 } 220 if so0.dirty != so1.dirty { 221 t.Fatalf("Dirty mismatch: have %v, want %v", so0.dirty, so1.dirty) 222 } 223 }