Merge pull request #2874 from filecoin-project/feat/dyn-base-fee
Introduce dynamic network fee
This commit is contained in:
commit
b7695f9408
@ -115,14 +115,17 @@ type FullNode interface {
|
|||||||
// becomes available
|
// becomes available
|
||||||
BeaconGetEntry(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error)
|
BeaconGetEntry(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error)
|
||||||
|
|
||||||
|
// GasEstimateFeeCap estimates gas fee cap
|
||||||
|
GasEstimateFeeCap(context.Context, int64, types.TipSetKey) (types.BigInt, error)
|
||||||
|
|
||||||
// GasEstimateGasLimit estimates gas used by the message and returns it.
|
// GasEstimateGasLimit estimates gas used by the message and returns it.
|
||||||
// It fails if message fails to execute.
|
// It fails if message fails to execute.
|
||||||
GasEstimateGasLimit(context.Context, *types.Message, types.TipSetKey) (int64, error)
|
GasEstimateGasLimit(context.Context, *types.Message, types.TipSetKey) (int64, error)
|
||||||
|
|
||||||
// GasEstimateGasPrice estimates what gas price should be used for a
|
// GasEsitmateGasPremium estimates what gas price should be used for a
|
||||||
// message to have high likelihood of inclusion in `nblocksincl` epochs.
|
// message to have high likelihood of inclusion in `nblocksincl` epochs.
|
||||||
|
|
||||||
GasEstimateGasPrice(_ context.Context, nblocksincl uint64,
|
GasEsitmateGasPremium(_ context.Context, nblocksincl uint64,
|
||||||
sender address.Address, gaslimit int64, tsk types.TipSetKey) (types.BigInt, error)
|
sender address.Address, gaslimit int64, tsk types.TipSetKey) (types.BigInt, error)
|
||||||
|
|
||||||
// MethodGroup: Sync
|
// MethodGroup: Sync
|
||||||
@ -170,10 +173,6 @@ type FullNode interface {
|
|||||||
MpoolGetNonce(context.Context, address.Address) (uint64, error)
|
MpoolGetNonce(context.Context, address.Address) (uint64, error)
|
||||||
MpoolSub(context.Context) (<-chan MpoolUpdate, error)
|
MpoolSub(context.Context) (<-chan MpoolUpdate, error)
|
||||||
|
|
||||||
// MpoolEstimateGasPrice is depracated
|
|
||||||
// Deprecated: use GasEstimateGasPrice instead
|
|
||||||
MpoolEstimateGasPrice(ctx context.Context, nblocksincl uint64, sender address.Address, gaslimit int64, tsk types.TipSetKey) (types.BigInt, error)
|
|
||||||
|
|
||||||
// MethodGroup: Miner
|
// MethodGroup: Miner
|
||||||
|
|
||||||
MinerGetBaseInfo(context.Context, address.Address, abi.ChainEpoch, types.TipSetKey) (*MiningBaseInfo, error)
|
MinerGetBaseInfo(context.Context, address.Address, abi.ChainEpoch, types.TipSetKey) (*MiningBaseInfo, error)
|
||||||
|
@ -87,8 +87,9 @@ type FullNodeStruct struct {
|
|||||||
|
|
||||||
BeaconGetEntry func(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error) `perm:"read"`
|
BeaconGetEntry func(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error) `perm:"read"`
|
||||||
|
|
||||||
GasEstimateGasPrice func(context.Context, uint64, address.Address, int64, types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
GasEsitmateGasPremium func(context.Context, uint64, address.Address, int64, types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||||
GasEstimateGasLimit func(context.Context, *types.Message, types.TipSetKey) (int64, error) `perm:"read"`
|
GasEstimateGasLimit func(context.Context, *types.Message, types.TipSetKey) (int64, error) `perm:"read"`
|
||||||
|
GasEstimateFeeCap func(context.Context, int64, types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||||
|
|
||||||
SyncState func(context.Context) (*api.SyncState, error) `perm:"read"`
|
SyncState func(context.Context) (*api.SyncState, error) `perm:"read"`
|
||||||
SyncSubmitBlock func(ctx context.Context, blk *types.BlockMsg) error `perm:"write"`
|
SyncSubmitBlock func(ctx context.Context, blk *types.BlockMsg) error `perm:"write"`
|
||||||
@ -430,9 +431,13 @@ func (c *FullNodeStruct) ClientDealSize(ctx context.Context, root cid.Cid) (api.
|
|||||||
return c.Internal.ClientDealSize(ctx, root)
|
return c.Internal.ClientDealSize(ctx, root)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *FullNodeStruct) GasEstimateGasPrice(ctx context.Context, nblocksincl uint64,
|
func (c *FullNodeStruct) GasEsitmateGasPremium(ctx context.Context, nblocksincl uint64,
|
||||||
sender address.Address, gaslimit int64, tsk types.TipSetKey) (types.BigInt, error) {
|
sender address.Address, gaslimit int64, tsk types.TipSetKey) (types.BigInt, error) {
|
||||||
return c.Internal.GasEstimateGasPrice(ctx, nblocksincl, sender, gaslimit, tsk)
|
return c.Internal.GasEsitmateGasPremium(ctx, nblocksincl, sender, gaslimit, tsk)
|
||||||
|
}
|
||||||
|
func (c *FullNodeStruct) GasEstimateFeeCap(ctx context.Context, maxqueueblks int64,
|
||||||
|
tsk types.TipSetKey) (types.BigInt, error) {
|
||||||
|
return c.Internal.GasEstimateFeeCap(ctx, maxqueueblks, tsk)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *FullNodeStruct) GasEstimateGasLimit(ctx context.Context, msg *types.Message,
|
func (c *FullNodeStruct) GasEstimateGasLimit(ctx context.Context, msg *types.Message,
|
||||||
@ -460,10 +465,6 @@ func (c *FullNodeStruct) MpoolSub(ctx context.Context) (<-chan api.MpoolUpdate,
|
|||||||
return c.Internal.MpoolSub(ctx)
|
return c.Internal.MpoolSub(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *FullNodeStruct) MpoolEstimateGasPrice(ctx context.Context, nblocksincl uint64, sender address.Address, limit int64, tsk types.TipSetKey) (types.BigInt, error) {
|
|
||||||
return c.Internal.GasEstimateGasPrice(ctx, nblocksincl, sender, limit, tsk)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FullNodeStruct) MinerGetBaseInfo(ctx context.Context, maddr address.Address, epoch abi.ChainEpoch, tsk types.TipSetKey) (*api.MiningBaseInfo, error) {
|
func (c *FullNodeStruct) MinerGetBaseInfo(ctx context.Context, maddr address.Address, epoch abi.ChainEpoch, tsk types.TipSetKey) (*api.MiningBaseInfo, error) {
|
||||||
return c.Internal.MinerGetBaseInfo(ctx, maddr, epoch, tsk)
|
return c.Internal.MinerGetBaseInfo(ctx, maddr, epoch, tsk)
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ func TestPaymentChannels(t *testing.T, b APIBuilder, blocktime time.Duration) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
sendFunds(ctx, t, paymentCreator, receiverAddr, abi.NewTokenAmount(1e10))
|
sendFunds(ctx, t, paymentCreator, receiverAddr, abi.NewTokenAmount(1e18))
|
||||||
|
|
||||||
// setup the payment channel
|
// setup the payment channel
|
||||||
createrAddr, err := paymentCreator.WalletDefaultAddress(ctx)
|
createrAddr, err := paymentCreator.WalletDefaultAddress(ctx)
|
||||||
@ -218,10 +218,9 @@ func waitForBlocks(ctx context.Context, t *testing.T, bm *blockMiner, paymentRec
|
|||||||
|
|
||||||
// Add a real block
|
// Add a real block
|
||||||
m, err := paymentReceiver.MpoolPushMessage(ctx, &types.Message{
|
m, err := paymentReceiver.MpoolPushMessage(ctx, &types.Message{
|
||||||
To: builtin.BurntFundsActorAddr,
|
To: builtin.BurntFundsActorAddr,
|
||||||
From: receiverAddr,
|
From: receiverAddr,
|
||||||
Value: types.NewInt(0),
|
Value: types.NewInt(0),
|
||||||
GasPrice: big.Zero(),
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -303,11 +302,9 @@ func sendFunds(ctx context.Context, t *testing.T, sender TestNode, addr address.
|
|||||||
}
|
}
|
||||||
|
|
||||||
msg := &types.Message{
|
msg := &types.Message{
|
||||||
From: senderAddr,
|
From: senderAddr,
|
||||||
To: addr,
|
To: addr,
|
||||||
Value: amount,
|
Value: amount,
|
||||||
GasLimit: 0,
|
|
||||||
GasPrice: abi.NewTokenAmount(0),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sm, err := sender.MpoolPushMessage(ctx, msg)
|
sm, err := sender.MpoolPushMessage(ctx, msg)
|
||||||
|
@ -88,8 +88,12 @@ const VerifSigCacheSize = 32000
|
|||||||
// Limits
|
// Limits
|
||||||
|
|
||||||
// TODO: If this is gonna stay, it should move to specs-actors
|
// TODO: If this is gonna stay, it should move to specs-actors
|
||||||
const BlockMessageLimit = 512
|
const BlockMessageLimit = 10000
|
||||||
const BlockGasLimit = 7_500_000_000
|
const BlockGasLimit = 10_000_000_000
|
||||||
|
const BlockGasTarget = BlockGasLimit / 2
|
||||||
|
const BaseFeeMaxChangeDenom = 8 // 12.5%
|
||||||
|
const InitialBaseFee = 100e6
|
||||||
|
const MinimumBaseFee = 100
|
||||||
|
|
||||||
// Actor consts
|
// Actor consts
|
||||||
// TODO: Pull from actors when its made not private
|
// TODO: Pull from actors when its made not private
|
||||||
|
@ -53,7 +53,7 @@ func (ve Version) EqMajorMinor(v2 Version) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// APIVersion is a semver version of the rpc api exposed
|
// APIVersion is a semver version of the rpc api exposed
|
||||||
var APIVersion Version = newVer(0, 8, 1)
|
var APIVersion Version = newVer(0, 9, 0)
|
||||||
|
|
||||||
//nolint:varcheck,deadcode
|
//nolint:varcheck,deadcode
|
||||||
const (
|
const (
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/ipfs/go-cid"
|
cid "github.com/ipfs/go-cid"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
xerrors "golang.org/x/xerrors"
|
xerrors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
@ -489,8 +489,9 @@ func getRandomMessages(cg *ChainGen) ([]*types.SignedMessage, error) {
|
|||||||
|
|
||||||
Method: 0,
|
Method: 0,
|
||||||
|
|
||||||
GasLimit: 100_000_000,
|
GasLimit: 100_000_000,
|
||||||
GasPrice: types.NewInt(0),
|
GasFeeCap: types.NewInt(0),
|
||||||
|
GasPremium: types.NewInt(0),
|
||||||
}
|
}
|
||||||
|
|
||||||
sig, err := cg.w.Sign(context.TODO(), cg.banker, msg.Cid().Bytes())
|
sig, err := cg.w.Sign(context.TODO(), cg.banker, msg.Cid().Bytes())
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/build"
|
||||||
"github.com/filecoin-project/lotus/chain/state"
|
"github.com/filecoin-project/lotus/chain/state"
|
||||||
"github.com/filecoin-project/lotus/chain/store"
|
"github.com/filecoin-project/lotus/chain/store"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
@ -321,7 +322,16 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci
|
|||||||
verifNeeds := make(map[address.Address]abi.PaddedPieceSize)
|
verifNeeds := make(map[address.Address]abi.PaddedPieceSize)
|
||||||
var sum abi.PaddedPieceSize
|
var sum abi.PaddedPieceSize
|
||||||
|
|
||||||
vm, err := vm.NewVM(stateroot, 0, &fakeRand{}, cs.Blockstore(), mkFakedSigSyscalls(cs.VMSys()), nil)
|
vmopt := vm.VMOpts{
|
||||||
|
StateBase: stateroot,
|
||||||
|
Epoch: 0,
|
||||||
|
Rand: &fakeRand{},
|
||||||
|
Bstore: cs.Blockstore(),
|
||||||
|
Syscalls: mkFakedSigSyscalls(cs.VMSys()),
|
||||||
|
VestedCalc: nil,
|
||||||
|
BaseFee: types.NewInt(0),
|
||||||
|
}
|
||||||
|
vm, err := vm.NewVM(&vmopt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err)
|
return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err)
|
||||||
}
|
}
|
||||||
@ -443,6 +453,7 @@ func MakeGenesisBlock(ctx context.Context, bs bstore.Blockstore, sys vm.SyscallB
|
|||||||
Data: make([]byte, 32),
|
Data: make([]byte, 32),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
ParentBaseFee: abi.NewTokenAmount(build.InitialBaseFee),
|
||||||
}
|
}
|
||||||
|
|
||||||
sb, err := b.ToStorageBlock()
|
sb, err := b.ToStorageBlock()
|
||||||
|
@ -4,9 +4,10 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/filecoin-project/lotus/chain/state"
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/state"
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
@ -60,7 +61,17 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
|||||||
return big.Zero(), nil
|
return big.Zero(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
vm, err := vm.NewVM(sroot, 0, &fakeRand{}, cs.Blockstore(), mkFakedSigSyscalls(cs.VMSys()), vc)
|
vmopt := &vm.VMOpts{
|
||||||
|
StateBase: sroot,
|
||||||
|
Epoch: 0,
|
||||||
|
Rand: &fakeRand{},
|
||||||
|
Bstore: cs.Blockstore(),
|
||||||
|
Syscalls: mkFakedSigSyscalls(cs.VMSys()),
|
||||||
|
VestedCalc: vc,
|
||||||
|
BaseFee: types.NewInt(0),
|
||||||
|
}
|
||||||
|
|
||||||
|
vm, err := vm.NewVM(vmopt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err)
|
return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,6 @@ func doExecValue(ctx context.Context, vm *vm.VM, to, from address.Address, value
|
|||||||
Method: method,
|
Method: method,
|
||||||
Params: params,
|
Params: params,
|
||||||
GasLimit: 1_000_000_000_000_000,
|
GasLimit: 1_000_000_000_000_000,
|
||||||
GasPrice: types.NewInt(0),
|
|
||||||
Value: value,
|
Value: value,
|
||||||
Nonce: act.Nonce,
|
Nonce: act.Nonce,
|
||||||
})
|
})
|
||||||
|
@ -109,6 +109,12 @@ func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.Wal
|
|||||||
}
|
}
|
||||||
next.ParentWeight = pweight
|
next.ParentWeight = pweight
|
||||||
|
|
||||||
|
baseFee, err := sm.ChainStore().ComputeBaseFee(ctx, pts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("computing base fee: %w", err)
|
||||||
|
}
|
||||||
|
next.ParentBaseFee = baseFee
|
||||||
|
|
||||||
cst := cbor.NewCborStore(sm.ChainStore().Blockstore())
|
cst := cbor.NewCborStore(sm.ChainStore().Blockstore())
|
||||||
tree, err := state.LoadStateTree(cst, st)
|
tree, err := state.LoadStateTree(cst, st)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -126,17 +126,17 @@ func (ms *msgSet) add(m *types.SignedMessage) (bool, error) {
|
|||||||
if has {
|
if has {
|
||||||
if m.Cid() != exms.Cid() {
|
if m.Cid() != exms.Cid() {
|
||||||
// check if RBF passes
|
// check if RBF passes
|
||||||
minPrice := exms.Message.GasPrice
|
minPrice := exms.Message.GasPremium
|
||||||
minPrice = types.BigAdd(minPrice, types.BigDiv(types.BigMul(minPrice, rbfNum), rbfDenom))
|
minPrice = types.BigAdd(minPrice, types.BigDiv(types.BigMul(minPrice, rbfNum), rbfDenom))
|
||||||
minPrice = types.BigAdd(minPrice, types.NewInt(1))
|
minPrice = types.BigAdd(minPrice, types.NewInt(1))
|
||||||
if types.BigCmp(m.Message.GasPrice, minPrice) >= 0 {
|
if types.BigCmp(m.Message.GasPremium, minPrice) >= 0 {
|
||||||
log.Infow("add with RBF", "oldprice", exms.Message.GasPrice,
|
log.Infow("add with RBF", "oldpremium", exms.Message.GasPremium,
|
||||||
"newprice", m.Message.GasPrice, "addr", m.Message.From, "nonce", m.Message.Nonce)
|
"newpremium", m.Message.GasPremium, "addr", m.Message.From, "nonce", m.Message.Nonce)
|
||||||
} else {
|
} else {
|
||||||
log.Info("add with duplicate nonce")
|
log.Info("add with duplicate nonce")
|
||||||
return false, xerrors.Errorf("message from %s with nonce %d already in mpool,"+
|
return false, xerrors.Errorf("message from %s with nonce %d already in mpool,"+
|
||||||
" increase GasPrice to %s from %s to trigger replace by fee",
|
" increase GasPremium to %s from %s to trigger replace by fee",
|
||||||
m.Message.From, m.Message.Nonce, minPrice, m.Message.GasPrice)
|
m.Message.From, m.Message.Nonce, minPrice, m.Message.GasPremium)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -154,6 +154,7 @@ type Provider interface {
|
|||||||
MessagesForBlock(*types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error)
|
MessagesForBlock(*types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error)
|
||||||
MessagesForTipset(*types.TipSet) ([]types.ChainMsg, error)
|
MessagesForTipset(*types.TipSet) ([]types.ChainMsg, error)
|
||||||
LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error)
|
LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error)
|
||||||
|
ChainComputeBaseFee(ctx context.Context, ts *types.TipSet) (types.BigInt, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type mpoolProvider struct {
|
type mpoolProvider struct {
|
||||||
@ -162,7 +163,7 @@ type mpoolProvider struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewProvider(sm *stmgr.StateManager, ps *pubsub.PubSub) Provider {
|
func NewProvider(sm *stmgr.StateManager, ps *pubsub.PubSub) Provider {
|
||||||
return &mpoolProvider{sm, ps}
|
return &mpoolProvider{sm: sm, ps: ps}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mpp *mpoolProvider) SubscribeHeadChanges(cb func(rev, app []*types.TipSet) error) *types.TipSet {
|
func (mpp *mpoolProvider) SubscribeHeadChanges(cb func(rev, app []*types.TipSet) error) *types.TipSet {
|
||||||
@ -199,6 +200,14 @@ func (mpp *mpoolProvider) LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error)
|
|||||||
return mpp.sm.ChainStore().LoadTipSet(tsk)
|
return mpp.sm.ChainStore().LoadTipSet(tsk)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mpp *mpoolProvider) ChainComputeBaseFee(ctx context.Context, ts *types.TipSet) (types.BigInt, error) {
|
||||||
|
baseFee, err := mpp.sm.ChainStore().ComputeBaseFee(ctx, ts)
|
||||||
|
if err != nil {
|
||||||
|
return types.NewInt(0), xerrors.Errorf("computing base fee at %s: %w", ts, err)
|
||||||
|
}
|
||||||
|
return baseFee, nil
|
||||||
|
}
|
||||||
|
|
||||||
func New(api Provider, ds dtypes.MetadataDS, netName dtypes.NetworkName) (*MessagePool, error) {
|
func New(api Provider, ds dtypes.MetadataDS, netName dtypes.NetworkName) (*MessagePool, error) {
|
||||||
cache, _ := lru.New2Q(build.BlsSignatureCacheSize)
|
cache, _ := lru.New2Q(build.BlsSignatureCacheSize)
|
||||||
verifcache, _ := lru.New2Q(build.VerifSigCacheSize)
|
verifcache, _ := lru.New2Q(build.VerifSigCacheSize)
|
||||||
|
@ -87,7 +87,7 @@ func (tma *testMpoolAPI) PubSubPublish(string, []byte) error {
|
|||||||
func (tma *testMpoolAPI) StateGetActor(addr address.Address, ts *types.TipSet) (*types.Actor, error) {
|
func (tma *testMpoolAPI) StateGetActor(addr address.Address, ts *types.TipSet) (*types.Actor, error) {
|
||||||
balance, ok := tma.balance[addr]
|
balance, ok := tma.balance[addr]
|
||||||
if !ok {
|
if !ok {
|
||||||
balance = types.NewInt(90000000)
|
balance = types.NewInt(1000e6)
|
||||||
tma.balance[addr] = balance
|
tma.balance[addr] = balance
|
||||||
}
|
}
|
||||||
return &types.Actor{
|
return &types.Actor{
|
||||||
@ -140,6 +140,10 @@ func (tma *testMpoolAPI) LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error)
|
|||||||
return nil, fmt.Errorf("tipset not found")
|
return nil, fmt.Errorf("tipset not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (tma *testMpoolAPI) ChainComputeBaseFee(ctx context.Context, ts *types.TipSet) (types.BigInt, error) {
|
||||||
|
return types.NewInt(100), nil
|
||||||
|
}
|
||||||
|
|
||||||
func assertNonce(t *testing.T, mp *MessagePool, addr address.Address, val uint64) {
|
func assertNonce(t *testing.T, mp *MessagePool, addr address.Address, val uint64) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
n, err := mp.GetNonce(addr)
|
n, err := mp.GetNonce(addr)
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (mp *MessagePool) pruneExcessMessages() error {
|
func (mp *MessagePool) pruneExcessMessages() error {
|
||||||
@ -30,6 +31,11 @@ func (mp *MessagePool) pruneMessages(ctx context.Context, ts *types.TipSet) erro
|
|||||||
log.Infof("message pruning took %s", time.Since(start))
|
log.Infof("message pruning took %s", time.Since(start))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
baseFee, err := mp.api.ChainComputeBaseFee(ctx, ts)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("computing basefee: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
pending, _ := mp.getPendingMessages(ts, ts)
|
pending, _ := mp.getPendingMessages(ts, ts)
|
||||||
|
|
||||||
// Collect all messages to track which ones to remove and create chains for block inclusion
|
// Collect all messages to track which ones to remove and create chains for block inclusion
|
||||||
@ -39,7 +45,7 @@ func (mp *MessagePool) pruneMessages(ctx context.Context, ts *types.TipSet) erro
|
|||||||
for _, m := range mset {
|
for _, m := range mset {
|
||||||
pruneMsgs[m.Message.Cid()] = m
|
pruneMsgs[m.Message.Cid()] = m
|
||||||
}
|
}
|
||||||
actorChains := mp.createMessageChains(actor, mset, ts)
|
actorChains := mp.createMessageChains(actor, mset, baseFee, ts)
|
||||||
chains = append(chains, actorChains...)
|
chains = append(chains, actorChains...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,20 +30,21 @@ type msgChain struct {
|
|||||||
|
|
||||||
func (mp *MessagePool) SelectMessages(ts *types.TipSet) ([]*types.SignedMessage, error) {
|
func (mp *MessagePool) SelectMessages(ts *types.TipSet) ([]*types.SignedMessage, error) {
|
||||||
mp.curTsLk.Lock()
|
mp.curTsLk.Lock()
|
||||||
curTs := mp.curTs
|
defer mp.curTsLk.Unlock()
|
||||||
mp.curTsLk.Unlock()
|
|
||||||
|
|
||||||
mp.lk.Lock()
|
mp.lk.Lock()
|
||||||
defer mp.lk.Unlock()
|
defer mp.lk.Unlock()
|
||||||
|
|
||||||
return mp.selectMessages(curTs, ts)
|
return mp.selectMessages(mp.curTs, ts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mp *MessagePool) selectMessages(curTs, ts *types.TipSet) ([]*types.SignedMessage, error) {
|
func (mp *MessagePool) selectMessages(curTs, ts *types.TipSet) ([]*types.SignedMessage, error) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
defer func() {
|
|
||||||
log.Infof("message selection took %s", time.Since(start))
|
baseFee, err := mp.api.ChainComputeBaseFee(context.TODO(), ts)
|
||||||
}()
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("computing basefee: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
// 0. Load messages for the target tipset; if it is the same as the current tipset in the mpool
|
// 0. Load messages for the target tipset; if it is the same as the current tipset in the mpool
|
||||||
// then this is just the pending messages
|
// then this is just the pending messages
|
||||||
@ -51,11 +52,19 @@ func (mp *MessagePool) selectMessages(curTs, ts *types.TipSet) ([]*types.SignedM
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if len(pending) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// defer only here so if we have no pending messages we don't spam
|
||||||
|
defer func() {
|
||||||
|
log.Infof("message selection took %s", time.Since(start))
|
||||||
|
}()
|
||||||
|
|
||||||
// 1. Create a list of dependent message chains with maximal gas reward per limit consumed
|
// 1. Create a list of dependent message chains with maximal gas reward per limit consumed
|
||||||
var chains []*msgChain
|
var chains []*msgChain
|
||||||
for actor, mset := range pending {
|
for actor, mset := range pending {
|
||||||
next := mp.createMessageChains(actor, mset, ts)
|
next := mp.createMessageChains(actor, mset, baseFee, ts)
|
||||||
chains = append(chains, next...)
|
chains = append(chains, next...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,6 +72,13 @@ func (mp *MessagePool) selectMessages(curTs, ts *types.TipSet) ([]*types.SignedM
|
|||||||
sort.Slice(chains, func(i, j int) bool {
|
sort.Slice(chains, func(i, j int) bool {
|
||||||
return chains[i].Before(chains[j])
|
return chains[i].Before(chains[j])
|
||||||
})
|
})
|
||||||
|
if len(chains) != 0 && chains[0].gasPerf < 0 {
|
||||||
|
log.Warnw("all messages in mpool have negative has performance", "bestGasPerf", chains[0].gasPerf)
|
||||||
|
//for i, m := range chains[0].msgs {
|
||||||
|
//log.Warnf("msg %d %+v", i, m.Message)
|
||||||
|
//}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
// 3. Merge the head chains to produce the list of messages selected for inclusion, subject to
|
// 3. Merge the head chains to produce the list of messages selected for inclusion, subject to
|
||||||
// the block gas limit.
|
// the block gas limit.
|
||||||
@ -72,7 +88,7 @@ func (mp *MessagePool) selectMessages(curTs, ts *types.TipSet) ([]*types.SignedM
|
|||||||
last := len(chains)
|
last := len(chains)
|
||||||
for i, chain := range chains {
|
for i, chain := range chains {
|
||||||
// does it fit in the block?
|
// does it fit in the block?
|
||||||
if chain.gasLimit <= gasLimit {
|
if chain.gasLimit <= gasLimit && chain.gasPerf > 0 {
|
||||||
gasLimit -= chain.gasLimit
|
gasLimit -= chain.gasLimit
|
||||||
result = append(result, chain.msgs...)
|
result = append(result, chain.msgs...)
|
||||||
continue
|
continue
|
||||||
@ -92,7 +108,7 @@ func (mp *MessagePool) selectMessages(curTs, ts *types.TipSet) ([]*types.SignedM
|
|||||||
tailLoop:
|
tailLoop:
|
||||||
for gasLimit >= minGas && last < len(chains) {
|
for gasLimit >= minGas && last < len(chains) {
|
||||||
// trim
|
// trim
|
||||||
chains[last].Trim(gasLimit, mp, ts)
|
chains[last].Trim(gasLimit, mp, baseFee, ts)
|
||||||
|
|
||||||
// push down if it hasn't been invalidated
|
// push down if it hasn't been invalidated
|
||||||
if chains[last].valid {
|
if chains[last].valid {
|
||||||
@ -111,7 +127,7 @@ tailLoop:
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// does it fit in the bock?
|
// does it fit in the bock?
|
||||||
if chain.gasLimit <= gasLimit {
|
if chain.gasLimit <= gasLimit && chain.gasPerf > 0 {
|
||||||
gasLimit -= chain.gasLimit
|
gasLimit -= chain.gasLimit
|
||||||
result = append(result, chain.msgs...)
|
result = append(result, chain.msgs...)
|
||||||
continue
|
continue
|
||||||
@ -208,7 +224,7 @@ func (mp *MessagePool) getPendingMessages(curTs, ts *types.TipSet) (map[address.
|
|||||||
if dupNonce {
|
if dupNonce {
|
||||||
// duplicate nonce, selfishly keep the message with the highest GasPrice
|
// duplicate nonce, selfishly keep the message with the highest GasPrice
|
||||||
// if the gas prices are the same, keep the one with the highest GasLimit
|
// if the gas prices are the same, keep the one with the highest GasLimit
|
||||||
switch m.Message.GasPrice.Int.Cmp(other.Message.GasPrice.Int) {
|
switch m.Message.GasPremium.Int.Cmp(other.Message.GasPremium.Int) {
|
||||||
case 0:
|
case 0:
|
||||||
if m.Message.GasLimit > other.Message.GasLimit {
|
if m.Message.GasLimit > other.Message.GasLimit {
|
||||||
mset[m.Message.Nonce] = m
|
mset[m.Message.Nonce] = m
|
||||||
@ -232,20 +248,12 @@ func (mp *MessagePool) getPendingMessages(curTs, ts *types.TipSet) (map[address.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mp *MessagePool) getGasReward(msg *types.SignedMessage, ts *types.TipSet) *big.Int {
|
func (mp *MessagePool) getGasReward(msg *types.SignedMessage, baseFee types.BigInt, ts *types.TipSet) *big.Int {
|
||||||
al := func(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*types.Actor, error) {
|
gasReward := abig.Mul(msg.Message.GasPremium, types.NewInt(uint64(msg.Message.GasLimit)))
|
||||||
return mp.api.StateGetActor(addr, ts)
|
maxReward := types.BigSub(msg.Message.GasFeeCap, baseFee)
|
||||||
|
if types.BigCmp(maxReward, gasReward) < 0 {
|
||||||
|
gasReward = maxReward
|
||||||
}
|
}
|
||||||
gasUsed, err := gasguess.GuessGasUsed(context.TODO(), types.EmptyTSK, msg, al)
|
|
||||||
if err != nil {
|
|
||||||
gasUsed = int64(gasguess.MaxGas)
|
|
||||||
if gasUsed > msg.Message.GasLimit/2 {
|
|
||||||
gasUsed = msg.Message.GasLimit / 2
|
|
||||||
}
|
|
||||||
// if we start seeing this warning we may have a problem with spammers!
|
|
||||||
log.Warnf("Cannot guess gas usage for message: %s; using %d", err, gasUsed)
|
|
||||||
}
|
|
||||||
gasReward := abig.Mul(msg.Message.GasPrice, types.NewInt(uint64(gasUsed)))
|
|
||||||
return gasReward.Int
|
return gasReward.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,7 +266,7 @@ func (mp *MessagePool) getGasPerf(gasReward *big.Int, gasLimit int64) float64 {
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mp *MessagePool) createMessageChains(actor address.Address, mset map[uint64]*types.SignedMessage, ts *types.TipSet) []*msgChain {
|
func (mp *MessagePool) createMessageChains(actor address.Address, mset map[uint64]*types.SignedMessage, baseFee types.BigInt, ts *types.TipSet) []*msgChain {
|
||||||
// collect all messages
|
// collect all messages
|
||||||
msgs := make([]*types.SignedMessage, 0, len(mset))
|
msgs := make([]*types.SignedMessage, 0, len(mset))
|
||||||
for _, m := range mset {
|
for _, m := range mset {
|
||||||
@ -320,7 +328,7 @@ func (mp *MessagePool) createMessageChains(actor address.Address, mset map[uint6
|
|||||||
balance = new(big.Int).Sub(balance, value)
|
balance = new(big.Int).Sub(balance, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
gasReward := mp.getGasReward(m, ts)
|
gasReward := mp.getGasReward(m, baseFee, ts)
|
||||||
rewards = append(rewards, gasReward)
|
rewards = append(rewards, gasReward)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -417,11 +425,11 @@ func (mc *msgChain) Before(other *msgChain) bool {
|
|||||||
(mc.gasPerf == other.gasPerf && mc.gasReward.Cmp(other.gasReward) > 0)
|
(mc.gasPerf == other.gasPerf && mc.gasReward.Cmp(other.gasReward) > 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mc *msgChain) Trim(gasLimit int64, mp *MessagePool, ts *types.TipSet) {
|
func (mc *msgChain) Trim(gasLimit int64, mp *MessagePool, baseFee types.BigInt, ts *types.TipSet) {
|
||||||
i := len(mc.msgs) - 1
|
i := len(mc.msgs) - 1
|
||||||
for i >= 0 && mc.gasLimit > gasLimit {
|
for i >= 0 && mc.gasLimit > gasLimit {
|
||||||
gasLimit -= mc.msgs[i].Message.GasLimit
|
gasLimit -= mc.msgs[i].Message.GasLimit
|
||||||
gasReward := mp.getGasReward(mc.msgs[i], ts)
|
gasReward := mp.getGasReward(mc.msgs[i], baseFee, ts)
|
||||||
mc.gasReward = new(big.Int).Sub(mc.gasReward, gasReward)
|
mc.gasReward = new(big.Int).Sub(mc.gasReward, gasReward)
|
||||||
mc.gasLimit -= mc.msgs[i].Message.GasLimit
|
mc.gasLimit -= mc.msgs[i].Message.GasLimit
|
||||||
if mc.gasLimit > 0 {
|
if mc.gasLimit > 0 {
|
||||||
|
@ -20,13 +20,14 @@ import (
|
|||||||
|
|
||||||
func makeTestMessage(w *wallet.Wallet, from, to address.Address, nonce uint64, gasLimit int64, gasPrice uint64) *types.SignedMessage {
|
func makeTestMessage(w *wallet.Wallet, from, to address.Address, nonce uint64, gasLimit int64, gasPrice uint64) *types.SignedMessage {
|
||||||
msg := &types.Message{
|
msg := &types.Message{
|
||||||
From: from,
|
From: from,
|
||||||
To: to,
|
To: to,
|
||||||
Method: 2,
|
Method: 2,
|
||||||
Value: types.FromFil(0),
|
Value: types.FromFil(0),
|
||||||
Nonce: nonce,
|
Nonce: nonce,
|
||||||
GasLimit: gasLimit,
|
GasLimit: gasLimit,
|
||||||
GasPrice: types.NewInt(gasPrice),
|
GasFeeCap: types.NewInt(100 + gasPrice),
|
||||||
|
GasPremium: types.NewInt(gasPrice),
|
||||||
}
|
}
|
||||||
sig, err := w.Sign(context.TODO(), from, msg.Cid().Bytes())
|
sig, err := w.Sign(context.TODO(), from, msg.Cid().Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -89,8 +90,9 @@ func TestMessageChains(t *testing.T) {
|
|||||||
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1))
|
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1))
|
||||||
mset[uint64(i)] = m
|
mset[uint64(i)] = m
|
||||||
}
|
}
|
||||||
|
baseFee := types.NewInt(0)
|
||||||
|
|
||||||
chains := mp.createMessageChains(a1, mset, ts)
|
chains := mp.createMessageChains(a1, mset, baseFee, ts)
|
||||||
if len(chains) != 1 {
|
if len(chains) != 1 {
|
||||||
t.Fatal("expected a single chain")
|
t.Fatal("expected a single chain")
|
||||||
}
|
}
|
||||||
@ -111,7 +113,7 @@ func TestMessageChains(t *testing.T) {
|
|||||||
mset[uint64(i)] = m
|
mset[uint64(i)] = m
|
||||||
}
|
}
|
||||||
|
|
||||||
chains = mp.createMessageChains(a1, mset, ts)
|
chains = mp.createMessageChains(a1, mset, baseFee, ts)
|
||||||
if len(chains) != 10 {
|
if len(chains) != 10 {
|
||||||
t.Fatal("expected 10 chains")
|
t.Fatal("expected 10 chains")
|
||||||
}
|
}
|
||||||
@ -135,7 +137,7 @@ func TestMessageChains(t *testing.T) {
|
|||||||
mset[uint64(i)] = m
|
mset[uint64(i)] = m
|
||||||
}
|
}
|
||||||
|
|
||||||
chains = mp.createMessageChains(a1, mset, ts)
|
chains = mp.createMessageChains(a1, mset, baseFee, ts)
|
||||||
if len(chains) != 2 {
|
if len(chains) != 2 {
|
||||||
t.Fatal("expected 1 chain")
|
t.Fatal("expected 1 chain")
|
||||||
}
|
}
|
||||||
@ -166,7 +168,7 @@ func TestMessageChains(t *testing.T) {
|
|||||||
mset[uint64(i)] = m
|
mset[uint64(i)] = m
|
||||||
}
|
}
|
||||||
|
|
||||||
chains = mp.createMessageChains(a1, mset, ts)
|
chains = mp.createMessageChains(a1, mset, baseFee, ts)
|
||||||
if len(chains) != 4 {
|
if len(chains) != 4 {
|
||||||
t.Fatal("expected 4 chains")
|
t.Fatal("expected 4 chains")
|
||||||
}
|
}
|
||||||
@ -199,7 +201,7 @@ func TestMessageChains(t *testing.T) {
|
|||||||
mset[uint64(i)] = m
|
mset[uint64(i)] = m
|
||||||
}
|
}
|
||||||
|
|
||||||
chains = mp.createMessageChains(a1, mset, ts)
|
chains = mp.createMessageChains(a1, mset, baseFee, ts)
|
||||||
if len(chains) != 1 {
|
if len(chains) != 1 {
|
||||||
t.Fatal("expected a single chain")
|
t.Fatal("expected a single chain")
|
||||||
}
|
}
|
||||||
@ -225,7 +227,7 @@ func TestMessageChains(t *testing.T) {
|
|||||||
mset[uint64(i)] = m
|
mset[uint64(i)] = m
|
||||||
}
|
}
|
||||||
|
|
||||||
chains = mp.createMessageChains(a1, mset, ts)
|
chains = mp.createMessageChains(a1, mset, baseFee, ts)
|
||||||
if len(chains) != 1 {
|
if len(chains) != 1 {
|
||||||
t.Fatal("expected a single chain")
|
t.Fatal("expected a single chain")
|
||||||
}
|
}
|
||||||
@ -248,7 +250,7 @@ func TestMessageChains(t *testing.T) {
|
|||||||
mset[uint64(i)] = makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1))
|
mset[uint64(i)] = makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1))
|
||||||
}
|
}
|
||||||
|
|
||||||
chains = mp.createMessageChains(a1, mset, ts)
|
chains = mp.createMessageChains(a1, mset, baseFee, ts)
|
||||||
if len(chains) != 1 {
|
if len(chains) != 1 {
|
||||||
t.Fatal("expected a single chain")
|
t.Fatal("expected a single chain")
|
||||||
}
|
}
|
||||||
@ -262,16 +264,16 @@ func TestMessageChains(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// test5: insufficient balance for all messages
|
// test5: insufficient balance for all messages
|
||||||
tma.setBalanceRaw(a1, types.NewInt(uint64(3*gasLimit+1)))
|
tma.setBalanceRaw(a1, types.NewInt(uint64((300)*gasLimit+1)))
|
||||||
|
|
||||||
mset = make(map[uint64]*types.SignedMessage)
|
mset = make(map[uint64]*types.SignedMessage)
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
mset[uint64(i)] = makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1))
|
mset[uint64(i)] = makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1))
|
||||||
}
|
}
|
||||||
|
|
||||||
chains = mp.createMessageChains(a1, mset, ts)
|
chains = mp.createMessageChains(a1, mset, baseFee, ts)
|
||||||
if len(chains) != 1 {
|
if len(chains) != 1 {
|
||||||
t.Fatal("expected a single chain")
|
t.Fatalf("expected a single chain: got %d", len(chains))
|
||||||
}
|
}
|
||||||
if len(chains[0].msgs) != 2 {
|
if len(chains[0].msgs) != 2 {
|
||||||
t.Fatalf("expected %d message in the chain but got %d", 2, len(chains[0].msgs))
|
t.Fatalf("expected %d message in the chain but got %d", 2, len(chains[0].msgs))
|
||||||
|
@ -22,7 +22,17 @@ func (sm *StateManager) CallRaw(ctx context.Context, msg *types.Message, bstate
|
|||||||
ctx, span := trace.StartSpan(ctx, "statemanager.CallRaw")
|
ctx, span := trace.StartSpan(ctx, "statemanager.CallRaw")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
vmi, err := vm.NewVM(bstate, bheight, r, sm.cs.Blockstore(), sm.cs.VMSys(), sm.GetVestedFunds)
|
vmopt := &vm.VMOpts{
|
||||||
|
StateBase: bstate,
|
||||||
|
Epoch: bheight,
|
||||||
|
Rand: r,
|
||||||
|
Bstore: sm.cs.Blockstore(),
|
||||||
|
Syscalls: sm.cs.VMSys(),
|
||||||
|
VestedCalc: sm.GetVestedFunds,
|
||||||
|
BaseFee: types.NewInt(0),
|
||||||
|
}
|
||||||
|
|
||||||
|
vmi, err := vm.NewVM(vmopt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("failed to set up vm: %w", err)
|
return nil, xerrors.Errorf("failed to set up vm: %w", err)
|
||||||
}
|
}
|
||||||
@ -30,9 +40,13 @@ func (sm *StateManager) CallRaw(ctx context.Context, msg *types.Message, bstate
|
|||||||
if msg.GasLimit == 0 {
|
if msg.GasLimit == 0 {
|
||||||
msg.GasLimit = build.BlockGasLimit
|
msg.GasLimit = build.BlockGasLimit
|
||||||
}
|
}
|
||||||
if msg.GasPrice == types.EmptyInt {
|
if msg.GasFeeCap == types.EmptyInt {
|
||||||
msg.GasPrice = types.NewInt(0)
|
msg.GasFeeCap = types.NewInt(0)
|
||||||
}
|
}
|
||||||
|
if msg.GasPremium == types.EmptyInt {
|
||||||
|
msg.GasPremium = types.NewInt(0)
|
||||||
|
}
|
||||||
|
|
||||||
if msg.Value == types.EmptyInt {
|
if msg.Value == types.EmptyInt {
|
||||||
msg.Value = types.NewInt(0)
|
msg.Value = types.NewInt(0)
|
||||||
}
|
}
|
||||||
@ -40,7 +54,7 @@ func (sm *StateManager) CallRaw(ctx context.Context, msg *types.Message, bstate
|
|||||||
if span.IsRecordingEvents() {
|
if span.IsRecordingEvents() {
|
||||||
span.AddAttributes(
|
span.AddAttributes(
|
||||||
trace.Int64Attribute("gas_limit", msg.GasLimit),
|
trace.Int64Attribute("gas_limit", msg.GasLimit),
|
||||||
trace.Int64Attribute("gas_price", int64(msg.GasPrice.Uint64())),
|
trace.StringAttribute("gas_feecap", msg.GasFeeCap.String()),
|
||||||
trace.StringAttribute("value", msg.Value.String()),
|
trace.StringAttribute("value", msg.Value.String()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -101,12 +115,21 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri
|
|||||||
if span.IsRecordingEvents() {
|
if span.IsRecordingEvents() {
|
||||||
span.AddAttributes(
|
span.AddAttributes(
|
||||||
trace.Int64Attribute("gas_limit", msg.GasLimit),
|
trace.Int64Attribute("gas_limit", msg.GasLimit),
|
||||||
trace.Int64Attribute("gas_price", int64(msg.GasPrice.Uint64())),
|
trace.StringAttribute("gas_feecap", msg.GasFeeCap.String()),
|
||||||
trace.StringAttribute("value", msg.Value.String()),
|
trace.StringAttribute("value", msg.Value.String()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
vmi, err := vm.NewVM(state, ts.Height(), r, sm.cs.Blockstore(), sm.cs.VMSys(), sm.GetVestedFunds)
|
vmopt := &vm.VMOpts{
|
||||||
|
StateBase: state,
|
||||||
|
Epoch: ts.Height(),
|
||||||
|
Rand: r,
|
||||||
|
Bstore: sm.cs.Blockstore(),
|
||||||
|
Syscalls: sm.cs.VMSys(),
|
||||||
|
VestedCalc: sm.GetVestedFunds,
|
||||||
|
BaseFee: ts.Blocks()[0].ParentBaseFee,
|
||||||
|
}
|
||||||
|
vmi, err := vm.NewVM(vmopt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("failed to set up vm: %w", err)
|
return nil, xerrors.Errorf("failed to set up vm: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -25,11 +25,9 @@ import (
|
|||||||
. "github.com/filecoin-project/lotus/chain/stmgr"
|
. "github.com/filecoin-project/lotus/chain/stmgr"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/chain/vm"
|
"github.com/filecoin-project/lotus/chain/vm"
|
||||||
"github.com/filecoin-project/lotus/lib/blockstore"
|
|
||||||
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
|
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
|
||||||
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
|
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
logging "github.com/ipfs/go-log"
|
logging "github.com/ipfs/go-log"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
@ -151,8 +149,8 @@ func TestForkHeightTriggers(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inv.Register(builtin.PaymentChannelActorCodeID, &testActor{}, &testActorState{})
|
inv.Register(builtin.PaymentChannelActorCodeID, &testActor{}, &testActorState{})
|
||||||
sm.SetVMConstructor(func(c cid.Cid, h abi.ChainEpoch, r vm.Rand, b blockstore.Blockstore, s vm.SyscallBuilder, vc vm.VestedCalculator) (*vm.VM, error) {
|
sm.SetVMConstructor(func(vmopt *vm.VMOpts) (*vm.VM, error) {
|
||||||
nvm, err := vm.NewVM(c, h, r, b, s, sm.GetVestedFunds)
|
nvm, err := vm.NewVM(vmopt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -175,7 +173,6 @@ func TestForkHeightTriggers(t *testing.T) {
|
|||||||
Method: builtin.MethodsInit.Exec,
|
Method: builtin.MethodsInit.Exec,
|
||||||
Params: enc,
|
Params: enc,
|
||||||
GasLimit: types.TestGasLimit,
|
GasLimit: types.TestGasLimit,
|
||||||
GasPrice: types.NewInt(0),
|
|
||||||
}
|
}
|
||||||
sig, err := cg.Wallet().Sign(ctx, cg.Banker(), m.Cid().Bytes())
|
sig, err := cg.Wallet().Sign(ctx, cg.Banker(), m.Cid().Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -202,7 +199,6 @@ func TestForkHeightTriggers(t *testing.T) {
|
|||||||
Params: nil,
|
Params: nil,
|
||||||
Nonce: nonce,
|
Nonce: nonce,
|
||||||
GasLimit: types.TestGasLimit,
|
GasLimit: types.TestGasLimit,
|
||||||
GasPrice: types.NewInt(0),
|
|
||||||
}
|
}
|
||||||
nonce++
|
nonce++
|
||||||
|
|
||||||
|
@ -3,9 +3,10 @@ package stmgr
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
@ -14,7 +15,6 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/chain/store"
|
"github.com/filecoin-project/lotus/chain/store"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/chain/vm"
|
"github.com/filecoin-project/lotus/chain/vm"
|
||||||
"github.com/filecoin-project/lotus/lib/blockstore"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
||||||
@ -41,7 +41,7 @@ type StateManager struct {
|
|||||||
compWait map[string]chan struct{}
|
compWait map[string]chan struct{}
|
||||||
stlk sync.Mutex
|
stlk sync.Mutex
|
||||||
genesisMsigLk sync.Mutex
|
genesisMsigLk sync.Mutex
|
||||||
newVM func(cid.Cid, abi.ChainEpoch, vm.Rand, blockstore.Blockstore, vm.SyscallBuilder, vm.VestedCalculator) (*vm.VM, error)
|
newVM func(*vm.VMOpts) (*vm.VM, error)
|
||||||
genesisMsigs []multisig.State
|
genesisMsigs []multisig.State
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,8 +150,19 @@ type BlockMessages struct {
|
|||||||
|
|
||||||
type ExecCallback func(cid.Cid, *types.Message, *vm.ApplyRet) error
|
type ExecCallback func(cid.Cid, *types.Message, *vm.ApplyRet) error
|
||||||
|
|
||||||
func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEpoch, pstate cid.Cid, bms []BlockMessages, epoch abi.ChainEpoch, r vm.Rand, cb ExecCallback) (cid.Cid, cid.Cid, error) {
|
func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEpoch, pstate cid.Cid, bms []BlockMessages, epoch abi.ChainEpoch, r vm.Rand, cb ExecCallback, baseFee abi.TokenAmount) (cid.Cid, cid.Cid, error) {
|
||||||
vmi, err := sm.newVM(pstate, epoch, r, sm.cs.Blockstore(), sm.cs.VMSys(), sm.GetVestedFunds)
|
|
||||||
|
vmopt := &vm.VMOpts{
|
||||||
|
StateBase: pstate,
|
||||||
|
Epoch: epoch,
|
||||||
|
Rand: r,
|
||||||
|
Bstore: sm.cs.Blockstore(),
|
||||||
|
Syscalls: sm.cs.VMSys(),
|
||||||
|
VestedCalc: sm.GetVestedFunds,
|
||||||
|
BaseFee: baseFee,
|
||||||
|
}
|
||||||
|
|
||||||
|
vmi, err := sm.newVM(vmopt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, cid.Undef, xerrors.Errorf("instantiating VM failed: %w", err)
|
return cid.Undef, cid.Undef, xerrors.Errorf("instantiating VM failed: %w", err)
|
||||||
}
|
}
|
||||||
@ -164,14 +175,15 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
|
|||||||
}
|
}
|
||||||
|
|
||||||
cronMsg := &types.Message{
|
cronMsg := &types.Message{
|
||||||
To: builtin.CronActorAddr,
|
To: builtin.CronActorAddr,
|
||||||
From: builtin.SystemActorAddr,
|
From: builtin.SystemActorAddr,
|
||||||
Nonce: ca.Nonce,
|
Nonce: ca.Nonce,
|
||||||
Value: types.NewInt(0),
|
Value: types.NewInt(0),
|
||||||
GasPrice: types.NewInt(0),
|
GasFeeCap: types.NewInt(0),
|
||||||
GasLimit: build.BlockGasLimit * 10000, // Make super sure this is never too little
|
GasPremium: types.NewInt(0),
|
||||||
Method: builtin.MethodsCron.EpochTick,
|
GasLimit: build.BlockGasLimit * 10000, // Make super sure this is never too little
|
||||||
Params: nil,
|
Method: builtin.MethodsCron.EpochTick,
|
||||||
|
Params: nil,
|
||||||
}
|
}
|
||||||
ret, err := vmi.ApplyImplicitMessage(ctx, cronMsg)
|
ret, err := vmi.ApplyImplicitMessage(ctx, cronMsg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -223,7 +235,7 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
|
|||||||
}
|
}
|
||||||
|
|
||||||
receipts = append(receipts, &r.MessageReceipt)
|
receipts = append(receipts, &r.MessageReceipt)
|
||||||
gasReward = big.Add(gasReward, big.Mul(m.GasPrice, big.NewInt(r.GasUsed)))
|
gasReward = big.Add(gasReward, r.MinerTip)
|
||||||
penalty = big.Add(penalty, r.Penalty)
|
penalty = big.Add(penalty, r.Penalty)
|
||||||
|
|
||||||
if cb != nil {
|
if cb != nil {
|
||||||
@ -251,14 +263,15 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
|
|||||||
}
|
}
|
||||||
|
|
||||||
rwMsg := &types.Message{
|
rwMsg := &types.Message{
|
||||||
From: builtin.SystemActorAddr,
|
From: builtin.SystemActorAddr,
|
||||||
To: builtin.RewardActorAddr,
|
To: builtin.RewardActorAddr,
|
||||||
Nonce: sysAct.Nonce,
|
Nonce: sysAct.Nonce,
|
||||||
Value: types.NewInt(0),
|
Value: types.NewInt(0),
|
||||||
GasPrice: types.NewInt(0),
|
GasFeeCap: types.NewInt(0),
|
||||||
GasLimit: 1 << 30,
|
GasPremium: types.NewInt(0),
|
||||||
Method: builtin.MethodsReward.AwardBlockReward,
|
GasLimit: 1 << 30,
|
||||||
Params: params,
|
Method: builtin.MethodsReward.AwardBlockReward,
|
||||||
|
Params: params,
|
||||||
}
|
}
|
||||||
ret, err := vmi.ApplyImplicitMessage(ctx, rwMsg)
|
ret, err := vmi.ApplyImplicitMessage(ctx, rwMsg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -354,8 +367,9 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, blks []*types.Bl
|
|||||||
|
|
||||||
blkmsgs = append(blkmsgs, bm)
|
blkmsgs = append(blkmsgs, bm)
|
||||||
}
|
}
|
||||||
|
baseFee := blks[0].ParentBaseFee
|
||||||
|
|
||||||
return sm.ApplyBlocks(ctx, parentEpoch, pstate, blkmsgs, blks[0].Height, r, cb)
|
return sm.ApplyBlocks(ctx, parentEpoch, pstate, blkmsgs, blks[0].Height, r, cb, baseFee)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *StateManager) parentState(ts *types.TipSet) cid.Cid {
|
func (sm *StateManager) parentState(ts *types.TipSet) cid.Cid {
|
||||||
@ -764,7 +778,7 @@ func (sm *StateManager) ValidateChain(ctx context.Context, ts *types.TipSet) err
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *StateManager) SetVMConstructor(nvm func(cid.Cid, abi.ChainEpoch, vm.Rand, blockstore.Blockstore, vm.SyscallBuilder, vm.VestedCalculator) (*vm.VM, error)) {
|
func (sm *StateManager) SetVMConstructor(nvm func(*vm.VMOpts) (*vm.VM, error)) {
|
||||||
sm.newVM = nvm
|
sm.newVM = nvm
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,7 +440,16 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch,
|
|||||||
}
|
}
|
||||||
|
|
||||||
r := store.NewChainRand(sm.cs, ts.Cids(), height)
|
r := store.NewChainRand(sm.cs, ts.Cids(), height)
|
||||||
vmi, err := vm.NewVM(base, height, r, sm.cs.Blockstore(), sm.cs.VMSys(), sm.GetVestedFunds)
|
vmopt := &vm.VMOpts{
|
||||||
|
StateBase: base,
|
||||||
|
Epoch: height,
|
||||||
|
Rand: r,
|
||||||
|
Bstore: sm.cs.Blockstore(),
|
||||||
|
Syscalls: sm.cs.VMSys(),
|
||||||
|
VestedCalc: sm.GetVestedFunds,
|
||||||
|
BaseFee: ts.Blocks()[0].ParentBaseFee,
|
||||||
|
}
|
||||||
|
vmi, err := vm.NewVM(vmopt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, nil, err
|
return cid.Undef, nil, err
|
||||||
}
|
}
|
||||||
@ -595,7 +604,16 @@ func (sm *StateManager) CirculatingSupply(ctx context.Context, ts *types.TipSet)
|
|||||||
}
|
}
|
||||||
|
|
||||||
r := store.NewChainRand(sm.cs, ts.Cids(), ts.Height())
|
r := store.NewChainRand(sm.cs, ts.Cids(), ts.Height())
|
||||||
vmi, err := vm.NewVM(st, ts.Height(), r, sm.cs.Blockstore(), sm.cs.VMSys(), sm.GetVestedFunds)
|
vmopt := &vm.VMOpts{
|
||||||
|
StateBase: st,
|
||||||
|
Epoch: ts.Height(),
|
||||||
|
Rand: r,
|
||||||
|
Bstore: sm.cs.Blockstore(),
|
||||||
|
Syscalls: sm.cs.VMSys(),
|
||||||
|
VestedCalc: sm.GetVestedFunds,
|
||||||
|
BaseFee: ts.Blocks()[0].ParentBaseFee,
|
||||||
|
}
|
||||||
|
vmi, err := vm.NewVM(vmopt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return big.Zero(), err
|
return big.Zero(), err
|
||||||
}
|
}
|
||||||
|
45
chain/store/basefee.go
Normal file
45
chain/store/basefee.go
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package store
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/build"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
)
|
||||||
|
|
||||||
|
func computeNextBaseFee(baseFee types.BigInt, gasLimitUsed int64, noOfBlocks int) types.BigInt {
|
||||||
|
delta := gasLimitUsed/int64(noOfBlocks) - build.BlockGasTarget
|
||||||
|
|
||||||
|
change := big.Mul(baseFee, big.NewInt(delta))
|
||||||
|
change = big.Div(change, big.NewInt(build.BlockGasTarget))
|
||||||
|
change = big.Div(change, big.NewInt(build.BaseFeeMaxChangeDenom))
|
||||||
|
|
||||||
|
nextBaseFee := big.Add(baseFee, change)
|
||||||
|
if big.Cmp(nextBaseFee, big.NewInt(build.MinimumBaseFee)) < 0 {
|
||||||
|
nextBaseFee = big.NewInt(build.MinimumBaseFee)
|
||||||
|
}
|
||||||
|
return nextBaseFee
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cs *ChainStore) ComputeBaseFee(ctx context.Context, ts *types.TipSet) (abi.TokenAmount, error) {
|
||||||
|
zero := abi.NewTokenAmount(0)
|
||||||
|
totalLimit := int64(0)
|
||||||
|
for _, b := range ts.Blocks() {
|
||||||
|
msg1, msg2, err := cs.MessagesForBlock(b)
|
||||||
|
if err != nil {
|
||||||
|
return zero, xerrors.Errorf("error getting messages for: %s: %w", b.Cid(), err)
|
||||||
|
}
|
||||||
|
for _, m := range msg1 {
|
||||||
|
totalLimit += m.GasLimit
|
||||||
|
}
|
||||||
|
for _, m := range msg2 {
|
||||||
|
totalLimit += m.Message.GasLimit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parentBaseFee := ts.Blocks()[0].ParentBaseFee
|
||||||
|
|
||||||
|
return computeNextBaseFee(parentBaseFee, totalLimit, len(ts.Blocks())), nil
|
||||||
|
}
|
34
chain/store/basefee_test.go
Normal file
34
chain/store/basefee_test.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package store
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/build"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBaseFee(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
basefee uint64
|
||||||
|
limitUsed int64
|
||||||
|
noOfBlocks int
|
||||||
|
output uint64
|
||||||
|
}{
|
||||||
|
{100e6, 0, 1, 87.5e6},
|
||||||
|
{100e6, 0, 5, 87.5e6},
|
||||||
|
{100e6, build.BlockGasTarget, 1, 100e6},
|
||||||
|
{100e6, build.BlockGasTarget * 2, 2, 100e6},
|
||||||
|
{100e6, build.BlockGasLimit * 2, 2, 112.5e6},
|
||||||
|
{100e6, build.BlockGasLimit * 1.5, 2, 106.25e6},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
test := test
|
||||||
|
t.Run(fmt.Sprintf("%v", test), func(t *testing.T) {
|
||||||
|
output := computeNextBaseFee(types.NewInt(test.basefee), test.limitUsed, test.noOfBlocks)
|
||||||
|
assert.Equal(t, fmt.Sprintf("%d", test.output), output.String())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -22,7 +22,7 @@ func (cs *ChainStore) Weight(ctx context.Context, ts *types.TipSet) (types.BigIn
|
|||||||
}
|
}
|
||||||
// >>> w[r] <<< + wFunction(totalPowerAtTipset(ts)) * 2^8 + (wFunction(totalPowerAtTipset(ts)) * sum(ts.blocks[].ElectionProof.WinCount) * wRatio_num * 2^8) / (e * wRatio_den)
|
// >>> w[r] <<< + wFunction(totalPowerAtTipset(ts)) * 2^8 + (wFunction(totalPowerAtTipset(ts)) * sum(ts.blocks[].ElectionProof.WinCount) * wRatio_num * 2^8) / (e * wRatio_den)
|
||||||
|
|
||||||
var out = new(big.Int).Set(ts.Blocks()[0].ParentWeight.Int)
|
var out = new(big.Int).Set(ts.ParentWeight().Int)
|
||||||
|
|
||||||
// >>> wFunction(totalPowerAtTipset(ts)) * 2^8 <<< + (wFunction(totalPowerAtTipset(ts)) * sum(ts.blocks[].ElectionProof.WinCount) * wRatio_num * 2^8) / (e * wRatio_den)
|
// >>> wFunction(totalPowerAtTipset(ts)) * 2^8 <<< + (wFunction(totalPowerAtTipset(ts)) * sum(ts.blocks[].ElectionProof.WinCount) * wRatio_num * 2^8) / (e * wRatio_den)
|
||||||
|
|
||||||
|
@ -199,8 +199,8 @@ func (syncer *Syncer) InformNewHead(from peer.ID, fts *store.FullTipSet) bool {
|
|||||||
|
|
||||||
syncer.Bsync.AddPeer(from)
|
syncer.Bsync.AddPeer(from)
|
||||||
|
|
||||||
bestPweight := syncer.store.GetHeaviestTipSet().Blocks()[0].ParentWeight
|
bestPweight := syncer.store.GetHeaviestTipSet().ParentWeight()
|
||||||
targetWeight := fts.TipSet().Blocks()[0].ParentWeight
|
targetWeight := fts.TipSet().ParentWeight()
|
||||||
if targetWeight.LessThan(bestPweight) {
|
if targetWeight.LessThan(bestPweight) {
|
||||||
var miners []string
|
var miners []string
|
||||||
for _, blk := range fts.TipSet().Blocks() {
|
for _, blk := range fts.TipSet().Blocks() {
|
||||||
@ -671,8 +671,6 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (er
|
|||||||
return xerrors.Errorf("failed to get latest beacon entry: %w", err)
|
return xerrors.Errorf("failed to get latest beacon entry: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
//nulls := h.Height - (baseTs.Height() + 1)
|
|
||||||
|
|
||||||
// fast checks first
|
// fast checks first
|
||||||
nulls := h.Height - (baseTs.Height() + 1)
|
nulls := h.Height - (baseTs.Height() + 1)
|
||||||
if tgtTs := baseTs.MinTimestamp() + build.BlockDelaySecs*uint64(nulls+1); h.Timestamp != tgtTs {
|
if tgtTs := baseTs.MinTimestamp() + build.BlockDelaySecs*uint64(nulls+1); h.Timestamp != tgtTs {
|
||||||
@ -701,6 +699,27 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (er
|
|||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
baseFeeCheck := async.Err(func() error {
|
||||||
|
baseFee, err := syncer.store.ComputeBaseFee(ctx, baseTs)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("computing base fee: %w", err)
|
||||||
|
}
|
||||||
|
if types.BigCmp(baseFee, b.Header.ParentBaseFee) != 0 {
|
||||||
|
return xerrors.Errorf("base fee doesn't match: %s (header) != %s (computed)",
|
||||||
|
b.Header.ParentBaseFee, baseFee)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
pweight, err := syncer.store.Weight(ctx, baseTs)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("getting parent weight: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if types.BigCmp(pweight, b.Header.ParentWeight) != 0 {
|
||||||
|
return xerrors.Errorf("parrent weight different: %s (header) != %s (computed)",
|
||||||
|
b.Header.ParentWeight, pweight)
|
||||||
|
}
|
||||||
|
|
||||||
// Stuff that needs stateroot / worker address
|
// Stuff that needs stateroot / worker address
|
||||||
stateroot, precp, err := syncer.sm.TipSetState(ctx, baseTs)
|
stateroot, precp, err := syncer.sm.TipSetState(ctx, baseTs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -843,6 +862,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (er
|
|||||||
wproofCheck,
|
wproofCheck,
|
||||||
winnerCheck,
|
winnerCheck,
|
||||||
msgsCheck,
|
msgsCheck,
|
||||||
|
baseFeeCheck,
|
||||||
}
|
}
|
||||||
|
|
||||||
var merr error
|
var merr error
|
||||||
@ -994,7 +1014,6 @@ func (syncer *Syncer) checkBlockMessages(ctx context.Context, b *types.FullBlock
|
|||||||
return xerrors.Errorf("failed to get actor: %w", err)
|
return xerrors.Errorf("failed to get actor: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// redundant check
|
|
||||||
if !act.IsAccountActor() {
|
if !act.IsAccountActor() {
|
||||||
return xerrors.New("Sender must be an account actor")
|
return xerrors.New("Sender must be an account actor")
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,9 @@ type BlockHeader struct {
|
|||||||
|
|
||||||
ForkSignaling uint64 // 14
|
ForkSignaling uint64 // 14
|
||||||
|
|
||||||
|
// ParentBaseFee is the base fee after executing parent tipset
|
||||||
|
ParentBaseFee abi.TokenAmount // 15
|
||||||
|
|
||||||
// internal
|
// internal
|
||||||
validated bool // true if the signature has been validated
|
validated bool // true if the signature has been validated
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ func testBlockHeader(t testing.TB) *BlockHeader {
|
|||||||
Height: 85919298723,
|
Height: 85919298723,
|
||||||
ParentStateRoot: c,
|
ParentStateRoot: c,
|
||||||
BlockSig: &crypto.Signature{Type: crypto.SigTypeBLS, Data: []byte("boo! im a signature")},
|
BlockSig: &crypto.Signature{Type: crypto.SigTypeBLS, Data: []byte("boo! im a signature")},
|
||||||
|
ParentBaseFee: NewInt(3432432843291),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +108,8 @@ func TestInteropBH(t *testing.T) {
|
|||||||
Type: crypto.SigTypeBLS,
|
Type: crypto.SigTypeBLS,
|
||||||
Data: []byte{0x3},
|
Data: []byte{0x3},
|
||||||
},
|
},
|
||||||
BLSAggregate: &crypto.Signature{},
|
BLSAggregate: &crypto.Signature{},
|
||||||
|
ParentBaseFee: NewInt(1000000000),
|
||||||
}
|
}
|
||||||
|
|
||||||
bhsb, err := bh.SigningBytes()
|
bhsb, err := bh.SigningBytes()
|
||||||
@ -116,7 +118,7 @@ func TestInteropBH(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
gfc := "8f5501d04cb15021bf6bd003073d79e2238d4e61f1ad2281430102038200420a0b818205410c818200410781d82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619cc430003e802d82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619ccd82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619ccd82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619cc410001f603"
|
gfc := "905501d04cb15021bf6bd003073d79e2238d4e61f1ad2281430102038200420a0b818205410c818200410781d82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619cc430003e802d82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619ccd82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619ccd82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619cc410001f60345003b9aca00"
|
||||||
require.Equal(t, gfc, hex.EncodeToString(bhsb))
|
require.Equal(t, gfc, hex.EncodeToString(bhsb))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,14 +9,14 @@ import (
|
|||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||||
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
|
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
|
||||||
"github.com/ipfs/go-cid"
|
cid "github.com/ipfs/go-cid"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
xerrors "golang.org/x/xerrors"
|
xerrors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = xerrors.Errorf
|
var _ = xerrors.Errorf
|
||||||
|
|
||||||
var lengthBufBlockHeader = []byte{143}
|
var lengthBufBlockHeader = []byte{144}
|
||||||
|
|
||||||
func (t *BlockHeader) MarshalCBOR(w io.Writer) error {
|
func (t *BlockHeader) MarshalCBOR(w io.Writer) error {
|
||||||
if t == nil {
|
if t == nil {
|
||||||
@ -142,6 +142,10 @@ func (t *BlockHeader) MarshalCBOR(w io.Writer) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// t.ParentBaseFee (big.Int) (struct)
|
||||||
|
if err := t.ParentBaseFee.MarshalCBOR(w); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +163,7 @@ func (t *BlockHeader) UnmarshalCBOR(r io.Reader) error {
|
|||||||
return fmt.Errorf("cbor input should be of type array")
|
return fmt.Errorf("cbor input should be of type array")
|
||||||
}
|
}
|
||||||
|
|
||||||
if extra != 15 {
|
if extra != 16 {
|
||||||
return fmt.Errorf("cbor input had wrong number of fields")
|
return fmt.Errorf("cbor input had wrong number of fields")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -439,6 +443,15 @@ func (t *BlockHeader) UnmarshalCBOR(r io.Reader) error {
|
|||||||
}
|
}
|
||||||
t.ForkSignaling = uint64(extra)
|
t.ForkSignaling = uint64(extra)
|
||||||
|
|
||||||
|
}
|
||||||
|
// t.ParentBaseFee (big.Int) (struct)
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
if err := t.ParentBaseFee.UnmarshalCBOR(br); err != nil {
|
||||||
|
return xerrors.Errorf("unmarshaling t.ParentBaseFee: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -619,7 +632,7 @@ func (t *ElectionProof) UnmarshalCBOR(r io.Reader) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var lengthBufMessage = []byte{137}
|
var lengthBufMessage = []byte{138}
|
||||||
|
|
||||||
func (t *Message) MarshalCBOR(w io.Writer) error {
|
func (t *Message) MarshalCBOR(w io.Writer) error {
|
||||||
if t == nil {
|
if t == nil {
|
||||||
@ -664,11 +677,6 @@ func (t *Message) MarshalCBOR(w io.Writer) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// t.GasPrice (big.Int) (struct)
|
|
||||||
if err := t.GasPrice.MarshalCBOR(w); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// t.GasLimit (int64) (int64)
|
// t.GasLimit (int64) (int64)
|
||||||
if t.GasLimit >= 0 {
|
if t.GasLimit >= 0 {
|
||||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.GasLimit)); err != nil {
|
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.GasLimit)); err != nil {
|
||||||
@ -680,6 +688,16 @@ func (t *Message) MarshalCBOR(w io.Writer) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// t.GasFeeCap (big.Int) (struct)
|
||||||
|
if err := t.GasFeeCap.MarshalCBOR(w); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// t.GasPremium (big.Int) (struct)
|
||||||
|
if err := t.GasPremium.MarshalCBOR(w); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// t.Method (abi.MethodNum) (uint64)
|
// t.Method (abi.MethodNum) (uint64)
|
||||||
|
|
||||||
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.Method)); err != nil {
|
if err := cbg.WriteMajorTypeHeaderBuf(scratch, w, cbg.MajUnsignedInt, uint64(t.Method)); err != nil {
|
||||||
@ -715,7 +733,7 @@ func (t *Message) UnmarshalCBOR(r io.Reader) error {
|
|||||||
return fmt.Errorf("cbor input should be of type array")
|
return fmt.Errorf("cbor input should be of type array")
|
||||||
}
|
}
|
||||||
|
|
||||||
if extra != 9 {
|
if extra != 10 {
|
||||||
return fmt.Errorf("cbor input had wrong number of fields")
|
return fmt.Errorf("cbor input had wrong number of fields")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -784,15 +802,6 @@ func (t *Message) UnmarshalCBOR(r io.Reader) error {
|
|||||||
return xerrors.Errorf("unmarshaling t.Value: %w", err)
|
return xerrors.Errorf("unmarshaling t.Value: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
// t.GasPrice (big.Int) (struct)
|
|
||||||
|
|
||||||
{
|
|
||||||
|
|
||||||
if err := t.GasPrice.UnmarshalCBOR(br); err != nil {
|
|
||||||
return xerrors.Errorf("unmarshaling t.GasPrice: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
// t.GasLimit (int64) (int64)
|
// t.GasLimit (int64) (int64)
|
||||||
{
|
{
|
||||||
@ -819,6 +828,24 @@ func (t *Message) UnmarshalCBOR(r io.Reader) error {
|
|||||||
|
|
||||||
t.GasLimit = int64(extraI)
|
t.GasLimit = int64(extraI)
|
||||||
}
|
}
|
||||||
|
// t.GasFeeCap (big.Int) (struct)
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
if err := t.GasFeeCap.UnmarshalCBOR(br); err != nil {
|
||||||
|
return xerrors.Errorf("unmarshaling t.GasFeeCap: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// t.GasPremium (big.Int) (struct)
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
if err := t.GasPremium.UnmarshalCBOR(br); err != nil {
|
||||||
|
return xerrors.Errorf("unmarshaling t.GasPremium: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
// t.Method (abi.MethodNum) (uint64)
|
// t.Method (abi.MethodNum) (uint64)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -32,10 +32,11 @@ type Message struct {
|
|||||||
|
|
||||||
Nonce uint64
|
Nonce uint64
|
||||||
|
|
||||||
Value BigInt
|
Value abi.TokenAmount
|
||||||
|
|
||||||
GasPrice BigInt
|
GasLimit int64
|
||||||
GasLimit int64
|
GasFeeCap abi.TokenAmount
|
||||||
|
GasPremium abi.TokenAmount
|
||||||
|
|
||||||
Method abi.MethodNum
|
Method abi.MethodNum
|
||||||
Params []byte
|
Params []byte
|
||||||
@ -106,7 +107,7 @@ func (m *Message) Cid() cid.Cid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Message) RequiredFunds() BigInt {
|
func (m *Message) RequiredFunds() BigInt {
|
||||||
return BigMul(m.GasPrice, NewInt(uint64(m.GasLimit)))
|
return BigMul(m.GasFeeCap, NewInt(uint64(m.GasLimit)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Message) VMMessage() *Message {
|
func (m *Message) VMMessage() *Message {
|
||||||
@ -138,8 +139,12 @@ func (m *Message) ValidForBlockInclusion(minGas int64) error {
|
|||||||
return xerrors.New("'Value' field cannot be greater than total filecoin supply")
|
return xerrors.New("'Value' field cannot be greater than total filecoin supply")
|
||||||
}
|
}
|
||||||
|
|
||||||
if m.GasPrice.LessThan(big.Zero()) {
|
if m.GasFeeCap.LessThan(big.Zero()) {
|
||||||
return xerrors.New("'GasPrice' field cannot be negative")
|
return xerrors.New("'GasFeeCap' field cannot be negative")
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.GasPremium.LessThan(big.Zero()) {
|
||||||
|
return xerrors.New("'GasPremium' field cannot be negative")
|
||||||
}
|
}
|
||||||
|
|
||||||
if m.GasLimit > build.BlockGasLimit {
|
if m.GasLimit > build.BlockGasLimit {
|
||||||
|
@ -23,12 +23,13 @@ func Address(i uint64) address.Address {
|
|||||||
|
|
||||||
func MkMessage(from, to address.Address, nonce uint64, w *wallet.Wallet) *types.SignedMessage {
|
func MkMessage(from, to address.Address, nonce uint64, w *wallet.Wallet) *types.SignedMessage {
|
||||||
msg := &types.Message{
|
msg := &types.Message{
|
||||||
To: to,
|
To: to,
|
||||||
From: from,
|
From: from,
|
||||||
Value: types.NewInt(1),
|
Value: types.NewInt(1),
|
||||||
Nonce: nonce,
|
Nonce: nonce,
|
||||||
GasLimit: 1000000,
|
GasLimit: 1000000,
|
||||||
GasPrice: types.NewInt(0),
|
GasFeeCap: types.NewInt(100),
|
||||||
|
GasPremium: types.NewInt(1),
|
||||||
}
|
}
|
||||||
|
|
||||||
sig, err := w.Sign(context.TODO(), from, msg.Cid().Bytes())
|
sig, err := w.Sign(context.TODO(), from, msg.Cid().Bytes())
|
||||||
|
@ -22,13 +22,14 @@ func blsaddr(n int64) address.Address {
|
|||||||
|
|
||||||
func BenchmarkSerializeMessage(b *testing.B) {
|
func BenchmarkSerializeMessage(b *testing.B) {
|
||||||
m := &Message{
|
m := &Message{
|
||||||
To: blsaddr(1),
|
To: blsaddr(1),
|
||||||
From: blsaddr(2),
|
From: blsaddr(2),
|
||||||
Nonce: 197,
|
Nonce: 197,
|
||||||
Method: 1231254,
|
Method: 1231254,
|
||||||
Params: []byte("some bytes, idk. probably at least ten of them"),
|
Params: []byte("some bytes, idk. probably at least ten of them"),
|
||||||
GasLimit: 126723,
|
GasLimit: 126723,
|
||||||
GasPrice: NewInt(1776234),
|
GasPremium: NewInt(1245667),
|
||||||
|
GasFeeCap: NewInt(1245667),
|
||||||
}
|
}
|
||||||
|
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
|
@ -13,14 +13,15 @@ func TestSignedMessageJsonRoundtrip(t *testing.T) {
|
|||||||
from, _ := address.NewIDAddress(603911192)
|
from, _ := address.NewIDAddress(603911192)
|
||||||
smsg := &types.SignedMessage{
|
smsg := &types.SignedMessage{
|
||||||
Message: types.Message{
|
Message: types.Message{
|
||||||
To: to,
|
To: to,
|
||||||
From: from,
|
From: from,
|
||||||
Params: []byte("some bytes, idk"),
|
Params: []byte("some bytes, idk"),
|
||||||
Method: 1235126,
|
Method: 1235126,
|
||||||
Value: types.NewInt(123123),
|
Value: types.NewInt(123123),
|
||||||
GasPrice: types.NewInt(1234),
|
GasFeeCap: types.NewInt(1234),
|
||||||
GasLimit: 100_000_000,
|
GasPremium: types.NewInt(132414234),
|
||||||
Nonce: 123123,
|
GasLimit: 100_000_000,
|
||||||
|
Nonce: 123123,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package validation
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
@ -89,6 +90,7 @@ func (a *Applier) ApplyTipSetMessages(epoch abi.ChainEpoch, blocks []vtypes.Bloc
|
|||||||
}
|
}
|
||||||
|
|
||||||
var receipts []vtypes.MessageReceipt
|
var receipts []vtypes.MessageReceipt
|
||||||
|
// TODO: base fee
|
||||||
sroot, _, err := sm.ApplyBlocks(context.TODO(), epoch-1, a.stateWrapper.Root(), bms, epoch, &randWrapper{rnd}, func(c cid.Cid, msg *types.Message, ret *vm.ApplyRet) error {
|
sroot, _, err := sm.ApplyBlocks(context.TODO(), epoch-1, a.stateWrapper.Root(), bms, epoch, &randWrapper{rnd}, func(c cid.Cid, msg *types.Message, ret *vm.ApplyRet) error {
|
||||||
if msg.From == builtin.SystemActorAddr {
|
if msg.From == builtin.SystemActorAddr {
|
||||||
return nil // ignore reward and cron calls
|
return nil // ignore reward and cron calls
|
||||||
@ -104,7 +106,7 @@ func (a *Applier) ApplyTipSetMessages(epoch abi.ChainEpoch, blocks []vtypes.Bloc
|
|||||||
GasUsed: vtypes.GasUnits(ret.GasUsed),
|
GasUsed: vtypes.GasUnits(ret.GasUsed),
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
})
|
}, abi.NewTokenAmount(100))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return vtypes.ApplyTipSetResult{}, err
|
return vtypes.ApplyTipSetResult{}, err
|
||||||
}
|
}
|
||||||
@ -136,7 +138,17 @@ func (a *Applier) applyMessage(epoch abi.ChainEpoch, lm types.ChainMsg) (vtypes.
|
|||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
base := a.stateWrapper.Root()
|
base := a.stateWrapper.Root()
|
||||||
|
|
||||||
lotusVM, err := vm.NewVM(base, epoch, &vmRand{}, a.stateWrapper.bs, a.syscalls, nil)
|
vmopt := &vm.VMOpts{
|
||||||
|
StateBase: base,
|
||||||
|
Epoch: epoch,
|
||||||
|
Rand: &vmRand{},
|
||||||
|
Bstore: a.stateWrapper.bs,
|
||||||
|
Syscalls: a.syscalls,
|
||||||
|
VestedCalc: nil,
|
||||||
|
BaseFee: abi.NewTokenAmount(100),
|
||||||
|
}
|
||||||
|
|
||||||
|
lotusVM, err := vm.NewVM(vmopt)
|
||||||
// need to modify the VM invoker to add the puppet actor
|
// need to modify the VM invoker to add the puppet actor
|
||||||
chainValInvoker := vm.NewInvoker()
|
chainValInvoker := vm.NewInvoker()
|
||||||
chainValInvoker.Register(puppet.PuppetActorCodeID, puppet.Actor{}, puppet.State{})
|
chainValInvoker.Register(puppet.PuppetActorCodeID, puppet.Actor{}, puppet.State{})
|
||||||
@ -177,9 +189,10 @@ func toLotusMsg(msg *vtypes.Message) *types.Message {
|
|||||||
Nonce: msg.CallSeqNum,
|
Nonce: msg.CallSeqNum,
|
||||||
Method: msg.Method,
|
Method: msg.Method,
|
||||||
|
|
||||||
Value: msg.Value,
|
Value: msg.Value,
|
||||||
GasPrice: msg.GasPrice,
|
GasLimit: msg.GasLimit,
|
||||||
GasLimit: msg.GasLimit,
|
GasFeeCap: msg.GasFeeCap,
|
||||||
|
GasPremium: msg.GasPremium,
|
||||||
|
|
||||||
Params: msg.Params,
|
Params: msg.Params,
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ import (
|
|||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
|
||||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||||
|
|
||||||
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
|
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
|
||||||
@ -24,6 +25,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
verifreg.MinVerifiedDealSize = big.NewInt(2048)
|
||||||
power.ConsensusMinerMinPower = big.NewInt(2048)
|
power.ConsensusMinerMinPower = big.NewInt(2048)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,7 +139,8 @@ func MakeUnsignedMessageVectors() []vectors.UnsignedMessageVector {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
to, err := address.NewIDAddress(rand.Uint64())
|
uint63mask := uint64(1<<63 - 1)
|
||||||
|
to, err := address.NewIDAddress(rand.Uint64() & uint63mask)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -146,14 +149,15 @@ func MakeUnsignedMessageVectors() []vectors.UnsignedMessageVector {
|
|||||||
rand.Read(params)
|
rand.Read(params)
|
||||||
|
|
||||||
msg := &types.Message{
|
msg := &types.Message{
|
||||||
To: to,
|
To: to,
|
||||||
From: from,
|
From: from,
|
||||||
Value: types.NewInt(rand.Uint64()),
|
Value: types.NewInt(rand.Uint64()),
|
||||||
Method: abi.MethodNum(rand.Uint64()),
|
Method: abi.MethodNum(rand.Uint64()),
|
||||||
GasPrice: types.NewInt(rand.Uint64()),
|
GasFeeCap: types.NewInt(rand.Uint64()),
|
||||||
GasLimit: rand.Int63(),
|
GasPremium: types.NewInt(rand.Uint64()),
|
||||||
Nonce: rand.Uint64(),
|
GasLimit: rand.Int63(),
|
||||||
Params: params,
|
Nonce: rand.Uint64() & (1<<63 - 1),
|
||||||
|
Params: params,
|
||||||
}
|
}
|
||||||
|
|
||||||
ser, err := msg.Serialize()
|
ser, err := msg.Serialize()
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
package vm
|
package vm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/big"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -9,9 +10,21 @@ const (
|
|||||||
gasOveruseDenom = 10
|
gasOveruseDenom = 10
|
||||||
)
|
)
|
||||||
|
|
||||||
// ComputeGasOutputs computes amount of gas to be refunded and amount of gas to be burned
|
type GasOutputs struct {
|
||||||
|
BaseFeeBurn abi.TokenAmount
|
||||||
|
OverEstimationBurn abi.TokenAmount
|
||||||
|
|
||||||
|
MinerPenalty abi.TokenAmount
|
||||||
|
MinerTip abi.TokenAmount
|
||||||
|
Refund abi.TokenAmount
|
||||||
|
|
||||||
|
GasRefund int64
|
||||||
|
GasBurned int64
|
||||||
|
}
|
||||||
|
|
||||||
|
// ComputeGasOverestimationBurn computes amount of gas to be refunded and amount of gas to be burned
|
||||||
// Result is (refund, burn)
|
// Result is (refund, burn)
|
||||||
func ComputeGasOutputs(gasUsed, gasLimit int64) (int64, int64) {
|
func ComputeGasOverestimationBurn(gasUsed, gasLimit int64) (int64, int64) {
|
||||||
if gasUsed == 0 {
|
if gasUsed == 0 {
|
||||||
return 0, gasLimit
|
return 0, gasLimit
|
||||||
}
|
}
|
||||||
@ -37,8 +50,48 @@ func ComputeGasOutputs(gasUsed, gasLimit int64) (int64, int64) {
|
|||||||
|
|
||||||
// needs bigint, as it overflows in pathological case gasLimit > 2^32 gasUsed = gasLimit / 2
|
// needs bigint, as it overflows in pathological case gasLimit > 2^32 gasUsed = gasLimit / 2
|
||||||
gasToBurn := big.NewInt(gasLimit - gasUsed)
|
gasToBurn := big.NewInt(gasLimit - gasUsed)
|
||||||
gasToBurn = gasToBurn.Mul(gasToBurn, big.NewInt(over))
|
gasToBurn = big.Mul(gasToBurn, big.NewInt(over))
|
||||||
gasToBurn = gasToBurn.Div(gasToBurn, big.NewInt(gasUsed))
|
gasToBurn = big.Div(gasToBurn, big.NewInt(gasUsed))
|
||||||
|
|
||||||
return gasLimit - gasUsed - gasToBurn.Int64(), gasToBurn.Int64()
|
return gasLimit - gasUsed - gasToBurn.Int64(), gasToBurn.Int64()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ComputeGasOutputs(gasUsed, gasLimit int64, baseFee, feeCap, gasPremium abi.TokenAmount) GasOutputs {
|
||||||
|
gasUsedBig := big.NewInt(gasUsed)
|
||||||
|
out := GasOutputs{
|
||||||
|
BaseFeeBurn: big.Zero(),
|
||||||
|
OverEstimationBurn: big.Zero(),
|
||||||
|
MinerPenalty: big.Zero(),
|
||||||
|
MinerTip: big.Zero(),
|
||||||
|
Refund: big.Zero(),
|
||||||
|
}
|
||||||
|
|
||||||
|
baseFeeToPay := baseFee
|
||||||
|
if baseFee.Cmp(feeCap.Int) > 0 {
|
||||||
|
baseFeeToPay = feeCap
|
||||||
|
out.MinerPenalty = big.Mul(big.Sub(baseFee, feeCap), gasUsedBig)
|
||||||
|
}
|
||||||
|
out.BaseFeeBurn = big.Mul(baseFeeToPay, gasUsedBig)
|
||||||
|
|
||||||
|
minerTip := gasPremium
|
||||||
|
if big.Cmp(big.Add(baseFeeToPay, minerTip), feeCap) > 0 {
|
||||||
|
minerTip = big.Sub(feeCap, baseFeeToPay)
|
||||||
|
}
|
||||||
|
out.MinerTip = big.Mul(minerTip, big.NewInt(gasLimit))
|
||||||
|
|
||||||
|
out.GasRefund, out.GasBurned = ComputeGasOverestimationBurn(gasUsed, gasLimit)
|
||||||
|
|
||||||
|
if out.GasBurned != 0 {
|
||||||
|
gasBurnedBig := big.NewInt(out.GasBurned)
|
||||||
|
out.OverEstimationBurn = big.Mul(baseFeeToPay, gasBurnedBig)
|
||||||
|
minerPenalty := big.Mul(big.Sub(baseFee, baseFeeToPay), gasBurnedBig)
|
||||||
|
out.MinerPenalty = big.Add(out.MinerPenalty, minerPenalty)
|
||||||
|
}
|
||||||
|
|
||||||
|
requiredFunds := big.Mul(big.NewInt(gasLimit), feeCap)
|
||||||
|
refund := big.Sub(requiredFunds, out.BaseFeeBurn)
|
||||||
|
refund = big.Sub(refund, out.MinerTip)
|
||||||
|
refund = big.Sub(refund, out.OverEstimationBurn)
|
||||||
|
out.Refund = refund
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -31,9 +32,47 @@ func TestGasBurn(t *testing.T) {
|
|||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
test := test
|
test := test
|
||||||
t.Run(fmt.Sprintf("%v", test), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%v", test), func(t *testing.T) {
|
||||||
refund, toBurn := ComputeGasOutputs(test.used, test.limit)
|
refund, toBurn := ComputeGasOverestimationBurn(test.used, test.limit)
|
||||||
assert.Equal(t, test.refund, refund, "refund")
|
assert.Equal(t, test.refund, refund, "refund")
|
||||||
assert.Equal(t, test.burn, toBurn, "burned")
|
assert.Equal(t, test.burn, toBurn, "burned")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGasOutputs(t *testing.T) {
|
||||||
|
baseFee := types.NewInt(10)
|
||||||
|
tests := []struct {
|
||||||
|
used int64
|
||||||
|
limit int64
|
||||||
|
|
||||||
|
feeCap uint64
|
||||||
|
premium uint64
|
||||||
|
|
||||||
|
BaseFeeBurn uint64
|
||||||
|
OverEstimationBurn uint64
|
||||||
|
MinerPenalty uint64
|
||||||
|
MinerTip uint64
|
||||||
|
Refund uint64
|
||||||
|
}{
|
||||||
|
{100, 110, 11, 1, 1000, 0, 0, 110, 100},
|
||||||
|
{100, 130, 11, 1, 1000, 60, 0, 130, 240},
|
||||||
|
{100, 110, 10, 1, 1000, 0, 0, 0, 100},
|
||||||
|
{100, 110, 6, 1, 600, 0, 400, 0, 60},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
test := test
|
||||||
|
t.Run(fmt.Sprintf("%v", test), func(t *testing.T) {
|
||||||
|
output := ComputeGasOutputs(test.used, test.limit, baseFee, types.NewInt(test.feeCap), types.NewInt(test.premium))
|
||||||
|
i2s := func(i uint64) string {
|
||||||
|
return fmt.Sprintf("%d", i)
|
||||||
|
}
|
||||||
|
assert.Equal(t, i2s(test.BaseFeeBurn), output.BaseFeeBurn.String(), "BaseFeeBurn")
|
||||||
|
assert.Equal(t, i2s(test.OverEstimationBurn), output.OverEstimationBurn.String(), "OverEstimationBurn")
|
||||||
|
assert.Equal(t, i2s(test.MinerPenalty), output.MinerPenalty.String(), "MinerPenalty")
|
||||||
|
assert.Equal(t, i2s(test.MinerTip), output.MinerTip.String(), "MinerTip")
|
||||||
|
assert.Equal(t, i2s(test.Refund), output.Refund.String(), "Refund")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -7,6 +7,9 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
bstore "github.com/filecoin-project/lotus/lib/blockstore"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
|
|
||||||
block "github.com/ipfs/go-block-format"
|
block "github.com/ipfs/go-block-format"
|
||||||
@ -149,28 +152,40 @@ type VM struct {
|
|||||||
inv *Invoker
|
inv *Invoker
|
||||||
rand Rand
|
rand Rand
|
||||||
vc VestedCalculator
|
vc VestedCalculator
|
||||||
|
baseFee abi.TokenAmount
|
||||||
|
|
||||||
Syscalls SyscallBuilder
|
Syscalls SyscallBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewVM(base cid.Cid, height abi.ChainEpoch, r Rand, cbs blockstore.Blockstore, syscalls SyscallBuilder, vestedCalc VestedCalculator) (*VM, error) {
|
type VMOpts struct {
|
||||||
buf := bufbstore.NewBufferedBstore(cbs)
|
StateBase cid.Cid
|
||||||
|
Epoch abi.ChainEpoch
|
||||||
|
Rand Rand
|
||||||
|
Bstore bstore.Blockstore
|
||||||
|
Syscalls SyscallBuilder
|
||||||
|
VestedCalc VestedCalculator
|
||||||
|
BaseFee abi.TokenAmount
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewVM(opts *VMOpts) (*VM, error) {
|
||||||
|
buf := bufbstore.NewBufferedBstore(opts.Bstore)
|
||||||
cst := cbor.NewCborStore(buf)
|
cst := cbor.NewCborStore(buf)
|
||||||
state, err := state.LoadStateTree(cst, base)
|
state, err := state.LoadStateTree(cst, opts.StateBase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &VM{
|
return &VM{
|
||||||
cstate: state,
|
cstate: state,
|
||||||
base: base,
|
base: opts.StateBase,
|
||||||
cst: cst,
|
cst: cst,
|
||||||
buf: buf,
|
buf: buf,
|
||||||
blockHeight: height,
|
blockHeight: opts.Epoch,
|
||||||
inv: NewInvoker(),
|
inv: NewInvoker(),
|
||||||
rand: r, // TODO: Probably should be a syscall
|
rand: opts.Rand, // TODO: Probably should be a syscall
|
||||||
vc: vestedCalc,
|
vc: opts.VestedCalc,
|
||||||
Syscalls: syscalls,
|
Syscalls: opts.Syscalls,
|
||||||
|
baseFee: opts.BaseFee,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,6 +197,7 @@ type ApplyRet struct {
|
|||||||
types.MessageReceipt
|
types.MessageReceipt
|
||||||
ActorErr aerrors.ActorError
|
ActorErr aerrors.ActorError
|
||||||
Penalty types.BigInt
|
Penalty types.BigInt
|
||||||
|
MinerTip types.BigInt
|
||||||
ExecutionTrace types.ExecutionTrace
|
ExecutionTrace types.ExecutionTrace
|
||||||
Duration time.Duration
|
Duration time.Duration
|
||||||
}
|
}
|
||||||
@ -277,8 +293,12 @@ func checkMessage(msg *types.Message) error {
|
|||||||
return xerrors.Errorf("message has negative gas limit")
|
return xerrors.Errorf("message has negative gas limit")
|
||||||
}
|
}
|
||||||
|
|
||||||
if msg.GasPrice == types.EmptyInt {
|
if msg.GasFeeCap == types.EmptyInt {
|
||||||
return xerrors.Errorf("message gas no gas price set")
|
return xerrors.Errorf("message fee cap not set")
|
||||||
|
}
|
||||||
|
|
||||||
|
if msg.GasPremium == types.EmptyInt {
|
||||||
|
return xerrors.Errorf("message gas premium not set")
|
||||||
}
|
}
|
||||||
|
|
||||||
if msg.Value == types.EmptyInt {
|
if msg.Value == types.EmptyInt {
|
||||||
@ -301,6 +321,7 @@ func (vm *VM) ApplyImplicitMessage(ctx context.Context, msg *types.Message) (*Ap
|
|||||||
ActorErr: actorErr,
|
ActorErr: actorErr,
|
||||||
ExecutionTrace: rt.executionTrace,
|
ExecutionTrace: rt.executionTrace,
|
||||||
Penalty: types.NewInt(0),
|
Penalty: types.NewInt(0),
|
||||||
|
MinerTip: types.NewInt(0),
|
||||||
Duration: time.Since(start),
|
Duration: time.Since(start),
|
||||||
}, actorErr
|
}, actorErr
|
||||||
}
|
}
|
||||||
@ -333,14 +354,15 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
|||||||
ExitCode: exitcode.SysErrOutOfGas,
|
ExitCode: exitcode.SysErrOutOfGas,
|
||||||
GasUsed: 0,
|
GasUsed: 0,
|
||||||
},
|
},
|
||||||
Penalty: types.BigMul(msg.GasPrice, types.NewInt(uint64(msgGasCost))),
|
Penalty: types.BigMul(vm.baseFee, abi.NewTokenAmount(msgGasCost)),
|
||||||
Duration: time.Since(start),
|
Duration: time.Since(start),
|
||||||
|
MinerTip: big.Zero(),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
st := vm.cstate
|
st := vm.cstate
|
||||||
|
|
||||||
minerPenaltyAmount := types.BigMul(msg.GasPrice, types.NewInt(uint64(msgGasCost)))
|
minerPenaltyAmount := types.BigMul(vm.baseFee, abi.NewTokenAmount(msg.GasLimit))
|
||||||
fromActor, err := st.GetActor(msg.From)
|
fromActor, err := st.GetActor(msg.From)
|
||||||
// this should never happen, but is currently still exercised by some tests
|
// this should never happen, but is currently still exercised by some tests
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -353,6 +375,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
|||||||
ActorErr: aerrors.Newf(exitcode.SysErrSenderInvalid, "actor not found: %s", msg.From),
|
ActorErr: aerrors.Newf(exitcode.SysErrSenderInvalid, "actor not found: %s", msg.From),
|
||||||
Penalty: minerPenaltyAmount,
|
Penalty: minerPenaltyAmount,
|
||||||
Duration: time.Since(start),
|
Duration: time.Since(start),
|
||||||
|
MinerTip: big.Zero(),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
return nil, xerrors.Errorf("failed to look up from actor: %w", err)
|
return nil, xerrors.Errorf("failed to look up from actor: %w", err)
|
||||||
@ -368,6 +391,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
|||||||
ActorErr: aerrors.Newf(exitcode.SysErrSenderInvalid, "send from not account actor: %s", fromActor.Code),
|
ActorErr: aerrors.Newf(exitcode.SysErrSenderInvalid, "send from not account actor: %s", fromActor.Code),
|
||||||
Penalty: minerPenaltyAmount,
|
Penalty: minerPenaltyAmount,
|
||||||
Duration: time.Since(start),
|
Duration: time.Since(start),
|
||||||
|
MinerTip: big.Zero(),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,10 +405,11 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
|||||||
"actor nonce invalid: msg:%d != state:%d", msg.Nonce, fromActor.Nonce),
|
"actor nonce invalid: msg:%d != state:%d", msg.Nonce, fromActor.Nonce),
|
||||||
Penalty: minerPenaltyAmount,
|
Penalty: minerPenaltyAmount,
|
||||||
Duration: time.Since(start),
|
Duration: time.Since(start),
|
||||||
|
MinerTip: big.Zero(),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
gascost := types.BigMul(types.NewInt(uint64(msg.GasLimit)), msg.GasPrice)
|
gascost := types.BigMul(types.NewInt(uint64(msg.GasLimit)), msg.GasFeeCap)
|
||||||
if fromActor.Balance.LessThan(gascost) {
|
if fromActor.Balance.LessThan(gascost) {
|
||||||
return &ApplyRet{
|
return &ApplyRet{
|
||||||
MessageReceipt: types.MessageReceipt{
|
MessageReceipt: types.MessageReceipt{
|
||||||
@ -395,6 +420,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
|||||||
"actor balance less than needed: %s < %s", types.FIL(fromActor.Balance), types.FIL(gascost)),
|
"actor balance less than needed: %s < %s", types.FIL(fromActor.Balance), types.FIL(gascost)),
|
||||||
Penalty: minerPenaltyAmount,
|
Penalty: minerPenaltyAmount,
|
||||||
Duration: time.Since(start),
|
Duration: time.Since(start),
|
||||||
|
MinerTip: big.Zero(),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,25 +480,25 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
|||||||
if gasUsed < 0 {
|
if gasUsed < 0 {
|
||||||
gasUsed = 0
|
gasUsed = 0
|
||||||
}
|
}
|
||||||
gasRefund, gasToBurn := ComputeGasOutputs(gasUsed, msg.GasLimit)
|
gasOutputs := ComputeGasOutputs(gasUsed, msg.GasLimit, vm.baseFee, msg.GasFeeCap, msg.GasPremium)
|
||||||
|
|
||||||
|
if err := vm.transferFromGasHolder(builtin.BurntFundsActorAddr, gasHolder,
|
||||||
|
gasOutputs.BaseFeeBurn); err != nil {
|
||||||
|
return nil, xerrors.Errorf("failed to burn base fee: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := vm.transferFromGasHolder(builtin.RewardActorAddr, gasHolder, gasOutputs.MinerTip); err != nil {
|
||||||
|
return nil, xerrors.Errorf("failed to give miner gas reward: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := vm.transferFromGasHolder(builtin.BurntFundsActorAddr, gasHolder,
|
||||||
|
gasOutputs.OverEstimationBurn); err != nil {
|
||||||
|
return nil, xerrors.Errorf("failed to burn overestimation fee: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
// refund unused gas
|
// refund unused gas
|
||||||
refund := types.BigMul(types.NewInt(uint64(gasRefund)), msg.GasPrice)
|
if err := vm.transferFromGasHolder(msg.From, gasHolder, gasOutputs.Refund); err != nil {
|
||||||
if err := vm.transferFromGasHolder(msg.From, gasHolder, refund); err != nil {
|
return nil, xerrors.Errorf("failed to refund gas: %w", err)
|
||||||
return nil, xerrors.Errorf("failed to refund gas")
|
|
||||||
}
|
|
||||||
|
|
||||||
if gasToBurn > 0 {
|
|
||||||
// burn overallocated gas
|
|
||||||
burn := types.BigMul(types.NewInt(uint64(gasToBurn)), msg.GasPrice)
|
|
||||||
if err := vm.transferFromGasHolder(builtin.BurntFundsActorAddr, gasHolder, burn); err != nil {
|
|
||||||
return nil, xerrors.Errorf("failed to burn over estimated gas")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gasReward := types.BigMul(msg.GasPrice, types.NewInt(uint64(gasUsed)))
|
|
||||||
if err := vm.transferFromGasHolder(builtin.RewardActorAddr, gasHolder, gasReward); err != nil {
|
|
||||||
return nil, xerrors.Errorf("failed to give miner gas reward: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if types.BigCmp(types.NewInt(0), gasHolder.Balance) != 0 {
|
if types.BigCmp(types.NewInt(0), gasHolder.Balance) != 0 {
|
||||||
@ -487,7 +513,8 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
|
|||||||
},
|
},
|
||||||
ActorErr: actorErr,
|
ActorErr: actorErr,
|
||||||
ExecutionTrace: rt.executionTrace,
|
ExecutionTrace: rt.executionTrace,
|
||||||
Penalty: types.NewInt(0),
|
Penalty: gasOutputs.MinerPenalty,
|
||||||
|
MinerTip: gasOutputs.MinerTip,
|
||||||
Duration: time.Since(start),
|
Duration: time.Since(start),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@ -766,6 +793,10 @@ func (vm *VM) transferFromGasHolder(addr address.Address, gasHolder *types.Actor
|
|||||||
return xerrors.Errorf("attempted to transfer negative value from gas holder")
|
return xerrors.Errorf("attempted to transfer negative value from gas holder")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if amt.Equals(big.NewInt(0)) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
return vm.cstate.MutateActor(addr, func(a *types.Actor) error {
|
return vm.cstate.MutateActor(addr, func(a *types.Actor) error {
|
||||||
if err := deductFunds(gasHolder, amt); err != nil {
|
if err := deductFunds(gasHolder, amt); err != nil {
|
||||||
return err
|
return err
|
||||||
|
14
cli/chain.go
14
cli/chain.go
@ -430,22 +430,22 @@ var chainListCmd = &cli.Command{
|
|||||||
psum := big.NewInt(0)
|
psum := big.NewInt(0)
|
||||||
for _, m := range msgs.BlsMessages {
|
for _, m := range msgs.BlsMessages {
|
||||||
limitSum += m.GasLimit
|
limitSum += m.GasLimit
|
||||||
psum = big.Add(psum, m.GasPrice)
|
psum = big.Add(psum, m.GasPremium)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, m := range msgs.SecpkMessages {
|
for _, m := range msgs.SecpkMessages {
|
||||||
limitSum += m.Message.GasLimit
|
limitSum += m.Message.GasLimit
|
||||||
psum = big.Add(psum, m.Message.GasPrice)
|
psum = big.Add(psum, m.Message.GasPremium)
|
||||||
}
|
}
|
||||||
|
|
||||||
lenmsgs := len(msgs.BlsMessages) + len(msgs.SecpkMessages)
|
lenmsgs := len(msgs.BlsMessages) + len(msgs.SecpkMessages)
|
||||||
|
|
||||||
avgprice := big.Zero()
|
avgpremium := big.Zero()
|
||||||
if lenmsgs > 0 {
|
if lenmsgs > 0 {
|
||||||
avgprice = big.Div(psum, big.NewInt(int64(lenmsgs)))
|
avgpremium = big.Div(psum, big.NewInt(int64(lenmsgs)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("\t%s: \t%d msgs, gasLimit: %d / %d (%0.2f%%), avgPrice: %s\n", b.Miner, len(msgs.BlsMessages)+len(msgs.SecpkMessages), limitSum, build.BlockGasLimit, 100*float64(limitSum)/float64(build.BlockGasLimit), avgprice)
|
fmt.Printf("\t%s: \t%d msgs, gasLimit: %d / %d (%0.2f%%), avgPrice: %s\n", b.Miner, len(msgs.BlsMessages)+len(msgs.SecpkMessages), limitSum, build.BlockGasLimit, 100*float64(limitSum)/float64(build.BlockGasLimit), avgpremium)
|
||||||
}
|
}
|
||||||
if i < len(tss)-1 {
|
if i < len(tss)-1 {
|
||||||
msgs, err := api.ChainGetParentMessages(ctx, tss[i+1].Blocks()[0].Cid())
|
msgs, err := api.ChainGetParentMessages(ctx, tss[i+1].Blocks()[0].Cid())
|
||||||
@ -1030,9 +1030,9 @@ var chainGasPriceCmd = &cli.Command{
|
|||||||
|
|
||||||
nb := []int{1, 2, 3, 5, 10, 20, 50, 100, 300}
|
nb := []int{1, 2, 3, 5, 10, 20, 50, 100, 300}
|
||||||
for _, nblocks := range nb {
|
for _, nblocks := range nb {
|
||||||
addr := builtin.SystemActorAddr // TODO: make real when used in GasEstimateGasPrice
|
addr := builtin.SystemActorAddr // TODO: make real when used in GasEsitmateGasPremium
|
||||||
|
|
||||||
est, err := api.GasEstimateGasPrice(ctx, uint64(nblocks), addr, 10000, types.EmptyTSK)
|
est, err := api.GasEsitmateGasPremium(ctx, uint64(nblocks), addr, 10000, types.EmptyTSK)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
18
cli/mpool.go
18
cli/mpool.go
@ -246,8 +246,12 @@ var mpoolReplaceCmd = &cli.Command{
|
|||||||
Name: "replace",
|
Name: "replace",
|
||||||
Usage: "replace a message in the mempool",
|
Usage: "replace a message in the mempool",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.Int64Flag{
|
&cli.StringFlag{
|
||||||
Name: "gas-price",
|
Name: "gas-feecap",
|
||||||
|
Usage: "gas feecap for new message",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "gas-premium",
|
||||||
Usage: "gas price for new message",
|
Usage: "gas price for new message",
|
||||||
},
|
},
|
||||||
&cli.Int64Flag{
|
&cli.Int64Flag{
|
||||||
@ -304,7 +308,15 @@ var mpoolReplaceCmd = &cli.Command{
|
|||||||
msg := found.Message
|
msg := found.Message
|
||||||
|
|
||||||
msg.GasLimit = cctx.Int64("gas-limit")
|
msg.GasLimit = cctx.Int64("gas-limit")
|
||||||
msg.GasPrice = types.NewInt(uint64(cctx.Int64("gas-price")))
|
msg.GasPremium, err = types.BigFromString(cctx.String("gas-premium"))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("parsing gas-premium: %w", err)
|
||||||
|
}
|
||||||
|
// TODO: estiamte fee cap here
|
||||||
|
msg.GasFeeCap, err = types.BigFromString(cctx.String("gas-feecap"))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("parsing gas-feecap: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
smsg, err := api.WalletSignMessage(ctx, msg.From, &msg)
|
smsg, err := api.WalletSignMessage(ctx, msg.From, &msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
26
cli/send.go
26
cli/send.go
@ -27,10 +27,15 @@ var sendCmd = &cli.Command{
|
|||||||
Usage: "optionally specify the account to send funds from",
|
Usage: "optionally specify the account to send funds from",
|
||||||
},
|
},
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "gas-price",
|
Name: "gas-premium",
|
||||||
Usage: "specify gas price to use in AttoFIL",
|
Usage: "specify gas price to use in AttoFIL",
|
||||||
Value: "0",
|
Value: "0",
|
||||||
},
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "gas-feecap",
|
||||||
|
Usage: "specify gas fee cap to use in AttoFIL",
|
||||||
|
Value: "0",
|
||||||
|
},
|
||||||
&cli.Int64Flag{
|
&cli.Int64Flag{
|
||||||
Name: "gas-limit",
|
Name: "gas-limit",
|
||||||
Usage: "specify gas limit",
|
Usage: "specify gas limit",
|
||||||
@ -99,6 +104,10 @@ var sendCmd = &cli.Command{
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
gfc, err := types.BigFromString(cctx.String("gas-feecap"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
method := abi.MethodNum(cctx.Uint64("method"))
|
method := abi.MethodNum(cctx.Uint64("method"))
|
||||||
|
|
||||||
@ -122,13 +131,14 @@ var sendCmd = &cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
msg := &types.Message{
|
msg := &types.Message{
|
||||||
From: fromAddr,
|
From: fromAddr,
|
||||||
To: toAddr,
|
To: toAddr,
|
||||||
Value: types.BigInt(val),
|
Value: types.BigInt(val),
|
||||||
GasPrice: gp,
|
GasPremium: gp,
|
||||||
GasLimit: cctx.Int64("gas-limit"),
|
GasFeeCap: gfc,
|
||||||
Method: method,
|
GasLimit: cctx.Int64("gas-limit"),
|
||||||
Params: params,
|
Method: method,
|
||||||
|
Params: params,
|
||||||
}
|
}
|
||||||
|
|
||||||
if cctx.Int64("nonce") > 0 {
|
if cctx.Int64("nonce") > 0 {
|
||||||
|
15
cli/state.go
15
cli/state.go
@ -5,7 +5,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/multiformats/go-multiaddr"
|
|
||||||
"html/template"
|
"html/template"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
@ -15,6 +14,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/multiformats/go-multiaddr"
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/libp2p/go-libp2p-core/peer"
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
"github.com/multiformats/go-multihash"
|
"github.com/multiformats/go-multihash"
|
||||||
@ -1383,13 +1384,11 @@ var stateCallCmd = &cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret, err := api.StateCall(ctx, &types.Message{
|
ret, err := api.StateCall(ctx, &types.Message{
|
||||||
From: froma,
|
From: froma,
|
||||||
To: toa,
|
To: toa,
|
||||||
Value: types.BigInt(value),
|
Value: types.BigInt(value),
|
||||||
GasLimit: 10000000000,
|
Method: abi.MethodNum(method),
|
||||||
GasPrice: types.NewInt(0),
|
Params: params,
|
||||||
Method: abi.MethodNum(method),
|
|
||||||
Params: params,
|
|
||||||
}, ts.Key())
|
}, ts.Key())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("state call failed: %s", err)
|
return fmt.Errorf("state call failed: %s", err)
|
||||||
|
@ -74,11 +74,9 @@ func sendSmallFundsTxs(ctx context.Context, api api.FullNode, from address.Addre
|
|||||||
select {
|
select {
|
||||||
case <-tick.C:
|
case <-tick.C:
|
||||||
msg := &types.Message{
|
msg := &types.Message{
|
||||||
From: from,
|
From: from,
|
||||||
To: sendSet[rand.Intn(20)],
|
To: sendSet[rand.Intn(20)],
|
||||||
Value: types.NewInt(1),
|
Value: types.NewInt(1),
|
||||||
GasLimit: 0,
|
|
||||||
GasPrice: types.NewInt(0),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
smsg, err := api.MpoolPushMessage(ctx, msg)
|
smsg, err := api.MpoolPushMessage(ctx, msg)
|
||||||
|
@ -30,8 +30,9 @@ create table if not exists messages
|
|||||||
"to" text not null,
|
"to" text not null,
|
||||||
nonce bigint not null,
|
nonce bigint not null,
|
||||||
value text not null,
|
value text not null,
|
||||||
gasprice bigint not null,
|
gas_fee_cap bigint not null,
|
||||||
gaslimit bigint not null,
|
gas_premium bigint not null,
|
||||||
|
gas_limit bigint not null,
|
||||||
method bigint,
|
method bigint,
|
||||||
params bytea
|
params bytea
|
||||||
);
|
);
|
||||||
@ -219,7 +220,7 @@ create temp table msgs (like messages excluding constraints) on commit drop;
|
|||||||
return xerrors.Errorf("prep temp: %w", err)
|
return xerrors.Errorf("prep temp: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
stmt, err := tx.Prepare(`copy msgs (cid, "from", "to", nonce, "value", gasprice, gaslimit, method, params) from stdin `)
|
stmt, err := tx.Prepare(`copy msgs (cid, "from", "to", nonce, "value", gas_premium, gas_fee_cap, gas_limit, method, params) from stdin `)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -231,7 +232,8 @@ create temp table msgs (like messages excluding constraints) on commit drop;
|
|||||||
m.To.String(),
|
m.To.String(),
|
||||||
m.Nonce,
|
m.Nonce,
|
||||||
m.Value.String(),
|
m.Value.String(),
|
||||||
m.GasPrice.String(),
|
m.GasPremium.String(),
|
||||||
|
m.GasFeeCap.String(),
|
||||||
m.GasLimit,
|
m.GasLimit,
|
||||||
m.Method,
|
m.Method,
|
||||||
m.Params,
|
m.Params,
|
||||||
|
@ -279,9 +279,6 @@ func (h *handler) send(w http.ResponseWriter, r *http.Request) {
|
|||||||
Value: types.BigInt(h.sendPerRequest),
|
Value: types.BigInt(h.sendPerRequest),
|
||||||
From: h.from,
|
From: h.from,
|
||||||
To: to,
|
To: to,
|
||||||
|
|
||||||
GasPrice: types.NewInt(0),
|
|
||||||
GasLimit: 0,
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(400)
|
w.WriteHeader(400)
|
||||||
@ -353,9 +350,6 @@ func (h *handler) mkminer(w http.ResponseWriter, r *http.Request) {
|
|||||||
Value: types.BigInt(h.sendPerRequest),
|
Value: types.BigInt(h.sendPerRequest),
|
||||||
From: h.from,
|
From: h.from,
|
||||||
To: owner,
|
To: owner,
|
||||||
|
|
||||||
GasPrice: types.NewInt(0),
|
|
||||||
GasLimit: 0,
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(400)
|
w.WriteHeader(400)
|
||||||
@ -390,9 +384,6 @@ func (h *handler) mkminer(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
Method: builtin.MethodsPower.CreateMiner,
|
Method: builtin.MethodsPower.CreateMiner,
|
||||||
Params: params,
|
Params: params,
|
||||||
|
|
||||||
GasLimit: 0,
|
|
||||||
GasPrice: types.NewInt(0),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
signed, err := h.api.MpoolPushMessage(r.Context(), createStorageMinerMsg)
|
signed, err := h.api.MpoolPushMessage(r.Context(), createStorageMinerMsg)
|
||||||
|
@ -51,7 +51,7 @@ var minerSelectMsgsCmd = &cli.Command{
|
|||||||
to = "..." + to[len(to)-8:]
|
to = "..." + to[len(to)-8:]
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("%d: %s -> %s, method %d, gasPrice %s, gasLimit %d, val %s\n", i, from, to, f.Message.Method, f.Message.GasPrice, f.Message.GasLimit, types.FIL(f.Message.Value))
|
fmt.Printf("%d: %s -> %s, method %d, gasFeecap %s, gasPremium %s, gasLimit %d, val %s\n", i, from, to, f.Message.Method, f.Message.GasFeeCap, f.Message.GasPremium, f.Message.GasLimit, types.FIL(f.Message.Value))
|
||||||
totalGas += f.Message.GasLimit
|
totalGas += f.Message.GasLimit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,12 +143,10 @@ var verifRegVerifyClientCmd = &cli.Command{
|
|||||||
ctx := lcli.ReqContext(cctx)
|
ctx := lcli.ReqContext(cctx)
|
||||||
|
|
||||||
msg := &types.Message{
|
msg := &types.Message{
|
||||||
To: builtin.VerifiedRegistryActorAddr,
|
To: builtin.VerifiedRegistryActorAddr,
|
||||||
From: fromk,
|
From: fromk,
|
||||||
Method: builtin.MethodsVerifiedRegistry.AddVerifiedClient,
|
Method: builtin.MethodsVerifiedRegistry.AddVerifiedClient,
|
||||||
GasPrice: types.NewInt(1),
|
Params: params,
|
||||||
GasLimit: 0,
|
|
||||||
Params: params,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
smsg, err := api.MpoolPushMessage(ctx, msg)
|
smsg, err := api.MpoolPushMessage(ctx, msg)
|
||||||
|
@ -102,8 +102,8 @@ var initCmd = &cli.Command{
|
|||||||
Usage: "don't use storageminer repo for sector storage",
|
Usage: "don't use storageminer repo for sector storage",
|
||||||
},
|
},
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "gas-price",
|
Name: "gas-premium",
|
||||||
Usage: "set gas price for initialization messages in AttoFIL",
|
Usage: "set gas premium for initialization messages in AttoFIL",
|
||||||
Value: "0",
|
Value: "0",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -116,7 +116,7 @@ var initCmd = &cli.Command{
|
|||||||
}
|
}
|
||||||
ssize := abi.SectorSize(sectorSizeInt)
|
ssize := abi.SectorSize(sectorSizeInt)
|
||||||
|
|
||||||
gasPrice, err := types.BigFromString(cctx.String("gas-price"))
|
gasPrice, err := types.BigFromString(cctx.String("gas-premium"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("failed to parse gas-price flag: %s", err)
|
return xerrors.Errorf("failed to parse gas-price flag: %s", err)
|
||||||
}
|
}
|
||||||
@ -552,13 +552,12 @@ func configureStorageMiner(ctx context.Context, api lapi.FullNode, addr address.
|
|||||||
}
|
}
|
||||||
|
|
||||||
msg := &types.Message{
|
msg := &types.Message{
|
||||||
To: addr,
|
To: addr,
|
||||||
From: mi.Worker,
|
From: mi.Worker,
|
||||||
Method: builtin.MethodsMiner.ChangePeerID,
|
Method: builtin.MethodsMiner.ChangePeerID,
|
||||||
Params: enc,
|
Params: enc,
|
||||||
Value: types.NewInt(0),
|
Value: types.NewInt(0),
|
||||||
GasPrice: gasPrice,
|
GasPremium: gasPrice,
|
||||||
GasLimit: 0,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
smsg, err := api.MpoolPushMessage(ctx, msg)
|
smsg, err := api.MpoolPushMessage(ctx, msg)
|
||||||
@ -637,8 +636,8 @@ func createStorageMiner(ctx context.Context, api lapi.FullNode, peerid peer.ID,
|
|||||||
Method: builtin.MethodsPower.CreateMiner,
|
Method: builtin.MethodsPower.CreateMiner,
|
||||||
Params: params,
|
Params: params,
|
||||||
|
|
||||||
GasLimit: 0,
|
GasLimit: 0,
|
||||||
GasPrice: gasPrice,
|
GasPremium: gasPrice,
|
||||||
}
|
}
|
||||||
|
|
||||||
signed, err := api.MpoolPushMessage(ctx, createStorageMinerMsg)
|
signed, err := api.MpoolPushMessage(ctx, createStorageMinerMsg)
|
||||||
|
2
extern/serialization-vectors
vendored
2
extern/serialization-vectors
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 0cef69d481950d24f0e26e2698e585a8bf203913
|
Subproject commit 5bfb928910b01ac8b940a693af2884f7f8276211
|
2
go.mod
2
go.mod
@ -18,7 +18,7 @@ require (
|
|||||||
github.com/drand/drand v1.0.3-0.20200714175734-29705eaf09d4
|
github.com/drand/drand v1.0.3-0.20200714175734-29705eaf09d4
|
||||||
github.com/drand/kyber v1.1.1
|
github.com/drand/kyber v1.1.1
|
||||||
github.com/fatih/color v1.8.0
|
github.com/fatih/color v1.8.0
|
||||||
github.com/filecoin-project/chain-validation v0.0.6-0.20200805210314-9844c5869f53
|
github.com/filecoin-project/chain-validation v0.0.6-0.20200807023228-a084d8d9919e
|
||||||
github.com/filecoin-project/filecoin-ffi v0.30.4-0.20200716204036-cddc56607e1d
|
github.com/filecoin-project/filecoin-ffi v0.30.4-0.20200716204036-cddc56607e1d
|
||||||
github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef
|
github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef
|
||||||
github.com/filecoin-project/go-amt-ipld/v2 v2.1.1-0.20200731171407-e559a0579161 // indirect
|
github.com/filecoin-project/go-amt-ipld/v2 v2.1.1-0.20200731171407-e559a0579161 // indirect
|
||||||
|
5
go.sum
5
go.sum
@ -215,8 +215,8 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv
|
|||||||
github.com/fatih/color v1.8.0 h1:5bzFgL+oy7JITMTxUPJ00n7VxmYd/PdMp5mHFX40/RY=
|
github.com/fatih/color v1.8.0 h1:5bzFgL+oy7JITMTxUPJ00n7VxmYd/PdMp5mHFX40/RY=
|
||||||
github.com/fatih/color v1.8.0/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGjnw8=
|
github.com/fatih/color v1.8.0/go.mod h1:3l45GVGkyrnYNl9HoIjnp2NnNWvh6hLAqD8yTfGjnw8=
|
||||||
github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E=
|
github.com/fd/go-nat v1.0.0/go.mod h1:BTBu/CKvMmOMUPkKVef1pngt2WFH/lg7E6yQnulfp6E=
|
||||||
github.com/filecoin-project/chain-validation v0.0.6-0.20200805210314-9844c5869f53 h1:XRrMct6lOMjVe11dOnurq6vsLayQQyotFJi0YW4Wp8E=
|
github.com/filecoin-project/chain-validation v0.0.6-0.20200807023228-a084d8d9919e h1:qHdxD1Of7i6yyFezaKNWk36CBNWGRHszp44oTq4oDQ0=
|
||||||
github.com/filecoin-project/chain-validation v0.0.6-0.20200805210314-9844c5869f53/go.mod h1:JICNIbIEZ+qNJ/PQlHxjei6SaeBbW+yV2r4BcShsXfI=
|
github.com/filecoin-project/chain-validation v0.0.6-0.20200807023228-a084d8d9919e/go.mod h1:jtOqSVob11urlSIM8Gw3XIrqmiqb+fBr7ZBIbOhzGPI=
|
||||||
github.com/filecoin-project/go-address v0.0.0-20200107215422-da8eea2842b5/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0=
|
github.com/filecoin-project/go-address v0.0.0-20200107215422-da8eea2842b5/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0=
|
||||||
github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0=
|
github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be/go.mod h1:SAOwJoakQ8EPjwNIsiakIQKsoKdkcbx8U3IapgCg9R0=
|
||||||
github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef h1:Wi5E+P1QfHP8IF27eUiTx5vYfqQZwfPxzq3oFEq8w8U=
|
github.com/filecoin-project/go-address v0.0.2-0.20200504173055-8b6f2fb2b3ef h1:Wi5E+P1QfHP8IF27eUiTx5vYfqQZwfPxzq3oFEq8w8U=
|
||||||
@ -270,7 +270,6 @@ github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVl
|
|||||||
github.com/filecoin-project/specs-actors v0.6.1/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY=
|
github.com/filecoin-project/specs-actors v0.6.1/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY=
|
||||||
github.com/filecoin-project/specs-actors v0.7.3-0.20200716231407-60a2ae96d2e6/go.mod h1:JOMUa7EijvpOO4ofD1yeHNmqohkmmnhTvz/IpB6so4c=
|
github.com/filecoin-project/specs-actors v0.7.3-0.20200716231407-60a2ae96d2e6/go.mod h1:JOMUa7EijvpOO4ofD1yeHNmqohkmmnhTvz/IpB6so4c=
|
||||||
github.com/filecoin-project/specs-actors v0.8.2/go.mod h1:Q3ACV5kBLvqPaYbthc/J1lGMJ5OwogmD9pzdtPRMdCw=
|
github.com/filecoin-project/specs-actors v0.8.2/go.mod h1:Q3ACV5kBLvqPaYbthc/J1lGMJ5OwogmD9pzdtPRMdCw=
|
||||||
github.com/filecoin-project/specs-actors v0.8.5/go.mod h1:Q3ACV5kBLvqPaYbthc/J1lGMJ5OwogmD9pzdtPRMdCw=
|
|
||||||
github.com/filecoin-project/specs-actors v0.8.7-0.20200805174427-9d42fb163883 h1:/LOix6EwCWshEuufhM8gAuCqP5jPWVMqPZn8HUQCw3Y=
|
github.com/filecoin-project/specs-actors v0.8.7-0.20200805174427-9d42fb163883 h1:/LOix6EwCWshEuufhM8gAuCqP5jPWVMqPZn8HUQCw3Y=
|
||||||
github.com/filecoin-project/specs-actors v0.8.7-0.20200805174427-9d42fb163883/go.mod h1:QRihI/fadrhWzt7HH6mT32upOdDFpSYCFnr3JEI1L50=
|
github.com/filecoin-project/specs-actors v0.8.7-0.20200805174427-9d42fb163883/go.mod h1:QRihI/fadrhWzt7HH6mT32upOdDFpSYCFnr3JEI1L50=
|
||||||
github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea h1:iixjULRQFPn7Q9KlIqfwLJnlAXO10bbkI+xy5GKGdLY=
|
github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea h1:iixjULRQFPn7Q9KlIqfwLJnlAXO10bbkI+xy5GKGdLY=
|
||||||
|
@ -123,12 +123,10 @@ func (c *ClientNodeAdapter) ListClientDeals(ctx context.Context, addr address.Ad
|
|||||||
func (c *ClientNodeAdapter) AddFunds(ctx context.Context, addr address.Address, amount abi.TokenAmount) (cid.Cid, error) {
|
func (c *ClientNodeAdapter) AddFunds(ctx context.Context, addr address.Address, amount abi.TokenAmount) (cid.Cid, error) {
|
||||||
// (Provider Node API)
|
// (Provider Node API)
|
||||||
smsg, err := c.MpoolPushMessage(ctx, &types.Message{
|
smsg, err := c.MpoolPushMessage(ctx, &types.Message{
|
||||||
To: builtin.StorageMarketActorAddr,
|
To: builtin.StorageMarketActorAddr,
|
||||||
From: addr,
|
From: addr,
|
||||||
Value: amount,
|
Value: amount,
|
||||||
GasPrice: types.NewInt(0),
|
Method: builtin.MethodsMarket.AddBalance,
|
||||||
GasLimit: 0,
|
|
||||||
Method: builtin.MethodsMarket.AddBalance,
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, err
|
return cid.Undef, err
|
||||||
|
@ -74,13 +74,11 @@ func (n *ProviderNodeAdapter) PublishDeals(ctx context.Context, deal storagemark
|
|||||||
|
|
||||||
// TODO: We may want this to happen after fetching data
|
// TODO: We may want this to happen after fetching data
|
||||||
smsg, err := n.MpoolPushMessage(ctx, &types.Message{
|
smsg, err := n.MpoolPushMessage(ctx, &types.Message{
|
||||||
To: builtin.StorageMarketActorAddr,
|
To: builtin.StorageMarketActorAddr,
|
||||||
From: mi.Worker,
|
From: mi.Worker,
|
||||||
Value: types.NewInt(0),
|
Value: types.NewInt(0),
|
||||||
GasPrice: types.NewInt(0),
|
Method: builtin.MethodsMarket.PublishStorageDeals,
|
||||||
GasLimit: 0,
|
Params: params,
|
||||||
Method: builtin.MethodsMarket.PublishStorageDeals,
|
|
||||||
Params: params,
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, err
|
return cid.Undef, err
|
||||||
@ -175,12 +173,10 @@ func (n *ProviderNodeAdapter) EnsureFunds(ctx context.Context, addr, wallet addr
|
|||||||
func (n *ProviderNodeAdapter) AddFunds(ctx context.Context, addr address.Address, amount abi.TokenAmount) (cid.Cid, error) {
|
func (n *ProviderNodeAdapter) AddFunds(ctx context.Context, addr address.Address, amount abi.TokenAmount) (cid.Cid, error) {
|
||||||
// (Provider Node API)
|
// (Provider Node API)
|
||||||
smsg, err := n.MpoolPushMessage(ctx, &types.Message{
|
smsg, err := n.MpoolPushMessage(ctx, &types.Message{
|
||||||
To: builtin.StorageMarketActorAddr,
|
To: builtin.StorageMarketActorAddr,
|
||||||
From: addr,
|
From: addr,
|
||||||
Value: amount,
|
Value: amount,
|
||||||
GasPrice: types.NewInt(0),
|
Method: builtin.MethodsMarket.AddBalance,
|
||||||
GasLimit: 0,
|
|
||||||
Method: builtin.MethodsMarket.AddBalance,
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, err
|
return cid.Undef, err
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
"github.com/ipfs/go-cid"
|
cid "github.com/ipfs/go-cid"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
xerrors "golang.org/x/xerrors"
|
xerrors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
package impl
|
package impl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
|
|
||||||
logging "github.com/ipfs/go-log/v2"
|
logging "github.com/ipfs/go-log/v2"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
"github.com/filecoin-project/lotus/node/impl/client"
|
"github.com/filecoin-project/lotus/node/impl/client"
|
||||||
"github.com/filecoin-project/lotus/node/impl/common"
|
"github.com/filecoin-project/lotus/node/impl/common"
|
||||||
"github.com/filecoin-project/lotus/node/impl/full"
|
"github.com/filecoin-project/lotus/node/impl/full"
|
||||||
@ -32,10 +28,4 @@ type FullNodeAPI struct {
|
|||||||
full.BeaconAPI
|
full.BeaconAPI
|
||||||
}
|
}
|
||||||
|
|
||||||
// MpoolEstimateGasPrice estimates gas price
|
|
||||||
// Deprecated: used GasEstimateGasPrice instead
|
|
||||||
func (fa *FullNodeAPI) MpoolEstimateGasPrice(ctx context.Context, nblocksincl uint64, sender address.Address, limit int64, tsk types.TipSetKey) (types.BigInt, error) {
|
|
||||||
return fa.GasEstimateGasPrice(ctx, nblocksincl, sender, limit, tsk)
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ api.FullNode = &FullNodeAPI{}
|
var _ api.FullNode = &FullNodeAPI{}
|
||||||
|
@ -2,6 +2,7 @@ package full
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"math"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
@ -26,9 +27,22 @@ type GasAPI struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const MinGasPrice = 1
|
const MinGasPrice = 1
|
||||||
|
const BaseFeeEstimNBlocks = 20
|
||||||
|
|
||||||
func (a *GasAPI) GasEstimateGasPrice(ctx context.Context, nblocksincl uint64,
|
func (a *GasAPI) GasEstimateFeeCap(ctx context.Context, maxqueueblks int64,
|
||||||
sender address.Address, gaslimit int64, tsk types.TipSetKey) (types.BigInt, error) {
|
tsk types.TipSetKey) (types.BigInt, error) {
|
||||||
|
ts := a.Chain.GetHeaviestTipSet()
|
||||||
|
|
||||||
|
parentBaseFee := ts.Blocks()[0].ParentBaseFee
|
||||||
|
increaseFactor := math.Pow(1+float64(1/build.BaseFeeMaxChangeDenom), BaseFeeEstimNBlocks)
|
||||||
|
|
||||||
|
out := types.BigMul(parentBaseFee, types.NewInt(uint64(increaseFactor*(1<<8))))
|
||||||
|
out = types.BigDiv(out, types.NewInt(1<<8))
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *GasAPI) GasEsitmateGasPremium(ctx context.Context, nblocksincl uint64,
|
||||||
|
sender address.Address, gaslimit int64, _ types.TipSetKey) (types.BigInt, error) {
|
||||||
|
|
||||||
if nblocksincl == 0 {
|
if nblocksincl == 0 {
|
||||||
nblocksincl = 1
|
nblocksincl = 1
|
||||||
@ -68,7 +82,7 @@ func (a *GasAPI) GasEstimateGasPrice(ctx context.Context, nblocksincl uint64,
|
|||||||
}
|
}
|
||||||
|
|
||||||
prices = append(prices, gasMeta{
|
prices = append(prices, gasMeta{
|
||||||
price: msg.VMMessage().GasPrice,
|
price: msg.VMMessage().GasPremium,
|
||||||
used: r.GasUsed,
|
used: r.GasUsed,
|
||||||
})
|
})
|
||||||
gasUsed += r.GasUsed
|
gasUsed += r.GasUsed
|
||||||
@ -111,7 +125,8 @@ func (a *GasAPI) GasEstimateGasLimit(ctx context.Context, msgIn *types.Message,
|
|||||||
|
|
||||||
msg := *msgIn
|
msg := *msgIn
|
||||||
msg.GasLimit = build.BlockGasLimit
|
msg.GasLimit = build.BlockGasLimit
|
||||||
msg.GasPrice = types.NewInt(1)
|
msg.GasFeeCap = types.NewInt(build.MinimumBaseFee + 1)
|
||||||
|
msg.GasPremium = types.NewInt(1)
|
||||||
|
|
||||||
currTs := a.Chain.GetHeaviestTipSet()
|
currTs := a.Chain.GetHeaviestTipSet()
|
||||||
fromA, err := a.Stmgr.ResolveToKeyAddress(ctx, msgIn.From, currTs)
|
fromA, err := a.Stmgr.ResolveToKeyAddress(ctx, msgIn.From, currTs)
|
||||||
|
@ -111,12 +111,20 @@ func (a *MpoolAPI) MpoolPushMessage(ctx context.Context, msg *types.Message) (*t
|
|||||||
msg.GasLimit = int64(float64(gasLimit) * GasMargin)
|
msg.GasLimit = int64(float64(gasLimit) * GasMargin)
|
||||||
}
|
}
|
||||||
|
|
||||||
if msg.GasPrice == types.EmptyInt || types.BigCmp(msg.GasPrice, types.NewInt(0)) == 0 {
|
if msg.GasPremium == types.EmptyInt || types.BigCmp(msg.GasPremium, types.NewInt(0)) == 0 {
|
||||||
gasPrice, err := a.GasEstimateGasPrice(ctx, 2, msg.From, msg.GasLimit, types.TipSetKey{})
|
gasPremium, err := a.GasEsitmateGasPremium(ctx, 2, msg.From, msg.GasLimit, types.TipSetKey{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("estimating gas price: %w", err)
|
return nil, xerrors.Errorf("estimating gas price: %w", err)
|
||||||
}
|
}
|
||||||
msg.GasPrice = gasPrice
|
msg.GasPremium = gasPremium
|
||||||
|
}
|
||||||
|
|
||||||
|
if msg.GasFeeCap == types.EmptyInt || types.BigCmp(msg.GasFeeCap, types.NewInt(0)) == 0 {
|
||||||
|
feeCap, err := a.GasEstimateFeeCap(ctx, 20, types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("estimating fee cap: %w", err)
|
||||||
|
}
|
||||||
|
msg.GasFeeCap = feeCap
|
||||||
}
|
}
|
||||||
|
|
||||||
return a.Mpool.PushWithNonce(ctx, msg.From, func(from address.Address, nonce uint64) (*types.SignedMessage, error) {
|
return a.Mpool.PushWithNonce(ctx, msg.From, func(from address.Address, nonce uint64) (*types.SignedMessage, error) {
|
||||||
|
@ -45,10 +45,6 @@ func (a *MsigAPI) MsigCreate(ctx context.Context, req uint64, addrs []address.Ad
|
|||||||
return cid.Undef, xerrors.Errorf("must provide source address")
|
return cid.Undef, xerrors.Errorf("must provide source address")
|
||||||
}
|
}
|
||||||
|
|
||||||
if gp == types.EmptyInt {
|
|
||||||
gp = types.NewInt(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up constructor parameters for multisig
|
// Set up constructor parameters for multisig
|
||||||
msigParams := &samsig.ConstructorParams{
|
msigParams := &samsig.ConstructorParams{
|
||||||
Signers: addrs,
|
Signers: addrs,
|
||||||
@ -74,12 +70,11 @@ func (a *MsigAPI) MsigCreate(ctx context.Context, req uint64, addrs []address.Ad
|
|||||||
|
|
||||||
// now we create the message to send this with
|
// now we create the message to send this with
|
||||||
msg := types.Message{
|
msg := types.Message{
|
||||||
To: builtin.InitActorAddr,
|
To: builtin.InitActorAddr,
|
||||||
From: src,
|
From: src,
|
||||||
Method: builtin.MethodsInit.Exec,
|
Method: builtin.MethodsInit.Exec,
|
||||||
Params: enc,
|
Params: enc,
|
||||||
Value: val,
|
Value: val,
|
||||||
GasPrice: gp,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// send the message out to the network
|
// send the message out to the network
|
||||||
|
@ -968,12 +968,10 @@ func (a *StateAPI) StateMinerPreCommitDepositForPower(ctx context.Context, maddr
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret, err := a.StateManager.Call(ctx, &types.Message{
|
ret, err := a.StateManager.Call(ctx, &types.Message{
|
||||||
From: maddr,
|
From: maddr,
|
||||||
To: builtin.StorageMarketActorAddr,
|
To: builtin.StorageMarketActorAddr,
|
||||||
Method: builtin.MethodsMarket.VerifyDealsForActivation,
|
Method: builtin.MethodsMarket.VerifyDealsForActivation,
|
||||||
GasLimit: 0,
|
Params: params,
|
||||||
GasPrice: types.NewInt(0),
|
|
||||||
Params: params,
|
|
||||||
}, ts)
|
}, ts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.EmptyInt, err
|
return types.EmptyInt, err
|
||||||
@ -1048,12 +1046,10 @@ func (a *StateAPI) StateMinerInitialPledgeCollateral(ctx context.Context, maddr
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret, err := a.StateManager.Call(ctx, &types.Message{
|
ret, err := a.StateManager.Call(ctx, &types.Message{
|
||||||
From: maddr,
|
From: maddr,
|
||||||
To: builtin.StorageMarketActorAddr,
|
To: builtin.StorageMarketActorAddr,
|
||||||
Method: builtin.MethodsMarket.VerifyDealsForActivation,
|
Method: builtin.MethodsMarket.VerifyDealsForActivation,
|
||||||
GasLimit: 0,
|
Params: params,
|
||||||
GasPrice: types.NewInt(0),
|
|
||||||
Params: params,
|
|
||||||
}, ts)
|
}, ts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.EmptyInt, err
|
return types.EmptyInt, err
|
||||||
|
@ -103,13 +103,11 @@ func testStorageNode(ctx context.Context, t *testing.T, waddr address.Address, a
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
msg := &types.Message{
|
msg := &types.Message{
|
||||||
To: act,
|
To: act,
|
||||||
From: waddr,
|
From: waddr,
|
||||||
Method: builtin.MethodsMiner.ChangePeerID,
|
Method: builtin.MethodsMiner.ChangePeerID,
|
||||||
Params: enc,
|
Params: enc,
|
||||||
Value: types.NewInt(0),
|
Value: types.NewInt(0),
|
||||||
GasPrice: types.NewInt(0),
|
|
||||||
GasLimit: 0,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = tnd.MpoolPushMessage(ctx, msg)
|
_, err = tnd.MpoolPushMessage(ctx, msg)
|
||||||
|
@ -241,13 +241,11 @@ func (ca *channelAccessor) createPaych(ctx context.Context, from, to address.Add
|
|||||||
}
|
}
|
||||||
|
|
||||||
msg := &types.Message{
|
msg := &types.Message{
|
||||||
To: builtin.InitActorAddr,
|
To: builtin.InitActorAddr,
|
||||||
From: from,
|
From: from,
|
||||||
Value: amt,
|
Value: amt,
|
||||||
Method: builtin.MethodsInit.Exec,
|
Method: builtin.MethodsInit.Exec,
|
||||||
Params: enc,
|
Params: enc,
|
||||||
GasLimit: 0,
|
|
||||||
GasPrice: types.NewInt(0),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
smsg, err := ca.api.MpoolPushMessage(ctx, msg)
|
smsg, err := ca.api.MpoolPushMessage(ctx, msg)
|
||||||
@ -323,12 +321,10 @@ func (ca *channelAccessor) waitPaychCreateMsg(channelID string, mcid cid.Cid) er
|
|||||||
// addFunds sends a message to add funds to the channel and returns the message cid
|
// addFunds sends a message to add funds to the channel and returns the message cid
|
||||||
func (ca *channelAccessor) addFunds(ctx context.Context, channelInfo *ChannelInfo, amt types.BigInt, cb onCompleteFn) (*cid.Cid, error) {
|
func (ca *channelAccessor) addFunds(ctx context.Context, channelInfo *ChannelInfo, amt types.BigInt, cb onCompleteFn) (*cid.Cid, error) {
|
||||||
msg := &types.Message{
|
msg := &types.Message{
|
||||||
To: *channelInfo.Channel,
|
To: *channelInfo.Channel,
|
||||||
From: channelInfo.Control,
|
From: channelInfo.Control,
|
||||||
Value: amt,
|
Value: amt,
|
||||||
Method: 0,
|
Method: 0,
|
||||||
GasLimit: 0,
|
|
||||||
GasPrice: types.NewInt(0),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
smsg, err := ca.api.MpoolPushMessage(ctx, msg)
|
smsg, err := ca.api.MpoolPushMessage(ctx, msg)
|
||||||
|
@ -237,15 +237,16 @@ func (s SealingAPIAdapter) StateMarketStorageDeal(ctx context.Context, dealID ab
|
|||||||
return deal.Proposal, nil
|
return deal.Proposal, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: rename/remove gasPrice and gasLimit
|
||||||
func (s SealingAPIAdapter) SendMsg(ctx context.Context, from, to address.Address, method abi.MethodNum, value, gasPrice big.Int, gasLimit int64, params []byte) (cid.Cid, error) {
|
func (s SealingAPIAdapter) SendMsg(ctx context.Context, from, to address.Address, method abi.MethodNum, value, gasPrice big.Int, gasLimit int64, params []byte) (cid.Cid, error) {
|
||||||
msg := types.Message{
|
msg := types.Message{
|
||||||
To: to,
|
To: to,
|
||||||
From: from,
|
From: from,
|
||||||
Value: value,
|
Value: value,
|
||||||
GasPrice: gasPrice,
|
GasPremium: gasPrice,
|
||||||
GasLimit: gasLimit,
|
GasLimit: gasLimit,
|
||||||
Method: method,
|
Method: method,
|
||||||
Params: params,
|
Params: params,
|
||||||
}
|
}
|
||||||
|
|
||||||
smsg, err := s.delegate.MpoolPushMessage(ctx, &msg)
|
smsg, err := s.delegate.MpoolPushMessage(ctx, &msg)
|
||||||
|
@ -281,7 +281,10 @@ func RecordTipsetMessagesPoints(ctx context.Context, api api.FullNode, pl *Point
|
|||||||
msgn := make(map[msgTag][]cid.Cid)
|
msgn := make(map[msgTag][]cid.Cid)
|
||||||
|
|
||||||
for i, msg := range msgs {
|
for i, msg := range msgs {
|
||||||
p := NewPoint("chain.message_gasprice", msg.Message.GasPrice.Int64())
|
// FIXME: use float so this doesn't overflow
|
||||||
|
p := NewPoint("chain.message_gaspremium", msg.Message.GasPremium.Int64())
|
||||||
|
pl.AddPoint(p)
|
||||||
|
p = NewPoint("chain.message_gasfeecap", msg.Message.GasFeeCap.Int64())
|
||||||
pl.AddPoint(p)
|
pl.AddPoint(p)
|
||||||
|
|
||||||
bs, err := msg.Message.Serialize()
|
bs, err := msg.Message.Serialize()
|
||||||
|
Loading…
Reference in New Issue
Block a user