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