github.com/aergoio/aergo@v1.3.1/state/contract_test.go (about) 1 package state 2 3 import ( 4 "os" 5 "testing" 6 7 "github.com/aergoio/aergo-lib/db" 8 "github.com/aergoio/aergo/types" 9 "github.com/stretchr/testify/assert" 10 ) 11 12 var chainStateDB *ChainStateDB 13 var stateDB *StateDB 14 15 func initTest(t *testing.T) { 16 chainStateDB = NewChainStateDB() 17 _ = chainStateDB.Init(string(db.BadgerImpl), "test", nil, false) 18 stateDB = chainStateDB.GetStateDB() 19 genesis := types.GetTestGenesis() 20 21 err := chainStateDB.SetGenesis(genesis, nil) 22 assert.NoError(t, err, "failed init") 23 } 24 func deinitTest() { 25 _ = chainStateDB.Close() 26 _ = os.RemoveAll("test") 27 } 28 func TestContractStateCode(t *testing.T) { 29 initTest(t) 30 defer deinitTest() 31 testAddress := []byte("test_address") 32 testBytes := []byte("test_bytes") 33 34 // open contract state 35 contractState, err := stateDB.OpenContractStateAccount(types.ToAccountID(testAddress)) 36 assert.NoError(t, err, "could not open contract state") 37 38 // set code 39 err = contractState.SetCode(testBytes) 40 assert.NoError(t, err, "set code to contract state") 41 42 // get code 43 res, err := contractState.GetCode() 44 assert.NoError(t, err, "get code from contract state") 45 assert.Equal(t, testBytes, res, "different code detected") 46 } 47 48 func TestContractStateData(t *testing.T) { 49 initTest(t) 50 defer deinitTest() 51 testAddress := []byte("test_address") 52 testBytes := []byte("test_bytes") 53 testKey := []byte("test_key") 54 55 // open contract state 56 contractState, err := stateDB.OpenContractStateAccount(types.ToAccountID(testAddress)) 57 assert.NoError(t, err, "could not open contract state") 58 59 // set data 60 err = contractState.SetData(testKey, testBytes) 61 assert.NoError(t, err, "set data to contract state") 62 63 // get data 64 res, err := contractState.GetData(testKey) 65 assert.NoError(t, err, "get data from contract state") 66 assert.Equal(t, testBytes, res, "different data detected") 67 68 // stage contract state 69 err = stateDB.StageContractState(contractState) 70 assert.NoError(t, err, "stage contract state") 71 } 72 73 func TestContractStateInitialData(t *testing.T) { 74 initTest(t) 75 defer deinitTest() 76 testAddress := []byte("test_address") 77 testBytes := []byte("test_bytes") 78 testKey := []byte("test_key") 79 80 // open contract state 81 contractState, err := stateDB.OpenContractStateAccount(types.ToAccountID(testAddress)) 82 assert.NoError(t, err, "could not open contract state") 83 84 // get initial data 85 res, err := contractState.GetInitialData(testKey) 86 assert.NoError(t, err, "get initial data from contract state") 87 assert.Nil(t, res, "get initial data from contract state") 88 89 // set data 90 err = contractState.SetData(testKey, testBytes) 91 assert.NoError(t, err, "set data to contract state") 92 93 // get data 94 res, err = contractState.GetData(testKey) 95 assert.NoError(t, err, "get data from contract state") 96 assert.Equal(t, testBytes, res, "different data detected") 97 98 // get initial data 99 res, err = contractState.GetInitialData(testKey) 100 assert.NoError(t, err, "get initial data from contract state") 101 assert.Nil(t, res, "get initial data from contract state") 102 103 // stage contract state 104 err = stateDB.StageContractState(contractState) 105 assert.NoError(t, err, "stage contract state") 106 107 // update and commit statedb 108 err = stateDB.Update() 109 assert.NoError(t, err, "update statedb") 110 err = stateDB.Commit() 111 assert.NoError(t, err, "commit statedb") 112 113 // reopen contract state 114 contractState, err = stateDB.OpenContractStateAccount(types.ToAccountID(testAddress)) 115 assert.NoError(t, err, "could not open contract state") 116 117 // get initial data 118 res, err = contractState.GetInitialData(testKey) 119 assert.NoError(t, err, "get initial data from contract state") 120 assert.Equal(t, testBytes, res, "get initial data from contract state") 121 } 122 123 func TestContractStateDataDelete(t *testing.T) { 124 initTest(t) 125 defer deinitTest() 126 testAddress := []byte("test_address") 127 testBytes := []byte("test_bytes") 128 testKey := []byte("test_key") 129 130 // open contract state and set test data 131 contractState, err := stateDB.OpenContractStateAccount(types.ToAccountID(testAddress)) 132 assert.NoError(t, err, "could not open contract state") 133 err = contractState.SetData(testKey, testBytes) 134 assert.NoError(t, err, "set data to contract state") 135 136 // stage and re-open contract state 137 err = stateDB.StageContractState(contractState) 138 assert.NoError(t, err, "stage contract state") 139 contractState, err = stateDB.OpenContractState(types.ToAccountID(testAddress), contractState.State) 140 assert.NoError(t, err, "could not open contract state") 141 142 // get and delete test data 143 res, err := contractState.GetData(testKey) 144 assert.NoError(t, err, "get data from contract state") 145 assert.Equal(t, testBytes, res, "different data detected") 146 err = contractState.DeleteData(testKey) 147 assert.NoError(t, err, "delete data from contract state") 148 149 // stage and re-open contract state 150 err = stateDB.StageContractState(contractState) 151 assert.NoError(t, err, "stage contract state") 152 contractState, err = stateDB.OpenContractState(types.ToAccountID(testAddress), contractState.State) 153 assert.NoError(t, err, "could not open contract state") 154 155 // get test data 156 res, err = contractState.GetData(testKey) 157 assert.NoError(t, err, "get data from contract state") 158 assert.Nil(t, res, "garbage data detected") 159 160 // stage contract state 161 err = stateDB.StageContractState(contractState) 162 assert.NoError(t, err, "stage contract state") 163 } 164 165 func TestContractStateHasKey(t *testing.T) { 166 initTest(t) 167 defer deinitTest() 168 testAddress := []byte("test_address") 169 testBytes := []byte("test_bytes") 170 testKey := []byte("test_key") 171 172 // open contract state and set test data 173 contractState, err := stateDB.OpenContractStateAccount(types.ToAccountID(testAddress)) 174 assert.NoError(t, err, "could not open contract state") 175 assert.False(t, contractState.HasKey(testKey)) 176 177 err = contractState.SetData(testKey, testBytes) 178 assert.NoError(t, err, "set data to contract state") 179 assert.True(t, contractState.HasKey(testKey)) 180 181 // get test data 182 _, err = contractState.GetData(testKey) 183 assert.NoError(t, err, "get data from contract state") 184 assert.True(t, contractState.HasKey(testKey)) 185 186 // delete test data 187 err = contractState.DeleteData(testKey) 188 assert.NoError(t, err, "delete data from contract state") 189 assert.True(t, contractState.HasKey(testKey)) 190 191 // stage contract state 192 err = stateDB.StageContractState(contractState) 193 assert.NoError(t, err, "stage contract state") 194 195 // update and commit 196 err = stateDB.Update() 197 assert.NoError(t, err, "failed to update stateDB") 198 err = stateDB.Commit() 199 assert.NoError(t, err, "failed to commit stateDB") 200 201 // re-open contract state 202 contractState, err = stateDB.OpenContractState(types.ToAccountID(testAddress), contractState.State) 203 assert.NoError(t, err, "could not open contract state") 204 205 // check key existence 206 assert.False(t, contractState.HasKey(testKey)) 207 } 208 209 func TestContractStateEmpty(t *testing.T) { 210 initTest(t) 211 defer deinitTest() 212 testAddress := []byte("test_address") 213 214 // open contract state 215 contractState, err := stateDB.OpenContractStateAccount(types.ToAccountID(testAddress)) 216 assert.NoError(t, err, "could not open contract state") 217 218 // stage contract state 219 err = stateDB.StageContractState(contractState) 220 assert.NoError(t, err, "stage contract state") 221 } 222 223 func TestContractStateReOpenData(t *testing.T) { 224 initTest(t) 225 defer deinitTest() 226 testAddress := []byte("test_address") 227 testBytes := []byte("test_bytes") 228 testKey := []byte("test_key") 229 230 // open contract state 231 contractState, err := stateDB.OpenContractStateAccount(types.ToAccountID(testAddress)) 232 assert.NoError(t, err, "could not open contract state") 233 234 // set data 235 err = contractState.SetData(testKey, testBytes) 236 assert.NoError(t, err, "set data to contract state") 237 238 // get data 239 res, err := contractState.GetData(testKey) 240 assert.NoError(t, err, "get data from contract state") 241 assert.Equal(t, testBytes, res, "different data detected") 242 243 // stage contract state 244 err = stateDB.StageContractState(contractState) 245 assert.NoError(t, err, "stage contract state") 246 247 // re-open contract state 248 //contractState2, err := chainStateDB.OpenContractStateAccount(types.ToAccountID(testAddress)) 249 contractState2, err := stateDB.OpenContractState(types.ToAccountID(testAddress), contractState.State) 250 assert.NoError(t, err, "could not open contract state") 251 252 // get data 253 res2, err := contractState2.GetData(testKey) 254 assert.NoError(t, err, "get data from contract state") 255 assert.Equal(t, testBytes, res2, "different data detected") 256 } 257 258 func TestContractStateRollback(t *testing.T) { 259 initTest(t) 260 defer deinitTest() 261 262 testAddress := []byte("test_address") 263 testKey := []byte("test_key") 264 265 // open contract state 266 contractState, err := stateDB.OpenContractStateAccount(types.ToAccountID(testAddress)) 267 assert.NoError(t, err, "could not open contract state") 268 269 // test data 270 _ = contractState.SetData(testKey, []byte("1")) // rev 1 271 _ = contractState.SetData(testKey, []byte("2")) // rev 2 272 res, _ := contractState.GetData(testKey) 273 assert.Equal(t, []byte("2"), res) 274 275 // snapshot: rev 2 276 revision := contractState.Snapshot() 277 t.Log("revision", revision) 278 assert.Equal(t, 2, int(revision)) 279 280 // test data 281 _ = contractState.SetData(testKey, []byte("3")) // rev 3 282 _ = contractState.SetData(testKey, []byte("4")) // rev 4 283 _ = contractState.SetData(testKey, []byte("5")) // rev 5 284 res, _ = contractState.GetData(testKey) 285 assert.Equal(t, []byte("5"), res) 286 287 // rollback: rev 2 288 contractState.Rollback(revision) 289 res, _ = contractState.GetData(testKey) 290 assert.Equal(t, []byte("2"), res) 291 292 // rollback to empty: rev 0 293 contractState.Rollback(Snapshot(0)) 294 res, _ = contractState.GetData(testKey) 295 assert.Nil(t, res) 296 }