Skip to content

Commit

Permalink
[state] Return err if receipt is nil (#3759)
Browse files Browse the repository at this point in the history
* fix issue 3555
  • Loading branch information
Liuhaai authored Jan 18, 2023
1 parent 29c07e1 commit bf2a606
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 44 deletions.
20 changes: 13 additions & 7 deletions blockchain/genesis/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ var (
)

func init() {
initTestDefaultConfig()
initTestDefaultConfig(&Default)
}

func defaultConfig() Genesis {
Expand Down Expand Up @@ -113,15 +113,21 @@ func defaultConfig() Genesis {
}
}

func initTestDefaultConfig() {
Default = defaultConfig()
Default.PacificBlockHeight = 0
// TestDefault is the default genesis config for testing
func TestDefault() Genesis {
ge := defaultConfig()
initTestDefaultConfig(&ge)
return ge
}

func initTestDefaultConfig(cfg *Genesis) {
cfg.PacificBlockHeight = 0
for i := 0; i < identityset.Size(); i++ {
addr := identityset.Address(i).String()
value := unit.ConvertIotxToRau(100000000).String()
Default.InitBalanceMap[addr] = value
if uint64(i) < Default.NumDelegates {
Default.Delegates = append(Default.Delegates, Delegate{
cfg.InitBalanceMap[addr] = value
if uint64(i) < cfg.NumDelegates {
cfg.Delegates = append(cfg.Delegates, Delegate{
OperatorAddrStr: addr,
RewardAddrStr: addr,
VotesStr: value,
Expand Down
11 changes: 6 additions & 5 deletions state/factory/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -959,14 +959,15 @@ func TestSTXRunActions(t *testing.T) {
cfg.Genesis.InitBalanceMap[identityset.Address(28).String()] = "100"
cfg.Genesis.InitBalanceMap[identityset.Address(29).String()] = "200"

registry := protocol.NewRegistry()
acc := account.NewProtocol(rewarding.DepositGas)
require.NoError(acc.Register(registry))

db2, err := db.CreateKVStoreWithCache(db.DefaultConfig, cfg.Chain.TrieDBPath, cfg.Chain.StateDBCacheSize)
require.NoError(err)
sdb, err := NewStateDB(cfg, db2, SkipBlockValidationStateDBOption())
sdb, err := NewStateDB(cfg, db2, SkipBlockValidationStateDBOption(), RegistryStateDBOption(registry))
require.NoError(err)

registry := protocol.NewRegistry()
acc := account.NewProtocol(rewarding.DepositGas)
require.NoError(acc.Register(registry))
ctx := protocol.WithBlockCtx(
genesis.WithGenesisContext(context.Background(), cfg.Genesis),
protocol.BlockCtx{},
Expand Down Expand Up @@ -1383,7 +1384,7 @@ func TestStateDBPatch(t *testing.T) {
SignAndBuild(identityset.PrivateKey(27))
require.NoError(err)
require.NoError(sdb.PutBlock(ctx, &blk2))
v11, err = trieDB.Get(n1, ha1)
_, err = trieDB.Get(n1, ha1)
require.EqualError(errors.Cause(err), db.ErrNotExist.Error())
v12, err = trieDB.Get(n1, ha2)
require.NoError(err)
Expand Down
12 changes: 5 additions & 7 deletions state/factory/workingset.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,23 +167,21 @@ func (ws *workingSet) runAction(
return nil, errors.Wrapf(err, "Failed to get hash")
}
var receipt *action.Receipt
defer ws.ResetSnapshots()
for _, actionHandler := range reg.All() {
receipt, err = actionHandler.Handle(ctx, elp.Action(), ws)
if err != nil {
err = errors.Wrapf(
return nil, errors.Wrapf(
err,
"error when action %x mutates states",
elpHash,
)
}
if receipt != nil || err != nil {
break
if receipt != nil {
return receipt, nil
}
}
ws.ResetSnapshots()

// TODO (zhi): return error if both receipt and err are nil
return receipt, err
return nil, errors.New("receipt is nil")
}

func validateChainID(ctx context.Context, chainID uint32) error {
Expand Down
75 changes: 50 additions & 25 deletions state/factory/workingset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ package factory

import (
"context"
"math/rand"
"math/big"
"testing"
"time"

Expand All @@ -17,10 +17,12 @@ import (

"github.com/iotexproject/iotex-core/action"
"github.com/iotexproject/iotex-core/action/protocol"
"github.com/iotexproject/iotex-core/action/protocol/account"
"github.com/iotexproject/iotex-core/action/protocol/rewarding"
"github.com/iotexproject/iotex-core/blockchain"
"github.com/iotexproject/iotex-core/blockchain/block"
"github.com/iotexproject/iotex-core/blockchain/genesis"
"github.com/iotexproject/iotex-core/db"
"github.com/iotexproject/iotex-core/pkg/unit"
"github.com/iotexproject/iotex-core/state"
"github.com/iotexproject/iotex-core/test/identityset"
"github.com/iotexproject/iotex-core/testutil"
Expand Down Expand Up @@ -183,40 +185,65 @@ func TestWorkingSet_Dock(t *testing.T) {
}

func TestWorkingSet_ValidateBlock(t *testing.T) {
require := require.New(t)
registry := protocol.NewRegistry()
require.NoError(account.NewProtocol(rewarding.DepositGas).Register(registry))
cfg := Config{
Chain: blockchain.DefaultConfig,
Genesis: genesis.TestDefault(),
}
cfg.Genesis.InitBalanceMap[identityset.Address(28).String()] = "100000000"
var (
require = require.New(t)
f1, _ = NewFactory(DefaultConfig, db.NewMemKVStore())
f2, _ = NewStateDB(DefaultConfig, db.NewMemKVStore())
f1, _ = NewFactory(cfg, db.NewMemKVStore(), RegistryOption(registry))
f2, _ = NewStateDB(cfg, db.NewMemKVStore(), RegistryStateDBOption(registry))
factories = []Factory{f1, f2}
digestHash = hash.Hash256b([]byte{65, 99, 99, 111, 117, 110, 116, 99, 117, 114, 114,
101, 110, 116, 72, 101, 105, 103, 104, 116, 1, 0, 0, 0, 0, 0, 0, 0})
digestHash = hash.BytesToHash256([]byte{67, 246, 156, 149, 78, 160, 19, 137, 23, 214, 154,
1, 247, 186, 71, 218, 116, 201, 156, 178, 198, 34, 159, 89, 105, 167, 240, 191,
83, 239, 183, 117})
receiptRoot = hash.BytesToHash256([]byte{43, 195, 20, 81, 149, 72, 181, 0, 230, 212, 137,
96, 64, 59, 99, 229, 48, 189, 105, 53, 69, 94, 195, 36, 128, 228, 210, 211, 189,
116, 62, 176})
tests = []struct {
block *block.Block
err error
}{
{makeBlock(t, 1, hash.ZeroHash256, digestHash), nil},
{
makeBlock(t, 3, hash.ZeroHash256, digestHash),
makeBlock(t, 1, hash.ZeroHash256, receiptRoot, digestHash),
nil,
},
{
makeBlock(t, 3, hash.ZeroHash256, receiptRoot, digestHash),
action.ErrNonceTooHigh,
},
{
makeBlock(t, 1, hash.Hash256b([]byte("test")), digestHash),
makeBlock(t, 1, hash.ZeroHash256, hash.Hash256b([]byte("test")), digestHash),
block.ErrReceiptRootMismatch,
},
{
makeBlock(t, 1, hash.ZeroHash256, hash.Hash256b([]byte("test"))),
makeBlock(t, 1, hash.ZeroHash256, receiptRoot, hash.Hash256b([]byte("test"))),
block.ErrDeltaStateMismatch,
},
}
)
gasLimit := testutil.TestGasLimit * 100000

ctx := protocol.WithBlockCtx(
genesis.WithGenesisContext(context.Background(), cfg.Genesis),
protocol.BlockCtx{},
)
require.NoError(f1.Start(ctx))
require.NoError(f2.Start(ctx))
defer func() {
require.NoError(f1.Stop(ctx))
require.NoError(f2.Stop(ctx))
}()

zctx := protocol.WithBlockCtx(context.Background(),
protocol.BlockCtx{
BlockHeight: uint64(1),
Producer: identityset.Address(27),
GasLimit: gasLimit,
GasLimit: testutil.TestGasLimit * 100000,
})
zctx = genesis.WithGenesisContext(zctx, genesis.Default)
zctx = genesis.WithGenesisContext(zctx, cfg.Genesis)
zctx = protocol.WithFeatureCtx(protocol.WithBlockchainCtx(zctx, protocol.BlockchainCtx{
ChainID: 1,
}))
Expand All @@ -227,17 +254,15 @@ func TestWorkingSet_ValidateBlock(t *testing.T) {
}
}

func makeBlock(t *testing.T, nonce uint64, rootHash hash.Hash256, digest hash.Hash256) *block.Block {
rand.Seed(time.Now().Unix())
func makeBlock(t *testing.T, nonce uint64, prevHash hash.Hash256, receiptRoot hash.Hash256, digest hash.Hash256) *block.Block {
var sevlps []action.SealedEnvelope
r := rand.Int()
tsf, err := action.NewTransfer(
uint64(r),
unit.ConvertIotxToRau(1000+int64(r)),
identityset.Address(r%identityset.Size()).String(),
uint64(nonce),
big.NewInt(1),
identityset.Address(29).String(),
nil,
20000+uint64(r),
unit.ConvertIotxToRau(1+int64(r)),
testutil.TestGasLimit,
big.NewInt(0),
)
require.NoError(t, err)
eb := action.EnvelopeBuilder{}
Expand All @@ -248,7 +273,7 @@ func makeBlock(t *testing.T, nonce uint64, rootHash hash.Hash256, digest hash.Ha
SetNonce(nonce).
SetVersion(1).
Build()
sevlp, err := action.Sign(evlp, identityset.PrivateKey((r+1)%identityset.Size()))
sevlp, err := action.Sign(evlp, identityset.PrivateKey(28))
require.NoError(t, err)
sevlps = append(sevlps, sevlp)
rap := block.RunnableActionsBuilder{}
Expand All @@ -257,9 +282,9 @@ func makeBlock(t *testing.T, nonce uint64, rootHash hash.Hash256, digest hash.Ha
SetHeight(1).
SetTimestamp(time.Now()).
SetVersion(1).
SetReceiptRoot(rootHash).
SetReceiptRoot(receiptRoot).
SetDeltaStateDigest(digest).
SetPrevBlockHash(hash.Hash256b([]byte("test"))).
SetPrevBlockHash(prevHash).
SignAndBuild(identityset.PrivateKey(0))
require.NoError(t, err)
return &blk
Expand Down

0 comments on commit bf2a606

Please sign in to comment.