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 }