From b3bac0c9e8b101350e54bc4196fe7dd047680adc Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 21 Jul 2020 23:59:15 +0200 Subject: [PATCH 1/3] Add better error messages for message pre-execution errors Signed-off-by: Jakub Sztandera --- chain/vm/vm.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/chain/vm/vm.go b/chain/vm/vm.go index 6aab57393..112d507f3 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -347,6 +347,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet, ExitCode: exitcode.SysErrSenderInvalid, GasUsed: 0, }, + ActorErr: aerrors.Newf(exitcode.SysErrSenderInvalid, "actor not found: %s", msg.From), Penalty: minerPenaltyAmount, Duration: time.Since(start), }, nil @@ -361,6 +362,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet, ExitCode: exitcode.SysErrSenderInvalid, GasUsed: 0, }, + ActorErr: aerrors.Newf(exitcode.SysErrSenderInvalid, "send from not account actor: %s", fromActor.Code), Penalty: minerPenaltyAmount, Duration: time.Since(start), }, nil @@ -373,6 +375,8 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet, ExitCode: exitcode.SysErrSenderStateInvalid, GasUsed: 0, }, + ActorErr: aerrors.Newf(exitcode.SysErrSenderStateInvalid, + "actor nonce invalid: msg:%d != state:%d", msg.Nonce, fromActor.Nonce), Penalty: minerPenaltyAmount, Duration: time.Since(start), }, nil @@ -386,6 +390,8 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet, ExitCode: exitcode.SysErrSenderStateInvalid, GasUsed: 0, }, + ActorErr: aerrors.Newf(exitcode.SysErrSenderStateInvalid, + "actor balance less than needed: %s < %s", fromActor.Balance, totalCost), Penalty: minerPenaltyAmount, Duration: time.Since(start), }, nil From 7d83349507cd93adf047356115c6fc38d25d094f Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Wed, 22 Jul 2020 01:15:37 +0200 Subject: [PATCH 2/3] Format FIL as FIL Signed-off-by: Jakub Sztandera --- chain/vm/vm.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/vm/vm.go b/chain/vm/vm.go index 112d507f3..f817486fc 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -391,7 +391,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet, GasUsed: 0, }, ActorErr: aerrors.Newf(exitcode.SysErrSenderStateInvalid, - "actor balance less than needed: %s < %s", fromActor.Balance, totalCost), + "actor balance less than needed: %s < %s", types.FIL(fromActor.Balance), types.FIL(totalCost)), Penalty: minerPenaltyAmount, Duration: time.Since(start), }, nil From 629e03f303121c109b89e6d2bbddffc990909d4e Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Wed, 22 Jul 2020 17:46:13 +0200 Subject: [PATCH 3/3] Apply sequence of messages Signed-off-by: Jakub Sztandera --- chain/messagepool/messagepool.go | 8 ++++++++ chain/stmgr/call.go | 9 ++++++++- node/impl/full/gas.go | 18 +++++++++++++----- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/chain/messagepool/messagepool.go b/chain/messagepool/messagepool.go index c12359482..3538fc6ec 100644 --- a/chain/messagepool/messagepool.go +++ b/chain/messagepool/messagepool.go @@ -617,6 +617,14 @@ func (mp *MessagePool) Pending() ([]*types.SignedMessage, *types.TipSet) { return out, mp.curTs } +func (mp *MessagePool) PendingFor(a address.Address) ([]*types.SignedMessage, *types.TipSet) { + mp.curTsLk.Lock() + defer mp.curTsLk.Unlock() + + mp.lk.Lock() + defer mp.lk.Unlock() + return mp.pendingFor(a), mp.curTs +} func (mp *MessagePool) pendingFor(a address.Address) []*types.SignedMessage { mset := mp.pending[a] diff --git a/chain/stmgr/call.go b/chain/stmgr/call.go index 29c97c3d8..4da912614 100644 --- a/chain/stmgr/call.go +++ b/chain/stmgr/call.go @@ -86,7 +86,7 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types. return sm.CallRaw(ctx, msg, state, r, ts.Height()) } -func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, ts *types.TipSet) (*api.InvocResult, error) { +func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, priorMsgs []types.ChainMsg, ts *types.TipSet) (*api.InvocResult, error) { ctx, span := trace.StartSpan(ctx, "statemanager.CallWithGas") defer span.End() @@ -110,6 +110,13 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, ts if err != nil { return nil, xerrors.Errorf("failed to set up vm: %w", err) } + for i, m := range priorMsgs { + _, err := vmi.ApplyMessage(ctx, m) + if err != nil { + return nil, xerrors.Errorf("applying prior message (%d, %s): %w", i, m.Cid(), err) + } + } + fromActor, err := vmi.StateTree().GetActor(msg.From) if err != nil { return nil, xerrors.Errorf("call raw get actor: %s", err) diff --git a/node/impl/full/gas.go b/node/impl/full/gas.go index 1d09e5844..74b288640 100644 --- a/node/impl/full/gas.go +++ b/node/impl/full/gas.go @@ -5,6 +5,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/messagepool" "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" @@ -17,6 +18,7 @@ type GasAPI struct { fx.In Stmgr *stmgr.StateManager Cs *store.ChainStore + Mpool *messagepool.MessagePool } const MinGasPrice = 1 @@ -35,19 +37,25 @@ func (a *GasAPI) GasEstimateGasPrice(ctx context.Context, nblocksincl uint64, } } -func (a *GasAPI) GasEstimateGasLimit(ctx context.Context, msgIn *types.Message, - tsk types.TipSetKey) (int64, error) { +func (a *GasAPI) GasEstimateGasLimit(ctx context.Context, msgIn *types.Message, _ types.TipSetKey) (int64, error) { msg := *msgIn msg.GasLimit = build.BlockGasLimit msg.GasPrice = types.NewInt(1) - ts, err := a.Cs.GetTipSetFromKey(tsk) + currTs := a.Cs.GetHeaviestTipSet() + fromA, err := a.Stmgr.ResolveToKeyAddress(ctx, msgIn.From, currTs) if err != nil { - return -1, xerrors.Errorf("could not get tipset: %w", err) + return -1, xerrors.Errorf("getting key address: %w", err) } - res, err := a.Stmgr.CallWithGas(ctx, &msg, ts) + pending, ts := a.Mpool.PendingFor(fromA) + priorMsgs := make([]types.ChainMsg, 0, len(pending)) + for _, m := range pending { + priorMsgs = append(priorMsgs, m) + } + + res, err := a.Stmgr.CallWithGas(ctx, &msg, priorMsgs, ts) if err != nil { return -1, xerrors.Errorf("CallWithGas failed: %w", err) }