diff --git a/api/api.go b/api/api.go index 8fcaadc5f..d99cfab0a 100644 --- a/api/api.go +++ b/api/api.go @@ -73,7 +73,9 @@ type FullNode interface { ChainWaitMsg(context.Context, cid.Cid) (*MsgWait, error) ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error) ChainGetBlockMessages(context.Context, cid.Cid) ([]*types.SignedMessage, error) - ChainCall(context.Context, *types.Message) (*types.MessageReceipt, error) + + // if tipset is nil, we'll use heaviest + ChainCall(context.Context, *types.Message, *types.TipSet) (*types.MessageReceipt, error) // messages diff --git a/api/struct.go b/api/struct.go index b33701b8e..321376376 100644 --- a/api/struct.go +++ b/api/struct.go @@ -39,14 +39,14 @@ type FullNodeStruct struct { CommonStruct Internal struct { - ChainNotify func(context.Context) (<-chan *store.HeadChange, error) `perm:"read"` - ChainSubmitBlock func(ctx context.Context, blk *chain.BlockMsg) error `perm:"write"` - ChainHead func(context.Context) (*types.TipSet, error) `perm:"read"` - ChainGetRandomness func(context.Context, *types.TipSet) ([]byte, error) `perm:"read"` - ChainWaitMsg func(context.Context, cid.Cid) (*MsgWait, error) `perm:"read"` - ChainGetBlock func(context.Context, cid.Cid) (*types.BlockHeader, error) `perm:"read"` - ChainGetBlockMessages func(context.Context, cid.Cid) ([]*types.SignedMessage, error) `perm:"read"` - ChainCall func(context.Context, *types.Message) (*types.MessageReceipt, error) `perm:"read"` + ChainNotify func(context.Context) (<-chan *store.HeadChange, error) `perm:"read"` + ChainSubmitBlock func(ctx context.Context, blk *chain.BlockMsg) error `perm:"write"` + ChainHead func(context.Context) (*types.TipSet, error) `perm:"read"` + ChainGetRandomness func(context.Context, *types.TipSet) ([]byte, error) `perm:"read"` + ChainWaitMsg func(context.Context, cid.Cid) (*MsgWait, error) `perm:"read"` + ChainGetBlock func(context.Context, cid.Cid) (*types.BlockHeader, error) `perm:"read"` + ChainGetBlockMessages func(context.Context, cid.Cid) ([]*types.SignedMessage, error) `perm:"read"` + ChainCall func(context.Context, *types.Message, *types.TipSet) (*types.MessageReceipt, error) `perm:"read"` MpoolPending func(context.Context, *types.TipSet) ([]*types.SignedMessage, error) `perm:"read"` MpoolPush func(context.Context, *types.SignedMessage) error `perm:"write"` @@ -156,8 +156,8 @@ func (c *FullNodeStruct) ChainWaitMsg(ctx context.Context, msgc cid.Cid) (*MsgWa return c.Internal.ChainWaitMsg(ctx, msgc) } -func (c *FullNodeStruct) ChainCall(ctx context.Context, msg *types.Message) (*types.MessageReceipt, error) { - return c.Internal.ChainCall(ctx, msg) +func (c *FullNodeStruct) ChainCall(ctx context.Context, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error) { + return c.Internal.ChainCall(ctx, msg, ts) } func (c *FullNodeStruct) WalletNew(ctx context.Context, typ string) (address.Address, error) { diff --git a/node/impl/full.go b/node/impl/full.go index 67ae2d8a6..9afd68e0e 100644 --- a/node/impl/full.go +++ b/node/impl/full.go @@ -86,14 +86,16 @@ func (a *FullNodeAPI) ChainGetBlockMessages(ctx context.Context, msg cid.Cid) ([ return a.Chain.MessagesForBlock(b) } -func (a *FullNodeAPI) ChainCall(ctx context.Context, msg *types.Message) (*types.MessageReceipt, error) { - hts := a.Chain.GetHeaviestTipSet() - state, err := a.Chain.TipSetState(hts.Cids()) +func (a *FullNodeAPI) ChainCall(ctx context.Context, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error) { + if ts == nil { + ts = a.Chain.GetHeaviestTipSet() + } + state, err := a.Chain.TipSetState(ts.Cids()) if err != nil { return nil, err } - vmi, err := vm.NewVM(state, hts.Height(), hts.Blocks()[0].Miner, a.Chain) + vmi, err := vm.NewVM(state, ts.Height(), ts.Blocks()[0].Miner, a.Chain) if err != nil { return nil, xerrors.Errorf("failed to set up vm: %w", err) } diff --git a/storage/miner.go b/storage/miner.go index f9eeb125a..2d99afa17 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -42,7 +42,7 @@ type storageMinerApi interface { //ReadState(ctx context.Context, addr address.Address) (????, error) // Call a read only method on actors (no interaction with the chain required) - ChainCall(ctx context.Context, msg *types.Message) (*types.MessageReceipt, error) + ChainCall(ctx context.Context, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error) MpoolPush(context.Context, *types.SignedMessage) error MpoolGetNonce(context.Context, address.Address) (uint64, error) @@ -187,7 +187,7 @@ func (m *Miner) getWorkerAddr(ctx context.Context) (address.Address, error) { Params: actors.EmptyStructCBOR, } - recpt, err := m.api.ChainCall(ctx, msg) + recpt, err := m.api.ChainCall(ctx, msg, nil) if err != nil { return address.Undef, errors.Wrapf(err, "calling getWorker(%s)", m.maddr) }