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  }