diff --git a/chain/gen/genesis/miners.go b/chain/gen/genesis/miners.go index 49e09d792..be83a8711 100644 --- a/chain/gen/genesis/miners.go +++ b/chain/gen/genesis/miners.go @@ -56,9 +56,9 @@ func (fss *fakedSigSyscalls) VerifySignature(signature crypto.Signature, signer } func mkFakedSigSyscalls(base vm.SyscallBuilder) vm.SyscallBuilder { - return func(ctx context.Context, cstate *state.StateTree, cst cbor.IpldStore) runtime2.Syscalls { + return func(ctx context.Context, rt *vm.Runtime) runtime2.Syscalls { return &fakedSigSyscalls{ - base(ctx, cstate, cst), + base(ctx, rt), } } } diff --git a/chain/stmgr/call.go b/chain/stmgr/call.go index 3d7d284bc..bb0f0e5ec 100644 --- a/chain/stmgr/call.go +++ b/chain/stmgr/call.go @@ -64,6 +64,7 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types. CircSupplyCalc: sm.GetVMCirculatingSupply, NtwkVersion: sm.GetNtwkVersion, BaseFee: types.NewInt(0), + LookbackState: LookbackStateGetterForTipset(sm, ts), } vmi, err := sm.newVM(ctx, vmopt) @@ -178,6 +179,7 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri CircSupplyCalc: sm.GetVMCirculatingSupply, NtwkVersion: sm.GetNtwkVersion, BaseFee: ts.Blocks()[0].ParentBaseFee, + LookbackState: LookbackStateGetterForTipset(sm, ts), } vmi, err := sm.newVM(ctx, vmopt) if err != nil { diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index 2822344b0..7e5809a84 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -241,6 +241,7 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp CircSupplyCalc: sm.GetVMCirculatingSupply, NtwkVersion: sm.GetNtwkVersion, BaseFee: baseFee, + LookbackState: LookbackStateGetterForTipset(sm, ts), } return sm.newVM(ctx, vmopt) diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index 486805786..5b144281d 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -366,6 +366,7 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch, CircSupplyCalc: sm.GetVMCirculatingSupply, NtwkVersion: sm.GetNtwkVersion, BaseFee: ts.Blocks()[0].ParentBaseFee, + LookbackState: LookbackStateGetterForTipset(sm, ts), } vmi, err := sm.newVM(ctx, vmopt) if err != nil { @@ -391,6 +392,16 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch, return root, trace, nil } +func LookbackStateGetterForTipset(sm *StateManager, ts *types.TipSet) vm.LookbackStateGetter { + return func(ctx context.Context, round abi.ChainEpoch) (*state.StateTree, error) { + _, st, err := GetLookbackTipSetForRound(ctx, sm, ts, round) + if err != nil { + return nil, err + } + return sm.StateTree(st) + } +} + func GetLookbackTipSetForRound(ctx context.Context, sm *StateManager, ts *types.TipSet, round abi.ChainEpoch) (*types.TipSet, cid.Cid, error) { var lbr abi.ChainEpoch lb := policy.GetWinningPoStSectorSetLookback(sm.GetNtwkVersion(ctx, round)) diff --git a/chain/vm/syscalls.go b/chain/vm/syscalls.go index 347c3409c..d2f1f77d3 100644 --- a/chain/vm/syscalls.go +++ b/chain/vm/syscalls.go @@ -34,15 +34,18 @@ func init() { // Actual type is defined in chain/types/vmcontext.go because the VMContext interface is there -type SyscallBuilder func(ctx context.Context, cstate *state.StateTree, cst cbor.IpldStore) runtime2.Syscalls +type SyscallBuilder func(ctx context.Context, rt *Runtime) runtime2.Syscalls func Syscalls(verifier ffiwrapper.Verifier) SyscallBuilder { - return func(ctx context.Context, cstate *state.StateTree, cst cbor.IpldStore) runtime2.Syscalls { + return func(ctx context.Context, rt *Runtime) runtime2.Syscalls { + return &syscallShim{ ctx: ctx, - cstate: cstate, - cst: cst, + actor: rt.Receiver(), + cstate: rt.state, + cst: rt.cst, + lbState: rt.vm.lbStateGet, verifier: verifier, } @@ -52,6 +55,8 @@ func Syscalls(verifier ffiwrapper.Verifier) SyscallBuilder { type syscallShim struct { ctx context.Context + lbState LookbackStateGetter + actor address.Address cstate *state.StateTree cst cbor.IpldStore verifier ffiwrapper.Verifier @@ -184,26 +189,7 @@ func (ss *syscallShim) VerifyConsensusFault(a, b, extra []byte) (*runtime2.Conse } func (ss *syscallShim) VerifyBlockSig(blk *types.BlockHeader) error { - - // get appropriate miner actor - act, err := ss.cstate.GetActor(blk.Miner) - if err != nil { - return err - } - - // use that to get the miner state - mas, err := miner.Load(adt.WrapStore(ss.ctx, ss.cst), act) - if err != nil { - return err - } - - info, err := mas.Info() - if err != nil { - return err - } - - // and use to get resolved workerKey - waddr, err := ResolveToKeyAddr(ss.cstate, ss.cst, info.Worker) + waddr, err := ss.workerKeyAtLookback(blk.Height) if err != nil { return err } @@ -215,6 +201,31 @@ func (ss *syscallShim) VerifyBlockSig(blk *types.BlockHeader) error { return nil } +func (ss *syscallShim) workerKeyAtLookback(height abi.ChainEpoch) (address.Address, error) { + lbState, err := ss.lbState(ss.ctx, height) + if err != nil { + return address.Undef, err + } + // get appropriate miner actor + act, err := lbState.GetActor(ss.actor) + if err != nil { + return address.Undef, err + } + + // use that to get the miner state + mas, err := miner.Load(adt.WrapStore(ss.ctx, ss.cst), act) + if err != nil { + return address.Undef, err + } + + info, err := mas.Info() + if err != nil { + return address.Undef, err + } + + return ResolveToKeyAddr(ss.cstate, ss.cst, info.Worker) +} + func (ss *syscallShim) VerifyPoSt(proof proof2.WindowPoStVerifyInfo) error { ok, err := ss.verifier.VerifyWindowPoSt(context.TODO(), proof) if err != nil { diff --git a/chain/vm/vm.go b/chain/vm/vm.go index a7aa05719..8b7f78074 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -134,11 +134,6 @@ func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, parent *Runti Blocks: &gasChargingBlocks{rt.chargeGasFunc(2), rt.pricelist, vm.cst.Blocks}, Atlas: vm.cst.Atlas, } - rt.Syscalls = pricedSyscalls{ - under: vm.Syscalls(ctx, vm.cstate, rt.cst), - chargeGas: rt.chargeGasFunc(1), - pl: rt.pricelist, - } vmm := *msg resF, ok := rt.ResolveAddress(msg.From) @@ -156,6 +151,12 @@ func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, parent *Runti rt.Message = &Message{msg: vmm} } + rt.Syscalls = pricedSyscalls{ + under: vm.Syscalls(ctx, rt), + chargeGas: rt.chargeGasFunc(1), + pl: rt.pricelist, + } + return rt } @@ -169,6 +170,7 @@ func (vm *UnsafeVM) MakeRuntime(ctx context.Context, msg *types.Message) *Runtim type CircSupplyCalculator func(context.Context, abi.ChainEpoch, *state.StateTree) (abi.TokenAmount, error) type NtwkVersionGetter func(context.Context, abi.ChainEpoch) network.Version +type LookbackStateGetter func(context.Context, abi.ChainEpoch) (*state.StateTree, error) type VM struct { cstate *state.StateTree @@ -181,6 +183,7 @@ type VM struct { circSupplyCalc CircSupplyCalculator ntwkVersion NtwkVersionGetter baseFee abi.TokenAmount + lbStateGet LookbackStateGetter Syscalls SyscallBuilder } @@ -194,6 +197,7 @@ type VMOpts struct { CircSupplyCalc CircSupplyCalculator NtwkVersion NtwkVersionGetter // TODO: stebalien: In what cases do we actually need this? It seems like even when creating new networks we want to use the 'global'/build-default version getter BaseFee abi.TokenAmount + LookbackState LookbackStateGetter } func NewVM(ctx context.Context, opts *VMOpts) (*VM, error) { @@ -216,6 +220,7 @@ func NewVM(ctx context.Context, opts *VMOpts) (*VM, error) { ntwkVersion: opts.NtwkVersion, Syscalls: opts.Syscalls, baseFee: opts.BaseFee, + lbStateGet: opts.LookbackState, }, nil }