Skip to content

Commit 82df3ce

Browse files
joshua-kimStephenButtolphmeaghanfitzgerald
authored
Sort transactions by gas price in P-Chain mempool (#3715)
Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Co-authored-by: Stephen Buttolph <stephen@avalabs.org> Co-authored-by: Meaghan FitzGerald <meag.fitz@avalabs.org>
1 parent dce38e9 commit 82df3ce

25 files changed

+2451
-413
lines changed

vms/platformvm/block/builder/builder.go

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import (
2525
"github.com/ava-labs/avalanchego/vms/platformvm/status"
2626
"github.com/ava-labs/avalanchego/vms/platformvm/txs"
2727
"github.com/ava-labs/avalanchego/vms/platformvm/txs/fee"
28-
"github.com/ava-labs/avalanchego/vms/txs/mempool"
28+
"github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool"
2929

3030
smblock "github.com/ava-labs/avalanchego/snow/engine/snowman/block"
3131
blockexecutor "github.com/ava-labs/avalanchego/vms/platformvm/block/executor"
@@ -53,7 +53,15 @@ var (
5353

5454
type Builder interface {
5555
smblock.BuildBlockWithContextChainVM
56-
mempool.Mempool[*txs.Tx]
56+
// Add adds `tx` to the mempool and clears its dropped status.
57+
Add(tx *txs.Tx) error
58+
// Get returns the tx corresponding to `txID` and if it was present
59+
Get(txID ids.ID) (*txs.Tx, bool)
60+
// GetDropReason returns why `txID` was dropped
61+
GetDropReason(txID ids.ID) error
62+
// WaitForEvent blocks until the mempool has txs that are ready to build into
63+
// a block.
64+
WaitForEvent(ctx context.Context) (common.Message, error)
5765

5866
// BuildBlock can be called to attempt to create a new block
5967
BuildBlock(context.Context) (snowman.Block, error)
@@ -68,14 +76,14 @@ type Builder interface {
6876

6977
// builder implements a simple builder to convert txs into valid blocks
7078
type builder struct {
71-
mempool.Mempool[*txs.Tx]
79+
*mempool.Mempool
7280

7381
txExecutorBackend *txexecutor.Backend
7482
blkManager blockexecutor.Manager
7583
}
7684

7785
func New(
78-
mempool mempool.Mempool[*txs.Tx],
86+
mempool *mempool.Mempool,
7987
txExecutorBackend *txexecutor.Backend,
8088
blkManager blockexecutor.Manager,
8189
) Builder {
@@ -348,7 +356,7 @@ func packDurangoBlockTxs(
348356
ctx context.Context,
349357
parentID ids.ID,
350358
parentState state.Chain,
351-
mempool mempool.Mempool[*txs.Tx],
359+
mempool *mempool.Mempool,
352360
backend *txexecutor.Backend,
353361
manager blockexecutor.Manager,
354362
timestamp time.Time,
@@ -409,7 +417,7 @@ func packEtnaBlockTxs(
409417
ctx context.Context,
410418
parentID ids.ID,
411419
parentState state.Chain,
412-
mempool mempool.Mempool[*txs.Tx],
420+
mempool *mempool.Mempool,
413421
backend *txexecutor.Backend,
414422
manager blockexecutor.Manager,
415423
timestamp time.Time,
@@ -509,15 +517,15 @@ func executeTx(
509517
ctx context.Context,
510518
parentID ids.ID,
511519
stateDiff state.Diff,
512-
mempool mempool.Mempool[*txs.Tx],
520+
mempool *mempool.Mempool,
513521
backend *txexecutor.Backend,
514522
manager blockexecutor.Manager,
515523
pChainHeight uint64,
516524
inputs *set.Set[ids.ID],
517525
feeCalculator fee.Calculator,
518526
tx *txs.Tx,
519527
) (bool, error) {
520-
mempool.Remove(tx)
528+
mempool.Remove(tx.ID())
521529

522530
// Invariant: [tx] has already been syntactically verified.
523531

vms/platformvm/block/builder/helpers_test.go

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
"github.com/ava-labs/avalanchego/utils/logging"
3333
"github.com/ava-labs/avalanchego/utils/timer/mockable"
3434
"github.com/ava-labs/avalanchego/utils/units"
35+
"github.com/ava-labs/avalanchego/vms/components/gas"
3536
"github.com/ava-labs/avalanchego/vms/platformvm/config"
3637
"github.com/ava-labs/avalanchego/vms/platformvm/fx"
3738
"github.com/ava-labs/avalanchego/vms/platformvm/genesis/genesistest"
@@ -51,7 +52,6 @@ import (
5152

5253
blockexecutor "github.com/ava-labs/avalanchego/vms/platformvm/block/executor"
5354
txexecutor "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor"
54-
txmempool "github.com/ava-labs/avalanchego/vms/txs/mempool"
5555
)
5656

5757
const (
@@ -68,7 +68,7 @@ type mutableSharedMemory struct {
6868
type environment struct {
6969
Builder
7070
blkManager blockexecutor.Manager
71-
mempool txmempool.Mempool[*txs.Tx]
71+
mempool *mempool.Mempool
7272
network *network.Network
7373
sender *enginetest.Sender
7474

@@ -143,7 +143,13 @@ func newEnvironment(t *testing.T, f upgradetest.Fork) *environment { //nolint:un
143143
metrics, err := metrics.New(registerer)
144144
require.NoError(err)
145145

146-
res.mempool, err = mempool.New("mempool", registerer)
146+
res.mempool, err = mempool.New(
147+
"mempool",
148+
res.config.DynamicFeeConfig.Weights,
149+
1_000_000,
150+
res.ctx.AVAXAssetID,
151+
registerer,
152+
)
147153
require.NoError(err)
148154

149155
res.blkManager = blockexecutor.NewManager(
@@ -181,6 +187,10 @@ func newEnvironment(t *testing.T, f upgradetest.Fork) *environment { //nolint:un
181187
res.blkManager.SetPreference(genesisID, nil)
182188
addSubnet(t, res)
183189

190+
// Dynamic fees require us to build blocks with a non-zero difference in time
191+
// from the last block
192+
res.clk.Set(res.clk.Time().Add(time.Second))
193+
184194
t.Cleanup(func() {
185195
res.ctx.Lock.Lock()
186196
defer res.ctx.Lock.Unlock()
@@ -272,11 +282,19 @@ func defaultConfig(f upgradetest.Fork) *config.Internal {
272282
Chains: chains.TestManager,
273283
UptimeLockedCalculator: uptime.NewLockedCalculator(),
274284
Validators: validators.NewManager(),
275-
MinValidatorStake: 5 * units.MilliAvax,
276-
MaxValidatorStake: 500 * units.MilliAvax,
277-
MinDelegatorStake: 1 * units.MilliAvax,
278-
MinStakeDuration: defaultMinStakingDuration,
279-
MaxStakeDuration: defaultMaxStakingDuration,
285+
DynamicFeeConfig: gas.Config{
286+
Weights: gas.Dimensions{1, 1, 1, 1},
287+
MaxCapacity: 1_000_000,
288+
MaxPerSecond: 1_000_000,
289+
TargetPerSecond: 100,
290+
MinPrice: 1,
291+
ExcessConversionConstant: 1,
292+
},
293+
MinValidatorStake: 5 * units.MilliAvax,
294+
MaxValidatorStake: 500 * units.MilliAvax,
295+
MinDelegatorStake: 1 * units.MilliAvax,
296+
MinStakeDuration: defaultMinStakingDuration,
297+
MaxStakeDuration: defaultMaxStakingDuration,
280298
RewardConfig: reward.Config{
281299
MaxConsumptionRate: .12 * reward.PercentDenominator,
282300
MinConsumptionRate: .10 * reward.PercentDenominator,

vms/platformvm/block/executor/backend.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,14 @@ import (
1212
"github.com/ava-labs/avalanchego/utils/set"
1313
"github.com/ava-labs/avalanchego/vms/platformvm/block"
1414
"github.com/ava-labs/avalanchego/vms/platformvm/state"
15-
"github.com/ava-labs/avalanchego/vms/platformvm/txs"
16-
"github.com/ava-labs/avalanchego/vms/txs/mempool"
15+
"github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool"
1716
)
1817

1918
var errConflictingParentTxs = errors.New("block contains a transaction that conflicts with a transaction in a parent block")
2019

2120
// Shared fields used by visitors.
2221
type backend struct {
23-
mempool.Mempool[*txs.Tx]
22+
*mempool.Mempool
2423
// lastAccepted is the ID of the last block that had Accept() called on it.
2524
lastAccepted ids.ID
2625

vms/platformvm/block/executor/helpers_test.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ import (
4747
"github.com/ava-labs/avalanchego/vms/platformvm/validators/validatorstest"
4848
"github.com/ava-labs/avalanchego/vms/secp256k1fx"
4949
"github.com/ava-labs/avalanchego/wallet/chain/p/wallet"
50-
51-
txmempool "github.com/ava-labs/avalanchego/vms/txs/mempool"
5250
)
5351

5452
const (
@@ -82,7 +80,7 @@ type test struct {
8280

8381
type environment struct {
8482
blkManager Manager
85-
mempool txmempool.Mempool[*txs.Tx]
83+
mempool *mempool.Mempool
8684

8785
isBootstrapped *utils.Atomic[bool]
8886
config *config.Internal
@@ -152,7 +150,13 @@ func newEnvironment(t *testing.T, ctrl *gomock.Controller, f upgradetest.Fork) *
152150
metrics := metrics.Noop
153151

154152
var err error
155-
res.mempool, err = mempool.New("mempool", registerer)
153+
res.mempool, err = mempool.New(
154+
"mempool",
155+
res.config.DynamicFeeConfig.Weights,
156+
1_000_000,
157+
res.ctx.AVAXAssetID,
158+
registerer,
159+
)
156160
if err != nil {
157161
panic(fmt.Errorf("failed to create mempool: %w", err))
158162
}

vms/platformvm/block/executor/manager.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ import (
1717
"github.com/ava-labs/avalanchego/vms/platformvm/txs"
1818
"github.com/ava-labs/avalanchego/vms/platformvm/txs/executor"
1919
"github.com/ava-labs/avalanchego/vms/platformvm/txs/fee"
20+
"github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool"
2021
"github.com/ava-labs/avalanchego/vms/platformvm/validators"
21-
"github.com/ava-labs/avalanchego/vms/txs/mempool"
2222

2323
snowmanblock "github.com/ava-labs/avalanchego/snow/engine/snowman/block"
2424
)
@@ -53,7 +53,7 @@ type Manager interface {
5353
}
5454

5555
func NewManager(
56-
mempool mempool.Mempool[*txs.Tx],
56+
mempool *mempool.Mempool,
5757
metrics metrics.Metrics,
5858
s state.State,
5959
txExecutorBackend *executor.Backend,

vms/platformvm/block/executor/rejector_test.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/ava-labs/avalanchego/ids"
1515
"github.com/ava-labs/avalanchego/snow"
1616
"github.com/ava-labs/avalanchego/utils/logging"
17+
"github.com/ava-labs/avalanchego/vms/components/gas"
1718
"github.com/ava-labs/avalanchego/vms/components/verify"
1819
"github.com/ava-labs/avalanchego/vms/platformvm/block"
1920
"github.com/ava-labs/avalanchego/vms/platformvm/state"
@@ -120,7 +121,13 @@ func TestRejectBlock(t *testing.T) {
120121
blk, err := tt.newBlockFunc()
121122
require.NoError(err)
122123

123-
mempool, err := mempool.New("", prometheus.NewRegistry())
124+
mempool, err := mempool.New(
125+
"",
126+
gas.Dimensions{},
127+
1_000_000,
128+
ids.ID{},
129+
prometheus.NewRegistry(),
130+
)
124131
require.NoError(err)
125132
state := state.NewMockState(ctrl)
126133
blkIDToState := map[ids.ID]*blockState{

vms/platformvm/block/executor/verifier.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ func (v *verifier) ApricotAtomicBlock(b *block.ApricotAtomicBlock) error {
243243
return err
244244
}
245245

246-
v.Mempool.Remove(b.Tx)
246+
v.Mempool.RemoveConflicts(b.Tx.InputIDs())
247247

248248
blkID := b.ID()
249249
v.blkIDToState[blkID] = &blockState{
@@ -432,7 +432,7 @@ func (v *verifier) proposalBlock(
432432
onCommitState.AddTx(tx, status.Committed)
433433
onAbortState.AddTx(tx, status.Aborted)
434434

435-
v.Mempool.Remove(tx)
435+
v.Mempool.RemoveConflicts(tx.InputIDs())
436436

437437
blkID := b.ID()
438438
v.blkIDToState[blkID] = &blockState{
@@ -490,7 +490,9 @@ func (v *verifier) standardBlock(
490490
return ErrStandardBlockWithoutChanges
491491
}
492492

493-
v.Mempool.Remove(txs...)
493+
for _, tx := range txs {
494+
v.Mempool.RemoveConflicts(tx.InputIDs())
495+
}
494496

495497
blkID := b.ID()
496498
v.blkIDToState[blkID] = &blockState{

vms/platformvm/block/executor/verifier_test.go

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,13 @@ func newTestVerifier(t testing.TB, c testVerifierConfig) *verifier {
7474
c.ValidatorFeeConfig = genesis.LocalParams.ValidatorFeeConfig
7575
}
7676

77-
mempool, err := mempool.New("", prometheus.NewRegistry())
77+
mempool, err := mempool.New(
78+
"",
79+
gas.Dimensions{},
80+
1_000_000,
81+
ids.ID{},
82+
prometheus.NewRegistry(),
83+
)
7884
require.NoError(err)
7985

8086
var (
@@ -453,7 +459,13 @@ func TestVerifierVisitCommitBlock(t *testing.T) {
453459

454460
// Create mocked dependencies.
455461
s := state.NewMockState(ctrl)
456-
mempool, err := mempool.New("", prometheus.NewRegistry())
462+
mempool, err := mempool.New(
463+
"",
464+
gas.Dimensions{},
465+
1_000_000,
466+
ids.ID{},
467+
prometheus.NewRegistry(),
468+
)
457469
require.NoError(err)
458470
parentID := ids.GenerateTestID()
459471
parentStatelessBlk := block.NewMockBlock(ctrl)
@@ -527,7 +539,13 @@ func TestVerifierVisitAbortBlock(t *testing.T) {
527539

528540
// Create mocked dependencies.
529541
s := state.NewMockState(ctrl)
530-
mempool, err := mempool.New("", prometheus.NewRegistry())
542+
mempool, err := mempool.New(
543+
"",
544+
gas.Dimensions{},
545+
1_000_000,
546+
ids.ID{},
547+
prometheus.NewRegistry(),
548+
)
531549
require.NoError(err)
532550
parentID := ids.GenerateTestID()
533551
parentStatelessBlk := block.NewMockBlock(ctrl)
@@ -602,7 +620,13 @@ func TestVerifyUnverifiedParent(t *testing.T) {
602620

603621
// Create mocked dependencies.
604622
s := state.NewMockState(ctrl)
605-
mempool, err := mempool.New("", prometheus.NewRegistry())
623+
mempool, err := mempool.New(
624+
"",
625+
gas.Dimensions{},
626+
1_000_000,
627+
ids.ID{},
628+
prometheus.NewRegistry(),
629+
)
606630
require.NoError(err)
607631
parentID := ids.GenerateTestID()
608632

@@ -673,7 +697,13 @@ func TestBanffAbortBlockTimestampChecks(t *testing.T) {
673697

674698
// Create mocked dependencies.
675699
s := state.NewMockState(ctrl)
676-
mempool, err := mempool.New("", prometheus.NewRegistry())
700+
mempool, err := mempool.New(
701+
"",
702+
gas.Dimensions{},
703+
1_000_000,
704+
ids.ID{},
705+
prometheus.NewRegistry(),
706+
)
677707
require.NoError(err)
678708
parentID := ids.GenerateTestID()
679709
parentStatelessBlk := block.NewMockBlock(ctrl)
@@ -774,7 +804,13 @@ func TestBanffCommitBlockTimestampChecks(t *testing.T) {
774804

775805
// Create mocked dependencies.
776806
s := state.NewMockState(ctrl)
777-
mempool, err := mempool.New("", prometheus.NewRegistry())
807+
mempool, err := mempool.New(
808+
"",
809+
gas.Dimensions{},
810+
1_000_000,
811+
ids.ID{},
812+
prometheus.NewRegistry(),
813+
)
778814
require.NoError(err)
779815
parentID := ids.GenerateTestID()
780816
parentStatelessBlk := block.NewMockBlock(ctrl)
@@ -843,7 +879,13 @@ func TestVerifierVisitApricotStandardBlockWithProposalBlockParent(t *testing.T)
843879

844880
// Create mocked dependencies.
845881
s := state.NewMockState(ctrl)
846-
mempool, err := mempool.New("", prometheus.NewRegistry())
882+
mempool, err := mempool.New(
883+
"",
884+
gas.Dimensions{},
885+
1_000_000,
886+
ids.ID{},
887+
prometheus.NewRegistry(),
888+
)
847889
require.NoError(err)
848890
parentID := ids.GenerateTestID()
849891
parentStatelessBlk := block.NewMockBlock(ctrl)
@@ -900,7 +942,13 @@ func TestVerifierVisitBanffStandardBlockWithProposalBlockParent(t *testing.T) {
900942

901943
// Create mocked dependencies.
902944
s := state.NewMockState(ctrl)
903-
mempool, err := mempool.New("", prometheus.NewRegistry())
945+
mempool, err := mempool.New(
946+
"",
947+
gas.Dimensions{},
948+
1_000_000,
949+
ids.ID{},
950+
prometheus.NewRegistry(),
951+
)
904952
require.NoError(err)
905953
parentID := ids.GenerateTestID()
906954
parentStatelessBlk := block.NewMockBlock(ctrl)

0 commit comments

Comments
 (0)