github.com/koko1123/flow-go-1@v0.29.6/fvm/environment/accounts_test.go (about) 1 package environment_test 2 3 import ( 4 "testing" 5 6 "github.com/onflow/atree" 7 "github.com/stretchr/testify/require" 8 9 "github.com/koko1123/flow-go-1/fvm/environment" 10 "github.com/koko1123/flow-go-1/fvm/errors" 11 "github.com/koko1123/flow-go-1/fvm/state" 12 "github.com/koko1123/flow-go-1/fvm/utils" 13 "github.com/koko1123/flow-go-1/model/flow" 14 ) 15 16 func TestAccounts_Create(t *testing.T) { 17 t.Run("Sets registers", func(t *testing.T) { 18 view := utils.NewSimpleView() 19 txnState := state.NewTransactionState(view, state.DefaultParameters()) 20 accounts := environment.NewAccounts(txnState) 21 22 address := flow.HexToAddress("01") 23 24 err := accounts.Create(nil, address) 25 require.NoError(t, err) 26 27 // account status 28 require.Equal(t, len(view.Ledger.RegisterTouches), 1) 29 }) 30 31 t.Run("Fails if account exists", func(t *testing.T) { 32 view := utils.NewSimpleView() 33 txnState := state.NewTransactionState(view, state.DefaultParameters()) 34 accounts := environment.NewAccounts(txnState) 35 address := flow.HexToAddress("01") 36 37 err := accounts.Create(nil, address) 38 require.NoError(t, err) 39 40 err = accounts.Create(nil, address) 41 42 require.Error(t, err) 43 }) 44 } 45 46 func TestAccounts_GetWithNoKeys(t *testing.T) { 47 view := utils.NewSimpleView() 48 txnState := state.NewTransactionState(view, state.DefaultParameters()) 49 accounts := environment.NewAccounts(txnState) 50 address := flow.HexToAddress("01") 51 52 err := accounts.Create(nil, address) 53 require.NoError(t, err) 54 55 require.NotPanics(t, func() { 56 _, _ = accounts.Get(address) 57 }) 58 } 59 60 func TestAccounts_GetPublicKey(t *testing.T) { 61 62 t.Run("non-existent key index", func(t *testing.T) { 63 64 address := flow.HexToAddress("01") 65 66 for _, ledgerValue := range [][]byte{{}, nil} { 67 68 view := utils.NewSimpleView() 69 70 err := view.Set( 71 string(address.Bytes()), 72 "public_key_0", 73 ledgerValue, 74 ) 75 require.NoError(t, err) 76 77 txnState := state.NewTransactionState(view, state.DefaultParameters()) 78 accounts := environment.NewAccounts(txnState) 79 80 err = accounts.Create(nil, address) 81 require.NoError(t, err) 82 83 _, err = accounts.GetPublicKey(address, 0) 84 require.True(t, errors.IsAccountAccountPublicKeyNotFoundError(err)) 85 } 86 }) 87 } 88 89 func TestAccounts_GetPublicKeyCount(t *testing.T) { 90 91 t.Run("non-existent key count", func(t *testing.T) { 92 93 address := flow.HexToAddress("01") 94 95 for _, ledgerValue := range [][]byte{{}, nil} { 96 97 view := utils.NewSimpleView() 98 err := view.Set( 99 string(address.Bytes()), 100 "public_key_count", 101 ledgerValue, 102 ) 103 require.NoError(t, err) 104 105 txnState := state.NewTransactionState(view, state.DefaultParameters()) 106 accounts := environment.NewAccounts(txnState) 107 108 err = accounts.Create(nil, address) 109 require.NoError(t, err) 110 111 count, err := accounts.GetPublicKeyCount(address) 112 require.NoError(t, err) 113 require.Equal(t, uint64(0), count) 114 } 115 }) 116 } 117 118 func TestAccounts_GetPublicKeys(t *testing.T) { 119 120 t.Run("non-existent key count", func(t *testing.T) { 121 122 address := flow.HexToAddress("01") 123 124 for _, ledgerValue := range [][]byte{{}, nil} { 125 126 view := utils.NewSimpleView() 127 err := view.Set( 128 string(address.Bytes()), 129 "public_key_count", 130 ledgerValue, 131 ) 132 require.NoError(t, err) 133 134 txnState := state.NewTransactionState(view, state.DefaultParameters()) 135 accounts := environment.NewAccounts(txnState) 136 137 err = accounts.Create(nil, address) 138 require.NoError(t, err) 139 140 keys, err := accounts.GetPublicKeys(address) 141 require.NoError(t, err) 142 require.Empty(t, keys) 143 } 144 }) 145 } 146 147 // Some old account could be created without key count register 148 // we recreate it in a test 149 func TestAccounts_GetWithNoKeysCounter(t *testing.T) { 150 view := utils.NewSimpleView() 151 152 txnState := state.NewTransactionState(view, state.DefaultParameters()) 153 accounts := environment.NewAccounts(txnState) 154 address := flow.HexToAddress("01") 155 156 err := accounts.Create(nil, address) 157 require.NoError(t, err) 158 159 err = view.Delete( 160 string(address.Bytes()), 161 "public_key_count") 162 163 require.NoError(t, err) 164 165 require.NotPanics(t, func() { 166 _, _ = accounts.Get(address) 167 }) 168 } 169 170 func TestAccounts_SetContracts(t *testing.T) { 171 172 address := flow.HexToAddress("0x01") 173 174 t.Run("Setting a contract puts it in Contracts", func(t *testing.T) { 175 view := utils.NewSimpleView() 176 txnState := state.NewTransactionState(view, state.DefaultParameters()) 177 a := environment.NewAccounts(txnState) 178 err := a.Create(nil, address) 179 require.NoError(t, err) 180 181 err = a.SetContract("Dummy", address, []byte("non empty string")) 182 require.NoError(t, err) 183 184 contractNames, err := a.GetContractNames(address) 185 require.NoError(t, err) 186 187 require.Len(t, contractNames, 1, "There should only be one contract") 188 require.Equal(t, contractNames[0], "Dummy") 189 }) 190 t.Run("Setting a contract again, does not add it to contracts", func(t *testing.T) { 191 view := utils.NewSimpleView() 192 txnState := state.NewTransactionState(view, state.DefaultParameters()) 193 a := environment.NewAccounts(txnState) 194 err := a.Create(nil, address) 195 require.NoError(t, err) 196 197 err = a.SetContract("Dummy", address, []byte("non empty string")) 198 require.NoError(t, err) 199 200 err = a.SetContract("Dummy", address, []byte("non empty string")) 201 require.NoError(t, err) 202 203 contractNames, err := a.GetContractNames(address) 204 require.NoError(t, err) 205 206 require.Len(t, contractNames, 1, "There should only be one contract") 207 require.Equal(t, contractNames[0], "Dummy") 208 }) 209 t.Run("Setting more contracts always keeps them sorted", func(t *testing.T) { 210 view := utils.NewSimpleView() 211 txnState := state.NewTransactionState(view, state.DefaultParameters()) 212 a := environment.NewAccounts(txnState) 213 err := a.Create(nil, address) 214 require.NoError(t, err) 215 216 err = a.SetContract("Dummy", address, []byte("non empty string")) 217 require.NoError(t, err) 218 219 err = a.SetContract("ZedDummy", address, []byte("non empty string")) 220 require.NoError(t, err) 221 222 err = a.SetContract("ADummy", address, []byte("non empty string")) 223 require.NoError(t, err) 224 225 contractNames, err := a.GetContractNames(address) 226 require.NoError(t, err) 227 228 require.Len(t, contractNames, 3) 229 require.Equal(t, contractNames[0], "ADummy") 230 require.Equal(t, contractNames[1], "Dummy") 231 require.Equal(t, contractNames[2], "ZedDummy") 232 }) 233 t.Run("Removing a contract does not fail if there is none", func(t *testing.T) { 234 view := utils.NewSimpleView() 235 txnState := state.NewTransactionState(view, state.DefaultParameters()) 236 a := environment.NewAccounts(txnState) 237 err := a.Create(nil, address) 238 require.NoError(t, err) 239 240 err = a.DeleteContract("Dummy", address) 241 require.NoError(t, err) 242 }) 243 t.Run("Removing a contract removes it", func(t *testing.T) { 244 view := utils.NewSimpleView() 245 txnState := state.NewTransactionState(view, state.DefaultParameters()) 246 a := environment.NewAccounts(txnState) 247 err := a.Create(nil, address) 248 require.NoError(t, err) 249 250 err = a.SetContract("Dummy", address, []byte("non empty string")) 251 require.NoError(t, err) 252 253 err = a.DeleteContract("Dummy", address) 254 require.NoError(t, err) 255 256 contractNames, err := a.GetContractNames(address) 257 require.NoError(t, err) 258 259 require.Len(t, contractNames, 0, "There should be no contract") 260 }) 261 } 262 263 func TestAccount_StorageUsed(t *testing.T) { 264 265 t.Run("Storage used on account creation is deterministic", func(t *testing.T) { 266 view := utils.NewSimpleView() 267 txnState := state.NewTransactionState(view, state.DefaultParameters()) 268 accounts := environment.NewAccounts(txnState) 269 address := flow.HexToAddress("01") 270 271 err := accounts.Create(nil, address) 272 require.NoError(t, err) 273 274 storageUsed, err := accounts.GetStorageUsed(address) 275 require.NoError(t, err) 276 require.Equal(t, uint64(40), storageUsed) 277 }) 278 279 t.Run("Storage used on register set increases", func(t *testing.T) { 280 view := utils.NewSimpleView() 281 txnState := state.NewTransactionState(view, state.DefaultParameters()) 282 accounts := environment.NewAccounts(txnState) 283 address := flow.HexToAddress("01") 284 285 err := accounts.Create(nil, address) 286 require.NoError(t, err) 287 288 err = accounts.SetValue(address, "some_key", createByteArray(12)) 289 require.NoError(t, err) 290 291 storageUsed, err := accounts.GetStorageUsed(address) 292 require.NoError(t, err) 293 require.Equal(t, uint64(40+32), storageUsed) 294 }) 295 296 t.Run("Storage used, set twice on same register to same value, stays the same", func(t *testing.T) { 297 view := utils.NewSimpleView() 298 txnState := state.NewTransactionState(view, state.DefaultParameters()) 299 accounts := environment.NewAccounts(txnState) 300 address := flow.HexToAddress("01") 301 302 err := accounts.Create(nil, address) 303 require.NoError(t, err) 304 305 err = accounts.SetValue(address, "some_key", createByteArray(12)) 306 require.NoError(t, err) 307 err = accounts.SetValue(address, "some_key", createByteArray(12)) 308 require.NoError(t, err) 309 310 storageUsed, err := accounts.GetStorageUsed(address) 311 require.NoError(t, err) 312 require.Equal(t, uint64(40+32), storageUsed) 313 }) 314 315 t.Run("Storage used, set twice on same register to larger value, increases", func(t *testing.T) { 316 view := utils.NewSimpleView() 317 txnState := state.NewTransactionState(view, state.DefaultParameters()) 318 accounts := environment.NewAccounts(txnState) 319 address := flow.HexToAddress("01") 320 321 err := accounts.Create(nil, address) 322 require.NoError(t, err) 323 324 err = accounts.SetValue(address, "some_key", createByteArray(12)) 325 require.NoError(t, err) 326 err = accounts.SetValue(address, "some_key", createByteArray(13)) 327 require.NoError(t, err) 328 329 storageUsed, err := accounts.GetStorageUsed(address) 330 require.NoError(t, err) 331 require.Equal(t, uint64(40+33), storageUsed) 332 }) 333 334 t.Run("Storage used, set twice on same register to smaller value, decreases", func(t *testing.T) { 335 view := utils.NewSimpleView() 336 txnState := state.NewTransactionState(view, state.DefaultParameters()) 337 accounts := environment.NewAccounts(txnState) 338 address := flow.HexToAddress("01") 339 340 err := accounts.Create(nil, address) 341 require.NoError(t, err) 342 343 err = accounts.SetValue(address, "some_key", createByteArray(12)) 344 require.NoError(t, err) 345 err = accounts.SetValue(address, "some_key", createByteArray(11)) 346 require.NoError(t, err) 347 348 storageUsed, err := accounts.GetStorageUsed(address) 349 require.NoError(t, err) 350 require.Equal(t, uint64(40+31), storageUsed) 351 }) 352 353 t.Run("Storage used, after register deleted, decreases", func(t *testing.T) { 354 view := utils.NewSimpleView() 355 txnState := state.NewTransactionState(view, state.DefaultParameters()) 356 accounts := environment.NewAccounts(txnState) 357 address := flow.HexToAddress("01") 358 359 err := accounts.Create(nil, address) 360 require.NoError(t, err) 361 362 err = accounts.SetValue(address, "some_key", createByteArray(12)) 363 require.NoError(t, err) 364 err = accounts.SetValue(address, "some_key", nil) 365 require.NoError(t, err) 366 367 storageUsed, err := accounts.GetStorageUsed(address) 368 require.NoError(t, err) 369 require.Equal(t, uint64(40+0), storageUsed) 370 }) 371 372 t.Run("Storage used on a complex scenario has correct value", func(t *testing.T) { 373 view := utils.NewSimpleView() 374 txnState := state.NewTransactionState(view, state.DefaultParameters()) 375 accounts := environment.NewAccounts(txnState) 376 address := flow.HexToAddress("01") 377 378 err := accounts.Create(nil, address) 379 require.NoError(t, err) 380 381 err = accounts.SetValue(address, "some_key", createByteArray(12)) 382 require.NoError(t, err) 383 err = accounts.SetValue(address, "some_key", createByteArray(11)) 384 require.NoError(t, err) 385 386 err = accounts.SetValue(address, "some_key2", createByteArray(22)) 387 require.NoError(t, err) 388 err = accounts.SetValue(address, "some_key2", createByteArray(23)) 389 require.NoError(t, err) 390 391 err = accounts.SetValue(address, "some_key3", createByteArray(22)) 392 require.NoError(t, err) 393 err = accounts.SetValue(address, "some_key3", createByteArray(0)) 394 require.NoError(t, err) 395 396 storageUsed, err := accounts.GetStorageUsed(address) 397 require.NoError(t, err) 398 require.Equal(t, uint64(40+33+42), storageUsed) 399 }) 400 } 401 402 func createByteArray(size int) []byte { 403 bytes := make([]byte, size) 404 for i := range bytes { 405 bytes[i] = 255 406 } 407 return bytes 408 } 409 410 func TestAccounts_AllocateStorageIndex(t *testing.T) { 411 view := utils.NewSimpleView() 412 413 txnState := state.NewTransactionState(view, state.DefaultParameters()) 414 accounts := environment.NewAccounts(txnState) 415 address := flow.HexToAddress("01") 416 417 err := accounts.Create(nil, address) 418 require.NoError(t, err) 419 420 // no register set case 421 i, err := accounts.AllocateStorageIndex(address) 422 require.NoError(t, err) 423 require.Equal(t, i, atree.StorageIndex([8]byte{0, 0, 0, 0, 0, 0, 0, 1})) 424 425 // register already set case 426 i, err = accounts.AllocateStorageIndex(address) 427 require.NoError(t, err) 428 require.Equal(t, i, atree.StorageIndex([8]byte{0, 0, 0, 0, 0, 0, 0, 2})) 429 430 // register update successful 431 i, err = accounts.AllocateStorageIndex(address) 432 require.NoError(t, err) 433 require.Equal(t, i, atree.StorageIndex([8]byte{0, 0, 0, 0, 0, 0, 0, 3})) 434 }