github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/core/state/state_test.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 12:09:34</date> 10 //</624342618259591168> 11 12 13 package state 14 15 import ( 16 "bytes" 17 "math/big" 18 "testing" 19 20 "github.com/ethereum/go-ethereum/common" 21 "github.com/ethereum/go-ethereum/crypto" 22 "github.com/ethereum/go-ethereum/ethdb" 23 checker "gopkg.in/check.v1" 24 ) 25 26 type StateSuite struct { 27 db *ethdb.MemDatabase 28 state *StateDB 29 } 30 31 var _ = checker.Suite(&StateSuite{}) 32 33 var toAddr = common.BytesToAddress 34 35 func (s *StateSuite) TestDump(c *checker.C) { 36 //生成一些条目 37 obj1 := s.state.GetOrNewStateObject(toAddr([]byte{0x01})) 38 obj1.AddBalance(big.NewInt(22)) 39 obj2 := s.state.GetOrNewStateObject(toAddr([]byte{0x01, 0x02})) 40 obj2.SetCode(crypto.Keccak256Hash([]byte{3, 3, 3, 3, 3, 3, 3}), []byte{3, 3, 3, 3, 3, 3, 3}) 41 obj3 := s.state.GetOrNewStateObject(toAddr([]byte{0x02})) 42 obj3.SetBalance(big.NewInt(44)) 43 44 //写一些给特里亚 45 s.state.updateStateObject(obj1) 46 s.state.updateStateObject(obj2) 47 s.state.Commit(false) 48 49 //检查转储是否包含trie中的状态对象 50 got := string(s.state.Dump()) 51 want := `{ 52 "root": "71edff0130dd2385947095001c73d9e28d862fc286fca2b922ca6f6f3cddfdd2", 53 "accounts": { 54 "0000000000000000000000000000000000000001": { 55 "balance": "22", 56 "nonce": 0, 57 "root": "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", 58 "codeHash": "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", 59 "code": "", 60 "storage": {} 61 }, 62 "0000000000000000000000000000000000000002": { 63 "balance": "44", 64 "nonce": 0, 65 "root": "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", 66 "codeHash": "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", 67 "code": "", 68 "storage": {} 69 }, 70 "0000000000000000000000000000000000000102": { 71 "balance": "0", 72 "nonce": 0, 73 "root": "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", 74 "codeHash": "87874902497a5bb968da31a2998d8f22e949d1ef6214bcdedd8bae24cca4b9e3", 75 "code": "03030303030303", 76 "storage": {} 77 } 78 } 79 }` 80 if got != want { 81 c.Errorf("dump mismatch:\ngot: %s\nwant: %s\n", got, want) 82 } 83 } 84 85 func (s *StateSuite) SetUpTest(c *checker.C) { 86 s.db = ethdb.NewMemDatabase() 87 s.state, _ = New(common.Hash{}, NewDatabase(s.db)) 88 } 89 90 func (s *StateSuite) TestNull(c *checker.C) { 91 address := common.HexToAddress("0x823140710bf13990e4500136726d8b55") 92 s.state.CreateAccount(address) 93 //值:=common.fromhex(“0x823140710BF13990E4500136726D8B55”) 94 var value common.Hash 95 s.state.SetState(address, common.Hash{}, value) 96 s.state.Commit(false) 97 value = s.state.GetState(address, common.Hash{}) 98 if value != (common.Hash{}) { 99 c.Errorf("expected empty hash. got %x", value) 100 } 101 } 102 103 func (s *StateSuite) TestSnapshot(c *checker.C) { 104 stateobjaddr := toAddr([]byte("aa")) 105 var storageaddr common.Hash 106 data1 := common.BytesToHash([]byte{42}) 107 data2 := common.BytesToHash([]byte{43}) 108 109 //设置初始状态对象值 110 s.state.SetState(stateobjaddr, storageaddr, data1) 111 //获取当前状态的快照 112 snapshot := s.state.Snapshot() 113 114 //设置新状态对象值 115 s.state.SetState(stateobjaddr, storageaddr, data2) 116 //还原快照 117 s.state.RevertToSnapshot(snapshot) 118 119 //获取状态存储值 120 res := s.state.GetState(stateobjaddr, storageaddr) 121 122 c.Assert(data1, checker.DeepEquals, res) 123 } 124 125 func (s *StateSuite) TestSnapshotEmpty(c *checker.C) { 126 s.state.RevertToSnapshot(s.state.Snapshot()) 127 } 128 129 //使用测试而不是检查器,因为检查器不支持 130 //打印/登录测试(-check.vv不工作) 131 func TestSnapshot2(t *testing.T) { 132 state, _ := New(common.Hash{}, NewDatabase(ethdb.NewMemDatabase())) 133 134 stateobjaddr0 := toAddr([]byte("so0")) 135 stateobjaddr1 := toAddr([]byte("so1")) 136 var storageaddr common.Hash 137 138 data0 := common.BytesToHash([]byte{17}) 139 data1 := common.BytesToHash([]byte{18}) 140 141 state.SetState(stateobjaddr0, storageaddr, data0) 142 state.SetState(stateobjaddr1, storageaddr, data1) 143 144 //db,trie已经是非空值 145 so0 := state.getStateObject(stateobjaddr0) 146 so0.SetBalance(big.NewInt(42)) 147 so0.SetNonce(43) 148 so0.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e'}), []byte{'c', 'a', 'f', 'e'}) 149 so0.suicided = false 150 so0.deleted = false 151 state.setStateObject(so0) 152 153 root, _ := state.Commit(false) 154 state.Reset(root) 155 156 //删除一个=真 157 so1 := state.getStateObject(stateobjaddr1) 158 so1.SetBalance(big.NewInt(52)) 159 so1.SetNonce(53) 160 so1.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e', '2'}), []byte{'c', 'a', 'f', 'e', '2'}) 161 so1.suicided = true 162 so1.deleted = true 163 state.setStateObject(so1) 164 165 so1 = state.getStateObject(stateobjaddr1) 166 if so1 != nil { 167 t.Fatalf("deleted object not nil when getting") 168 } 169 170 snapshot := state.Snapshot() 171 state.RevertToSnapshot(snapshot) 172 173 so0Restored := state.getStateObject(stateobjaddr0) 174 //在比较之前更新延迟加载的值。 175 so0Restored.GetState(state.db, storageaddr) 176 so0Restored.Code(state.db) 177 //未删除等于(还原) 178 compareStateObjects(so0Restored, so0, t) 179 180 //在恢复状态副本之前和之后,删除的内容应为零。 181 so1Restored := state.getStateObject(stateobjaddr1) 182 if so1Restored != nil { 183 t.Fatalf("deleted object not nil after restoring snapshot: %+v", so1Restored) 184 } 185 } 186 187 func compareStateObjects(so0, so1 *stateObject, t *testing.T) { 188 if so0.Address() != so1.Address() { 189 t.Fatalf("Address mismatch: have %v, want %v", so0.address, so1.address) 190 } 191 if so0.Balance().Cmp(so1.Balance()) != 0 { 192 t.Fatalf("Balance mismatch: have %v, want %v", so0.Balance(), so1.Balance()) 193 } 194 if so0.Nonce() != so1.Nonce() { 195 t.Fatalf("Nonce mismatch: have %v, want %v", so0.Nonce(), so1.Nonce()) 196 } 197 if so0.data.Root != so1.data.Root { 198 t.Errorf("Root mismatch: have %x, want %x", so0.data.Root[:], so1.data.Root[:]) 199 } 200 if !bytes.Equal(so0.CodeHash(), so1.CodeHash()) { 201 t.Fatalf("CodeHash mismatch: have %v, want %v", so0.CodeHash(), so1.CodeHash()) 202 } 203 if !bytes.Equal(so0.code, so1.code) { 204 t.Fatalf("Code mismatch: have %v, want %v", so0.code, so1.code) 205 } 206 207 if len(so1.cachedStorage) != len(so0.cachedStorage) { 208 t.Errorf("Storage size mismatch: have %d, want %d", len(so1.cachedStorage), len(so0.cachedStorage)) 209 } 210 for k, v := range so1.cachedStorage { 211 if so0.cachedStorage[k] != v { 212 t.Errorf("Storage key %x mismatch: have %v, want %v", k, so0.cachedStorage[k], v) 213 } 214 } 215 for k, v := range so0.cachedStorage { 216 if so1.cachedStorage[k] != v { 217 t.Errorf("Storage key %x mismatch: have %v, want none.", k, v) 218 } 219 } 220 221 if so0.suicided != so1.suicided { 222 t.Fatalf("suicided mismatch: have %v, want %v", so0.suicided, so1.suicided) 223 } 224 if so0.deleted != so1.deleted { 225 t.Fatalf("Deleted mismatch: have %v, want %v", so0.deleted, so1.deleted) 226 } 227 } 228