Handle worker key changes correctly in runtime
This commit is contained in:
parent
2663d6c3cb
commit
f23034305f
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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))
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user