From d9463433f0ccc5c2ec3e95276c0c22c18c8da9a2 Mon Sep 17 00:00:00 2001 From: dustinxie Date: Mon, 6 Jun 2022 10:51:41 -0700 Subject: [PATCH 1/8] [action] add NewExecutionAccessList() for access-list type execution (#3427) --- action/builder.go | 2 +- action/execution.go | 26 +++++++++++++++++++++++++- action/execution_test.go | 20 ++++++++++---------- api/grpcserver.go | 30 +++++++----------------------- 4 files changed, 43 insertions(+), 35 deletions(-) diff --git a/action/builder.go b/action/builder.go index d5e535e5b9..3b8e9901d5 100644 --- a/action/builder.go +++ b/action/builder.go @@ -181,7 +181,7 @@ func getRecipientAddr(addr *common.Address) string { // BuildExecution loads executino action into envelope func (b *EnvelopeBuilder) BuildExecution(tx *types.Transaction) (Envelope, error) { b.setEnvelopeCommonFields(tx) - exec, err := NewExecution(getRecipientAddr(tx.To()), tx.Nonce(), tx.Value(), tx.Gas(), tx.GasPrice(), tx.Data()) + exec, err := NewExecutionWithAccessList(getRecipientAddr(tx.To()), tx.Nonce(), tx.Value(), tx.Gas(), tx.GasPrice(), tx.Data(), tx.AccessList()) if err != nil { return nil, err } diff --git a/action/execution.go b/action/execution.go index 9b0ec5386c..5cccd50ae8 100644 --- a/action/execution.go +++ b/action/execution.go @@ -42,7 +42,7 @@ type Execution struct { accessList types.AccessList } -// NewExecution returns a Execution instance +// NewExecution returns an Execution instance (w/o access list) func NewExecution( contractAddress string, nonce uint64, @@ -64,6 +64,30 @@ func NewExecution( }, nil } +// NewExecutionWithAccessList returns an Execution instance with access list +func NewExecutionWithAccessList( + contractAddress string, + nonce uint64, + amount *big.Int, + gasLimit uint64, + gasPrice *big.Int, + data []byte, + list types.AccessList, +) (*Execution, error) { + return &Execution{ + AbstractAction: AbstractAction{ + version: version.ProtocolVersion, + nonce: nonce, + gasLimit: gasLimit, + gasPrice: gasPrice, + }, + contract: contractAddress, + amount: amount, + data: data, + accessList: list, + }, nil +} + // Contract returns a contract address func (ex *Execution) Contract() string { return ex.contract } diff --git a/action/execution_test.go b/action/execution_test.go index 1f919ad4e4..96c571aea5 100644 --- a/action/execution_test.go +++ b/action/execution_test.go @@ -80,15 +80,6 @@ var ( func TestExecutionAccessList(t *testing.T) { require := require.New(t) - ex, err := NewExecution( - identityset.Address(29).String(), - 1, - big.NewInt(20), - uint64(100), - big.NewInt(1000000), - []byte("test"), - ) - require.NoError(err) ex1 := &Execution{} for _, v := range []struct { @@ -114,7 +105,16 @@ func TestExecutionAccessList(t *testing.T) { }, 30900, }, } { - ex.accessList = v.list + ex, err := NewExecutionWithAccessList( + identityset.Address(29).String(), + 1, + big.NewInt(20), + uint64(100), + big.NewInt(1000000), + []byte("test"), + v.list, + ) + require.NoError(err) require.NoError(ex1.LoadProto(ex.Proto())) ex1.AbstractAction = ex.AbstractAction require.Equal(ex, ex1) diff --git a/api/grpcserver.go b/api/grpcserver.go index 445d52f6bb..a89417e85f 100644 --- a/api/grpcserver.go +++ b/api/grpcserver.go @@ -10,7 +10,6 @@ import ( "context" "encoding/hex" "fmt" - "math/big" "net" "strconv" "time" @@ -37,7 +36,7 @@ import ( "github.com/iotexproject/iotex-core/action" "github.com/iotexproject/iotex-core/action/protocol" - logfilter "github.com/iotexproject/iotex-core/api/logfilter" + "github.com/iotexproject/iotex-core/api/logfilter" "github.com/iotexproject/iotex-core/pkg/log" "github.com/iotexproject/iotex-core/pkg/tracer" ) @@ -576,37 +575,22 @@ func (svr *GRPCServer) TraceTransactionStructLogs(ctx context.Context, in *iotex if err != nil { return nil, err } - exec, ok := actInfo.Action.Core.Action.(*iotextypes.ActionCore_Execution) - if !ok { - return nil, status.Error(codes.InvalidArgument, "the type of action is not supported") - } - callerAddr, err := address.FromString(actInfo.Sender) + act, err := (&action.Deserializer{}).ActionToSealedEnvelope(actInfo.Action) if err != nil { return nil, err } + sc, ok := act.Action().(*action.Execution) + if !ok { + return nil, status.Error(codes.InvalidArgument, "the type of action is not supported") + } tracer := vm.NewStructLogger(nil) ctx = protocol.WithVMConfigCtx(ctx, vm.Config{ Debug: true, Tracer: tracer, NoBaseFee: true, }) - amount, ok := new(big.Int).SetString(exec.Execution.GetAmount(), 10) - if !ok { - return nil, errors.New("failed to set execution amount") - } - sc, err := action.NewExecution( - exec.Execution.GetContract(), - actInfo.Action.Core.Nonce, - amount, - actInfo.Action.Core.GasLimit, - big.NewInt(0), - exec.Execution.GetData(), - ) - if err != nil { - return nil, err - } - _, _, err = svr.coreService.SimulateExecution(ctx, callerAddr, sc) + _, _, err = svr.coreService.SimulateExecution(ctx, act.SrcPubkey().Address(), sc) if err != nil { return nil, err } From f4d472d0a1487256ec9881bfdd4e2d741f750686 Mon Sep 17 00:00:00 2001 From: saito Date: Tue, 7 Jun 2022 05:28:58 +0800 Subject: [PATCH 2/8] [test] move ClassifyActions() to test (#3429) --- action/action.go | 16 ---------------- action/action_test.go | 18 ------------------ blockchain/integrity/integrity_test.go | 20 ++++++++++++++++++-- blockindex/indexbuilder_test.go | 20 ++++++++++++++++++-- blockindex/indexer_test.go | 2 +- 5 files changed, 37 insertions(+), 39 deletions(-) diff --git a/action/action.go b/action/action.go index 299ad64645..ff53d970d7 100644 --- a/action/action.go +++ b/action/action.go @@ -78,22 +78,6 @@ func AssembleSealedEnvelope(act Envelope, pk crypto.PublicKey, sig []byte) Seale return sealed } -// ClassifyActions classfies actions -func ClassifyActions(actions []SealedEnvelope) ([]*Transfer, []*Execution) { - tsfs := make([]*Transfer, 0) - exes := make([]*Execution, 0) - for _, elp := range actions { - act := elp.Action() - switch act := act.(type) { - case *Transfer: - tsfs = append(tsfs, act) - case *Execution: - exes = append(exes, act) - } - } - return tsfs, exes -} - // CalculateIntrinsicGas returns the intrinsic gas of an action func CalculateIntrinsicGas(baseIntrinsicGas uint64, payloadGas uint64, payloadSize uint64) (uint64, error) { if payloadGas == 0 && payloadSize == 0 { diff --git a/action/action_test.go b/action/action_test.go index 1cadaac85e..39d9de851d 100644 --- a/action/action_test.go +++ b/action/action_test.go @@ -70,24 +70,6 @@ func TestActionProtoAndVerify(t *testing.T) { }) } -func TestActionClassifyActions(t *testing.T) { - require := require.New(t) - var ( - producerAddr = identityset.Address(27).String() - producerPriKey = identityset.PrivateKey(27) - amount = big.NewInt(0) - selp0, _ = SignedTransfer(producerAddr, producerPriKey, 1, amount, nil, 100, big.NewInt(0)) - selp1, _ = SignedTransfer(identityset.Address(28).String(), producerPriKey, 1, amount, nil, 100, big.NewInt(0)) - selp2, _ = SignedTransfer(identityset.Address(29).String(), producerPriKey, 1, amount, nil, 100, big.NewInt(0)) - selp3, _ = SignedExecution(producerAddr, producerPriKey, uint64(1), amount, uint64(100000), big.NewInt(10), []byte{}) - selp4, _ = SignedExecution(producerAddr, producerPriKey, uint64(2), amount, uint64(100000), big.NewInt(10), []byte{}) - ) - actions := []SealedEnvelope{selp0, selp1, selp2, selp3, selp4} - tsfs, exes := ClassifyActions(actions) - require.Equal(len(tsfs), 3) - require.Equal(len(exes), 2) -} - func TestActionFakeSeal(t *testing.T) { require := require.New(t) priKey := identityset.PrivateKey(27) diff --git a/blockchain/integrity/integrity_test.go b/blockchain/integrity/integrity_test.go index 9d734e9aee..0191bda009 100644 --- a/blockchain/integrity/integrity_test.go +++ b/blockchain/integrity/integrity_test.go @@ -833,7 +833,7 @@ type MockSubscriber struct { func (ms *MockSubscriber) ReceiveBlock(blk *block.Block) error { ms.mu.Lock() - tsfs, _ := action.ClassifyActions(blk.Actions) + tsfs, _ := classifyActions(blk.Actions) ms.counter += len(tsfs) ms.mu.Unlock() return nil @@ -1292,7 +1292,7 @@ func TestLoadBlockchainfromDB(t *testing.T) { require.EqualValues(blkIndex.NumAction(), len(blk.Actions)) // verify getting transfer amount - tsfs, _ := action.ClassifyActions(blk.Actions) + tsfs, _ := classifyActions(blk.Actions) tsfa := big.NewInt(0) for _, tsf := range tsfs { tsfa.Add(tsfa, tsf.Amount()) @@ -1903,4 +1903,20 @@ func makeTransfer(contract string, bc blockchain.Blockchain, ap actpool.ActPool, return blk } +// classifyActions classfies actions +func classifyActions(actions []action.SealedEnvelope) ([]*action.Transfer, []*action.Execution) { + tsfs := make([]*action.Transfer, 0) + exes := make([]*action.Execution, 0) + for _, elp := range actions { + act := elp.Action() + switch act := act.(type) { + case *action.Transfer: + tsfs = append(tsfs, act) + case *action.Execution: + exes = append(exes, act) + } + } + return tsfs, exes +} + // TODO: add func TestValidateBlock() diff --git a/blockindex/indexbuilder_test.go b/blockindex/indexbuilder_test.go index a44dad2542..27df65d2d0 100644 --- a/blockindex/indexbuilder_test.go +++ b/blockindex/indexbuilder_test.go @@ -6,12 +6,12 @@ import ( "testing" "time" + "github.com/iotexproject/iotex-core/action" "github.com/pkg/errors" "github.com/stretchr/testify/require" "github.com/iotexproject/go-pkgs/hash" - "github.com/iotexproject/iotex-core/action" "github.com/iotexproject/iotex-core/action/protocol" "github.com/iotexproject/iotex-core/blockchain/blockdao" "github.com/iotexproject/iotex-core/blockchain/genesis" @@ -136,7 +136,7 @@ func TestIndexBuilder(t *testing.T) { for i := 0; i < 3; i++ { amount := big.NewInt(0) - tsfs, _ := action.ClassifyActions(blks[i].Actions) + tsfs, _ := classifyActions(blks[i].Actions) for _, tsf := range tsfs { amount.Add(amount, tsf.Amount()) } @@ -189,3 +189,19 @@ func TestIndexBuilder(t *testing.T) { }) } } + +// classifyActions classfies actions +func classifyActions(actions []action.SealedEnvelope) ([]*action.Transfer, []*action.Execution) { + tsfs := make([]*action.Transfer, 0) + exes := make([]*action.Execution, 0) + for _, elp := range actions { + act := elp.Action() + switch act := act.(type) { + case *action.Transfer: + tsfs = append(tsfs, act) + case *action.Execution: + exes = append(exes, act) + } + } + return tsfs, exes +} diff --git a/blockindex/indexer_test.go b/blockindex/indexer_test.go index 9a5c164f7e..0fb863a450 100644 --- a/blockindex/indexer_test.go +++ b/blockindex/indexer_test.go @@ -201,7 +201,7 @@ func TestIndexer(t *testing.T) { // test amount amount := big.NewInt(0) - tsfs, _ := action.ClassifyActions(blks[i].Actions) + tsfs, _ := classifyActions(blks[i].Actions) for _, tsf := range tsfs { amount.Add(amount, tsf.Amount()) } From b194df6fccadfc5e8815db064b8c51fd1556f50b Mon Sep 17 00:00:00 2001 From: Haaai <55118568+Liuhaai@users.noreply.github.com> Date: Mon, 6 Jun 2022 18:11:35 -0700 Subject: [PATCH 3/8] [api] fix todo in GetLogs (#3434) --- api/grpcserver.go | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/api/grpcserver.go b/api/grpcserver.go index a89417e85f..34c141fab2 100644 --- a/api/grpcserver.go +++ b/api/grpcserver.go @@ -420,43 +420,42 @@ func (svr *GRPCServer) GetRawBlocks(ctx context.Context, in *iotexapi.GetRawBloc } // GetLogs get logs filtered by contract address and topics -// TODO: simplify loop logic func (svr *GRPCServer) GetLogs(ctx context.Context, in *iotexapi.GetLogsRequest) (*iotexapi.GetLogsResponse, error) { if in.GetFilter() == nil { return nil, status.Error(codes.InvalidArgument, "empty filter") } var ( - logs []*action.Log - hashes []hash.Hash256 - err error + ret = make([]*iotextypes.Log, 0) ) switch { case in.GetByBlock() != nil: blkHash := hash.BytesToHash256(in.GetByBlock().BlockHash) - logs, err = svr.coreService.LogsInBlockByHash(logfilter.NewLogFilter(in.GetFilter()), blkHash) + logs, err := svr.coreService.LogsInBlockByHash(logfilter.NewLogFilter(in.GetFilter()), blkHash) if err != nil { - break + return nil, status.Error(codes.InvalidArgument, err.Error()) } - hashes = make([]hash.Hash256, 0, len(logs)) - for range logs { - hashes = append(hashes, blkHash) + for i := range logs { + ret = append(ret, toLogPb(logs[i], blkHash)) } case in.GetByRange() != nil: req := in.GetByRange() - logs, hashes, err = svr.coreService.LogsInRange(logfilter.NewLogFilter(in.GetFilter()), req.GetFromBlock(), req.GetToBlock(), req.GetPaginationSize()) + logs, hashes, err := svr.coreService.LogsInRange(logfilter.NewLogFilter(in.GetFilter()), req.GetFromBlock(), req.GetToBlock(), req.GetPaginationSize()) + if err != nil { + return nil, status.Error(codes.InvalidArgument, err.Error()) + } + for i := range logs { + ret = append(ret, toLogPb(logs[i], hashes[i])) + } default: return nil, status.Error(codes.InvalidArgument, "invalid GetLogsRequest type") } - if err != nil { - return nil, status.Error(codes.InvalidArgument, err.Error()) - } - ret := make([]*iotextypes.Log, 0, len(logs)) - for i := range logs { - logPb := logs[i].ConvertToLogPb() - logPb.BlkHash = hashes[i][:] - ret = append(ret, logPb) - } - return &iotexapi.GetLogsResponse{Logs: ret}, err + return &iotexapi.GetLogsResponse{Logs: ret}, nil +} + +func toLogPb(lg *action.Log, blkHash hash.Hash256) *iotextypes.Log { + logPb := lg.ConvertToLogPb() + logPb.BlkHash = blkHash[:] + return logPb } // StreamBlocks streams blocks From 30e0cdf67d24b7eb2de609b20c3c6f6f53001e3d Mon Sep 17 00:00:00 2001 From: Haaai <55118568+Liuhaai@users.noreply.github.com> Date: Tue, 7 Jun 2022 10:49:49 -0700 Subject: [PATCH 4/8] [api] Add mutex to chainListener (#3433) --- api/listener.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/api/listener.go b/api/listener.go index 38ce1e5984..95d0854854 100644 --- a/api/listener.go +++ b/api/listener.go @@ -3,6 +3,7 @@ package api import ( "encoding/hex" "math/rand" + "sync" "time" "github.com/pkg/errors" @@ -32,6 +33,7 @@ type ( maxCapacity int streamMap *ttl.Cache // all registered idGenerator *randID + mu sync.Mutex } ) @@ -84,9 +86,10 @@ func (cl *chainListener) ReceiveBlock(blk *block.Block) error { return nil } -// TODO: add lock to enable thread safety // AddResponder adds a new responder func (cl *chainListener) AddResponder(responder apitypes.Responder) (string, error) { + cl.mu.Lock() + defer cl.mu.Unlock() if cl.streamMap.Count() >= cl.maxCapacity { return "", errorCapacityReached } @@ -109,6 +112,8 @@ func (cl *chainListener) AddResponder(responder apitypes.Responder) (string, err // RemoveResponder delete the responder func (cl *chainListener) RemoveResponder(listenerID string) (bool, error) { + cl.mu.Lock() + defer cl.mu.Unlock() value, exist := cl.streamMap.Get(listenerID) if !exist { return false, errListenerNotFound From 2e8ef35e6432a489d5a3596857979c6b66a36b8c Mon Sep 17 00:00:00 2001 From: Haaai <55118568+Liuhaai@users.noreply.github.com> Date: Tue, 7 Jun 2022 11:12:52 -0700 Subject: [PATCH 5/8] [api] Remove ActionsByBlock() in coreService (#3432) * remove ActionsByBlock() in coreService --- api/coreservice.go | 93 ++----------------- api/grpcserver.go | 62 ++++++++++++- api/web3server.go | 12 +-- api/web3server_utils.go | 6 +- .../mock_apicoreservice.go | 30 ++---- 5 files changed, 86 insertions(+), 117 deletions(-) diff --git a/api/coreservice.go b/api/coreservice.go index 9aa1b47dd3..16da4dabe9 100644 --- a/api/coreservice.go +++ b/api/coreservice.go @@ -58,8 +58,8 @@ import ( "github.com/iotexproject/iotex-core/state/factory" ) -var ( - _workerNumbers int = 5 +const ( + _workerNumbers = 5 ) type ( @@ -106,10 +106,8 @@ type ( ActionsByAddress(addr address.Address, start uint64, count uint64) ([]*iotexapi.ActionInfo, error) // ActionByActionHash returns action by action hash ActionByActionHash(h hash.Hash256) (action.SealedEnvelope, hash.Hash256, uint64, uint32, error) - // ActionsByBlock returns all actions in a block - ActionsByBlock(blkHash string, start uint64, count uint64) ([]*iotexapi.ActionInfo, error) - // ActionsInBlockByHash returns all actions in a block - ActionsInBlockByHash(string) ([]action.SealedEnvelope, []*action.Receipt, error) + // BlockByHash returns the block and its receipt + BlockByHash(string) (*block.Store, error) // ActPoolActions returns the all Transaction Identifiers in the mempool ActPoolActions(actHashes []string) ([]*iotextypes.Action, error) // UnconfirmedActionsByAddress returns all unconfirmed actions in actpool associated with an address @@ -1010,48 +1008,24 @@ func (core *coreService) UnconfirmedActionsByAddress(address string, start uint6 return res, nil } -// ActionsByBlock returns all actions in a block -func (core *coreService) ActionsByBlock(blkHash string, start uint64, count uint64) ([]*iotexapi.ActionInfo, error) { +// BlockByHash returns the block and its receipt +func (core *coreService) BlockByHash(blkHash string) (*block.Store, error) { if err := core.checkActionIndex(); err != nil { return nil, err } - if count == 0 { - return nil, status.Error(codes.InvalidArgument, "count must be greater than zero") - } - if count > core.cfg.RangeQueryLimit && count != math.MaxUint64 { - return nil, status.Error(codes.InvalidArgument, "range exceeds the limit") - } hash, err := hash.HexStringToHash256(blkHash) if err != nil { - return nil, status.Error(codes.InvalidArgument, err.Error()) - } - blk, err := core.dao.GetBlock(hash) - if err != nil { - return nil, status.Error(codes.NotFound, err.Error()) - } - if start >= uint64(len(blk.Actions)) { - return nil, status.Error(codes.InvalidArgument, "start exceeds the limit") - } - - return core.actionsInBlock(blk, start, count), nil -} - -// TODO: replace ActionsByBlock with ActionsInBlockByHash -// ActionsInBlockByHash returns all sealedEnvelopes and receipts in the block -func (core *coreService) ActionsInBlockByHash(blkHash string) ([]action.SealedEnvelope, []*action.Receipt, error) { - hash, err := hash.HexStringToHash256(blkHash) - if err != nil { - return nil, nil, err + return nil, err } blk, err := core.dao.GetBlock(hash) if err != nil { - return nil, nil, errors.Wrap(ErrNotFound, err.Error()) + return nil, errors.Wrap(ErrNotFound, err.Error()) } receipts, err := core.dao.GetReceipts(blk.Height()) if err != nil { - return nil, nil, errors.Wrap(ErrNotFound, err.Error()) + return nil, errors.Wrap(ErrNotFound, err.Error()) } - return blk.Actions, receipts, nil + return &block.Store{blk, receipts}, nil } // BlockMetas returns blockmetas response within the height range @@ -1248,53 +1222,6 @@ func (core *coreService) getAction(actHash hash.Hash256, checkPending bool) (*io return core.pendingAction(selp) } -func (core *coreService) actionsInBlock(blk *block.Block, start, count uint64) []*iotexapi.ActionInfo { - var res []*iotexapi.ActionInfo - if len(blk.Actions) == 0 || start >= uint64(len(blk.Actions)) { - return res - } - - h := blk.HashBlock() - blkHash := hex.EncodeToString(h[:]) - blkHeight := blk.Height() - - lastAction := start + count - if count == math.MaxUint64 { - // count = -1 means to get all actions - lastAction = uint64(len(blk.Actions)) - } else { - if lastAction >= uint64(len(blk.Actions)) { - lastAction = uint64(len(blk.Actions)) - } - } - for i := start; i < lastAction; i++ { - selp := blk.Actions[i] - actHash, err := selp.Hash() - if err != nil { - log.Logger("api").Debug("Skipping action due to hash error", zap.Error(err)) - continue - } - receipt, err := core.dao.GetReceiptByActionHash(actHash, blkHeight) - if err != nil { - log.Logger("api").Debug("Skipping action due to failing to get receipt", zap.Error(err)) - continue - } - gas := new(big.Int).Mul(selp.GasPrice(), big.NewInt(int64(receipt.GasConsumed))) - sender := selp.SrcPubkey().Address() - res = append(res, &iotexapi.ActionInfo{ - Action: selp.Proto(), - ActHash: hex.EncodeToString(actHash[:]), - BlkHash: blkHash, - Timestamp: blk.Header.BlockHeaderCoreProto().Timestamp, - BlkHeight: blkHeight, - Sender: sender.String(), - GasFee: gas.String(), - Index: uint32(i), - }) - } - return res -} - func (core *coreService) reverseActionsInBlock(blk *block.Block, reverseStart, count uint64) []*iotexapi.ActionInfo { h := blk.HashBlock() blkHash := hex.EncodeToString(h[:]) diff --git a/api/grpcserver.go b/api/grpcserver.go index 34c141fab2..fc7b443b4d 100644 --- a/api/grpcserver.go +++ b/api/grpcserver.go @@ -10,6 +10,8 @@ import ( "context" "encoding/hex" "fmt" + "math" + "math/big" "net" "strconv" "time" @@ -37,6 +39,7 @@ import ( "github.com/iotexproject/iotex-core/action" "github.com/iotexproject/iotex-core/action/protocol" "github.com/iotexproject/iotex-core/api/logfilter" + "github.com/iotexproject/iotex-core/blockchain/block" "github.com/iotexproject/iotex-core/pkg/log" "github.com/iotexproject/iotex-core/pkg/tracer" ) @@ -170,8 +173,15 @@ func (svr *GRPCServer) GetActions(ctx context.Context, in *iotexapi.GetActionsRe request := in.GetUnconfirmedByAddr() ret, err = svr.coreService.UnconfirmedActionsByAddress(request.Address, request.Start, request.Count) case in.GetByBlk() != nil: - request := in.GetByBlk() - ret, err = svr.coreService.ActionsByBlock(request.BlkHash, request.Start, request.Count) + var ( + request = in.GetByBlk() + blkStore *block.Store + ) + blkStore, err = svr.coreService.BlockByHash(request.BlkHash) + if err != nil { + break + } + ret, err = actionsInBlock(blkStore.Block, blkStore.Receipts, request.Start, request.Count) default: return nil, status.Error(codes.NotFound, "invalid GetActionsRequest type") } @@ -184,6 +194,54 @@ func (svr *GRPCServer) GetActions(ctx context.Context, in *iotexapi.GetActionsRe }, nil } +func actionsInBlock(blk *block.Block, receipts []*action.Receipt, start, count uint64) ([]*iotexapi.ActionInfo, error) { + var res []*iotexapi.ActionInfo + if len(blk.Actions) == 0 { + return res, nil + } + if count == 0 { + return nil, status.Error(codes.InvalidArgument, "count must be greater than zero") + } + if start >= uint64(len(blk.Actions)) { + return nil, status.Error(codes.InvalidArgument, "start exceeds the limit") + } + + h := blk.HashBlock() + blkHash := hex.EncodeToString(h[:]) + blkHeight := blk.Height() + + lastAction := start + count + if count == math.MaxUint64 { + // count = -1 means to get all actions + lastAction = uint64(len(blk.Actions)) + } else { + if lastAction >= uint64(len(blk.Actions)) { + lastAction = uint64(len(blk.Actions)) + } + } + for i := start; i < lastAction; i++ { + selp, receipt := blk.Actions[i], receipts[i] + actHash, err := selp.Hash() + if err != nil { + log.Logger("api").Debug("Skipping action due to hash error", zap.Error(err)) + continue + } + gas := new(big.Int).Mul(selp.GasPrice(), big.NewInt(int64(receipt.GasConsumed))) + sender := selp.SrcPubkey().Address() + res = append(res, &iotexapi.ActionInfo{ + Action: selp.Proto(), + ActHash: hex.EncodeToString(actHash[:]), + BlkHash: blkHash, + Timestamp: blk.Header.BlockHeaderCoreProto().Timestamp, + BlkHeight: blkHeight, + Sender: sender.String(), + GasFee: gas.String(), + Index: uint32(i), + }) + } + return res, nil +} + // GetBlockMetas returns block metadata func (svr *GRPCServer) GetBlockMetas(ctx context.Context, in *iotexapi.GetBlockMetasRequest) (*iotexapi.GetBlockMetasResponse, error) { var ( diff --git a/api/web3server.go b/api/web3server.go index 3335498a59..ee7bb3d56f 100644 --- a/api/web3server.go +++ b/api/web3server.go @@ -590,14 +590,14 @@ func (svr *web3Handler) getTransactionByBlockHashAndIndex(in *gjson.Result) (int return nil, err } blkHash := util.Remove0xPrefix(blkHashStr.String()) - selps, receipts, err := svr.coreService.ActionsInBlockByHash(blkHash) - if errors.Cause(err) == ErrNotFound || idx >= uint64(len(receipts)) || len(receipts) == 0 { + blkStore, err := svr.coreService.BlockByHash(blkHash) + if errors.Cause(err) == ErrNotFound || idx >= uint64(len(blkStore.Receipts)) || len(blkStore.Receipts) == 0 { return nil, nil } if err != nil { return nil, err } - return svr.getTransactionFromActionInfo(blkHash, selps[idx], receipts[idx]) + return svr.getTransactionFromActionInfo(blkHash, blkStore.Block.Actions[idx], blkStore.Receipts[idx]) } func (svr *web3Handler) getTransactionByBlockNumberAndIndex(in *gjson.Result) (interface{}, error) { @@ -624,14 +624,14 @@ func (svr *web3Handler) getTransactionByBlockNumberAndIndex(in *gjson.Result) (i if len(blkMetas) == 0 { return nil, nil } - selps, receipts, err := svr.coreService.ActionsInBlockByHash(blkMetas[0].Hash) - if errors.Cause(err) == ErrNotFound || idx >= uint64(len(receipts)) || len(receipts) == 0 { + blkStore, err := svr.coreService.BlockByHash(blkMetas[0].Hash) + if errors.Cause(err) == ErrNotFound || idx >= uint64(len(blkStore.Receipts)) || len(blkStore.Receipts) == 0 { return nil, nil } if err != nil { return nil, err } - return svr.getTransactionFromActionInfo(blkMetas[0].Hash, selps[idx], receipts[idx]) + return svr.getTransactionFromActionInfo(blkMetas[0].Hash, blkStore.Block.Actions[idx], blkStore.Receipts[idx]) } func (svr *web3Handler) getStorageAt(in *gjson.Result) (interface{}, error) { diff --git a/api/web3server_utils.go b/api/web3server_utils.go index db5e765b31..1e51470f2d 100644 --- a/api/web3server_utils.go +++ b/api/web3server_utils.go @@ -65,13 +65,13 @@ func intStrToHex(str string) (string, error) { func (svr *web3Handler) getBlockWithTransactions(blkMeta *iotextypes.BlockMeta, isDetailed bool) (*getBlockResult, error) { transactions := make([]interface{}, 0) if blkMeta.Height > 0 { - selps, receipts, err := svr.coreService.ActionsInBlockByHash(blkMeta.Hash) + blkStore, err := svr.coreService.BlockByHash(blkMeta.Hash) if err != nil { return nil, err } - for i, selp := range selps { + for i, selp := range blkStore.Block.Actions { if isDetailed { - tx, err := svr.getTransactionFromActionInfo(blkMeta.Hash, selp, receipts[i]) + tx, err := svr.getTransactionFromActionInfo(blkMeta.Hash, selp, blkStore.Receipts[i]) if err != nil { if errors.Cause(err) != errUnsupportedAction { h, _ := selp.Hash() diff --git a/test/mock/mock_apicoreservice/mock_apicoreservice.go b/test/mock/mock_apicoreservice/mock_apicoreservice.go index fc7121fc45..7defb2eb43 100644 --- a/test/mock/mock_apicoreservice/mock_apicoreservice.go +++ b/test/mock/mock_apicoreservice/mock_apicoreservice.go @@ -136,35 +136,19 @@ func (mr *MockCoreServiceMockRecorder) ActionsByAddress(addr, start, count inter return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActionsByAddress", reflect.TypeOf((*MockCoreService)(nil).ActionsByAddress), addr, start, count) } -// ActionsByBlock mocks base method. -func (m *MockCoreService) ActionsByBlock(blkHash string, start, count uint64) ([]*iotexapi.ActionInfo, error) { +// BlockByHash mocks base method. +func (m *MockCoreService) BlockByHash(arg0 string) (*block.Store, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ActionsByBlock", blkHash, start, count) - ret0, _ := ret[0].([]*iotexapi.ActionInfo) + ret := m.ctrl.Call(m, "BlockByHash", arg0) + ret0, _ := ret[0].(*block.Store) ret1, _ := ret[1].(error) return ret0, ret1 } -// ActionsByBlock indicates an expected call of ActionsByBlock. -func (mr *MockCoreServiceMockRecorder) ActionsByBlock(blkHash, start, count interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActionsByBlock", reflect.TypeOf((*MockCoreService)(nil).ActionsByBlock), blkHash, start, count) -} - -// ActionsInBlockByHash mocks base method. -func (m *MockCoreService) ActionsInBlockByHash(arg0 string) ([]action.SealedEnvelope, []*action.Receipt, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ActionsInBlockByHash", arg0) - ret0, _ := ret[0].([]action.SealedEnvelope) - ret1, _ := ret[1].([]*action.Receipt) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// ActionsInBlockByHash indicates an expected call of ActionsInBlockByHash. -func (mr *MockCoreServiceMockRecorder) ActionsInBlockByHash(arg0 interface{}) *gomock.Call { +// BlockByHash indicates an expected call of BlockByHash. +func (mr *MockCoreServiceMockRecorder) BlockByHash(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActionsInBlockByHash", reflect.TypeOf((*MockCoreService)(nil).ActionsInBlockByHash), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockByHash", reflect.TypeOf((*MockCoreService)(nil).BlockByHash), arg0) } // BlockHashByBlockHeight mocks base method. From 7d6669869a568492206bc108dcdd3c0662f6f25f Mon Sep 17 00:00:00 2001 From: dustinxie Date: Wed, 8 Jun 2022 13:11:04 -0700 Subject: [PATCH 6/8] [protocol] remove config.EVMNetworkID() from EVM/execution (#3431) --- action/protocol/context.go | 4 +++- action/protocol/context_test.go | 12 ++++++++-- action/protocol/execution/evm/evm.go | 9 ++++---- action/protocol/execution/evm/evm_test.go | 24 ++++++++++++-------- action/protocol/execution/protocol_test.go | 2 -- blockchain/blockchain.go | 11 +++++++-- test/mock/mock_blockchain/mock_blockchain.go | 14 ++++++++++++ 7 files changed, 56 insertions(+), 20 deletions(-) diff --git a/action/protocol/context.go b/action/protocol/context.go index 3f993fcd67..9121e028e6 100644 --- a/action/protocol/context.go +++ b/action/protocol/context.go @@ -44,8 +44,10 @@ type ( BlockchainCtx struct { // Tip is the information of tip block Tip TipInfo - //ChainID of the node + //ChainID is the native chain ID ChainID uint32 + // EvmNetworkID is the EVM network ID + EvmNetworkID uint32 } // BlockCtx provides block auxiliary information. diff --git a/action/protocol/context_test.go b/action/protocol/context_test.go index 28d234beb7..ffd0e2009a 100644 --- a/action/protocol/context_test.go +++ b/action/protocol/context_test.go @@ -39,11 +39,19 @@ func TestWithBlockchainCtx(t *testing.T) { func TestGetBlockchainCtx(t *testing.T) { require := require.New(t) - bcCtx := BlockchainCtx{} + bcCtx := BlockchainCtx{ + Tip: TipInfo{ + Height: 1024, + Timestamp: time.Now(), + }, + ChainID: 1, + EvmNetworkID: 100, + } ctx := WithBlockchainCtx(context.Background(), bcCtx) require.NotNil(ctx) - _, ok := GetBlockchainCtx(ctx) + bcCtx1, ok := GetBlockchainCtx(ctx) require.True(ok) + require.Equal(bcCtx, bcCtx1) } func TestMustGetBlockchainCtx(t *testing.T) { diff --git a/action/protocol/execution/evm/evm.go b/action/protocol/execution/evm/evm.go index 762f820739..6081638664 100644 --- a/action/protocol/execution/evm/evm.go +++ b/action/protocol/execution/evm/evm.go @@ -28,7 +28,6 @@ import ( "github.com/iotexproject/iotex-core/action" "github.com/iotexproject/iotex-core/action/protocol" "github.com/iotexproject/iotex-core/blockchain/genesis" - "github.com/iotexproject/iotex-core/config" "github.com/iotexproject/iotex-core/pkg/log" "github.com/iotexproject/iotex-core/pkg/tracer" "github.com/iotexproject/iotex-core/pkg/util/byteutil" @@ -74,6 +73,7 @@ type ( context vm.BlockContext txCtx vm.TxContext nonce uint64 + evmNetworkID uint32 executorRawAddress string amount *big.Int contract *common.Address @@ -165,6 +165,7 @@ func newParams( GasPrice: execution.GasPrice(), }, execution.Nonce(), + protocol.MustGetBlockchainCtx(ctx).EvmNetworkID, actionCtx.Caller.String(), execution.Amount(), contractAddrPointer, @@ -321,7 +322,7 @@ func prepareStateDB(ctx context.Context, sm protocol.StateManager) *StateDBAdapt ) } -func getChainConfig(g genesis.Blockchain, height uint64) *params.ChainConfig { +func getChainConfig(g genesis.Blockchain, height uint64, id uint32) *params.ChainConfig { var chainConfig params.ChainConfig chainConfig.ConstantinopleBlock = new(big.Int).SetUint64(0) // Constantinople switch block (nil = no fork, 0 = already activated) chainConfig.BeringBlock = new(big.Int).SetUint64(g.BeringBlockHeight) @@ -331,7 +332,7 @@ func getChainConfig(g genesis.Blockchain, height uint64) *params.ChainConfig { chainConfig.IstanbulBlock = new(big.Int).SetUint64(g.IcelandBlockHeight) chainConfig.MuirGlacierBlock = new(big.Int).SetUint64(g.IcelandBlockHeight) if g.IsIceland(height) { - chainConfig.ChainID = new(big.Int).SetUint64(uint64(config.EVMNetworkID())) + chainConfig.ChainID = new(big.Int).SetUint64(uint64(id)) } // enable Berlin and London chainConfig.BerlinBlock = new(big.Int).SetUint64(g.ToBeEnabledBlockHeight) @@ -353,7 +354,7 @@ func executeInEVM(ctx context.Context, evmParams *Params, stateDB *StateDBAdapte if vmCfg, ok := protocol.GetVMConfigCtx(ctx); ok { config = vmCfg } - chainConfig := getChainConfig(g, blockHeight) + chainConfig := getChainConfig(g, blockHeight, evmParams.evmNetworkID) evm := vm.NewEVM(evmParams.context, evmParams.txCtx, stateDB, chainConfig, config) if g.IsToBeEnabled(blockHeight) { accessList = evmParams.accessList diff --git a/action/protocol/execution/evm/evm_test.go b/action/protocol/execution/evm/evm_test.go index fba8cf1016..53e2c54667 100644 --- a/action/protocol/execution/evm/evm_test.go +++ b/action/protocol/execution/evm/evm_test.go @@ -23,7 +23,6 @@ import ( "github.com/iotexproject/iotex-core/action" "github.com/iotexproject/iotex-core/action/protocol" "github.com/iotexproject/iotex-core/blockchain/genesis" - "github.com/iotexproject/iotex-core/config" "github.com/iotexproject/iotex-core/state" "github.com/iotexproject/iotex-core/test/identityset" "github.com/iotexproject/iotex-core/test/mock/mock_chainmanager" @@ -57,7 +56,10 @@ func TestExecuteContractFailure(t *testing.T) { }) ctx = genesis.WithGenesisContext(ctx, genesis.Default) - ctx = protocol.WithFeatureCtx(ctx) + ctx = protocol.WithBlockchainCtx(protocol.WithFeatureCtx(ctx), protocol.BlockchainCtx{ + ChainID: 1, + EvmNetworkID: 100, + }) retval, receipt, err := ExecuteContract(ctx, sm, e, func(uint64) (hash.Hash256, error) { return hash.ZeroHash256, nil @@ -80,8 +82,12 @@ func TestConstantinople(t *testing.T) { Caller: identityset.Address(27), }) + evmNetworkID := uint32(100) g := genesis.Default - ctx = genesis.WithGenesisContext(ctx, g) + ctx = protocol.WithBlockchainCtx(genesis.WithGenesisContext(ctx, g), protocol.BlockchainCtx{ + ChainID: 1, + EvmNetworkID: evmNetworkID, + }) execHeights := []struct { contract string @@ -210,19 +216,19 @@ func TestConstantinople(t *testing.T) { } stateDB := NewStateDBAdapter(sm, e.height, hash.ZeroHash256, opt...) - ctx = protocol.WithBlockCtx(ctx, protocol.BlockCtx{ + fCtx := protocol.WithBlockCtx(ctx, protocol.BlockCtx{ Producer: identityset.Address(27), GasLimit: testutil.TestGasLimit, BlockHeight: e.height, }) - ctx = protocol.WithFeatureCtx(ctx) - ps, err := newParams(ctx, ex, stateDB, func(uint64) (hash.Hash256, error) { + fCtx = protocol.WithFeatureCtx(fCtx) + ps, err := newParams(fCtx, ex, stateDB, func(uint64) (hash.Hash256, error) { return hash.ZeroHash256, nil }) require.NoError(err) var evmConfig vm.Config - chainConfig := getChainConfig(g.Blockchain, e.height) + chainConfig := getChainConfig(g.Blockchain, e.height, ps.evmNetworkID) evm := vm.NewEVM(ps.context, ps.txCtx, stateDB, chainConfig, evmConfig) evmChainConfig := evm.ChainConfig() @@ -253,7 +259,7 @@ func TestConstantinople(t *testing.T) { // iceland = support chainID + enable Istanbul and Muir Glacier isIceland := g.IsIceland(e.height) if isIceland { - require.EqualValues(config.EVMNetworkID(), evmChainConfig.ChainID.Uint64()) + require.EqualValues(evmNetworkID, evmChainConfig.ChainID.Uint64()) } else { require.Nil(evmChainConfig.ChainID) } @@ -342,7 +348,7 @@ func TestGasEstimate(t *testing.T) { for _, v := range []struct { gas, consume, refund, size uint64 }{ - {config.Default.Genesis.BlockGasLimit, 8200300, 1000000, 20000}, + {genesis.Default.BlockGasLimit, 8200300, 1000000, 20000}, {1000000, 245600, 100000, 5600}, {500000, 21000, 10000, 36}, } { diff --git a/action/protocol/execution/protocol_test.go b/action/protocol/execution/protocol_test.go index 94c01aef61..be95b66359 100644 --- a/action/protocol/execution/protocol_test.go +++ b/action/protocol/execution/protocol_test.go @@ -941,8 +941,6 @@ func TestMaxTime(t *testing.T) { } func TestIstanbulEVM(t *testing.T) { - cfg := config.Default - config.SetEVMNetworkID(cfg.Chain.EVMNetworkID) t.Run("ArrayReturn", func(t *testing.T) { NewSmartContractTest(t, "testdata-istanbul/array-return.json") }) diff --git a/blockchain/blockchain.go b/blockchain/blockchain.go index 08cedb4e45..6e455d40c3 100644 --- a/blockchain/blockchain.go +++ b/blockchain/blockchain.go @@ -69,6 +69,8 @@ type ( BlockFooterByHeight(height uint64) (*block.Footer, error) // ChainID returns the chain ID ChainID() uint32 + // EvmNetworkID returns the evm network ID + EvmNetworkID() uint32 // ChainAddress returns chain address on parent chain, the root chain return empty. ChainAddress() string // TipHash returns tip block's hash @@ -214,6 +216,10 @@ func (bc *blockchain) ChainID() uint32 { return atomic.LoadUint32(&bc.config.Chain.ID) } +func (bc *blockchain) EvmNetworkID() uint32 { + return atomic.LoadUint32(&bc.config.Chain.EVMNetworkID) +} + func (bc *blockchain) ChainAddress() string { return bc.config.Chain.Address } @@ -365,8 +371,9 @@ func (bc *blockchain) context(ctx context.Context, tipInfoFlag bool) (context.Co protocol.WithBlockchainCtx( ctx, protocol.BlockchainCtx{ - Tip: tip, - ChainID: bc.ChainID(), + Tip: tip, + ChainID: bc.ChainID(), + EvmNetworkID: bc.EvmNetworkID(), }, ), bc.config.Genesis, diff --git a/test/mock/mock_blockchain/mock_blockchain.go b/test/mock/mock_blockchain/mock_blockchain.go index 335d516026..11db24dc7c 100644 --- a/test/mock/mock_blockchain/mock_blockchain.go +++ b/test/mock/mock_blockchain/mock_blockchain.go @@ -141,6 +141,20 @@ func (mr *MockBlockchainMockRecorder) Context(arg0 interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockBlockchain)(nil).Context), arg0) } +// EvmNetworkID mocks base method. +func (m *MockBlockchain) EvmNetworkID() uint32 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EvmNetworkID") + ret0, _ := ret[0].(uint32) + return ret0 +} + +// EvmNetworkID indicates an expected call of EvmNetworkID. +func (mr *MockBlockchainMockRecorder) EvmNetworkID() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EvmNetworkID", reflect.TypeOf((*MockBlockchain)(nil).EvmNetworkID)) +} + // Genesis mocks base method. func (m *MockBlockchain) Genesis() genesis.Genesis { m.ctrl.T.Helper() From a22243101524bcf848312a573ed7380b4610ffae Mon Sep 17 00:00:00 2001 From: saito Date: Thu, 9 Jun 2022 09:39:20 +0800 Subject: [PATCH 7/8] [action] add `address` and `hash` field in SealedEnvelope (#3420) * [action] add `address` and `hash` field in SealedEnvelope --- action/action_deserializer_test.go | 5 ++++ action/sealedenvelope.go | 24 +++++++++++++++++++ action/sealedenvelope_test.go | 10 +++++--- actpool/actpool_test.go | 20 ++++++++++++++-- blockchain/blockdao/blockdao_test.go | 36 ++++++++++++++++++++++++---- 5 files changed, 86 insertions(+), 9 deletions(-) diff --git a/action/action_deserializer_test.go b/action/action_deserializer_test.go index ca97cef043..ed6c49a399 100644 --- a/action/action_deserializer_test.go +++ b/action/action_deserializer_test.go @@ -10,6 +10,7 @@ import ( "encoding/hex" "testing" + "github.com/iotexproject/go-pkgs/hash" "github.com/iotexproject/iotex-proto/golang/iotextypes" "github.com/stretchr/testify/require" "google.golang.org/protobuf/proto" @@ -34,8 +35,12 @@ func TestActionDeserializer(t *testing.T) { r.Equal(_signByte, se.Signature()) r.Zero(se.Encoding()) + // use valid signature and reset se.Hash se.signature = _validSig + se.hash = hash.ZeroHash256 + se.Hash() se1, err := (&Deserializer{}).ActionToSealedEnvelope(se.Proto()) + se1.Hash() r.NoError(err) r.Equal(se, se1) } diff --git a/action/sealedenvelope.go b/action/sealedenvelope.go index c586c9ab76..1527a56604 100644 --- a/action/sealedenvelope.go +++ b/action/sealedenvelope.go @@ -5,6 +5,7 @@ import ( "github.com/iotexproject/go-pkgs/crypto" "github.com/iotexproject/go-pkgs/hash" + "github.com/iotexproject/iotex-address/address" "github.com/iotexproject/iotex-proto/golang/iotextypes" "github.com/pkg/errors" "go.uber.org/zap" @@ -22,6 +23,8 @@ type SealedEnvelope struct { evmNetworkID uint32 srcPubkey crypto.PublicKey signature []byte + srcAddress address.Address + hash hash.Hash256 } // envelopeHash returns the raw hash of embedded Envelope (this is the hash to be signed) @@ -48,6 +51,17 @@ func (sealed *SealedEnvelope) envelopeHash() (hash.Hash256, error) { // Hash returns the hash value of SealedEnvelope. // an all-0 return value means the transaction is invalid func (sealed *SealedEnvelope) Hash() (hash.Hash256, error) { + if sealed.hash == hash.ZeroHash256 { + hashVal, hashErr := sealed.calcHash() + if hashErr == nil { + sealed.hash = hashVal + } + return sealed.hash, hashErr + } + return sealed.hash, nil +} + +func (sealed *SealedEnvelope) calcHash() (hash.Hash256, error) { switch sealed.encoding { case iotextypes.Encoding_ETHEREUM_RLP: act, ok := sealed.Action().(EthCompatibleAction) @@ -69,6 +83,14 @@ func (sealed *SealedEnvelope) Hash() (hash.Hash256, error) { // SrcPubkey returns the source public key func (sealed *SealedEnvelope) SrcPubkey() crypto.PublicKey { return sealed.srcPubkey } +// SenderAddress returns address of the source public key +func (sealed *SealedEnvelope) SenderAddress() address.Address { + if sealed.srcAddress == nil { + sealed.srcAddress = sealed.srcPubkey.Address() + } + return sealed.srcAddress +} + // Signature returns signature bytes func (sealed *SealedEnvelope) Signature() []byte { sig := make([]byte, len(sealed.signature)) @@ -141,6 +163,8 @@ func (sealed *SealedEnvelope) LoadProto(pbAct *iotextypes.Action) error { sealed.signature = make([]byte, sigSize) copy(sealed.signature, pbAct.GetSignature()) sealed.encoding = encoding + sealed.hash = hash.ZeroHash256 + sealed.srcAddress = nil return nil } diff --git a/action/sealedenvelope_test.go b/action/sealedenvelope_test.go index 850cf0b425..7358de6de7 100644 --- a/action/sealedenvelope_test.go +++ b/action/sealedenvelope_test.go @@ -156,7 +156,6 @@ func TestSealedEnvelope_Proto(t *testing.T) { req.Contains(se2.LoadProto(se.Proto()).Error(), v.err) } - se.signature = _validSig for _, v := range []struct { enc iotextypes.Encoding hash string @@ -164,17 +163,22 @@ func TestSealedEnvelope_Proto(t *testing.T) { {0, "0562e100b057804ee3cb4fa906a897852aa8075013a02ef1e229360f1e5ee339"}, {1, "d5dc789026c12cc69f1ea7997fbe0aa1bcc02e85176848c7b2ecf4da6b4560d0"}, } { + se, err = createSealedEnvelope(0) + se.signature = _validSig se.encoding = v.enc req.NoError(se2.LoadProto(se.Proto())) if v.enc > 0 { se.evmNetworkID = config.EVMNetworkID() } + h, _ := se.Hash() + req.Equal(v.hash, hex.EncodeToString(h[:])) + se.SenderAddress() + _, _ = se2.Hash() + se2.SenderAddress() req.Equal(se, se2) tsf2, ok := se2.Envelope.Action().(*Transfer) req.True(ok) req.Equal(tsf, tsf2) - h, _ := se.Hash() - req.Equal(v.hash, hex.EncodeToString(h[:])) } } diff --git a/actpool/actpool_test.go b/actpool/actpool_test.go index 4f7e5fd5d4..8a6ab1a765 100644 --- a/actpool/actpool_test.go +++ b/actpool/actpool_test.go @@ -902,7 +902,15 @@ func TestActPool_GetUnconfirmedActs(t *testing.T) { require.Equal([]action.SealedEnvelope(nil), acts) acts = ap.GetUnconfirmedActs(_addr1) - require.Equal([]action.SealedEnvelope{tsf1, tsf3, tsf4, tsf5}, acts) + validated := []action.SealedEnvelope{tsf1, tsf3, tsf4, tsf5} + require.Equal(len(acts), len(validated)) + for i := 0; i < len(acts); i++ { + hashVal1, hashErr1 := validated[i].Hash() + require.NoError(hashErr1) + hashVal2, hashErr2 := acts[i].Hash() + require.NoError(hashErr2) + require.Equal(hashVal1, hashVal2) + } } func TestActPool_GetActionByHash(t *testing.T) { @@ -1089,7 +1097,15 @@ func TestActPool_SpeedUpAction(t *testing.T) { appliedActionList = append(appliedActionList, bestAction) } // tsf1 is replaced by tsf3 with higher gas price - require.Equal(appliedActionList, []action.SealedEnvelope{tsf3, tsf2}) + validated := []action.SealedEnvelope{tsf3, tsf2} + require.Equal(len(appliedActionList), len(validated)) + for i := 0; i < len(appliedActionList); i++ { + hashVal1, hashErr1 := validated[i].Hash() + require.NoError(hashErr1) + hashVal2, hashErr2 := appliedActionList[i].Hash() + require.NoError(hashErr2) + require.Equal(hashVal1, hashVal2) + } } // Helper function to return the correct pending nonce just in case of empty queue diff --git a/blockchain/blockdao/blockdao_test.go b/blockchain/blockdao/blockdao_test.go index c2e92be90c..42d6caecb9 100644 --- a/blockchain/blockdao/blockdao_test.go +++ b/blockchain/blockdao/blockdao_test.go @@ -203,10 +203,24 @@ func TestBlockDAO(t *testing.T) { require.Equal(tipBlk.Height(), height) blk, err := dao.GetBlock(hash) require.NoError(err) - require.Equal(tipBlk, blk) + require.Equal(len(blk.Actions), len(tipBlk.Actions)) + for i := 0; i < len(blk.Actions); i++ { + hashVal1, hashErr1 := blk.Actions[i].Hash() + require.NoError(hashErr1) + hashVal2, hashErr2 := tipBlk.Actions[i].Hash() + require.NoError(hashErr2) + require.Equal(hashVal1, hashVal2) + } blk, err = dao.GetBlockByHeight(height) require.NoError(err) - require.Equal(tipBlk, blk) + require.Equal(len(blk.Actions), len(tipBlk.Actions)) + for i := 0; i < len(blk.Actions); i++ { + hashVal1, hashErr1 := blk.Actions[i].Hash() + require.NoError(hashErr1) + hashVal2, hashErr2 := tipBlk.Actions[i].Hash() + require.NoError(hashErr2) + require.Equal(hashVal1, hashVal2) + } r, err := dao.GetReceipts(height) require.NoError(err) require.Equal(len(receipts[i]), len(r)) @@ -329,10 +343,24 @@ func TestBlockDAO(t *testing.T) { require.Equal(tipHeight, height) blk, err := dao.GetBlock(h) require.NoError(err) - require.Equal(tipBlk, blk) + require.Equal(len(blk.Actions), len(tipBlk.Actions)) + for i := 0; i < len(blk.Actions); i++ { + hashVal1, hashErr1 := blk.Actions[i].Hash() + require.NoError(hashErr1) + hashVal2, hashErr2 := tipBlk.Actions[i].Hash() + require.NoError(hashErr2) + require.Equal(hashVal1, hashVal2) + } blk, err = dao.GetBlockByHeight(height) require.NoError(err) - require.Equal(tipBlk, blk) + require.Equal(len(blk.Actions), len(tipBlk.Actions)) + for i := 0; i < len(blk.Actions); i++ { + hashVal1, hashErr1 := blk.Actions[i].Hash() + require.NoError(hashErr1) + hashVal2, hashErr2 := tipBlk.Actions[i].Hash() + require.NoError(hashErr2) + require.Equal(hashVal1, hashVal2) + } // test BlockDAO's API, 2nd loop to test LRU cache for i := 0; i < 2; i++ { From 5b4a96e7365a7f7e51479a92347c57d9b319ee1e Mon Sep 17 00:00:00 2001 From: xianhuawei <258022429@qq.com> Date: Fri, 10 Jun 2022 15:18:45 +0800 Subject: [PATCH 8/8] Update config.yml --- .circleci/config.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 346eb33eba..ae11ea65d0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -201,6 +201,7 @@ workflows: only: - master jobs: - - nightly_build_docker - - nightly_bin_build_docker - - nightly_bin_build_darwin + - build_test_docker +# - nightly_build_docker +# - nightly_bin_build_docker +# - nightly_bin_build_darwin