github.com/iotexproject/iotex-core@v1.14.1-rc1/state/factory/factory_test.go (about) 1 // Copyright (c) 2019 IoTeX Foundation 2 // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability 3 // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. 4 // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. 5 6 package factory 7 8 import ( 9 "context" 10 "encoding/csv" 11 "encoding/hex" 12 "math/big" 13 "math/rand" 14 "os" 15 "path/filepath" 16 "testing" 17 "time" 18 19 "github.com/golang/mock/gomock" 20 "github.com/pkg/errors" 21 "github.com/stretchr/testify/require" 22 23 "github.com/iotexproject/go-pkgs/crypto" 24 "github.com/iotexproject/go-pkgs/hash" 25 "github.com/iotexproject/iotex-address/address" 26 "github.com/iotexproject/iotex-election/test/mock/mock_committee" 27 "github.com/iotexproject/iotex-election/types" 28 29 "github.com/iotexproject/iotex-core/action" 30 "github.com/iotexproject/iotex-core/action/protocol" 31 "github.com/iotexproject/iotex-core/action/protocol/account" 32 accountutil "github.com/iotexproject/iotex-core/action/protocol/account/util" 33 "github.com/iotexproject/iotex-core/action/protocol/execution/evm" 34 "github.com/iotexproject/iotex-core/action/protocol/poll" 35 "github.com/iotexproject/iotex-core/action/protocol/rewarding" 36 "github.com/iotexproject/iotex-core/action/protocol/rolldpos" 37 "github.com/iotexproject/iotex-core/action/protocol/vote/candidatesutil" 38 "github.com/iotexproject/iotex-core/blockchain" 39 "github.com/iotexproject/iotex-core/blockchain/block" 40 "github.com/iotexproject/iotex-core/blockchain/genesis" 41 "github.com/iotexproject/iotex-core/db" 42 "github.com/iotexproject/iotex-core/pkg/enc" 43 "github.com/iotexproject/iotex-core/pkg/util/fileutil" 44 "github.com/iotexproject/iotex-core/state" 45 "github.com/iotexproject/iotex-core/test/identityset" 46 "github.com/iotexproject/iotex-core/test/mock/mock_actpool" 47 "github.com/iotexproject/iotex-core/testutil" 48 ) 49 50 const ( 51 _triePath = "trie.test" 52 _stateDBPath = "stateDB.test" 53 ) 54 55 var _letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") 56 57 func randStringRunes(n int) string { 58 b := make([]rune, n) 59 for i := range b { 60 b[i] = _letterRunes[rand.Intn(len(_letterRunes))] 61 } 62 return string(b) 63 } 64 65 func TestGenerateConfig(t *testing.T) { 66 require := require.New(t) 67 cfg := GenerateConfig(blockchain.DefaultConfig, genesis.Default) 68 require.Equal(27, len(cfg.Genesis.InitBalanceMap)) 69 require.Equal(blockchain.DefaultConfig.ChainDBPath, cfg.Chain.ChainDBPath) 70 } 71 72 func TestSnapshot(t *testing.T) { 73 require := require.New(t) 74 testTriePath, err := testutil.PathOfTempFile(_triePath) 75 require.NoError(err) 76 77 cfg := DefaultConfig 78 db1, err := db.CreateKVStore(db.DefaultConfig, testTriePath) 79 require.NoError(err) 80 81 cfg.Genesis.InitBalanceMap[identityset.Address(28).String()] = "5" 82 cfg.Genesis.InitBalanceMap[identityset.Address(29).String()] = "7" 83 registry := protocol.NewRegistry() 84 sf, err := NewFactory(cfg, db1, RegistryOption(registry)) 85 require.NoError(err) 86 acc := account.NewProtocol(rewarding.DepositGas) 87 require.NoError(acc.Register(registry)) 88 ctx := protocol.WithBlockCtx( 89 genesis.WithGenesisContext(context.Background(), cfg.Genesis), 90 protocol.BlockCtx{}, 91 ) 92 require.NoError(sf.Start(ctx)) 93 defer func() { 94 require.NoError(sf.Stop(ctx)) 95 testutil.CleanupPath(testTriePath) 96 }() 97 ws, err := sf.(workingSetCreator).newWorkingSet(ctx, 1) 98 require.NoError(err) 99 testSnapshot(ws, t) 100 testRevert(ws, t) 101 } 102 103 func TestSDBSnapshot(t *testing.T) { 104 require := require.New(t) 105 testStateDBPath, err := testutil.PathOfTempFile(_stateDBPath) 106 require.NoError(err) 107 defer testutil.CleanupPath(testStateDBPath) 108 109 cfg := DefaultConfig 110 cfg.Chain.TrieDBPatchFile = "" 111 cfg.Chain.TrieDBPath = testStateDBPath 112 cfg.Genesis.InitBalanceMap[identityset.Address(28).String()] = "5" 113 cfg.Genesis.InitBalanceMap[identityset.Address(29).String()] = "7" 114 registry := protocol.NewRegistry() 115 db2, err := db.CreateKVStoreWithCache(db.DefaultConfig, cfg.Chain.TrieDBPath, cfg.Chain.StateDBCacheSize) 116 require.NoError(err) 117 sdb, err := NewStateDB(cfg, db2, RegistryStateDBOption(registry)) 118 require.NoError(err) 119 acc := account.NewProtocol(rewarding.DepositGas) 120 require.NoError(acc.Register(registry)) 121 ctx := protocol.WithBlockCtx( 122 genesis.WithGenesisContext(context.Background(), cfg.Genesis), 123 protocol.BlockCtx{}, 124 ) 125 require.NoError(sdb.Start(ctx)) 126 height, err := sdb.Height() 127 require.NoError(err) 128 ws, err := sdb.(workingSetCreator).newWorkingSet(ctx, height) 129 require.NoError(err) 130 testSnapshot(ws, t) 131 testSDBRevert(ws, t) 132 } 133 134 func testRevert(ws *workingSet, t *testing.T) { 135 require := require.New(t) 136 sHash := hash.BytesToHash160(identityset.Address(28).Bytes()) 137 138 s, err := accountutil.LoadAccount(ws, identityset.Address(28)) 139 require.NoError(err) 140 require.Equal(big.NewInt(5), s.Balance) 141 s0 := ws.Snapshot() 142 require.Equal(1, s0) 143 144 require.NoError(s.AddBalance(big.NewInt(5))) 145 require.Equal(big.NewInt(10), s.Balance) 146 _, err = ws.PutState(s, protocol.LegacyKeyOption(sHash)) 147 require.NoError(err) 148 149 require.NoError(ws.Revert(s0)) 150 _, err = ws.State(s, protocol.LegacyKeyOption(sHash)) 151 require.NoError(err) 152 require.Equal(big.NewInt(5), s.Balance) 153 } 154 155 func testSDBRevert(ws *workingSet, t *testing.T) { 156 require := require.New(t) 157 sHash := hash.BytesToHash160(identityset.Address(28).Bytes()) 158 159 s, err := accountutil.LoadAccount(ws, identityset.Address(28)) 160 require.NoError(err) 161 require.Equal(big.NewInt(5), s.Balance) 162 s0 := ws.Snapshot() 163 require.Equal(1, s0) 164 165 require.NoError(s.AddBalance(big.NewInt(5))) 166 require.Equal(big.NewInt(10), s.Balance) 167 _, err = ws.PutState(s, protocol.LegacyKeyOption(sHash)) 168 require.NoError(err) 169 170 require.NoError(ws.Revert(s0)) 171 _, err = ws.State(s, protocol.LegacyKeyOption(sHash)) 172 require.NoError(err) 173 require.Equal(big.NewInt(5), s.Balance) 174 } 175 176 func testSnapshot(ws *workingSet, t *testing.T) { 177 require := require.New(t) 178 sHash := hash.BytesToHash160(identityset.Address(28).Bytes()) 179 sHashAddr := identityset.Address(28) 180 tHash := hash.BytesToHash160(identityset.Address(29).Bytes()) 181 tHashAddr := identityset.Address(29) 182 183 s, err := accountutil.LoadAccount(ws, tHashAddr) 184 require.NoError(err) 185 require.Equal(big.NewInt(7), s.Balance) 186 s, err = accountutil.LoadAccount(ws, sHashAddr) 187 require.NoError(err) 188 require.Equal(big.NewInt(5), s.Balance) 189 s0 := ws.Snapshot() 190 require.Zero(s0) 191 require.NoError(s.AddBalance(big.NewInt(5))) 192 require.Equal(big.NewInt(10), s.Balance) 193 _, err = ws.PutState(s, protocol.LegacyKeyOption(sHash)) 194 require.NoError(err) 195 s1 := ws.Snapshot() 196 require.Equal(1, s1) 197 require.NoError(s.AddBalance(big.NewInt(5))) 198 require.Equal(big.NewInt(15), s.Balance) 199 _, err = ws.PutState(s, protocol.LegacyKeyOption(sHash)) 200 require.NoError(err) 201 202 s, err = accountutil.LoadAccount(ws, tHashAddr) 203 require.NoError(err) 204 require.Equal(big.NewInt(7), s.Balance) 205 s2 := ws.Snapshot() 206 require.Equal(2, s2) 207 require.NoError(s.AddBalance(big.NewInt(6))) 208 require.Equal(big.NewInt(13), s.Balance) 209 _, err = ws.PutState(s, protocol.LegacyKeyOption(tHash)) 210 require.NoError(err) 211 212 require.NoError(ws.Revert(s2)) 213 _, err = ws.State(s, protocol.LegacyKeyOption(sHash)) 214 require.NoError(err) 215 require.Equal(big.NewInt(15), s.Balance) 216 _, err = ws.State(s, protocol.LegacyKeyOption(tHash)) 217 require.NoError(err) 218 require.Equal(big.NewInt(7), s.Balance) 219 require.NoError(ws.Revert(s1)) 220 _, err = ws.State(s, protocol.LegacyKeyOption(sHash)) 221 require.NoError(err) 222 require.Equal(big.NewInt(10), s.Balance) 223 require.NoError(ws.Revert(s0)) 224 _, err = ws.State(s, protocol.LegacyKeyOption(sHash)) 225 require.NoError(err) 226 require.Equal(big.NewInt(5), s.Balance) 227 } 228 229 func TestCandidates(t *testing.T) { 230 cfg := DefaultConfig 231 sf, err := NewFactory(cfg, db.NewMemKVStore(), SkipBlockValidationOption()) 232 require.NoError(t, err) 233 testCandidates(sf, t) 234 } 235 236 func TestSDBCandidates(t *testing.T) { 237 cfg := DefaultConfig 238 sdb, err := NewStateDB(cfg, db.NewMemKVStore(), SkipBlockValidationStateDBOption()) 239 require.NoError(t, err) 240 testCandidates(sdb, t) 241 } 242 243 func testCandidates(sf Factory, t *testing.T) { 244 sc := state.CandidateList{} 245 result := types.NewElectionResultForTest(time.Now()) 246 for _, c := range result.Delegates() { 247 oa, err := address.FromString(string(c.OperatorAddress())) 248 require.NoError(t, err) 249 ra, err := address.FromString(string(c.RewardAddress())) 250 require.NoError(t, err) 251 sc = append(sc, &state.Candidate{ 252 Address: oa.String(), 253 Votes: c.Score(), 254 RewardAddress: ra.String(), 255 CanName: c.Name(), 256 }) 257 } 258 act := action.NewPutPollResult(1, 1, sc) 259 bd := &action.EnvelopeBuilder{} 260 elp := bd.SetGasLimit(uint64(100000)). 261 SetGasPrice(big.NewInt(10)). 262 SetAction(act).Build() 263 selp, err := action.Sign(elp, identityset.PrivateKey(27)) 264 require.NoError(t, err) 265 require.NotNil(t, selp) 266 267 ctrl := gomock.NewController(t) 268 269 committee := mock_committee.NewMockCommittee(ctrl) 270 committee.EXPECT().ResultByHeight(uint64(123456)).Return(result, nil).AnyTimes() 271 committee.EXPECT().HeightByTime(gomock.Any()).Return(uint64(123456), nil).AnyTimes() 272 273 require.NoError(t, sf.Register(rolldpos.NewProtocol(36, 36, 20))) 274 cfg := DefaultConfig 275 slasher, err := poll.NewSlasher( 276 func(uint64, uint64) (map[string]uint64, error) { 277 return nil, nil 278 }, 279 nil, 280 nil, 281 nil, 282 nil, 283 cfg.Genesis.NumCandidateDelegates, 284 cfg.Genesis.NumDelegates, 285 cfg.Genesis.DardanellesNumSubEpochs, 286 cfg.Genesis.ProductivityThreshold, 287 cfg.Genesis.ProbationEpochPeriod, 288 cfg.Genesis.UnproductiveDelegateMaxCacheSize, 289 cfg.Genesis.ProbationIntensityRate) 290 require.NoError(t, err) 291 p, err := poll.NewGovernanceChainCommitteeProtocol( 292 nil, 293 committee, 294 uint64(123456), 295 func(uint64) (time.Time, error) { return time.Now(), nil }, 296 cfg.Chain.PollInitialCandidatesInterval, 297 slasher, 298 ) 299 require.NoError(t, err) 300 require.NoError(t, sf.Register(p)) 301 gasLimit := testutil.TestGasLimit 302 303 // TODO: investigate why registry cannot be added in the Blockchain Ctx 304 ctx := protocol.WithBlockCtx( 305 genesis.WithGenesisContext(context.Background(), cfg.Genesis), 306 protocol.BlockCtx{ 307 BlockHeight: 0, 308 Producer: identityset.Address(27), 309 GasLimit: gasLimit, 310 }, 311 ) 312 ctx = protocol.WithFeatureCtx(protocol.WithFeatureWithHeightCtx(ctx)) 313 require.NoError(t, sf.Start(ctx)) 314 defer require.NoError(t, sf.Stop(ctx)) 315 316 blk, err := block.NewTestingBuilder(). 317 SetHeight(1). 318 SetPrevBlockHash(hash.ZeroHash256). 319 SetTimeStamp(testutil.TimestampNow()). 320 AddActions([]*action.SealedEnvelope{selp}...). 321 SignAndBuild(identityset.PrivateKey(27)) 322 require.NoError(t, err) 323 require.NoError(t, sf.PutBlock( 324 protocol.WithFeatureCtx(protocol.WithFeatureWithHeightCtx( 325 protocol.WithBlockchainCtx( 326 protocol.WithBlockCtx( 327 genesis.WithGenesisContext(context.Background(), cfg.Genesis), 328 protocol.BlockCtx{ 329 BlockHeight: 1, 330 Producer: identityset.Address(27), 331 GasLimit: gasLimit, 332 }, 333 ), 334 protocol.BlockchainCtx{ 335 ChainID: 1, 336 }, 337 ), 338 ), 339 ), &blk)) 340 341 candidates, _, err := candidatesutil.CandidatesFromDB(sf, 1, true, false) 342 require.NoError(t, err) 343 require.Equal(t, len(sc), len(candidates)) 344 for i, c := range candidates { 345 require.True(t, c.Equal(sc[i])) 346 } 347 } 348 349 func TestState(t *testing.T) { 350 testTriePath, err := testutil.PathOfTempFile(_triePath) 351 require.NoError(t, err) 352 defer testutil.CleanupPath(testTriePath) 353 354 cfg := DefaultConfig 355 db1, err := db.CreateKVStore(db.DefaultConfig, testTriePath) 356 require.NoError(t, err) 357 sf, err := NewFactory(cfg, db1, SkipBlockValidationOption()) 358 require.NoError(t, err) 359 testState(sf, t) 360 } 361 362 func TestHistoryState(t *testing.T) { 363 r := require.New(t) 364 var err error 365 // using factory and enable history 366 cfg := DefaultConfig 367 cfg.Chain.TrieDBPath, err = testutil.PathOfTempFile(_triePath) 368 r.NoError(err) 369 cfg.Chain.EnableArchiveMode = true 370 db1, err := db.CreateKVStore(db.DefaultConfig, cfg.Chain.TrieDBPath) 371 r.NoError(err) 372 sf, err := NewFactory(cfg, db1, SkipBlockValidationOption()) 373 r.NoError(err) 374 testHistoryState(sf, t, false, cfg.Chain.EnableArchiveMode) 375 376 // using stateDB and enable history 377 cfg.Chain.TrieDBPath, err = testutil.PathOfTempFile(_triePath) 378 r.NoError(err) 379 db2, err := db.CreateKVStoreWithCache(db.DefaultConfig, cfg.Chain.TrieDBPath, cfg.Chain.StateDBCacheSize) 380 r.NoError(err) 381 sf, err = NewStateDB(cfg, db2, SkipBlockValidationStateDBOption()) 382 r.NoError(err) 383 testHistoryState(sf, t, true, cfg.Chain.EnableArchiveMode) 384 385 // using factory and disable history 386 cfg.Chain.TrieDBPath, err = testutil.PathOfTempFile(_triePath) 387 r.NoError(err) 388 cfg.Chain.EnableArchiveMode = false 389 db1, err = db.CreateKVStore(db.DefaultConfig, cfg.Chain.TrieDBPath) 390 r.NoError(err) 391 sf, err = NewFactory(cfg, db1, SkipBlockValidationOption()) 392 r.NoError(err) 393 testHistoryState(sf, t, false, cfg.Chain.EnableArchiveMode) 394 395 // using stateDB and disable history 396 cfg.Chain.TrieDBPath, err = testutil.PathOfTempFile(_triePath) 397 r.NoError(err) 398 db2, err = db.CreateKVStoreWithCache(db.DefaultConfig, cfg.Chain.TrieDBPath, cfg.Chain.StateDBCacheSize) 399 r.NoError(err) 400 sf, err = NewStateDB(cfg, db2, SkipBlockValidationStateDBOption()) 401 r.NoError(err) 402 testHistoryState(sf, t, true, cfg.Chain.EnableArchiveMode) 403 defer func() { 404 testutil.CleanupPath(cfg.Chain.TrieDBPath) 405 }() 406 } 407 408 func TestFactoryStates(t *testing.T) { 409 r := require.New(t) 410 var err error 411 cfg := DefaultConfig 412 // using factory 413 cfg.Chain.TrieDBPath, err = testutil.PathOfTempFile(_triePath) 414 r.NoError(err) 415 db1, err := db.CreateKVStore(db.DefaultConfig, cfg.Chain.TrieDBPath) 416 r.NoError(err) 417 sf, err := NewFactory(cfg, db1, SkipBlockValidationOption()) 418 r.NoError(err) 419 testFactoryStates(sf, t) 420 421 // using stateDB 422 cfg.Chain.TrieDBPath, err = testutil.PathOfTempFile(_triePath) 423 r.NoError(err) 424 db2, err := db.CreateKVStoreWithCache(db.DefaultConfig, cfg.Chain.TrieDBPath, cfg.Chain.StateDBCacheSize) 425 r.NoError(err) 426 sf, err = NewStateDB(cfg, db2, SkipBlockValidationStateDBOption()) 427 r.NoError(err) 428 testFactoryStates(sf, t) 429 defer testutil.CleanupPath(cfg.Chain.TrieDBPath) 430 } 431 432 func TestSDBState(t *testing.T) { 433 testDBPath, err := testutil.PathOfTempFile(_stateDBPath) 434 require.NoError(t, err) 435 defer testutil.CleanupPath(testDBPath) 436 437 cfg := DefaultConfig 438 cfg.Chain.TrieDBPath = testDBPath 439 db1, err := db.CreateKVStoreWithCache(db.DefaultConfig, cfg.Chain.TrieDBPath, cfg.Chain.StateDBCacheSize) 440 require.NoError(t, err) 441 sdb, err := NewStateDB(cfg, db1, SkipBlockValidationStateDBOption()) 442 require.NoError(t, err) 443 testState(sdb, t) 444 } 445 446 func testState(sf Factory, t *testing.T) { 447 // Create a dummy iotex address 448 a := identityset.Address(28) 449 priKeyA := identityset.PrivateKey(28) 450 acc := account.NewProtocol(rewarding.DepositGas) 451 require.NoError(t, sf.Register(acc)) 452 ge := genesis.Default 453 ge.InitBalanceMap[a.String()] = "100" 454 gasLimit := uint64(1000000) 455 ctx := protocol.WithBlockchainCtx(protocol.WithBlockCtx( 456 context.Background(), 457 protocol.BlockCtx{ 458 BlockHeight: 0, 459 Producer: identityset.Address(27), 460 GasLimit: gasLimit, 461 }, 462 ), protocol.BlockchainCtx{ 463 ChainID: 1, 464 }) 465 ctx = genesis.WithGenesisContext(ctx, ge) 466 467 require.NoError(t, sf.Start(ctx)) 468 defer func() { 469 require.NoError(t, sf.Stop(ctx)) 470 }() 471 472 tsf, err := action.NewTransfer(1, big.NewInt(10), identityset.Address(31).String(), nil, uint64(20000), big.NewInt(0)) 473 require.NoError(t, err) 474 bd := &action.EnvelopeBuilder{} 475 elp := bd.SetAction(tsf).SetGasLimit(20000).SetNonce(1).Build() 476 selp, err := action.Sign(elp, priKeyA) 477 require.NoError(t, err) 478 ctx = protocol.WithBlockCtx( 479 ctx, 480 protocol.BlockCtx{ 481 BlockHeight: 1, 482 Producer: identityset.Address(27), 483 GasLimit: gasLimit, 484 }, 485 ) 486 blk, err := block.NewTestingBuilder(). 487 SetHeight(1). 488 SetPrevBlockHash(hash.ZeroHash256). 489 SetTimeStamp(testutil.TimestampNow()). 490 AddActions([]*action.SealedEnvelope{selp}...). 491 SignAndBuild(identityset.PrivateKey(27)) 492 require.NoError(t, err) 493 require.NoError(t, sf.PutBlock(ctx, &blk)) 494 495 //test AccountState() & State() 496 testAccount := &state.Account{} 497 accountA, err := accountutil.AccountState(ctx, sf, a) 498 require.NoError(t, err) 499 sHash := hash.BytesToHash160(identityset.Address(28).Bytes()) 500 _, err = sf.State(testAccount, protocol.LegacyKeyOption(sHash)) 501 require.NoError(t, err) 502 require.Equal(t, accountA, testAccount) 503 require.Equal(t, big.NewInt(90), accountA.Balance) 504 } 505 506 func testHistoryState(sf Factory, t *testing.T, statetx, archive bool) { 507 // Create a dummy iotex address 508 a := identityset.Address(28) 509 b := identityset.Address(31) 510 priKeyA := identityset.PrivateKey(28) 511 acc := account.NewProtocol(rewarding.DepositGas) 512 require.NoError(t, sf.Register(acc)) 513 ge := genesis.Default 514 ge.InitBalanceMap[a.String()] = "100" 515 gasLimit := uint64(1000000) 516 ctx := protocol.WithBlockCtx( 517 context.Background(), 518 protocol.BlockCtx{ 519 BlockHeight: 0, 520 Producer: identityset.Address(27), 521 GasLimit: gasLimit, 522 }, 523 ) 524 ctx = genesis.WithGenesisContext(ctx, ge) 525 526 require.NoError(t, sf.Start(ctx)) 527 defer func() { 528 require.NoError(t, sf.Stop(ctx)) 529 }() 530 accountA, err := accountutil.AccountState(ctx, sf, a) 531 require.NoError(t, err) 532 accountB, err := accountutil.AccountState(ctx, sf, b) 533 require.NoError(t, err) 534 require.Equal(t, big.NewInt(100), accountA.Balance) 535 require.Equal(t, big.NewInt(0), accountB.Balance) 536 tsf, err := action.NewTransfer(1, big.NewInt(10), b.String(), nil, uint64(20000), big.NewInt(0)) 537 require.NoError(t, err) 538 bd := &action.EnvelopeBuilder{} 539 elp := bd.SetAction(tsf).SetGasLimit(20000).SetNonce(1).Build() 540 selp, err := action.Sign(elp, priKeyA) 541 require.NoError(t, err) 542 ctx = protocol.WithBlockCtx( 543 ctx, 544 protocol.BlockCtx{ 545 BlockHeight: 1, 546 Producer: identityset.Address(27), 547 GasLimit: gasLimit, 548 }, 549 ) 550 ctx = protocol.WithBlockchainCtx(ctx, protocol.BlockchainCtx{ 551 ChainID: 1, 552 }) 553 blk, err := block.NewTestingBuilder(). 554 SetHeight(1). 555 SetPrevBlockHash(hash.ZeroHash256). 556 SetTimeStamp(testutil.TimestampNow()). 557 AddActions([]*action.SealedEnvelope{selp}...). 558 SignAndBuild(identityset.PrivateKey(27)) 559 require.NoError(t, err) 560 require.NoError(t, sf.PutBlock(ctx, &blk)) 561 562 // check latest balance 563 accountA, err = accountutil.AccountState(ctx, sf, a) 564 require.NoError(t, err) 565 accountB, err = accountutil.AccountState(ctx, sf, b) 566 require.NoError(t, err) 567 require.Equal(t, big.NewInt(90), accountA.Balance) 568 require.Equal(t, big.NewInt(10), accountB.Balance) 569 570 // check archive data 571 if statetx { 572 // statetx not support archive mode 573 _, err = accountutil.AccountState(ctx, NewHistoryStateReader(sf, 0), a) 574 require.Equal(t, ErrNotSupported, errors.Cause(err)) 575 _, err = accountutil.AccountState(ctx, NewHistoryStateReader(sf, 0), b) 576 require.Equal(t, ErrNotSupported, errors.Cause(err)) 577 } else { 578 if !archive { 579 _, err = accountutil.AccountState(ctx, NewHistoryStateReader(sf, 0), a) 580 require.Equal(t, ErrNoArchiveData, errors.Cause(err)) 581 _, err = accountutil.AccountState(ctx, NewHistoryStateReader(sf, 0), b) 582 require.Equal(t, ErrNoArchiveData, errors.Cause(err)) 583 } else { 584 accountA, err = accountutil.AccountState(ctx, NewHistoryStateReader(sf, 0), a) 585 require.NoError(t, err) 586 accountB, err = accountutil.AccountState(ctx, NewHistoryStateReader(sf, 0), b) 587 require.NoError(t, err) 588 require.Equal(t, big.NewInt(100), accountA.Balance) 589 require.Equal(t, big.NewInt(0), accountB.Balance) 590 } 591 } 592 } 593 594 func testFactoryStates(sf Factory, t *testing.T) { 595 // Create a dummy iotex address 596 a := identityset.Address(28).String() 597 b := identityset.Address(31).String() 598 priKeyA := identityset.PrivateKey(28) 599 acc := account.NewProtocol(rewarding.DepositGas) 600 require.NoError(t, sf.Register(acc)) 601 ge := genesis.Default 602 ge.InitBalanceMap = make(map[string]string) 603 ge.InitBalanceMap[a] = "100" 604 ge.InitBalanceMap[b] = "100" 605 gasLimit := uint64(1000000) 606 ctx := protocol.WithBlockCtx( 607 context.Background(), 608 protocol.BlockCtx{ 609 BlockHeight: 0, 610 Producer: identityset.Address(27), 611 GasLimit: gasLimit, 612 }, 613 ) 614 ctx = genesis.WithGenesisContext(ctx, ge) 615 616 require.NoError(t, sf.Start(ctx)) 617 defer func() { 618 require.NoError(t, sf.Stop(ctx)) 619 }() 620 tsf, err := action.NewTransfer(1, big.NewInt(10), b, nil, uint64(20000), big.NewInt(0)) 621 require.NoError(t, err) 622 bd := &action.EnvelopeBuilder{} 623 elp := bd.SetAction(tsf).SetGasLimit(20000).SetNonce(1).Build() 624 selp, err := action.Sign(elp, priKeyA) 625 require.NoError(t, err) 626 ctx = protocol.WithBlockCtx( 627 ctx, 628 protocol.BlockCtx{ 629 BlockHeight: 1, 630 Producer: identityset.Address(27), 631 GasLimit: gasLimit, 632 }, 633 ) 634 ctx = protocol.WithBlockchainCtx(ctx, protocol.BlockchainCtx{ 635 ChainID: 1, 636 }) 637 blk, err := block.NewTestingBuilder(). 638 SetHeight(1). 639 SetPrevBlockHash(hash.ZeroHash256). 640 SetTimeStamp(testutil.TimestampNow()). 641 AddActions([]*action.SealedEnvelope{selp}...). 642 SignAndBuild(identityset.PrivateKey(27)) 643 require.NoError(t, err) 644 require.NoError(t, sf.PutBlock(ctx, &blk)) 645 646 // case I: check KeyOption 647 keyOpt := protocol.KeyOption([]byte("")) 648 _, _, err = sf.States(keyOpt) 649 require.Equal(t, ErrNotSupported, errors.Cause(err)) 650 651 // case II: check without namespace & keys 652 height, iter, err := sf.States() 653 require.NoError(t, err) 654 require.Equal(t, uint64(1), height) 655 // two accounts and one CurrentHeightKey 656 require.Equal(t, 3, iter.Size()) 657 accounts := make([]*state.Account, 0) 658 for i := 0; i < iter.Size(); i++ { 659 c := &state.Account{} 660 err = iter.Next(c) 661 if err != nil { 662 continue 663 } 664 accounts = append(accounts, c) 665 } 666 require.Equal(t, uint64(90), accounts[0].Balance.Uint64()) 667 require.Equal(t, uint64(110), accounts[1].Balance.Uint64()) 668 669 // case III: check without cond,with AccountKVNamespace namespace,key not exists 670 namespaceOpt := protocol.NamespaceOption(AccountKVNamespace) 671 height, iter, err = sf.States(namespaceOpt) 672 require.NoError(t, err) 673 require.Equal(t, uint64(1), height) 674 // two accounts and one CurrentHeightKey 675 require.Equal(t, 3, iter.Size()) 676 accounts = make([]*state.Account, 0) 677 for i := 0; i < iter.Size(); i++ { 678 c := &state.Account{} 679 err = iter.Next(c) 680 if err != nil { 681 continue 682 } 683 accounts = append(accounts, c) 684 } 685 require.Equal(t, uint64(90), accounts[0].Balance.Uint64()) 686 require.Equal(t, uint64(110), accounts[1].Balance.Uint64()) 687 688 // case IV: check without cond,with AccountKVNamespace namespace 689 namespaceOpt = protocol.NamespaceOption(AccountKVNamespace) 690 height, iter, err = sf.States(namespaceOpt) 691 require.NoError(t, err) 692 require.Equal(t, uint64(1), height) 693 // two accounts and one CurrentHeightKey 694 require.Equal(t, 3, iter.Size()) 695 accounts = make([]*state.Account, 0) 696 for i := 0; i < iter.Size(); i++ { 697 c := &state.Account{} 698 err = iter.Next(c) 699 if err != nil { 700 continue 701 } 702 accounts = append(accounts, c) 703 } 704 require.Equal(t, uint64(90), accounts[0].Balance.Uint64()) 705 require.Equal(t, uint64(110), accounts[1].Balance.Uint64()) 706 707 // case V: check cond,with AccountKVNamespace namespace 708 namespaceOpt = protocol.NamespaceOption(AccountKVNamespace) 709 addrHash := hash.BytesToHash160(identityset.Address(28).Bytes()) 710 height, iter, err = sf.States(namespaceOpt, protocol.KeysOption(func() ([][]byte, error) { 711 return [][]byte{addrHash[:]}, nil 712 })) 713 require.NoError(t, err) 714 require.Equal(t, uint64(1), height) 715 require.Equal(t, 1, iter.Size()) 716 accounts = make([]*state.Account, 0) 717 for i := 0; i < iter.Size(); i++ { 718 c := &state.Account{} 719 require.NoError(t, iter.Next(c)) 720 accounts = append(accounts, c) 721 } 722 require.Equal(t, uint64(90), accounts[0].Balance.Uint64()) 723 } 724 725 func TestNonce(t *testing.T) { 726 testTriePath, err := testutil.PathOfTempFile(_triePath) 727 require.NoError(t, err) 728 defer testutil.CleanupPath(testTriePath) 729 730 cfg := DefaultConfig 731 db1, err := db.CreateKVStore(db.DefaultConfig, testTriePath) 732 require.NoError(t, err) 733 734 reg := protocol.NewRegistry() 735 acc := account.NewProtocol(rewarding.DepositGas) 736 err = acc.Register(reg) 737 require.NoError(t, err) 738 739 sf, err := NewFactory(cfg, db1, SkipBlockValidationOption(), RegistryOption(reg)) 740 require.NoError(t, err) 741 testNonce(protocol.WithRegistry(context.Background(), reg), sf, t) 742 } 743 744 func TestSDBNonce(t *testing.T) { 745 testDBPath, err := testutil.PathOfTempFile(_stateDBPath) 746 require.NoError(t, err) 747 defer testutil.CleanupPath(testDBPath) 748 749 cfg := DefaultConfig 750 cfg.Chain.TrieDBPath = testDBPath 751 752 db2, err := db.CreateKVStoreWithCache(db.DefaultConfig, cfg.Chain.TrieDBPath, cfg.Chain.StateDBCacheSize) 753 require.NoError(t, err) 754 755 reg := protocol.NewRegistry() 756 acc := account.NewProtocol(rewarding.DepositGas) 757 err = acc.Register(reg) 758 require.NoError(t, err) 759 760 sdb, err := NewStateDB(cfg, db2, SkipBlockValidationStateDBOption(), RegistryStateDBOption(reg)) 761 require.NoError(t, err) 762 763 testNonce(protocol.WithRegistry(context.Background(), reg), sdb, t) 764 } 765 766 func testNonce(ctx context.Context, sf Factory, t *testing.T) { 767 // Create two dummy iotex address 768 a := identityset.Address(28) 769 priKeyA := identityset.PrivateKey(28) 770 b := identityset.Address(29).String() 771 ge := genesis.Default 772 ge.InitBalanceMap[a.String()] = "100" 773 gasLimit := uint64(1000000) 774 ctx = protocol.WithBlockCtx(ctx, 775 protocol.BlockCtx{ 776 BlockHeight: 0, 777 Producer: identityset.Address(27), 778 GasLimit: gasLimit, 779 }) 780 ctx = protocol.WithFeatureCtx(genesis.WithGenesisContext(ctx, ge)) 781 782 require.NoError(t, sf.Start(ctx)) 783 defer func() { 784 require.NoError(t, sf.Stop(ctx)) 785 }() 786 ws, err := sf.(workingSetCreator).newWorkingSet(ctx, 1) 787 require.NoError(t, err) 788 789 tx, err := action.NewTransfer(0, big.NewInt(2), b, nil, uint64(20000), big.NewInt(0)) 790 require.NoError(t, err) 791 bd := &action.EnvelopeBuilder{} 792 elp := bd.SetAction(tx).SetNonce(0).SetGasLimit(20000).Build() 793 selp, err := action.Sign(elp, priKeyA) 794 require.NoError(t, err) 795 796 ctx = protocol.WithBlockCtx(ctx, 797 protocol.BlockCtx{ 798 BlockHeight: 1, 799 Producer: identityset.Address(27), 800 GasLimit: gasLimit, 801 }) 802 intrinsicGas, err := selp.IntrinsicGas() 803 require.NoError(t, err) 804 selpHash, err := selp.Hash() 805 require.NoError(t, err) 806 ctx = protocol.WithActionCtx( 807 ctx, 808 protocol.ActionCtx{ 809 Caller: a, 810 ActionHash: selpHash, 811 GasPrice: selp.GasPrice(), 812 Nonce: selp.Nonce(), 813 IntrinsicGas: intrinsicGas, 814 }, 815 ) 816 ctx = protocol.WithBlockchainCtx(ctx, protocol.BlockchainCtx{ 817 ChainID: 1, 818 }) 819 _, err = ws.runAction(ctx, selp) 820 require.NoError(t, err) 821 state, err := accountutil.AccountState(ctx, sf, a) 822 require.NoError(t, err) 823 require.Equal(t, uint64(1), state.PendingNonce()) 824 825 tx, err = action.NewTransfer(1, big.NewInt(2), b, nil, uint64(20000), big.NewInt(0)) 826 require.NoError(t, err) 827 bd = &action.EnvelopeBuilder{} 828 elp = bd.SetAction(tx).SetNonce(1).SetGasLimit(20000).Build() 829 selp, err = action.Sign(elp, priKeyA) 830 require.NoError(t, err) 831 832 blk, err := block.NewTestingBuilder(). 833 SetHeight(1). 834 SetPrevBlockHash(hash.ZeroHash256). 835 SetTimeStamp(testutil.TimestampNow()). 836 AddActions([]*action.SealedEnvelope{selp}...). 837 SignAndBuild(identityset.PrivateKey(27)) 838 require.NoError(t, err) 839 840 require.NoError(t, sf.PutBlock(ctx, &blk)) 841 state, err = accountutil.AccountState(ctx, sf, a) 842 require.NoError(t, err) 843 require.Equal(t, uint64(2), state.PendingNonce()) 844 } 845 846 func TestLoadStoreHeight(t *testing.T) { 847 testTriePath, err := testutil.PathOfTempFile(_triePath) 848 require.NoError(t, err) 849 defer testutil.CleanupPath(testTriePath) 850 851 cfg := DefaultConfig 852 cfg.Chain.TrieDBPath = testTriePath 853 854 db1, err := db.CreateKVStore(db.DefaultConfig, cfg.Chain.TrieDBPath) 855 require.NoError(t, err) 856 statefactory, err := NewFactory(cfg, db1, SkipBlockValidationOption()) 857 require.NoError(t, err) 858 859 testLoadStoreHeight(statefactory, t) 860 } 861 862 func TestLoadStoreHeightInMem(t *testing.T) { 863 testTriePath, err := testutil.PathOfTempFile(_triePath) 864 require.NoError(t, err) 865 defer testutil.CleanupPath(testTriePath) 866 867 cfg := DefaultConfig 868 cfg.Chain.TrieDBPath = testTriePath 869 statefactory, err := NewFactory(cfg, db.NewMemKVStore(), SkipBlockValidationOption()) 870 require.NoError(t, err) 871 testLoadStoreHeight(statefactory, t) 872 } 873 874 func TestSDBLoadStoreHeight(t *testing.T) { 875 testDBPath, err := testutil.PathOfTempFile(_stateDBPath) 876 require.NoError(t, err) 877 defer testutil.CleanupPath(testDBPath) 878 879 cfg := DefaultConfig 880 cfg.Chain.TrieDBPath = testDBPath 881 882 db2, err := db.CreateKVStoreWithCache(db.DefaultConfig, cfg.Chain.TrieDBPath, cfg.Chain.StateDBCacheSize) 883 require.NoError(t, err) 884 db, err := NewStateDB(cfg, db2, SkipBlockValidationStateDBOption()) 885 require.NoError(t, err) 886 887 testLoadStoreHeight(db, t) 888 } 889 890 func TestSDBLoadStoreHeightInMem(t *testing.T) { 891 testDBPath, err := testutil.PathOfTempFile(_stateDBPath) 892 require.NoError(t, err) 893 defer testutil.CleanupPath(testDBPath) 894 cfg := DefaultConfig 895 cfg.Chain.TrieDBPath = testDBPath 896 db, err := NewStateDB(cfg, db.NewMemKVStore(), SkipBlockValidationStateDBOption()) 897 require.NoError(t, err) 898 899 testLoadStoreHeight(db, t) 900 } 901 902 func testLoadStoreHeight(sf Factory, t *testing.T) { 903 require := require.New(t) 904 ctx := genesis.WithGenesisContext(context.Background(), genesis.Default) 905 require.NoError(sf.Start(ctx)) 906 defer func() { 907 require.NoError(sf.Stop(ctx)) 908 }() 909 height, err := sf.Height() 910 require.NoError(err) 911 require.Equal(uint64(0), height) 912 lastBlockHash := hash.ZeroHash256 913 for i := uint64(1); i <= 10; i++ { 914 ctx = protocol.WithBlockCtx(ctx, protocol.BlockCtx{ 915 BlockHeight: i, 916 Producer: identityset.Address(27), 917 GasLimit: testutil.TestGasLimit, 918 }) 919 blk, err := block.NewTestingBuilder(). 920 SetHeight(i). 921 SetPrevBlockHash(lastBlockHash). 922 SetTimeStamp(testutil.TimestampNow()). 923 AddActions([]*action.SealedEnvelope{}...). 924 SignAndBuild(identityset.PrivateKey(27)) 925 require.NoError(err) 926 require.NoError(sf.PutBlock(ctx, &blk)) 927 928 height, err = sf.Height() 929 require.NoError(err) 930 require.Equal(uint64(i), height) 931 } 932 } 933 934 func TestRunActions(t *testing.T) { 935 require := require.New(t) 936 testTriePath, err := testutil.PathOfTempFile(_triePath) 937 require.NoError(err) 938 939 cfg := DefaultConfig 940 db1, err := db.CreateKVStore(db.DefaultConfig, testTriePath) 941 require.NoError(err) 942 cfg.Genesis.InitBalanceMap[identityset.Address(28).String()] = "100" 943 cfg.Genesis.InitBalanceMap[identityset.Address(29).String()] = "200" 944 registry := protocol.NewRegistry() 945 sf, err := NewFactory(cfg, db1, RegistryOption(registry), SkipBlockValidationOption()) 946 require.NoError(err) 947 948 acc := account.NewProtocol(rewarding.DepositGas) 949 require.NoError(acc.Register(registry)) 950 ctx := protocol.WithBlockCtx( 951 genesis.WithGenesisContext(context.Background(), cfg.Genesis), 952 protocol.BlockCtx{}, 953 ) 954 require.NoError(sf.Start(ctx)) 955 defer func() { 956 require.NoError(sf.Stop(ctx)) 957 testutil.CleanupPath(testTriePath) 958 }() 959 testCommit(sf, t) 960 } 961 962 func TestSTXRunActions(t *testing.T) { 963 require := require.New(t) 964 testStateDBPath, err := testutil.PathOfTempFile(_stateDBPath) 965 require.NoError(err) 966 967 cfg := DefaultConfig 968 cfg.Chain.TrieDBPath = testStateDBPath 969 cfg.Genesis.InitBalanceMap[identityset.Address(28).String()] = "100" 970 cfg.Genesis.InitBalanceMap[identityset.Address(29).String()] = "200" 971 972 registry := protocol.NewRegistry() 973 acc := account.NewProtocol(rewarding.DepositGas) 974 require.NoError(acc.Register(registry)) 975 976 db2, err := db.CreateKVStoreWithCache(db.DefaultConfig, cfg.Chain.TrieDBPath, cfg.Chain.StateDBCacheSize) 977 require.NoError(err) 978 sdb, err := NewStateDB(cfg, db2, SkipBlockValidationStateDBOption(), RegistryStateDBOption(registry)) 979 require.NoError(err) 980 981 ctx := protocol.WithBlockCtx( 982 genesis.WithGenesisContext(context.Background(), cfg.Genesis), 983 protocol.BlockCtx{}, 984 ) 985 require.NoError(sdb.Start(ctx)) 986 defer func() { 987 require.NoError(sdb.Stop(ctx)) 988 testutil.CleanupPath(testStateDBPath) 989 }() 990 testCommit(sdb, t) 991 } 992 993 func testCommit(factory Factory, t *testing.T) { 994 require := require.New(t) 995 a := identityset.Address(28).String() 996 priKeyA := identityset.PrivateKey(28) 997 b := identityset.Address(29).String() 998 priKeyB := identityset.PrivateKey(29) 999 1000 tx1, err := action.NewTransfer(uint64(1), big.NewInt(10), b, nil, uint64(100000), big.NewInt(0)) 1001 require.NoError(err) 1002 bd := &action.EnvelopeBuilder{} 1003 elp := bd.SetNonce(1).SetAction(tx1).Build() 1004 selp1, err := action.Sign(elp, priKeyA) 1005 require.NoError(err) 1006 1007 tx2, err := action.NewTransfer(uint64(1), big.NewInt(20), a, nil, uint64(100000), big.NewInt(0)) 1008 require.NoError(err) 1009 bd = &action.EnvelopeBuilder{} 1010 elp = bd.SetNonce(1).SetAction(tx2).Build() 1011 selp2, err := action.Sign(elp, priKeyB) 1012 require.NoError(err) 1013 1014 blkHash, err := selp1.Hash() 1015 require.NoError(err) 1016 1017 gasLimit := uint64(1000000) 1018 ctx := protocol.WithBlockCtx(context.Background(), 1019 protocol.BlockCtx{ 1020 BlockHeight: 1, 1021 Producer: identityset.Address(27), 1022 GasLimit: gasLimit, 1023 }) 1024 ctx = genesis.WithGenesisContext( 1025 protocol.WithBlockchainCtx( 1026 ctx, 1027 protocol.BlockchainCtx{ 1028 Tip: protocol.TipInfo{ 1029 Height: 0, 1030 Hash: blkHash, 1031 }, 1032 }), 1033 genesis.Default, 1034 ) 1035 1036 blk, err := block.NewTestingBuilder(). 1037 SetHeight(1). 1038 SetPrevBlockHash(blkHash). 1039 SetTimeStamp(testutil.TimestampNow()). 1040 AddActions(selp1, selp2). 1041 SignAndBuild(identityset.PrivateKey(27)) 1042 require.NoError(err) 1043 1044 require.NoError(factory.PutBlock(ctx, &blk)) 1045 } 1046 1047 func TestPickAndRunActions(t *testing.T) { 1048 require := require.New(t) 1049 testTriePath, err := testutil.PathOfTempFile(_triePath) 1050 require.NoError(err) 1051 1052 cfg := DefaultConfig 1053 db1, err := db.CreateKVStore(db.DefaultConfig, testTriePath) 1054 require.NoError(err) 1055 cfg.Genesis.InitBalanceMap[identityset.Address(28).String()] = "100" 1056 cfg.Genesis.InitBalanceMap[identityset.Address(29).String()] = "200" 1057 registry := protocol.NewRegistry() 1058 sf, err := NewFactory(cfg, db1, RegistryOption(registry)) 1059 require.NoError(err) 1060 1061 acc := account.NewProtocol(rewarding.DepositGas) 1062 require.NoError(acc.Register(registry)) 1063 ctx := protocol.WithBlockCtx( 1064 genesis.WithGenesisContext(context.Background(), cfg.Genesis), 1065 protocol.BlockCtx{}, 1066 ) 1067 require.NoError(sf.Start(ctx)) 1068 defer func() { 1069 require.NoError(sf.Stop(ctx)) 1070 testutil.CleanupPath(testTriePath) 1071 }() 1072 testNewBlockBuilder(sf, t) 1073 } 1074 1075 func TestSTXPickAndRunActions(t *testing.T) { 1076 require := require.New(t) 1077 testStateDBPath, err := testutil.PathOfTempFile(_stateDBPath) 1078 require.NoError(err) 1079 1080 cfg := DefaultConfig 1081 cfg.Chain.TrieDBPath = testStateDBPath 1082 cfg.Genesis.InitBalanceMap[identityset.Address(28).String()] = "100" 1083 cfg.Genesis.InitBalanceMap[identityset.Address(29).String()] = "200" 1084 registry := protocol.NewRegistry() 1085 db2, err := db.CreateKVStoreWithCache(db.DefaultConfig, cfg.Chain.TrieDBPath, cfg.Chain.StateDBCacheSize) 1086 require.NoError(err) 1087 sdb, err := NewStateDB(cfg, db2, RegistryStateDBOption(registry)) 1088 require.NoError(err) 1089 1090 acc := account.NewProtocol(rewarding.DepositGas) 1091 require.NoError(acc.Register(registry)) 1092 ctx := protocol.WithBlockCtx( 1093 genesis.WithGenesisContext(context.Background(), cfg.Genesis), 1094 protocol.BlockCtx{}, 1095 ) 1096 require.NoError(sdb.Start(ctx)) 1097 defer func() { 1098 require.NoError(sdb.Stop(ctx)) 1099 testutil.CleanupPath(testStateDBPath) 1100 }() 1101 testNewBlockBuilder(sdb, t) 1102 } 1103 1104 func testNewBlockBuilder(factory Factory, t *testing.T) { 1105 require := require.New(t) 1106 a := identityset.Address(28).String() 1107 priKeyA := identityset.PrivateKey(28) 1108 b := identityset.Address(29).String() 1109 priKeyB := identityset.PrivateKey(29) 1110 1111 accMap := make(map[string][]*action.SealedEnvelope) 1112 tx1, err := action.NewTransfer(uint64(1), big.NewInt(10), b, nil, uint64(100000), big.NewInt(0)) 1113 require.NoError(err) 1114 bd := &action.EnvelopeBuilder{} 1115 elp := bd.SetNonce(1).SetAction(tx1).Build() 1116 selp1, err := action.Sign(elp, priKeyA) 1117 require.NoError(err) 1118 accMap[identityset.Address(28).String()] = []*action.SealedEnvelope{selp1} 1119 1120 addr0 := identityset.Address(27).String() 1121 tsf0, err := action.SignedTransfer(addr0, identityset.PrivateKey(0), 1, big.NewInt(90000000), nil, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)) 1122 require.NoError(err) 1123 accMap[identityset.Address(0).String()] = []*action.SealedEnvelope{tsf0} 1124 1125 tx2, err := action.NewTransfer(uint64(1), big.NewInt(20), a, nil, uint64(100000), big.NewInt(0)) 1126 require.NoError(err) 1127 bd = &action.EnvelopeBuilder{} 1128 elp = bd.SetNonce(1).SetAction(tx2).Build() 1129 selp2, err := action.Sign(elp, priKeyB) 1130 require.NoError(err) 1131 accMap[identityset.Address(29).String()] = []*action.SealedEnvelope{selp2} 1132 ctrl := gomock.NewController(t) 1133 ap := mock_actpool.NewMockActPool(ctrl) 1134 ap.EXPECT().PendingActionMap().Return(accMap).Times(1) 1135 gasLimit := uint64(1000000) 1136 ctx := protocol.WithBlockCtx(context.Background(), 1137 protocol.BlockCtx{ 1138 BlockHeight: 1, 1139 Producer: identityset.Address(27), 1140 GasLimit: gasLimit, 1141 }) 1142 ctx = protocol.WithBlockchainCtx( 1143 genesis.WithGenesisContext(ctx, genesis.Default), 1144 protocol.BlockchainCtx{}, 1145 ) 1146 ctx = protocol.WithFeatureCtx(protocol.WithFeatureWithHeightCtx(ctx)) 1147 blkBuilder, err := factory.NewBlockBuilder(ctx, ap, nil) 1148 require.NoError(err) 1149 require.NotNil(blkBuilder) 1150 blk, err := blkBuilder.SignAndBuild(identityset.PrivateKey(27)) 1151 require.NoError(err) 1152 require.NoError(factory.PutBlock(ctx, &blk)) 1153 } 1154 1155 func TestSimulateExecution(t *testing.T) { 1156 require := require.New(t) 1157 testTriePath, err := testutil.PathOfTempFile(_triePath) 1158 require.NoError(err) 1159 1160 cfg := DefaultConfig 1161 db1, err := db.CreateKVStore(db.DefaultConfig, testTriePath) 1162 require.NoError(err) 1163 cfg.Genesis.InitBalanceMap[identityset.Address(28).String()] = "100" 1164 cfg.Genesis.InitBalanceMap[identityset.Address(29).String()] = "200" 1165 registry := protocol.NewRegistry() 1166 sf, err := NewFactory(cfg, db1, RegistryOption(registry)) 1167 require.NoError(err) 1168 1169 acc := account.NewProtocol(rewarding.DepositGas) 1170 require.NoError(acc.Register(registry)) 1171 ctx := protocol.WithBlockchainCtx( 1172 protocol.WithBlockCtx( 1173 genesis.WithGenesisContext(context.Background(), cfg.Genesis), 1174 protocol.BlockCtx{}, 1175 ), 1176 protocol.BlockchainCtx{}, 1177 ) 1178 require.NoError(sf.Start(ctx)) 1179 defer func() { 1180 require.NoError(sf.Stop(ctx)) 1181 testutil.CleanupPath(testTriePath) 1182 }() 1183 testSimulateExecution(ctx, sf, t) 1184 } 1185 1186 func TestSTXSimulateExecution(t *testing.T) { 1187 require := require.New(t) 1188 testStateDBPath, err := testutil.PathOfTempFile(_stateDBPath) 1189 require.NoError(err) 1190 1191 cfg := DefaultConfig 1192 cfg.Chain.TrieDBPath = testStateDBPath 1193 cfg.Genesis.InitBalanceMap[identityset.Address(28).String()] = "100" 1194 cfg.Genesis.InitBalanceMap[identityset.Address(29).String()] = "200" 1195 registry := protocol.NewRegistry() 1196 db2, err := db.CreateKVStoreWithCache(db.DefaultConfig, cfg.Chain.TrieDBPath, cfg.Chain.StateDBCacheSize) 1197 require.NoError(err) 1198 sdb, err := NewStateDB(cfg, db2, RegistryStateDBOption(registry)) 1199 require.NoError(err) 1200 1201 acc := account.NewProtocol(rewarding.DepositGas) 1202 require.NoError(acc.Register(registry)) 1203 ctx := protocol.WithBlockchainCtx( 1204 protocol.WithBlockCtx( 1205 genesis.WithGenesisContext(context.Background(), cfg.Genesis), 1206 protocol.BlockCtx{}, 1207 ), 1208 protocol.BlockchainCtx{}, 1209 ) 1210 require.NoError(sdb.Start(ctx)) 1211 defer func() { 1212 require.NoError(sdb.Stop(ctx)) 1213 testutil.CleanupPath(testStateDBPath) 1214 }() 1215 testSimulateExecution(ctx, sdb, t) 1216 } 1217 1218 func testSimulateExecution(ctx context.Context, sf Factory, t *testing.T) { 1219 require := require.New(t) 1220 1221 data, _ := hex.DecodeString("608060405234801561001057600080fd5b5060df8061001f6000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c146078575b600080fd5b348015605957600080fd5b5060766004803603810190808035906020019092919050505060a0565b005b348015608357600080fd5b50608a60aa565b6040518082815260200191505060405180910390f35b8060008190555050565b600080549050905600a165627a7a7230582002faabbefbbda99b20217cf33cb8ab8100caf1542bf1f48117d72e2c59139aea0029") 1222 ex, err := action.NewExecution(action.EmptyAddress, 1, big.NewInt(0), uint64(100000), big.NewInt(0), data) 1223 require.NoError(err) 1224 addr, err := address.FromString(address.ZeroAddress) 1225 require.NoError(err) 1226 1227 ctx = evm.WithHelperCtx(ctx, evm.HelperContext{ 1228 GetBlockHash: func(uint64) (hash.Hash256, error) { 1229 return hash.ZeroHash256, nil 1230 }, 1231 GetBlockTime: func(u uint64) (time.Time, error) { 1232 return time.Time{}, nil 1233 }, 1234 }) 1235 _, _, err = sf.SimulateExecution(ctx, addr, ex) 1236 require.NoError(err) 1237 } 1238 1239 func TestCachedBatch(t *testing.T) { 1240 sf, err := NewFactory(DefaultConfig, db.NewMemKVStore()) 1241 require.NoError(t, err) 1242 ctx := genesis.WithGenesisContext( 1243 protocol.WithRegistry(context.Background(), protocol.NewRegistry()), 1244 genesis.Default, 1245 ) 1246 require.NoError(t, sf.Start(ctx)) 1247 ws, err := sf.(workingSetCreator).newWorkingSet(ctx, 1) 1248 require.NoError(t, err) 1249 testCachedBatch(ws, t) 1250 } 1251 1252 func TestSTXCachedBatch(t *testing.T) { 1253 sdb, err := NewStateDB(DefaultConfig, db.NewMemKVStore()) 1254 require.NoError(t, err) 1255 ctx := genesis.WithGenesisContext( 1256 protocol.WithRegistry(context.Background(), protocol.NewRegistry()), 1257 genesis.Default, 1258 ) 1259 require.NoError(t, sdb.Start(ctx)) 1260 ws, err := sdb.(workingSetCreator).newWorkingSet(ctx, 1) 1261 require.NoError(t, err) 1262 testCachedBatch(ws, t) 1263 } 1264 1265 func testCachedBatch(ws *workingSet, t *testing.T) { 1266 require := require.New(t) 1267 1268 // test PutState() 1269 hashA := hash.BytesToHash160(identityset.Address(28).Bytes()) 1270 accountA, err := state.NewAccount() 1271 require.NoError(err) 1272 require.NoError(accountA.AddBalance(big.NewInt(70))) 1273 _, err = ws.PutState(accountA, protocol.LegacyKeyOption(hashA)) 1274 require.NoError(err) 1275 1276 // test State() 1277 testAccount := &state.Account{} 1278 _, err = ws.State(testAccount, protocol.LegacyKeyOption(hashA)) 1279 require.NoError(err) 1280 require.Equal(accountA, testAccount) 1281 1282 // test DelState() 1283 _, err = ws.DelState(protocol.LegacyKeyOption(hashA)) 1284 require.NoError(err) 1285 1286 // can't state account "alfa" anymore 1287 _, err = ws.State(testAccount, protocol.LegacyKeyOption(hashA)) 1288 require.Error(err) 1289 } 1290 1291 func TestStateDBPatch(t *testing.T) { 1292 require := require.New(t) 1293 n1 := "n1" 1294 n2 := "n2" 1295 a1 := "a1" 1296 a2 := "a2" 1297 b11 := "bb11" 1298 b12 := "bb12" 1299 b21 := "bb21" 1300 b22 := "bb22" 1301 ha1, err := hex.DecodeString(a1) 1302 require.NoError(err) 1303 ha2, err := hex.DecodeString(a2) 1304 require.NoError(err) 1305 hb11, err := hex.DecodeString(b11) 1306 require.NoError(err) 1307 hb12, err := hex.DecodeString(b12) 1308 require.NoError(err) 1309 hb21, err := hex.DecodeString(b21) 1310 require.NoError(err) 1311 hb22, err := hex.DecodeString(b22) 1312 require.NoError(err) 1313 patchTest := [][]string{ 1314 {"1", "PUT", n1, a1, b11}, 1315 {"1", "PUT", n1, a2, b12}, 1316 {"1", "PUT", n2, a1, b21}, 1317 {"2", "DELETE", n1, a1}, 1318 {"2", "PUT", n2, a2, b22}, 1319 } 1320 patchFile, err := testutil.PathOfTempFile(_triePath + ".patch") 1321 require.NoError(err) 1322 f, err := os.Create(patchFile) 1323 require.NoError(err) 1324 require.NoError(csv.NewWriter(f).WriteAll(patchTest)) 1325 require.NoError(f.Close()) 1326 1327 testDBPath, err := testutil.PathOfTempFile(_stateDBPath) 1328 require.NoError(err) 1329 cfg := DefaultConfig 1330 dbcfg := db.DefaultConfig 1331 dbcfg.DbPath = testDBPath 1332 cfg.Chain.TrieDBPatchFile = patchFile 1333 trieDB := db.NewBoltDB(dbcfg) 1334 sdb, err := NewStateDB(cfg, trieDB, DefaultPatchOption(), SkipBlockValidationStateDBOption()) 1335 require.NoError(err) 1336 gasLimit := testutil.TestGasLimit 1337 1338 ctx := protocol.WithBlockCtx( 1339 context.Background(), 1340 protocol.BlockCtx{ 1341 BlockHeight: 0, 1342 Producer: identityset.Address(27), 1343 GasLimit: gasLimit, 1344 }, 1345 ) 1346 ctx = genesis.WithGenesisContext(ctx, genesis.Default) 1347 1348 require.NoError(sdb.Start(ctx)) 1349 defer func() { 1350 require.NoError(sdb.Stop(ctx)) 1351 testutil.CleanupPath(patchFile) 1352 testutil.CleanupPath(testDBPath) 1353 }() 1354 ctx = protocol.WithBlockchainCtx(protocol.WithBlockCtx(ctx, 1355 protocol.BlockCtx{ 1356 BlockHeight: 1, 1357 Producer: identityset.Address(27), 1358 GasLimit: gasLimit, 1359 }), protocol.BlockchainCtx{ 1360 ChainID: 1, 1361 }) 1362 _, err = trieDB.Get(n1, ha1) 1363 require.EqualError(errors.Cause(err), db.ErrNotExist.Error()) 1364 _, err = trieDB.Get(n1, ha2) 1365 require.EqualError(errors.Cause(err), db.ErrNotExist.Error()) 1366 _, err = trieDB.Get(n2, ha1) 1367 require.EqualError(errors.Cause(err), db.ErrNotExist.Error()) 1368 _, err = trieDB.Get(n2, ha2) 1369 require.EqualError(errors.Cause(err), db.ErrNotExist.Error()) 1370 blk1, err := block.NewTestingBuilder(). 1371 SetHeight(1). 1372 SetPrevBlockHash(hash.ZeroHash256). 1373 SetTimeStamp(testutil.TimestampNow()). 1374 SignAndBuild(identityset.PrivateKey(27)) 1375 require.NoError(err) 1376 require.NoError(sdb.PutBlock(ctx, &blk1)) 1377 v11, err := trieDB.Get(n1, ha1) 1378 require.NoError(err) 1379 require.Equal(v11, hb11) 1380 v12, err := trieDB.Get(n1, ha2) 1381 require.NoError(err) 1382 require.Equal(v12, hb12) 1383 v21, err := trieDB.Get(n2, ha1) 1384 require.NoError(err) 1385 require.Equal(v21, hb21) 1386 _, err = trieDB.Get(n2, ha2) 1387 require.EqualError(errors.Cause(err), db.ErrNotExist.Error()) 1388 ctx = protocol.WithBlockchainCtx(protocol.WithBlockCtx(ctx, 1389 protocol.BlockCtx{ 1390 BlockHeight: 2, 1391 Producer: identityset.Address(27), 1392 GasLimit: gasLimit, 1393 }), protocol.BlockchainCtx{ 1394 ChainID: 1, 1395 }) 1396 blk2, err := block.NewTestingBuilder(). 1397 SetHeight(2). 1398 SetPrevBlockHash(blk1.HashBlock()). 1399 SetTimeStamp(testutil.TimestampNow()). 1400 SignAndBuild(identityset.PrivateKey(27)) 1401 require.NoError(err) 1402 require.NoError(sdb.PutBlock(ctx, &blk2)) 1403 _, err = trieDB.Get(n1, ha1) 1404 require.EqualError(errors.Cause(err), db.ErrNotExist.Error()) 1405 v12, err = trieDB.Get(n1, ha2) 1406 require.NoError(err) 1407 require.Equal(v12, hb12) 1408 v21, err = trieDB.Get(n2, ha1) 1409 require.NoError(err) 1410 require.Equal(v21, hb21) 1411 v22, err := trieDB.Get(n2, ha2) 1412 require.NoError(err) 1413 require.Equal(v22, hb22) 1414 1415 require.NoError(os.RemoveAll(patchFile)) 1416 } 1417 1418 func TestDeleteAndPutSameKey(t *testing.T) { 1419 testDeleteAndPutSameKey := func(t *testing.T, ws *workingSet) { 1420 key := hash.Hash160b([]byte("test")) 1421 acc, err := state.NewAccount() 1422 require.NoError(t, err) 1423 require.NoError(t, acc.SetPendingNonce(1)) 1424 require.NoError(t, acc.SetPendingNonce(2)) 1425 _, err = ws.PutState(acc, protocol.LegacyKeyOption(key)) 1426 require.NoError(t, err) 1427 _, err = ws.DelState(protocol.LegacyKeyOption(key)) 1428 require.NoError(t, err) 1429 _, err = ws.State(acc, protocol.LegacyKeyOption(key)) 1430 require.Equal(t, state.ErrStateNotExist, errors.Cause(err)) 1431 _, err = ws.State(acc, protocol.LegacyKeyOption(hash.Hash160b([]byte("other")))) 1432 require.Equal(t, state.ErrStateNotExist, errors.Cause(err)) 1433 } 1434 ctx := genesis.WithGenesisContext( 1435 protocol.WithRegistry(context.Background(), protocol.NewRegistry()), 1436 genesis.Default, 1437 ) 1438 t.Run("workingSet", func(t *testing.T) { 1439 sf, err := NewFactory(DefaultConfig, db.NewMemKVStore()) 1440 require.NoError(t, err) 1441 ws, err := sf.(workingSetCreator).newWorkingSet(ctx, 0) 1442 require.NoError(t, err) 1443 testDeleteAndPutSameKey(t, ws) 1444 }) 1445 t.Run("stateTx", func(t *testing.T) { 1446 sdb, err := NewStateDB(DefaultConfig, db.NewMemKVStore()) 1447 require.NoError(t, err) 1448 ws, err := sdb.(workingSetCreator).newWorkingSet(ctx, 0) 1449 require.NoError(t, err) 1450 testDeleteAndPutSameKey(t, ws) 1451 }) 1452 } 1453 1454 func BenchmarkInMemRunAction(b *testing.B) { 1455 cfg := DefaultConfig 1456 sf, err := NewFactory(cfg, db.NewMemKVStore(), SkipBlockValidationOption()) 1457 if err != nil { 1458 b.Fatal(err) 1459 } 1460 benchRunAction(sf, b) 1461 } 1462 1463 func BenchmarkDBRunAction(b *testing.B) { 1464 tp := filepath.Join(os.TempDir(), _triePath) 1465 if fileutil.FileExists(tp) && os.RemoveAll(tp) != nil { 1466 b.Error("Fail to remove testDB file") 1467 } 1468 1469 cfg := DefaultConfig 1470 db1, err := db.CreateKVStore(db.DefaultConfig, tp) 1471 require.NoError(b, err) 1472 sf, err := NewFactory(cfg, db1, SkipBlockValidationOption()) 1473 if err != nil { 1474 b.Fatal(err) 1475 } 1476 benchRunAction(sf, b) 1477 1478 if fileutil.FileExists(tp) && os.RemoveAll(tp) != nil { 1479 b.Error("Fail to remove testDB file") 1480 } 1481 } 1482 1483 func BenchmarkSDBInMemRunAction(b *testing.B) { 1484 cfg := DefaultConfig 1485 sdb, err := NewStateDB(cfg, db.NewMemKVStore(), SkipBlockValidationStateDBOption()) 1486 if err != nil { 1487 b.Fatal(err) 1488 } 1489 benchRunAction(sdb, b) 1490 } 1491 1492 func BenchmarkSDBRunAction(b *testing.B) { 1493 tp := filepath.Join(os.TempDir(), _stateDBPath) 1494 if fileutil.FileExists(tp) && os.RemoveAll(tp) != nil { 1495 b.Error("Fail to remove testDB file") 1496 } 1497 cfg := DefaultConfig 1498 cfg.Chain.TrieDBPath = tp 1499 db1, err := db.CreateKVStore(db.DefaultConfig, cfg.Chain.TrieDBPath) 1500 require.NoError(b, err) 1501 sdb, err := NewStateDB(cfg, db1, SkipBlockValidationStateDBOption()) 1502 if err != nil { 1503 b.Fatal(err) 1504 } 1505 benchRunAction(sdb, b) 1506 if fileutil.FileExists(tp) && os.RemoveAll(tp) != nil { 1507 b.Error("Fail to remove testDB file") 1508 } 1509 } 1510 1511 func BenchmarkCachedSDBRunAction(b *testing.B) { 1512 tp := filepath.Join(os.TempDir(), _stateDBPath) 1513 if fileutil.FileExists(tp) && os.RemoveAll(tp) != nil { 1514 b.Error("Fail to remove testDB file") 1515 } 1516 cfg := DefaultConfig 1517 cfg.Chain.TrieDBPath = tp 1518 db2, err := db.CreateKVStoreWithCache(db.DefaultConfig, cfg.Chain.TrieDBPath, cfg.Chain.StateDBCacheSize) 1519 require.NoError(b, err) 1520 sdb, err := NewStateDB(cfg, db2, SkipBlockValidationStateDBOption()) 1521 if err != nil { 1522 b.Fatal(err) 1523 } 1524 benchRunAction(sdb, b) 1525 if fileutil.FileExists(tp) && os.RemoveAll(tp) != nil { 1526 b.Error("Fail to remove testDB file") 1527 } 1528 } 1529 1530 func benchRunAction(sf Factory, b *testing.B) { 1531 // set up 1532 accounts := []string{ 1533 identityset.Address(28).String(), 1534 identityset.Address(29).String(), 1535 identityset.Address(30).String(), 1536 identityset.Address(31).String(), 1537 identityset.Address(32).String(), 1538 identityset.Address(33).String(), 1539 } 1540 pubKeys := []crypto.PublicKey{ 1541 identityset.PrivateKey(28).PublicKey(), 1542 identityset.PrivateKey(29).PublicKey(), 1543 identityset.PrivateKey(30).PublicKey(), 1544 identityset.PrivateKey(31).PublicKey(), 1545 identityset.PrivateKey(32).PublicKey(), 1546 identityset.PrivateKey(33).PublicKey(), 1547 } 1548 nonces := make([]uint64, len(accounts)) 1549 ge := genesis.Default 1550 prevHash := ge.Hash() 1551 for _, acc := range accounts { 1552 ge.InitBalanceMap[acc] = big.NewInt(int64(b.N * 100)).String() 1553 } 1554 acc := account.NewProtocol(rewarding.DepositGas) 1555 if err := sf.Register(acc); err != nil { 1556 b.Fatal(err) 1557 } 1558 ctx := genesis.WithGenesisContext(context.Background(), ge) 1559 1560 if err := sf.Start(ctx); err != nil { 1561 b.Fatal(err) 1562 } 1563 defer func() { 1564 if err := sf.Stop(ctx); err != nil { 1565 b.Fatal(err) 1566 } 1567 }() 1568 1569 gasLimit := testutil.TestGasLimit * 100000 1570 1571 for n := 1; n < b.N; n++ { 1572 // put 500 actions together to run 1573 b.StopTimer() 1574 total := 500 1575 acts := make([]*action.SealedEnvelope, 0, total) 1576 for numActs := 0; numActs < total; numActs++ { 1577 senderIdx := rand.Int() % len(accounts) 1578 1579 var chainIDBytes [4]byte 1580 enc.MachineEndian.PutUint32(chainIDBytes[:], 1) 1581 payload := []byte(randStringRunes(20)) 1582 receiverAddr, err := address.FromBytes(payload) 1583 if err != nil { 1584 b.Fatal(err) 1585 } 1586 receiver := receiverAddr.String() 1587 nonces[senderIdx] += nonces[senderIdx] 1588 tx, err := action.NewTransfer(nonces[senderIdx], big.NewInt(1), receiver, nil, uint64(0), big.NewInt(0)) 1589 if err != nil { 1590 b.Fatal(err) 1591 } 1592 bd := &action.EnvelopeBuilder{} 1593 elp := bd.SetNonce(nonces[senderIdx]).SetAction(tx).Build() 1594 selp := action.FakeSeal(elp, pubKeys[senderIdx]) 1595 acts = append(acts, selp) 1596 } 1597 b.StartTimer() 1598 zctx := protocol.WithBlockCtx(context.Background(), 1599 protocol.BlockCtx{ 1600 BlockHeight: uint64(n), 1601 Producer: identityset.Address(27), 1602 GasLimit: gasLimit, 1603 }) 1604 zctx = genesis.WithGenesisContext(zctx, genesis.Default) 1605 1606 blk, err := block.NewTestingBuilder(). 1607 SetHeight(uint64(n)). 1608 SetPrevBlockHash(prevHash). 1609 SetTimeStamp(testutil.TimestampNow()). 1610 AddActions(acts...). 1611 SignAndBuild(identityset.PrivateKey(27)) 1612 if err != nil { 1613 b.Fatal(err) 1614 } 1615 1616 if err := sf.PutBlock(zctx, &blk); err != nil { 1617 b.Fatal(err) 1618 } 1619 prevHash = blk.HashBlock() 1620 } 1621 } 1622 1623 func BenchmarkSDBState(b *testing.B) { 1624 tp := filepath.Join(os.TempDir(), _stateDBPath) 1625 if fileutil.FileExists(tp) && os.RemoveAll(tp) != nil { 1626 b.Error("Fail to remove testDB file") 1627 } 1628 cfg := DefaultConfig 1629 cfg.Chain.TrieDBPath = tp 1630 db1, err := db.CreateKVStore(db.DefaultConfig, cfg.Chain.TrieDBPath) 1631 require.NoError(b, err) 1632 sdb, err := NewStateDB(cfg, db1, SkipBlockValidationStateDBOption()) 1633 if err != nil { 1634 b.Fatal(err) 1635 } 1636 benchState(sdb, b) 1637 if fileutil.FileExists(tp) && os.RemoveAll(tp) != nil { 1638 b.Error("Fail to remove testDB file") 1639 } 1640 } 1641 1642 func BenchmarkCachedSDBState(b *testing.B) { 1643 tp := filepath.Join(os.TempDir(), _stateDBPath) 1644 if fileutil.FileExists(tp) && os.RemoveAll(tp) != nil { 1645 b.Error("Fail to remove testDB file") 1646 } 1647 cfg := DefaultConfig 1648 cfg.Chain.TrieDBPath = tp 1649 db2, err := db.CreateKVStoreWithCache(db.DefaultConfig, cfg.Chain.TrieDBPath, cfg.Chain.StateDBCacheSize) 1650 require.NoError(b, err) 1651 sdb, err := NewStateDB(cfg, db2, SkipBlockValidationStateDBOption()) 1652 if err != nil { 1653 b.Fatal(err) 1654 } 1655 benchState(sdb, b) 1656 if fileutil.FileExists(tp) && os.RemoveAll(tp) != nil { 1657 b.Error("Fail to remove testDB file") 1658 } 1659 } 1660 1661 func benchState(sf Factory, b *testing.B) { 1662 b.StopTimer() 1663 // set up 1664 accounts := []string{ 1665 identityset.Address(28).String(), 1666 identityset.Address(29).String(), 1667 identityset.Address(30).String(), 1668 identityset.Address(31).String(), 1669 identityset.Address(32).String(), 1670 identityset.Address(33).String(), 1671 } 1672 pubKeys := []crypto.PublicKey{ 1673 identityset.PrivateKey(28).PublicKey(), 1674 identityset.PrivateKey(29).PublicKey(), 1675 identityset.PrivateKey(30).PublicKey(), 1676 identityset.PrivateKey(31).PublicKey(), 1677 identityset.PrivateKey(32).PublicKey(), 1678 identityset.PrivateKey(33).PublicKey(), 1679 } 1680 nonces := make([]uint64, len(accounts)) 1681 ge := genesis.Default 1682 prevHash := ge.Hash() 1683 for _, acc := range accounts { 1684 ge.InitBalanceMap[acc] = big.NewInt(int64(1000)).String() 1685 } 1686 acc := account.NewProtocol(rewarding.DepositGas) 1687 if err := sf.Register(acc); err != nil { 1688 b.Fatal(err) 1689 } 1690 ctx := genesis.WithGenesisContext(context.Background(), ge) 1691 1692 if err := sf.Start(ctx); err != nil { 1693 b.Fatal(err) 1694 } 1695 defer func() { 1696 if err := sf.Stop(ctx); err != nil { 1697 b.Fatal(err) 1698 } 1699 }() 1700 1701 gasLimit := testutil.TestGasLimit * 100000 1702 1703 total := 500 1704 acts := make([]*action.SealedEnvelope, 0, total) 1705 for numActs := 0; numActs < total; numActs++ { 1706 senderIdx := rand.Int() % len(accounts) 1707 1708 var chainIDBytes [4]byte 1709 enc.MachineEndian.PutUint32(chainIDBytes[:], 1) 1710 payload := []byte(randStringRunes(20)) 1711 receiverAddr, err := address.FromBytes(payload) 1712 if err != nil { 1713 b.Fatal(err) 1714 } 1715 receiver := receiverAddr.String() 1716 nonces[senderIdx] += nonces[senderIdx] 1717 tx, err := action.NewTransfer(nonces[senderIdx], big.NewInt(1), receiver, nil, uint64(0), big.NewInt(0)) 1718 if err != nil { 1719 b.Fatal(err) 1720 } 1721 bd := &action.EnvelopeBuilder{} 1722 elp := bd.SetNonce(nonces[senderIdx]).SetAction(tx).Build() 1723 selp := action.FakeSeal(elp, pubKeys[senderIdx]) 1724 acts = append(acts, selp) 1725 } 1726 zctx := protocol.WithBlockCtx(context.Background(), 1727 protocol.BlockCtx{ 1728 BlockHeight: uint64(1), 1729 Producer: identityset.Address(27), 1730 GasLimit: gasLimit, 1731 }) 1732 zctx = genesis.WithGenesisContext(zctx, genesis.Default) 1733 1734 blk, err := block.NewTestingBuilder(). 1735 SetHeight(uint64(1)). 1736 SetPrevBlockHash(prevHash). 1737 SetTimeStamp(testutil.TimestampNow()). 1738 AddActions(acts...). 1739 SignAndBuild(identityset.PrivateKey(27)) 1740 if err != nil { 1741 b.Fatal(err) 1742 } 1743 if err := sf.PutBlock(zctx, &blk); err != nil { 1744 b.Fatal(err) 1745 } 1746 1747 // measure state read time 1748 for n := 1; n < b.N; n++ { 1749 b.StartTimer() 1750 idx := rand.Int() % len(accounts) 1751 addr, err := address.FromString(accounts[idx]) 1752 if err != nil { 1753 b.Fatal(err) 1754 } 1755 _, err = accountutil.AccountState(zctx, sf, addr) 1756 if err != nil { 1757 b.Fatal(err) 1758 } 1759 b.StopTimer() 1760 } 1761 } 1762 1763 func init() { 1764 rand.Seed(time.Now().UnixNano()) 1765 }