github.com/aergoio/aergo@v1.3.1/state/statedb_test.go (about)

     1  package state
     2  
     3  import (
     4  	"bytes"
     5  	"math/big"
     6  	"testing"
     7  
     8  	"github.com/aergoio/aergo/types"
     9  	"github.com/stretchr/testify/assert"
    10  )
    11  
    12  var (
    13  	testAccount = types.ToAccountID([]byte("test_address"))
    14  	//testRoot, _ = enc.ToBytes("5eGvHsNc5526JBqd8FhKFrtti2fT7xiCyB6rJXt9egFc")
    15  	testRoot   = []byte{0xde, 0xf0, 0x85, 0x93, 0x70, 0x51, 0x4d, 0x51, 0x36, 0x82, 0x9e, 0xeb, 0x4a, 0xd1, 0x6, 0x57, 0x7c, 0xd1, 0xc8, 0x52, 0xc, 0xcb, 0x74, 0xb2, 0xa6, 0x4b, 0xf0, 0x34, 0xc6, 0xf4, 0x5d, 0x80}
    16  	testStates = []types.State{
    17  		types.State{Nonce: 1, Balance: new(big.Int).SetUint64(100).Bytes()},
    18  		types.State{Nonce: 2, Balance: new(big.Int).SetUint64(200).Bytes()},
    19  		types.State{Nonce: 3, Balance: new(big.Int).SetUint64(300).Bytes()},
    20  		types.State{Nonce: 4, Balance: new(big.Int).SetUint64(400).Bytes()},
    21  		types.State{Nonce: 5, Balance: new(big.Int).SetUint64(500).Bytes()},
    22  	}
    23  	//testSecondRoot, _ = enc.ToBytes("GGKZy5XqNPU1VWYspHPwEtm8hnZX2yhcP236ztKf6Pif")
    24  	testSecondRoot   = []byte{0x66, 0xf9, 0x19, 0x2, 0x91, 0xe6, 0xb5, 0x74, 0x3, 0x69, 0x1e, 0x86, 0x87, 0x22, 0x78, 0x1f, 0x4, 0xc3, 0x67, 0x5, 0xf1, 0xb6, 0xce, 0x4b, 0x63, 0x61, 0x6, 0x2c, 0x24, 0xb1, 0xe7, 0xda}
    25  	testSecondStates = []types.State{
    26  		types.State{Nonce: 6, Balance: new(big.Int).SetUint64(600).Bytes()},
    27  		types.State{Nonce: 7, Balance: new(big.Int).SetUint64(700).Bytes()},
    28  		types.State{Nonce: 8, Balance: new(big.Int).SetUint64(800).Bytes()},
    29  	}
    30  )
    31  
    32  func stateEquals(expected, actual *types.State) bool {
    33  	return expected.Nonce == actual.Nonce &&
    34  		bytes.Equal(expected.Balance, actual.Balance) &&
    35  		bytes.Equal(expected.CodeHash, actual.CodeHash) &&
    36  		bytes.Equal(expected.StorageRoot, actual.StorageRoot) &&
    37  		expected.SqlRecoveryPoint == actual.SqlRecoveryPoint
    38  }
    39  
    40  func TestStateDBGetEmptyState(t *testing.T) {
    41  	initTest(t)
    42  	defer deinitTest()
    43  
    44  	// get nil state
    45  	st, err := stateDB.GetState(testAccount)
    46  	if err != nil {
    47  		t.Errorf("failed to get state: %v", err.Error())
    48  	}
    49  	assert.Nil(t, st)
    50  
    51  	// get empty state
    52  	st, err = stateDB.GetAccountState(testAccount)
    53  	if err != nil {
    54  		t.Errorf("failed to get account state: %v", err.Error())
    55  	}
    56  	assert.NotNil(t, st)
    57  	assert.Empty(t, st)
    58  }
    59  
    60  func TestStateDBPutState(t *testing.T) {
    61  	initTest(t)
    62  	defer deinitTest()
    63  
    64  	// put state
    65  	err := stateDB.PutState(testAccount, &testStates[0])
    66  	if err != nil {
    67  		t.Errorf("failed to put state: %v", err.Error())
    68  	}
    69  
    70  	// get state
    71  	st, err := stateDB.GetAccountState(testAccount)
    72  	if err != nil {
    73  		t.Errorf("failed to get account state: %v", err.Error())
    74  	}
    75  	assert.NotNil(t, st)
    76  	assert.True(t, stateEquals(&testStates[0], st))
    77  }
    78  
    79  func TestStateDBRollback(t *testing.T) {
    80  	initTest(t)
    81  	defer deinitTest()
    82  
    83  	// put states
    84  	initialRevision := stateDB.Snapshot()
    85  	for _, v := range testStates {
    86  		_ = stateDB.PutState(testAccount, &v)
    87  	}
    88  	revision := stateDB.Snapshot()
    89  	for _, v := range testSecondStates {
    90  		_ = stateDB.PutState(testAccount, &v)
    91  	}
    92  
    93  	// get state
    94  	st, err := stateDB.GetAccountState(testAccount)
    95  	if err != nil {
    96  		t.Errorf("failed to get account state: %v", err.Error())
    97  	}
    98  	assert.NotNil(t, st)
    99  	assert.True(t, stateEquals(&testSecondStates[2], st))
   100  
   101  	// rollback to snapshot
   102  	err = stateDB.Rollback(revision)
   103  	if err != nil {
   104  		t.Errorf("failed to rollback: %v", err.Error())
   105  	}
   106  	st, err = stateDB.GetAccountState(testAccount)
   107  	if err != nil {
   108  		t.Errorf("failed to get account state: %v", err.Error())
   109  	}
   110  	assert.NotNil(t, st)
   111  	assert.True(t, stateEquals(&testStates[4], st))
   112  
   113  	// rollback to initial revision snapshot
   114  	err = stateDB.Rollback(initialRevision)
   115  	if err != nil {
   116  		t.Errorf("failed to rollback: %v", err.Error())
   117  	}
   118  	st, err = stateDB.GetAccountState(testAccount)
   119  	if err != nil {
   120  		t.Errorf("failed to get account state: %v", err.Error())
   121  	}
   122  	assert.NotNil(t, st)
   123  	assert.Empty(t, st)
   124  }
   125  
   126  func TestStateDBUpdateAndCommit(t *testing.T) {
   127  	initTest(t)
   128  	defer deinitTest()
   129  
   130  	assert.Nil(t, stateDB.GetRoot())
   131  	for _, v := range testStates {
   132  		_ = stateDB.PutState(testAccount, &v)
   133  	}
   134  	assert.Nil(t, stateDB.GetRoot())
   135  
   136  	err := stateDB.Update()
   137  	if err != nil {
   138  		t.Errorf("failed to update: %v", err.Error())
   139  	}
   140  	assert.NotNil(t, stateDB.GetRoot())
   141  	assert.Equal(t, testRoot, stateDB.GetRoot())
   142  
   143  	err = stateDB.Commit()
   144  	if err != nil {
   145  		t.Errorf("failed to commit: %v", err.Error())
   146  	}
   147  	assert.Equal(t, testRoot, stateDB.GetRoot())
   148  }
   149  
   150  func TestStateDBSetRoot(t *testing.T) {
   151  	initTest(t)
   152  	defer deinitTest()
   153  
   154  	// put states
   155  	assert.Nil(t, stateDB.GetRoot())
   156  	for _, v := range testStates {
   157  		_ = stateDB.PutState(testAccount, &v)
   158  	}
   159  	_ = stateDB.Update()
   160  	_ = stateDB.Commit()
   161  	assert.Equal(t, testRoot, stateDB.GetRoot())
   162  
   163  	// put additional states
   164  	for _, v := range testSecondStates {
   165  		_ = stateDB.PutState(testAccount, &v)
   166  	}
   167  	_ = stateDB.Update()
   168  	_ = stateDB.Commit()
   169  	assert.Equal(t, testSecondRoot, stateDB.GetRoot())
   170  
   171  	// get state
   172  	st, _ := stateDB.GetAccountState(testAccount)
   173  	assert.True(t, stateEquals(&testSecondStates[2], st))
   174  
   175  	// set root
   176  	err := stateDB.SetRoot(testRoot)
   177  	if err != nil {
   178  		t.Errorf("failed to set root: %v", err.Error())
   179  	}
   180  	assert.Equal(t, testRoot, stateDB.GetRoot())
   181  
   182  	// get state after setting root
   183  	st, err = stateDB.GetAccountState(testAccount)
   184  	if err != nil {
   185  		t.Errorf("failed to get account state: %v", err.Error())
   186  	}
   187  	assert.True(t, stateEquals(&testStates[4], st))
   188  }
   189  
   190  func TestStateDBParallel(t *testing.T) {
   191  	initTest(t)
   192  	defer deinitTest()
   193  
   194  	// put states
   195  	assert.Nil(t, stateDB.GetRoot())
   196  	for _, v := range testStates {
   197  		_ = stateDB.PutState(testAccount, &v)
   198  	}
   199  	_ = stateDB.Update()
   200  	_ = stateDB.Commit()
   201  	assert.Equal(t, testRoot, stateDB.GetRoot())
   202  
   203  	// put additional states
   204  	for _, v := range testSecondStates {
   205  		_ = stateDB.PutState(testAccount, &v)
   206  	}
   207  	_ = stateDB.Update()
   208  	_ = stateDB.Commit()
   209  	assert.Equal(t, testSecondRoot, stateDB.GetRoot())
   210  
   211  	// get state
   212  	st, _ := stateDB.GetAccountState(testAccount)
   213  	assert.True(t, stateEquals(&testSecondStates[2], st))
   214  
   215  	// open another statedb with root hash of previous state
   216  	anotherStateDB := chainStateDB.OpenNewStateDB(testRoot)
   217  	assert.Equal(t, testRoot, anotherStateDB.GetRoot())
   218  	assert.Equal(t, testSecondRoot, stateDB.GetRoot())
   219  
   220  	// get state from statedb
   221  	st1, err := stateDB.GetAccountState(testAccount)
   222  	if err != nil {
   223  		t.Errorf("failed to get state: %v", err.Error())
   224  	}
   225  	assert.True(t, stateEquals(&testSecondStates[2], st1))
   226  
   227  	// get state from another statedb
   228  	st2, err := anotherStateDB.GetAccountState(testAccount)
   229  	if err != nil {
   230  		t.Errorf("failed to get state: %v", err.Error())
   231  	}
   232  	assert.True(t, stateEquals(&testStates[4], st2))
   233  }
   234  
   235  func TestStateDBMarker(t *testing.T) {
   236  	initTest(t)
   237  	defer deinitTest()
   238  	assert.Nil(t, stateDB.GetRoot())
   239  
   240  	for _, v := range testStates {
   241  		_ = stateDB.PutState(testAccount, &v)
   242  	}
   243  	_ = stateDB.Update()
   244  	_ = stateDB.Commit()
   245  	assert.Equal(t, testRoot, stateDB.GetRoot())
   246  
   247  	assert.True(t, stateDB.HasMarker(stateDB.GetRoot()))
   248  	assert.False(t, stateDB.HasMarker(testSecondRoot))
   249  	assert.False(t, stateDB.HasMarker([]byte{}))
   250  	assert.False(t, stateDB.HasMarker(nil))
   251  }