Skip to content

Commit 3f6a1e5

Browse files
Liuhaaidustinxie
authored andcommitted
fix test and speedup validation
1 parent f060949 commit 3f6a1e5

File tree

3 files changed

+151
-11
lines changed

3 files changed

+151
-11
lines changed

blockchain/integrity/benchmark_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,6 @@ func newChainInDB() (blockchain.Blockchain, actpool.ActPool, error) {
289289
var genesisNonce uint64 = 0
290290

291291
// make a transfer from genesisAccount to a and b,because stateTX cannot store data in height 0
292-
genesisNonce++
293292
tsf, err := action.SignedTransfer(userA.String(), genesisPriKey, genesisNonce, big.NewInt(1e17), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64))
294293
if err != nil {
295294
return nil, nil, err

blockchain/integrity/integrity_test.go

Lines changed: 94 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1466,9 +1466,6 @@ func TestBlockchain_AccountState(t *testing.T) {
14661466
require := require.New(t)
14671467

14681468
cfg := config.Default
1469-
// disable account-based testing
1470-
// create chain
1471-
cfg.Genesis.InitBalanceMap[identityset.Address(0).String()] = "100"
14721469
ctx := genesis.WithGenesisContext(context.Background(), cfg.Genesis)
14731470
registry := protocol.NewRegistry()
14741471
acc := account.NewProtocol(rewarding.DepositGas)
@@ -1480,14 +1477,104 @@ func TestBlockchain_AccountState(t *testing.T) {
14801477
require.NoError(err)
14811478
dao := blockdao.NewBlockDAOInMemForTest([]blockdao.BlockIndexer{sf})
14821479
bc := blockchain.NewBlockchain(cfg.Chain, cfg.Genesis, dao, factory.NewMinter(sf, ap))
1483-
require.NoError(bc.Start(context.Background()))
1480+
require.NoError(bc.Start(ctx))
14841481
require.NotNil(bc)
1482+
defer func() {
1483+
require.NoError(bc.Stop(ctx))
1484+
}()
14851485
s, err := accountutil.AccountState(ctx, sf, identityset.Address(0))
14861486
require.NoError(err)
14871487
require.Equal(uint64(1), s.PendingNonce())
1488-
require.Equal(big.NewInt(100), s.Balance)
1489-
require.Equal(hash.ZeroHash256, s.Root)
1490-
require.Equal([]byte(nil), s.CodeHash)
1488+
require.Equal(unit.ConvertIotxToRau(100000000), s.Balance)
1489+
require.Zero(s.Root)
1490+
require.Nil(s.CodeHash)
1491+
}
1492+
1493+
func TestNewAccountAction(t *testing.T) {
1494+
require := require.New(t)
1495+
1496+
cfg := config.Default
1497+
cfg.Genesis.OkhotskBlockHeight = 1
1498+
ctx := genesis.WithGenesisContext(context.Background(), cfg.Genesis)
1499+
registry := protocol.NewRegistry()
1500+
acc := account.NewProtocol(rewarding.DepositGas)
1501+
require.NoError(acc.Register(registry))
1502+
factoryCfg := factory.GenerateConfig(cfg.Chain, cfg.Genesis)
1503+
sf, err := factory.NewFactory(factoryCfg, db.NewMemKVStore(), factory.RegistryOption(registry))
1504+
require.NoError(err)
1505+
ap, err := actpool.NewActPool(cfg.Genesis, sf, cfg.ActPool)
1506+
require.NoError(err)
1507+
dao := blockdao.NewBlockDAOInMemForTest([]blockdao.BlockIndexer{sf})
1508+
bc := blockchain.NewBlockchain(cfg.Chain, cfg.Genesis, dao, factory.NewMinter(sf, ap))
1509+
require.NoError(bc.Start(ctx))
1510+
require.NotNil(bc)
1511+
defer func() {
1512+
require.NoError(bc.Stop(ctx))
1513+
}()
1514+
1515+
// create a new address, transfer 4 IOTX
1516+
newSk, err := iotexcrypto.HexStringToPrivateKey("55499c1b09f687488af9e4ee9e2bd53c7c8c3ddc69d4d9345a04b13030cffabe")
1517+
require.NoError(err)
1518+
newAddr := newSk.PublicKey().Address()
1519+
tx, err := action.SignedTransfer(newAddr.String(), identityset.PrivateKey(0), 1, big.NewInt(4*unit.Iotx), nil, testutil.TestGasLimit, testutil.TestGasPrice)
1520+
require.NoError(err)
1521+
require.NoError(ap.Add(ctx, tx))
1522+
blk, err := bc.MintNewBlock(testutil.TimestampNow())
1523+
require.NoError(err)
1524+
require.NoError(bc.CommitBlock(blk))
1525+
ap.Reset()
1526+
1527+
// initiate transfer from new address
1528+
tx, err = action.SignedTransfer(identityset.Address(0).String(), newSk, 0, big.NewInt(unit.Iotx), nil, testutil.TestGasLimit, testutil.TestGasPrice)
1529+
require.NoError(err)
1530+
require.NoError(ap.Add(ctx, tx))
1531+
tx1, err := action.SignedTransfer(identityset.Address(1).String(), newSk, 1, big.NewInt(unit.Iotx), nil, testutil.TestGasLimit, testutil.TestGasPrice)
1532+
require.NoError(err)
1533+
require.NoError(ap.Add(ctx, tx1))
1534+
blk1, err := bc.MintNewBlock(testutil.TimestampNow())
1535+
require.NoError(err)
1536+
require.NoError(bc.CommitBlock(blk1))
1537+
ap.Reset()
1538+
1539+
// commit 2 blocks into a new chain
1540+
for _, validateNonce := range []bool{false, true} {
1541+
if validateNonce {
1542+
cfg.Genesis.PalauBlockHeight = 2
1543+
} else {
1544+
cfg.Genesis.PalauBlockHeight = 20
1545+
}
1546+
ctx = genesis.WithGenesisContext(context.Background(), cfg.Genesis)
1547+
factoryCfg = factory.GenerateConfig(cfg.Chain, cfg.Genesis)
1548+
sf1, err := factory.NewFactory(factoryCfg, db.NewMemKVStore(), factory.RegistryOption(registry))
1549+
require.NoError(err)
1550+
dao1 := blockdao.NewBlockDAOInMemForTest([]blockdao.BlockIndexer{sf1})
1551+
bc1 := blockchain.NewBlockchain(cfg.Chain, cfg.Genesis, dao1, factory.NewMinter(sf1, ap))
1552+
require.NoError(bc1.Start(ctx))
1553+
require.NotNil(bc1)
1554+
defer func() {
1555+
require.NoError(bc1.Stop(ctx))
1556+
}()
1557+
require.NoError(bc1.CommitBlock(blk))
1558+
err = bc1.CommitBlock(blk1)
1559+
if validateNonce {
1560+
require.NoError(err)
1561+
} else {
1562+
require.Equal(action.ErrNonceTooHigh, errors.Cause(err))
1563+
}
1564+
1565+
// verify new addr
1566+
s, err := accountutil.AccountState(ctx, sf1, newAddr)
1567+
require.NoError(err)
1568+
if validateNonce {
1569+
require.EqualValues(2, s.PendingNonce())
1570+
require.Equal(big.NewInt(2*unit.Iotx), s.Balance)
1571+
} else {
1572+
require.Zero(s.PendingNonce())
1573+
require.Equal(big.NewInt(4*unit.Iotx), s.Balance)
1574+
}
1575+
require.Zero(s.Root)
1576+
require.Nil(s.CodeHash)
1577+
}
14911578
}
14921579

14931580
func TestBlocks(t *testing.T) {

state/factory/workingset.go

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/iotexproject/iotex-core/actpool"
2424
"github.com/iotexproject/iotex-core/actpool/actioniterator"
2525
"github.com/iotexproject/iotex-core/blockchain/block"
26+
"github.com/iotexproject/iotex-core/blockchain/genesis"
2627
"github.com/iotexproject/iotex-core/pkg/log"
2728
"github.com/iotexproject/iotex-core/state"
2829
)
@@ -352,7 +353,54 @@ func (ws *workingSet) validateNonce(ctx context.Context, blk *block.Block) error
352353
if nonce != pendingNonce+uint64(i) {
353354
return errors.Wrapf(
354355
action.ErrNonceTooHigh,
355-
"the %d nonce %d of address %s (init pending nonce %d) is not continuously increasing",
356+
"the %d-th nonce %d of address %s (init pending nonce %d) is not continuously increasing",
357+
i,
358+
nonce,
359+
srcAddr,
360+
pendingNonce,
361+
)
362+
}
363+
}
364+
}
365+
return nil
366+
}
367+
368+
func (ws *workingSet) validateNonce2(ctx context.Context, blk *block.Block) error {
369+
accountNonceMap := make(map[string][]uint64)
370+
for _, selp := range blk.Actions {
371+
if action.IsSystemAction(selp) {
372+
continue
373+
}
374+
375+
caller := selp.SenderAddress()
376+
if caller == nil {
377+
return errors.New("failed to get address")
378+
}
379+
srcAddr := caller.String()
380+
if _, ok := accountNonceMap[srcAddr]; !ok {
381+
accountNonceMap[srcAddr] = make([]uint64, 0)
382+
}
383+
accountNonceMap[srcAddr] = append(accountNonceMap[srcAddr], selp.Nonce())
384+
}
385+
386+
// Special handling for genesis block
387+
if blk.Height() == 0 {
388+
return nil
389+
}
390+
// Verify each account's Nonce
391+
for srcAddr, receivedNonces := range accountNonceMap {
392+
addr, _ := address.FromString(srcAddr)
393+
confirmedState, err := accountutil.AccountState(ctx, ws, addr)
394+
if err != nil {
395+
return errors.Wrapf(err, "failed to get the confirmed nonce of address %s", srcAddr)
396+
}
397+
sort.Slice(receivedNonces, func(i, j int) bool { return receivedNonces[i] < receivedNonces[j] })
398+
pendingNonce := confirmedState.PendingNonce()
399+
for i, nonce := range receivedNonces {
400+
if nonce != pendingNonce+uint64(i) {
401+
return errors.Wrapf(
402+
action.ErrNonceTooHigh,
403+
"the %d-th nonce %d of address %s (init pending nonce %d) is not continuously increasing",
356404
i,
357405
nonce,
358406
srcAddr,
@@ -517,8 +565,14 @@ func updateReceiptIndex(receipts []*action.Receipt) {
517565
}
518566

519567
func (ws *workingSet) ValidateBlock(ctx context.Context, blk *block.Block) error {
520-
if err := ws.validateNonce(ctx, blk); err != nil {
521-
return errors.Wrap(err, "failed to validate nonce")
568+
if g := genesis.MustExtractGenesisContext(ctx); g.IsPalau(blk.Height()) {
569+
if err := ws.validateNonce2(ctx, blk); err != nil {
570+
return errors.Wrap(err, "failed to validate nonce")
571+
}
572+
} else {
573+
if err := ws.validateNonce(ctx, blk); err != nil {
574+
return errors.Wrap(err, "failed to validate nonce")
575+
}
522576
}
523577
if err := ws.process(ctx, blk.RunnableActions().Actions()); err != nil {
524578
log.L().Error("Failed to update state.", zap.Uint64("height", ws.height), zap.Error(err))

0 commit comments

Comments
 (0)