github.com/cheng762/platon-go@v1.8.17-0.20190529111256-7deff2d7be26/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 "github.com/PlatONnetwork/PlatON-Go/trie" 21 "bytes" 22 "fmt" 23 "math/big" 24 "testing" 25 26 "github.com/PlatONnetwork/PlatON-Go/common" 27 "github.com/PlatONnetwork/PlatON-Go/crypto" 28 "github.com/PlatONnetwork/PlatON-Go/ethdb" 29 checker "gopkg.in/check.v1" 30 //"github.com/PlatONnetwork/PlatON-Go/rlp" 31 "github.com/PlatONnetwork/PlatON-Go/rlp" 32 ) 33 34 type StateSuite struct { 35 db *ethdb.MemDatabase 36 state *StateDB 37 } 38 39 var _ = checker.Suite(&StateSuite{}) 40 41 var toAddr = common.BytesToAddress 42 43 func (s *StateSuite) TestDump(c *checker.C) { 44 // generate a few entries 45 obj1 := s.state.GetOrNewStateObject(toAddr([]byte{0x01})) 46 obj1.AddBalance(big.NewInt(22)) 47 obj2 := s.state.GetOrNewStateObject(toAddr([]byte{0x01, 0x02})) 48 obj2.SetCode(crypto.Keccak256Hash([]byte{3, 3, 3, 3, 3, 3, 3}), []byte{3, 3, 3, 3, 3, 3, 3}) 49 obj3 := s.state.GetOrNewStateObject(toAddr([]byte{0x02})) 50 obj3.SetBalance(big.NewInt(44)) 51 52 // write some of them to the trie 53 s.state.updateStateObject(obj1) 54 s.state.updateStateObject(obj2) 55 s.state.Commit(false) 56 57 // check that dump contains the state objects that are in trie 58 got := string(s.state.Dump()) 59 want := `{ 60 "root": "1d75ab73e172edb7c3b3c0fd004d9896992fb96b617f6f954641d7618159e5e4", 61 "accounts": { 62 "0000000000000000000000000000000000000001": { 63 "balance": "22", 64 "nonce": 0, 65 "root": "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", 66 "codeHash": "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", 67 "code": "", 68 "storage": {} 69 }, 70 "0000000000000000000000000000000000000002": { 71 "balance": "44", 72 "nonce": 0, 73 "root": "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", 74 "codeHash": "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", 75 "code": "", 76 "storage": {} 77 }, 78 "0000000000000000000000000000000000000102": { 79 "balance": "0", 80 "nonce": 0, 81 "root": "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", 82 "codeHash": "87874902497a5bb968da31a2998d8f22e949d1ef6214bcdedd8bae24cca4b9e3", 83 "code": "03030303030303", 84 "storage": {} 85 } 86 } 87 }` 88 if got != want { 89 c.Errorf("dump mismatch:\ngot: %s\nwant: %s\n", got, want) 90 } 91 } 92 93 func (s *StateSuite) SetUpTest(c *checker.C) { 94 s.db = ethdb.NewMemDatabase() 95 s.state, _ = New(common.Hash{}, NewDatabase(s.db), big.NewInt(0), common.Hash{}) 96 } 97 98 func (s *StateSuite) TestNull(c *checker.C) { 99 address := common.HexToAddress("0x823140710bf13990e4500136726d8b55") 100 s.state.CreateAccount(address) 101 value := common.FromHex("0x823140710bf13990e4500136726d8b55") 102 //value := nil 103 key := common.FromHex("0x823140710bf13990e4500136726d8b55") 104 105 //s.state.SetState(address, common.Hash{}, value) 106 s.state.SetState(address, key, value) 107 s.state.Commit(false) 108 109 if value := s.state.GetState(address, key); bytes.Compare(value, value) != 0 { 110 c.Error("expected empty current value") 111 } 112 } 113 114 func (s *StateSuite) TestSnapshot(c *checker.C) { 115 stateobjaddr := toAddr([]byte("aa")) 116 var storageaddr common.Hash 117 data1 := common.BytesToHash([]byte{42}) 118 data2 := common.BytesToHash([]byte{43}) 119 120 // snapshot the genesis state 121 genesis := s.state.Snapshot() 122 123 // set initial state object value 124 s.state.SetState(stateobjaddr, storageaddr.Bytes(), data1.Bytes()) 125 snapshot := s.state.Snapshot() 126 127 // set a new state object value, revert it and ensure correct content 128 s.state.SetState(stateobjaddr, storageaddr.Bytes(), data2.Bytes()) 129 s.state.RevertToSnapshot(snapshot) 130 131 c.Assert(common.BytesToHash(s.state.GetState(stateobjaddr, storageaddr.Bytes())), checker.DeepEquals, data1) 132 133 // revert up to the genesis state and ensure correct content 134 s.state.RevertToSnapshot(genesis) 135 c.Assert(common.BytesToHash(s.state.GetState(stateobjaddr, storageaddr.Bytes())), checker.DeepEquals, common.Hash{}) 136 } 137 138 func (s *StateSuite) TestSnapshotEmpty(c *checker.C) { 139 s.state.RevertToSnapshot(s.state.Snapshot()) 140 } 141 142 // use testing instead of checker because checker does not support 143 // printing/logging in tests (-check.vv does not work) 144 func TestSnapshot2(t *testing.T) { 145 state, _ := New(common.Hash{}, NewDatabase(ethdb.NewMemDatabase()), big.NewInt(0), common.Hash{}) 146 147 stateobjaddr0 := toAddr([]byte("so0")) 148 stateobjaddr1 := toAddr([]byte("so1")) 149 var storageaddr common.Address 150 151 data0 := common.BytesToHash([]byte{17}) 152 data1 := common.BytesToHash([]byte{18}) 153 154 state.SetState(stateobjaddr0, storageaddr.Bytes(), data0.Bytes()) 155 state.SetState(stateobjaddr1, storageaddr.Bytes(), data1.Bytes()) 156 157 // db, trie are already non-empty values 158 so0 := state.getStateObject(stateobjaddr0) 159 so0.SetBalance(big.NewInt(42)) 160 so0.SetNonce(43) 161 so0.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e'}), []byte{'c', 'a', 'f', 'e'}) 162 so0.suicided = false 163 so0.deleted = false 164 state.setStateObject(so0) 165 166 root, _ := state.Commit(false) 167 state.Reset(root) 168 169 // and one with deleted == true 170 so1 := state.getStateObject(stateobjaddr1) 171 so1.SetBalance(big.NewInt(52)) 172 so1.SetNonce(53) 173 so1.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e', '2'}), []byte{'c', 'a', 'f', 'e', '2'}) 174 so1.suicided = true 175 so1.deleted = true 176 state.setStateObject(so1) 177 178 so1 = state.getStateObject(stateobjaddr1) 179 if so1 != nil { 180 t.Fatalf("deleted object not nil when getting") 181 } 182 183 snapshot := state.Snapshot() 184 state.RevertToSnapshot(snapshot) 185 186 so0Restored := state.getStateObject(stateobjaddr0) 187 // Update lazily-loaded values before comparing. 188 key, _, _ := getKeyValue(stateobjaddr0, storageaddr.Bytes(), nil) 189 so0Restored.GetState(state.db, key) 190 so0Restored.Code(state.db) 191 // non-deleted is equal (restored) 192 compareStateObjects(so0Restored, so0, t) 193 194 // deleted should be nil, both before and after restore of state copy 195 so1Restored := state.getStateObject(stateobjaddr1) 196 if so1Restored != nil { 197 t.Fatalf("deleted object not nil after restoring snapshot: %+v", so1Restored) 198 } 199 } 200 201 func compareStateObjects(so0, so1 *stateObject, t *testing.T) { 202 if so0.Address() != so1.Address() { 203 t.Fatalf("Address mismatch: have %v, want %v", so0.address, so1.address) 204 } 205 if so0.Balance().Cmp(so1.Balance()) != 0 { 206 t.Fatalf("Balance mismatch: have %v, want %v", so0.Balance(), so1.Balance()) 207 } 208 if so0.Nonce() != so1.Nonce() { 209 t.Fatalf("Nonce mismatch: have %v, want %v", so0.Nonce(), so1.Nonce()) 210 } 211 if so0.data.Root != so1.data.Root { 212 t.Errorf("Root mismatch: have %x, want %x", so0.data.Root[:], so1.data.Root[:]) 213 } 214 if !bytes.Equal(so0.CodeHash(), so1.CodeHash()) { 215 t.Fatalf("CodeHash mismatch: have %v, want %v", so0.CodeHash(), so1.CodeHash()) 216 } 217 if !bytes.Equal(so0.code, so1.code) { 218 t.Fatalf("Code mismatch: have %v, want %v", so0.code, so1.code) 219 } 220 221 if len(so1.dirtyStorage) != len(so0.dirtyStorage) { 222 t.Errorf("Dirty storage size mismatch: have %d, want %d", len(so1.dirtyStorage), len(so0.dirtyStorage)) 223 } 224 for k, v := range so1.dirtyStorage { 225 if so0.dirtyStorage[k] != v { 226 t.Errorf("Dirty storage key %x mismatch: have %v, want %v", k, so0.dirtyStorage[k], v) 227 } 228 } 229 for k, v := range so0.dirtyStorage { 230 if so1.dirtyStorage[k] != v { 231 t.Errorf("Dirty storage key %x mismatch: have %v, want none.", k, v) 232 } 233 } 234 if len(so1.originStorage) != len(so0.originStorage) { 235 t.Errorf("Origin storage size mismatch: have %d, want %d", len(so1.originStorage), len(so0.originStorage)) 236 } 237 for k, v := range so1.originStorage { 238 if so0.originStorage[k] != v { 239 t.Errorf("Origin storage key %x mismatch: have %v, want %v", k, so0.originStorage[k], v) 240 } 241 } 242 for k, v := range so0.originStorage { 243 if so1.originStorage[k] != v { 244 t.Errorf("Origin storage key %x mismatch: have %v, want none.", k, v) 245 } 246 } 247 } 248 249 func TestEmptyByte(t *testing.T) { 250 db := ethdb.NewMemDatabase() 251 state, _ := New(common.Hash{}, NewDatabase(db), big.NewInt(0), common.Hash{}) 252 253 address := common.HexToAddress("0x823140710bf13990e4500136726d8b55") 254 state.CreateAccount(address) 255 so := state.getStateObject(address) 256 257 //value := common.FromHex("0x823140710bf13990e4500136726d8b55") 258 //pvalue := []byte("b") 259 type Candidate struct { 260 Deposit uint64 261 BlockNumber *big.Int 262 TxIndex uint32 263 CandidateId string 264 Host string 265 Port string 266 } 267 can := Candidate{Deposit: 100, BlockNumber: new(big.Int).SetUint64(12), CandidateId: "AA", Host: "10.0.0.0"} 268 prefix := []byte("im") 269 pvalue, _ := rlp.EncodeToBytes(&can) 270 key := append(prefix, []byte("a")...) 271 state.SetState(address, key, pvalue) 272 //state.Commit(false) 273 274 if value := state.GetState(address, key); !bytes.Equal(value, pvalue) { 275 t.Errorf("expected empty current value, got %x", value) 276 }else{ 277 var can Candidate 278 rlp.DecodeBytes(value, &can) 279 fmt.Printf("%+v \n", can) 280 } 281 282 //if value := state.GetCommittedState(address, key); !bytes.Equal(value, pvalue) { 283 // t.Errorf("expected empty committed value, got %x", value) 284 //} 285 286 state.trie.NodeIterator(nil) 287 it := trie.NewIterator(so.trie.NodeIterator(nil)) 288 for it.Next() { 289 var a Candidate 290 rlp.DecodeBytes(so.db.trie.GetKey(it.Value), &a) 291 fmt.Println("Initialize comparison key-value pairs", string(so.db.trie.GetKey(it.Key)), "== ", &a) 292 } 293 294 can2 := Candidate{Deposit: 100, BlockNumber: new(big.Int).SetUint64(12), CandidateId: "OK", Host: "10.0.0.0"} 295 prefix2 := []byte("im") 296 pvalue2, _ := rlp.EncodeToBytes(&can2) 297 key2 := append(prefix2, []byte("b")...) 298 state.SetState(address, key2, pvalue2) 299 //state.Commit(false) 300 301 if value := state.GetState(address, key2); !bytes.Equal(value, pvalue2) { 302 t.Errorf("expected empty current value, got %x", value) 303 }else{ 304 var can Candidate 305 rlp.DecodeBytes(value, &can) 306 fmt.Printf("%+v \n", can) 307 } 308 //if value := state.GetCommittedState(address, key2); !bytes.Equal(value, pvalue2) { 309 // t.Errorf("expected empty committed value, got %x", value) 310 //} 311 312 state.trie.NodeIterator(nil) 313 it = trie.NewIterator(so.trie.NodeIterator(nil)) 314 for it.Next() { 315 var a Candidate 316 rlp.DecodeBytes(so.db.trie.GetKey(it.Value), &a) 317 fmt.Println("Compare key-value pairs after adding", string(so.db.trie.GetKey(it.Key)), "== ", &a) 318 } 319 320 321 322 pvalue = []byte{} 323 state.SetState(address, key, pvalue) 324 //state.Commit(false) 325 326 if value := state.GetState(address, key); !bytes.Equal(value, pvalue) { 327 t.Errorf("expected empty current value, got %x", value) 328 } 329 //if value := state.GetCommittedState(address, key); !bytes.Equal(value, pvalue) { 330 // t.Errorf("expected empty committed value, got %x", value) 331 //} 332 333 state.trie.NodeIterator(nil) 334 it = trie.NewIterator(so.trie.NodeIterator(nil)) 335 for it.Next() { 336 var a Candidate 337 rlp.DecodeBytes(so.db.trie.GetKey(it.Value), &a) 338 fmt.Println("Compare key-value pairs after deletion", string(so.db.trie.GetKey(it.Key)), "==", &a) 339 } 340 341 // insert empty value 342 key = []byte("bb") 343 pvalue = []byte{} 344 state.SetState(address, key, pvalue) 345 346 if value := state.GetState(address, key); !bytes.Equal(value, pvalue) { 347 t.Errorf("expected empty current value, got %x", value) 348 }else { 349 var a Candidate 350 rlp.DecodeBytes(so.db.trie.GetKey(it.Value), &a) 351 fmt.Println("Compare key-value pairs after inserting null values", string(so.db.trie.GetKey(it.Key)), "==", &a) 352 } 353 //if value := state.GetCommittedState(address, key); !bytes.Equal(value, pvalue) { 354 // t.Errorf("expected empty committed value, got %x", value) 355 //} 356 357 state.trie.NodeIterator(nil) 358 it = trie.NewIterator(so.trie.NodeIterator(nil)) 359 for it.Next() { 360 var a Candidate 361 rlp.DecodeBytes(so.db.trie.GetKey(it.Value), &a) 362 fmt.Println("Compare key-value pairs after inserting null values", string(so.db.trie.GetKey(it.Key)), "==", &a) 363 } 364 } 365 366 func TestSlice(t *testing.T){ 367 db := ethdb.NewMemDatabase() 368 state, _ := New(common.Hash{}, NewDatabase(db), big.NewInt(0), common.Hash{}) 369 370 address := common.HexToAddress("0x823140710bf13990e4500136726d8b55") 371 state.CreateAccount(address) 372 so := state.getStateObject(address) 373 374 type Candidate struct { 375 Deposit uint64 376 BlockNumber *big.Int 377 TxIndex uint32 378 CandidateId string 379 Host string 380 Port string 381 } 382 can1 := Candidate{Deposit: 100, BlockNumber: new(big.Int).SetUint64(12), CandidateId: "AA", Host: "10.0.0.0"} 383 can2 := Candidate{Deposit: 200, BlockNumber: new(big.Int).SetUint64(13), CandidateId: "AA", Host: "127.0.0.1"} 384 arr := []*Candidate{&can1, &can2} 385 prefix := []byte("im") 386 pvalue, _ := rlp.EncodeToBytes(&arr) 387 key := append(prefix, []byte("a")...) 388 state.SetState(address, key, pvalue) 389 state.Commit(false) 390 391 if value := state.GetState(address, key); !bytes.Equal(value, pvalue) { 392 t.Errorf("expected empty current value, got %x", value) 393 } 394 395 state.trie.NodeIterator(nil) 396 it := trie.NewIterator(so.trie.NodeIterator(nil)) 397 for it.Next() { 398 var arr []*Candidate 399 rlp.DecodeBytes(so.db.trie.GetKey(it.Value), &arr) 400 fmt.Printf("Initialize comparison key-value pairs %v == %+v", string(so.db.trie.GetKey(it.Key)), &arr) 401 } 402 } 403 404 func TestIntermediateRoot(t *testing.T) { 405 406 }