diff --git a/chain/consensus/filcns/filecoin.go b/chain/consensus/filcns/filecoin.go index 3aa85c7c5..b364ece4f 100644 --- a/chain/consensus/filcns/filecoin.go +++ b/chain/consensus/filcns/filecoin.go @@ -467,7 +467,7 @@ func (filec *FilecoinEC) checkBlockMessages(ctx context.Context, b *types.FullBl } nv := filec.sm.GetNetworkVersion(ctx, b.Header.Height) - pl := vm.PricelistByEpoch(b.Header.Height) + pl := vm.PricelistByEpochAndNetworkVersion(b.Header.Height, nv) var sumGasLimit int64 checkMsg := func(msg types.ChainMsg) error { m := msg.VMMessage() diff --git a/chain/messagepool/check.go b/chain/messagepool/check.go index 92cfb458a..7c7469f76 100644 --- a/chain/messagepool/check.go +++ b/chain/messagepool/check.go @@ -281,12 +281,11 @@ func (mp *MessagePool) checkMessages(ctx context.Context, msgs []*types.Message, // gas checks // 4. Min Gas - minGas := vm.PricelistByEpoch(epoch).OnChainMessage(m.ChainLength()) + minGas := vm.PricelistByEpochAndNetworkVersion(epoch, nv).OnChainMessage(m.ChainLength()) check = api.MessageCheckStatus{ Cid: m.Cid(), - CheckStatus: api.CheckStatus{ - Code: api.CheckStatusMessageMinGas, + CheckStatus: api.CheckStatus{Code: api.CheckStatusMessageMinGas, Hint: map[string]interface{}{ "minGas": minGas, }, diff --git a/chain/messagepool/messagepool.go b/chain/messagepool/messagepool.go index 1520d45b4..34daa6f7c 100644 --- a/chain/messagepool/messagepool.go +++ b/chain/messagepool/messagepool.go @@ -629,7 +629,11 @@ func (mp *MessagePool) addLocal(ctx context.Context, m *types.SignedMessage) err // a (soft) validation error. func (mp *MessagePool) verifyMsgBeforeAdd(m *types.SignedMessage, curTs *types.TipSet, local bool) (bool, error) { epoch := curTs.Height() + 1 - minGas := vm.PricelistByEpoch(epoch).OnChainMessage(m.ChainLength()) + nv, err := mp.getNtwkVersion(epoch) + if err != nil { + return false, xerrors.Errorf("getting network version: %w", err) + } + minGas := vm.PricelistByEpochAndNetworkVersion(epoch, nv).OnChainMessage(m.ChainLength()) if err := m.VMMessage().ValidForBlockInclusion(minGas.Total(), build.NewestNetworkVersion); err != nil { return false, xerrors.Errorf("message will not be included in a block: %w", err) diff --git a/chain/messagepool/selection.go b/chain/messagepool/selection.go index 633e9b23f..b3024b779 100644 --- a/chain/messagepool/selection.go +++ b/chain/messagepool/selection.go @@ -781,6 +781,7 @@ func (mp *MessagePool) createMessageChains(actor address.Address, mset map[uint6 // cannot exceed the block limit; drop all messages that exceed the limit // - the total gasReward cannot exceed the actor's balance; drop all messages that exceed // the balance + a, err := mp.api.GetActorAfter(actor, ts) if err != nil { log.Errorf("failed to load actor state, not building chain for %s: %v", actor, err) @@ -793,6 +794,12 @@ func (mp *MessagePool) createMessageChains(actor address.Address, mset map[uint6 skip := 0 i := 0 rewards := make([]*big.Int, 0, len(msgs)) + + nv, err := mp.getNtwkVersion(ts.Height()) + if err != nil { + log.Errorf("getting network version: %v", err) + return nil + } for i = 0; i < len(msgs); i++ { m := msgs[i] @@ -808,7 +815,7 @@ func (mp *MessagePool) createMessageChains(actor address.Address, mset map[uint6 } curNonce++ - minGas := vm.PricelistByEpoch(ts.Height()).OnChainMessage(m.ChainLength()).Total() + minGas := vm.PricelistByEpochAndNetworkVersion(ts.Height(), nv).OnChainMessage(m.ChainLength()).Total() if m.Message.GasLimit < minGas { break } diff --git a/chain/vm/fvm.go b/chain/vm/fvm.go index 72c84f966..e3a064de6 100644 --- a/chain/vm/fvm.go +++ b/chain/vm/fvm.go @@ -38,6 +38,7 @@ type FvmExtern struct { Rand blockstore.Blockstore epoch abi.ChainEpoch + nv network.Version lbState LookbackStateGetter base cid.Cid } @@ -175,7 +176,7 @@ func (x *FvmExtern) workerKeyAtLookback(ctx context.Context, minerId address.Add } cstWithoutGas := cbor.NewCborStore(x.Blockstore) - cbb := &gasChargingBlocks{gasAdder, PricelistByEpoch(x.epoch), x.Blockstore} + cbb := &gasChargingBlocks{gasAdder, PricelistByEpochAndNetworkVersion(x.epoch, x.nv), x.Blockstore} cstWithGas := cbor.NewCborStore(cbb) lbState, err := x.lbState(ctx, height) @@ -234,7 +235,7 @@ func NewFVM(ctx context.Context, opts *VMOpts) (*FVM, error) { } fvm, err := ffi.CreateFVM(0, - &FvmExtern{Rand: opts.Rand, Blockstore: opts.Bstore, lbState: opts.LookbackState, base: opts.StateBase, epoch: opts.Epoch}, + &FvmExtern{Rand: opts.Rand, Blockstore: opts.Bstore, lbState: opts.LookbackState, base: opts.StateBase, epoch: opts.Epoch, nv: opts.NetworkVersion}, opts.Epoch, opts.BaseFee, circToReport, opts.NetworkVersion, opts.StateBase, ) if err != nil { diff --git a/chain/vm/gas.go b/chain/vm/gas.go index 5beaae40b..90d9ac4e8 100644 --- a/chain/vm/gas.go +++ b/chain/vm/gas.go @@ -3,6 +3,8 @@ package vm import ( "fmt" + "github.com/filecoin-project/go-state-types/network" + vmr "github.com/filecoin-project/specs-actors/v7/actors/runtime" proof7 "github.com/filecoin-project/specs-actors/v7/actors/runtime/proof" @@ -82,145 +84,153 @@ type Pricelist interface { OnVerifyConsensusFault() GasCharge } -// Prices are the price lists per starting epoch. Public for testing purposes -// (concretely to allow the test vector runner to rebase prices). -var Prices = map[abi.ChainEpoch]Pricelist{ - abi.ChainEpoch(0): &pricelistV0{ - computeGasMulti: 1, - storageGasMulti: 1000, +var priceListGenesis = pricelistV0{ + computeGasMulti: 1, + storageGasMulti: 1000, - onChainMessageComputeBase: 38863, - onChainMessageStorageBase: 36, - onChainMessageStoragePerByte: 1, + onChainMessageComputeBase: 38863, + onChainMessageStorageBase: 36, + onChainMessageStoragePerByte: 1, - onChainReturnValuePerByte: 1, + onChainReturnValuePerByte: 1, - sendBase: 29233, - sendTransferFunds: 27500, - sendTransferOnlyPremium: 159672, - sendInvokeMethod: -5377, + sendBase: 29233, + sendTransferFunds: 27500, + sendTransferOnlyPremium: 159672, + sendInvokeMethod: -5377, - ipldGetBase: 75242, - ipldPutBase: 84070, - ipldPutPerByte: 1, + ipldGetBase: 75242, + ipldPutBase: 84070, + ipldPutPerByte: 1, - createActorCompute: 1108454, - createActorStorage: 36 + 40, - deleteActor: -(36 + 40), // -createActorStorage + createActorCompute: 1108454, + createActorStorage: 36 + 40, + deleteActor: -(36 + 40), // -createActorStorage - verifySignature: map[crypto.SigType]int64{ - crypto.SigTypeBLS: 16598605, - crypto.SigTypeSecp256k1: 1637292, - }, - - hashingBase: 31355, - computeUnsealedSectorCidBase: 98647, - verifySealBase: 2000, // TODO gas , it VerifySeal syscall is not used - verifyAggregateSealBase: 0, - verifyPostLookup: map[abi.RegisteredPoStProof]scalingCost{ - abi.RegisteredPoStProof_StackedDrgWindow512MiBV1: { - flat: 123861062, - scale: 9226981, - }, - abi.RegisteredPoStProof_StackedDrgWindow32GiBV1: { - flat: 748593537, - scale: 85639, - }, - abi.RegisteredPoStProof_StackedDrgWindow64GiBV1: { - flat: 748593537, - scale: 85639, - }, - }, - verifyPostDiscount: true, - verifyConsensusFault: 495422, + verifySignature: map[crypto.SigType]int64{ + crypto.SigTypeBLS: 16598605, + crypto.SigTypeSecp256k1: 1637292, }, - abi.ChainEpoch(build.UpgradeCalicoHeight): &pricelistV0{ - computeGasMulti: 1, - storageGasMulti: 1300, - onChainMessageComputeBase: 38863, - onChainMessageStorageBase: 36, - onChainMessageStoragePerByte: 1, - - onChainReturnValuePerByte: 1, - - sendBase: 29233, - sendTransferFunds: 27500, - sendTransferOnlyPremium: 159672, - sendInvokeMethod: -5377, - - ipldGetBase: 114617, - ipldPutBase: 353640, - ipldPutPerByte: 1, - - createActorCompute: 1108454, - createActorStorage: 36 + 40, - deleteActor: -(36 + 40), // -createActorStorage - - verifySignature: map[crypto.SigType]int64{ - crypto.SigTypeBLS: 16598605, - crypto.SigTypeSecp256k1: 1637292, + hashingBase: 31355, + computeUnsealedSectorCidBase: 98647, + verifySealBase: 2000, // TODO gas , it VerifySeal syscall is not used + verifyAggregateSealBase: 0, + verifyPostLookup: map[abi.RegisteredPoStProof]scalingCost{ + abi.RegisteredPoStProof_StackedDrgWindow512MiBV1: { + flat: 123861062, + scale: 9226981, }, - - hashingBase: 31355, - computeUnsealedSectorCidBase: 98647, - verifySealBase: 2000, // TODO gas, it VerifySeal syscall is not used - - verifyAggregateSealPer: map[abi.RegisteredSealProof]int64{ - abi.RegisteredSealProof_StackedDrg32GiBV1_1: 449900, - abi.RegisteredSealProof_StackedDrg64GiBV1_1: 359272, + abi.RegisteredPoStProof_StackedDrgWindow32GiBV1: { + flat: 748593537, + scale: 85639, }, - verifyAggregateSealSteps: map[abi.RegisteredSealProof]stepCost{ - abi.RegisteredSealProof_StackedDrg32GiBV1_1: { - {4, 103994170}, - {7, 112356810}, - {13, 122912610}, - {26, 137559930}, - {52, 162039100}, - {103, 210960780}, - {205, 318351180}, - {410, 528274980}, - }, - abi.RegisteredSealProof_StackedDrg64GiBV1_1: { - {4, 102581240}, - {7, 110803030}, - {13, 120803700}, - {26, 134642130}, - {52, 157357890}, - {103, 203017690}, - {205, 304253590}, - {410, 509880640}, - }, + abi.RegisteredPoStProof_StackedDrgWindow64GiBV1: { + flat: 748593537, + scale: 85639, }, - - verifyPostLookup: map[abi.RegisteredPoStProof]scalingCost{ - abi.RegisteredPoStProof_StackedDrgWindow512MiBV1: { - flat: 117680921, - scale: 43780, - }, - abi.RegisteredPoStProof_StackedDrgWindow32GiBV1: { - flat: 117680921, - scale: 43780, - }, - abi.RegisteredPoStProof_StackedDrgWindow64GiBV1: { - flat: 117680921, - scale: 43780, - }, - }, - verifyPostDiscount: false, - verifyConsensusFault: 495422, - - verifyReplicaUpdate: 36316136, }, + verifyPostDiscount: true, + verifyConsensusFault: 495422, } -// PricelistByEpoch finds the latest prices for the given epoch -func PricelistByEpoch(epoch abi.ChainEpoch) Pricelist { +var priceListCalico = pricelistV0{ + computeGasMulti: 1, + storageGasMulti: 1300, + + onChainMessageComputeBase: 38863, + onChainMessageStorageBase: 36, + onChainMessageStoragePerByte: 1, + + onChainReturnValuePerByte: 1, + + sendBase: 29233, + sendTransferFunds: 27500, + sendTransferOnlyPremium: 159672, + sendInvokeMethod: -5377, + + ipldGetBase: 114617, + ipldPutBase: 353640, + ipldPutPerByte: 1, + + createActorCompute: 1108454, + createActorStorage: 36 + 40, + deleteActor: -(36 + 40), // -createActorStorage + + verifySignature: map[crypto.SigType]int64{ + crypto.SigTypeBLS: 16598605, + crypto.SigTypeSecp256k1: 1637292, + }, + + hashingBase: 31355, + computeUnsealedSectorCidBase: 98647, + verifySealBase: 2000, // TODO gas, it VerifySeal syscall is not used + + verifyAggregateSealPer: map[abi.RegisteredSealProof]int64{ + abi.RegisteredSealProof_StackedDrg32GiBV1_1: 449900, + abi.RegisteredSealProof_StackedDrg64GiBV1_1: 359272, + }, + verifyAggregateSealSteps: map[abi.RegisteredSealProof]stepCost{ + abi.RegisteredSealProof_StackedDrg32GiBV1_1: { + {4, 103994170}, + {7, 112356810}, + {13, 122912610}, + {26, 137559930}, + {52, 162039100}, + {103, 210960780}, + {205, 318351180}, + {410, 528274980}, + }, + abi.RegisteredSealProof_StackedDrg64GiBV1_1: { + {4, 102581240}, + {7, 110803030}, + {13, 120803700}, + {26, 134642130}, + {52, 157357890}, + {103, 203017690}, + {205, 304253590}, + {410, 509880640}, + }, + }, + + verifyPostLookup: map[abi.RegisteredPoStProof]scalingCost{ + abi.RegisteredPoStProof_StackedDrgWindow512MiBV1: { + flat: 117680921, + scale: 43780, + }, + abi.RegisteredPoStProof_StackedDrgWindow32GiBV1: { + flat: 117680921, + scale: 43780, + }, + abi.RegisteredPoStProof_StackedDrgWindow64GiBV1: { + flat: 117680921, + scale: 43780, + }, + }, + verifyPostDiscount: false, + verifyConsensusFault: 495422, + + verifyReplicaUpdate: 36316136, +} + +// Prices are the price lists per starting epoch. +// For network v8 and onwards, this is disregarded; the pricelist is selected by network version. +var pricesByEpoch = map[abi.ChainEpoch]Pricelist{ + abi.ChainEpoch(0): &priceListGenesis, + abi.ChainEpoch(build.UpgradeCalicoHeight): &priceListCalico, +} + +// PricelistByEpochAndNetworkVersion finds the latest prices for the given epoch +func PricelistByEpochAndNetworkVersion(epoch abi.ChainEpoch, nv network.Version) Pricelist { + if nv >= network.Version8 { + return &priceListCalico + } + // since we are storing the prices as map or epoch to price // we need to get the price with the highest epoch that is lower or equal to the `epoch` arg bestEpoch := abi.ChainEpoch(0) - bestPrice := Prices[bestEpoch] - for e, pl := range Prices { + bestPrice := pricesByEpoch[bestEpoch] + for e, pl := range pricesByEpoch { // if `e` happened after `bestEpoch` and `e` is earlier or equal to the target `epoch` if e > bestEpoch && e <= epoch { bestEpoch = e diff --git a/chain/vm/mkactor.go b/chain/vm/mkactor.go index 5716b5006..6666f16ad 100644 --- a/chain/vm/mkactor.go +++ b/chain/vm/mkactor.go @@ -51,7 +51,7 @@ var EmptyObjectCid cid.Cid // TryCreateAccountActor creates account actors from only BLS/SECP256K1 addresses. func TryCreateAccountActor(rt *Runtime, addr address.Address) (*types.Actor, address.Address, aerrors.ActorError) { - if err := rt.chargeGasSafe(PricelistByEpoch(rt.height).OnCreateActor()); err != nil { + if err := rt.chargeGasSafe(PricelistByEpochAndNetworkVersion(rt.height, rt.NetworkVersion()).OnCreateActor()); err != nil { return nil, address.Undef, err } diff --git a/chain/vm/vm.go b/chain/vm/vm.go index a0ca446a7..4c99fb4f8 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -135,7 +135,7 @@ func (vm *LegacyVM) makeRuntime(ctx context.Context, msg *types.Message, parent gasAvailable: msg.GasLimit, depth: 0, numActorsCreated: 0, - pricelist: PricelistByEpoch(vm.blockHeight), + pricelist: PricelistByEpochAndNetworkVersion(vm.blockHeight, vm.networkVersion), allowInternal: true, callerValidated: false, executionTrace: types.ExecutionTrace{Msg: msg}, @@ -431,7 +431,7 @@ func (vm *LegacyVM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*App return nil, err } - pl := PricelistByEpoch(vm.blockHeight) + pl := PricelistByEpochAndNetworkVersion(vm.blockHeight, vm.networkVersion) msgGas := pl.OnChainMessage(cmsg.ChainLength()) msgGasCost := msgGas.Total() diff --git a/conformance/runner.go b/conformance/runner.go index fd44ecff9..162c934b9 100644 --- a/conformance/runner.go +++ b/conformance/runner.go @@ -7,7 +7,6 @@ import ( "encoding/base64" "fmt" "io/ioutil" - "math" "os" "os/exec" "strconv" @@ -29,7 +28,6 @@ import ( "github.com/filecoin-project/test-vectors/schema" "github.com/filecoin-project/lotus/blockstore" - "github.com/filecoin-project/lotus/chain/consensus/filcns" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/vm" ) @@ -53,52 +51,6 @@ var TipsetVectorOpts struct { OnTipsetApplied []func(bs blockstore.Blockstore, params *ExecuteTipsetParams, res *ExecuteTipsetResult) } -type GasPricingRestoreFn func() - -// adjustGasPricing adjusts the global gas price mapping to make sure that the -// gas pricelist for vector's network version is used at the vector's epoch. -// Because it manipulates a global, it returns a function that reverts the -// change. The caller MUST invoke this function or the test vector runner will -// become invalid. -func adjustGasPricing(vectorEpoch abi.ChainEpoch, vectorNv network.Version) GasPricingRestoreFn { - // Stash the current pricing mapping. - // Ok to take a reference instead of a copy, because we override the map - // with a new one below. - var old = vm.Prices - - // Resolve the epoch at which the vector network version kicks in. - var epoch abi.ChainEpoch = math.MaxInt64 - if vectorNv == network.Version0 { - // genesis is not an upgrade. - epoch = 0 - } else { - for _, u := range filcns.DefaultUpgradeSchedule() { - if u.Network == vectorNv { - epoch = u.Height - break - } - } - } - - if epoch == math.MaxInt64 { - panic(fmt.Sprintf("could not resolve network version %d to height", vectorNv)) - } - - // Find the right pricelist for this network version. - pricelist := vm.PricelistByEpoch(epoch) - - // Override the pricing mapping by setting the relevant pricelist for the - // network version at the epoch where the vector runs. - vm.Prices = map[abi.ChainEpoch]vm.Pricelist{ - vectorEpoch: pricelist, - } - - // Return a function to restore the original mapping. - return func() { - vm.Prices = old - } -} - // ExecuteMessageVector executes a message-class test vector. func ExecuteMessageVector(r Reporter, vector *schema.TestVector, variant *schema.Variant) (diffs []string, err error) { var ( @@ -117,10 +69,6 @@ func ExecuteMessageVector(r Reporter, vector *schema.TestVector, variant *schema // Create a new Driver. driver := NewDriver(ctx, vector.Selector, DriverOpts{DisableVMFlush: true}) - // Monkey patch the gas pricing. - revertFn := adjustGasPricing(baseEpoch, nv) - defer revertFn() - // Apply every message. for i, m := range vector.ApplyMessages { msg, err := types.DecodeMessage(m.Bytes)