Compare commits
62 Commits
pascal-har
...
txpool-new
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60bdc2539e | ||
|
|
0dd0bd7b38 | ||
|
|
f41bb13160 | ||
|
|
0e67514ee7 | ||
|
|
8170d99b2f | ||
|
|
7a929d6324 | ||
|
|
00a36bb0cc | ||
|
|
3a6dbe4d85 | ||
|
|
72ec06eae7 | ||
|
|
5d44ba9c6a | ||
|
|
9c72c02502 | ||
|
|
a8959fe60e | ||
|
|
31c9465eac | ||
|
|
4e69ac4a0f | ||
|
|
d5b10e09a7 | ||
|
|
1ad40cda3f | ||
|
|
355dee9000 | ||
|
|
6a6e09c849 | ||
|
|
846e55b9a4 | ||
|
|
09575625db | ||
|
|
3e3c56b235 | ||
|
|
629af6dab4 | ||
|
|
774e314096 | ||
|
|
b818cb78db | ||
|
|
cf10c5cfe6 | ||
|
|
248bb6b0d6 | ||
|
|
0a5dbef9f4 | ||
|
|
0e61543954 | ||
|
|
706a24eb2c | ||
|
|
5f398db90a | ||
|
|
8e6833cec4 | ||
|
|
53042e15d7 | ||
|
|
aeec0c7129 | ||
|
|
76d157d08b | ||
|
|
0f8a1b5c5a | ||
|
|
16a2a53635 | ||
|
|
e7d0a16bc4 | ||
|
|
70ece9355a | ||
|
|
069eaf22f7 | ||
|
|
e45e7eb9c6 | ||
|
|
bdb4cc2acd | ||
|
|
ebd8f590a3 | ||
|
|
6673f3e75a | ||
|
|
40dcfcd776 | ||
|
|
0692a99ea9 | ||
|
|
253d9a566b | ||
|
|
a1a25e91a4 | ||
|
|
9d7298f0c1 | ||
|
|
6daecfb105 | ||
|
|
ed2d1d7f8f | ||
|
|
94a60a9006 | ||
|
|
d03f7e5e94 | ||
|
|
6b4e16ba7b | ||
|
|
5bb78b34be | ||
|
|
5faf41359a | ||
|
|
d0d6a272f0 | ||
|
|
4369e3d997 | ||
|
|
4538e92dbb | ||
|
|
8655d30cb9 | ||
|
|
f80ac01c95 | ||
|
|
e30248be3a | ||
|
|
dfb046e852 |
@@ -24,7 +24,6 @@ import (
|
||||
"github.com/ethereum/go-ethereum"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -101,7 +100,7 @@ type ContractTransactor interface {
|
||||
PendingNonceAt(ctx context.Context, account common.Address) (uint64, error)
|
||||
|
||||
// SendTransactionConditional injects the conditional transaction into the pending pool for execution after verification.
|
||||
SendTransactionConditional(ctx context.Context, tx *types.Transaction, opts ethapi.TransactionOpts) error
|
||||
SendTransactionConditional(ctx context.Context, tx *types.Transaction, opts types.TransactionOpts) error
|
||||
}
|
||||
|
||||
// DeployBackend wraps the operations needed by WaitMined and WaitDeployed.
|
||||
|
||||
@@ -31,7 +31,6 @@ import (
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
@@ -76,7 +75,7 @@ func (mt *mockTransactor) SendTransaction(ctx context.Context, tx *types.Transac
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mt *mockTransactor) SendTransactionConditional(ctx context.Context, tx *types.Transaction, opts ethapi.TransactionOpts) error {
|
||||
func (mt *mockTransactor) SendTransactionConditional(ctx context.Context, tx *types.Transaction, opts types.TransactionOpts) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -92,6 +92,7 @@ var (
|
||||
utils.TxPoolGlobalSlotsFlag,
|
||||
utils.TxPoolAccountQueueFlag,
|
||||
utils.TxPoolGlobalQueueFlag,
|
||||
utils.TxPoolOverflowPoolSlotsFlag,
|
||||
utils.TxPoolLifetimeFlag,
|
||||
utils.TxPoolReannounceTimeFlag,
|
||||
utils.BlobPoolDataDirFlag,
|
||||
|
||||
@@ -458,6 +458,12 @@ var (
|
||||
Value: ethconfig.Defaults.TxPool.GlobalQueue,
|
||||
Category: flags.TxPoolCategory,
|
||||
}
|
||||
TxPoolOverflowPoolSlotsFlag = &cli.Uint64Flag{
|
||||
Name: "txpool.overflowpoolslots",
|
||||
Usage: "Maximum number of transaction slots in overflow pool",
|
||||
Value: ethconfig.Defaults.TxPool.OverflowPoolSlots,
|
||||
Category: flags.TxPoolCategory,
|
||||
}
|
||||
TxPoolLifetimeFlag = &cli.DurationFlag{
|
||||
Name: "txpool.lifetime",
|
||||
Usage: "Maximum amount of time non-executable transaction are queued",
|
||||
@@ -1789,6 +1795,9 @@ func setTxPool(ctx *cli.Context, cfg *legacypool.Config) {
|
||||
if ctx.IsSet(TxPoolGlobalQueueFlag.Name) {
|
||||
cfg.GlobalQueue = ctx.Uint64(TxPoolGlobalQueueFlag.Name)
|
||||
}
|
||||
if ctx.IsSet(TxPoolOverflowPoolSlotsFlag.Name) {
|
||||
cfg.OverflowPoolSlots = ctx.Uint64(TxPoolOverflowPoolSlotsFlag.Name)
|
||||
}
|
||||
if ctx.IsSet(TxPoolLifetimeFlag.Name) {
|
||||
cfg.Lifetime = ctx.Duration(TxPoolLifetimeFlag.Name)
|
||||
}
|
||||
@@ -2310,16 +2319,17 @@ func EnableNodeInfo(poolConfig *legacypool.Config, nodeInfo *p2p.NodeInfo) Setup
|
||||
return func() {
|
||||
// register node info into metrics
|
||||
metrics.NewRegisteredLabel("node-info", nil).Mark(map[string]interface{}{
|
||||
"Enode": nodeInfo.Enode,
|
||||
"ENR": nodeInfo.ENR,
|
||||
"ID": nodeInfo.ID,
|
||||
"PriceLimit": poolConfig.PriceLimit,
|
||||
"PriceBump": poolConfig.PriceBump,
|
||||
"AccountSlots": poolConfig.AccountSlots,
|
||||
"GlobalSlots": poolConfig.GlobalSlots,
|
||||
"AccountQueue": poolConfig.AccountQueue,
|
||||
"GlobalQueue": poolConfig.GlobalQueue,
|
||||
"Lifetime": poolConfig.Lifetime,
|
||||
"Enode": nodeInfo.Enode,
|
||||
"ENR": nodeInfo.ENR,
|
||||
"ID": nodeInfo.ID,
|
||||
"PriceLimit": poolConfig.PriceLimit,
|
||||
"PriceBump": poolConfig.PriceBump,
|
||||
"AccountSlots": poolConfig.AccountSlots,
|
||||
"GlobalSlots": poolConfig.GlobalSlots,
|
||||
"AccountQueue": poolConfig.AccountQueue,
|
||||
"GlobalQueue": poolConfig.GlobalQueue,
|
||||
"OverflowPoolSlots": poolConfig.OverflowPoolSlots,
|
||||
"Lifetime": poolConfig.Lifetime,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -781,87 +781,87 @@ func init() {
|
||||
Configs: []*UpgradeConfig{
|
||||
{
|
||||
ContractAddr: common.HexToAddress(ValidatorContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.MainnetValidatorContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(SlashContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.MainnetSlashContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(SystemRewardContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.MainnetSystemRewardContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(LightClientContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.MainnetLightClientContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(TokenHubContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.MainnetTokenHubContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(RelayerIncentivizeContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.MainnetRelayerIncentivizeContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(RelayerHubContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.MainnetRelayerHubContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(GovHubContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.MainnetGovHubContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(TokenManagerContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.MainnetTokenManagerContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(CrossChainContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.MainnetCrossChainContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(StakingContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.MainnetStakingContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(StakeHubContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.MainnetStakeHubContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(StakeCreditContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.MainnetStakeCreditContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(GovernorContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.MainnetGovernorContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(GovTokenContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.MainnetGovTokenContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(TimelockContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.MainnetTimelockContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(TokenRecoverPortalContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.MainnetTokenRecoverPortalContract,
|
||||
},
|
||||
},
|
||||
@@ -872,87 +872,87 @@ func init() {
|
||||
Configs: []*UpgradeConfig{
|
||||
{
|
||||
ContractAddr: common.HexToAddress(ValidatorContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.ChapelValidatorContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(SlashContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.ChapelSlashContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(SystemRewardContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.ChapelSystemRewardContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(LightClientContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.ChapelLightClientContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(TokenHubContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.ChapelTokenHubContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(RelayerIncentivizeContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.ChapelRelayerIncentivizeContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(RelayerHubContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.ChapelRelayerHubContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(GovHubContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.ChapelGovHubContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(TokenManagerContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.ChapelTokenManagerContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(CrossChainContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.ChapelCrossChainContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(StakingContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.ChapelStakingContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(StakeHubContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.ChapelStakeHubContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(StakeCreditContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.ChapelStakeCreditContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(GovernorContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.ChapelGovernorContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(GovTokenContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.ChapelGovTokenContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(TimelockContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.ChapelTimelockContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(TokenRecoverPortalContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.ChapelTokenRecoverPortalContract,
|
||||
},
|
||||
},
|
||||
@@ -963,87 +963,87 @@ func init() {
|
||||
Configs: []*UpgradeConfig{
|
||||
{
|
||||
ContractAddr: common.HexToAddress(ValidatorContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.RialtoValidatorContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(SlashContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.RialtoSlashContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(SystemRewardContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.RialtoSystemRewardContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(LightClientContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.RialtoLightClientContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(TokenHubContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.RialtoTokenHubContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(RelayerIncentivizeContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.RialtoRelayerIncentivizeContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(RelayerHubContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.RialtoRelayerHubContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(GovHubContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.RialtoGovHubContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(TokenManagerContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.RialtoTokenManagerContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(CrossChainContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.RialtoCrossChainContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(StakingContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.RialtoStakingContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(StakeHubContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.RialtoStakeHubContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(StakeCreditContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.RialtoStakeCreditContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(GovernorContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.RialtoGovernorContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(GovTokenContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.RialtoGovTokenContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(TimelockContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.RialtoTimelockContract,
|
||||
},
|
||||
{
|
||||
ContractAddr: common.HexToAddress(TokenRecoverPortalContract),
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/4c03f8222f8ac13e3b6bd424e1235698282bb28d",
|
||||
CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/020c0459e37d1f9d635c1cff86dd1099ab1383fa",
|
||||
Code: pascal.RialtoTokenRecoverPortalContract,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -19,6 +19,7 @@ package legacypool
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
"sort"
|
||||
@@ -99,10 +100,11 @@ var (
|
||||
// that this number is pretty low, since txpool reorgs happen very frequently.
|
||||
dropBetweenReorgHistogram = metrics.NewRegisteredHistogram("txpool/dropbetweenreorg", nil, metrics.NewExpDecaySample(1028, 0.015))
|
||||
|
||||
pendingGauge = metrics.NewRegisteredGauge("txpool/pending", nil)
|
||||
queuedGauge = metrics.NewRegisteredGauge("txpool/queued", nil)
|
||||
localGauge = metrics.NewRegisteredGauge("txpool/local", nil)
|
||||
slotsGauge = metrics.NewRegisteredGauge("txpool/slots", nil)
|
||||
pendingGauge = metrics.NewRegisteredGauge("txpool/pending", nil)
|
||||
queuedGauge = metrics.NewRegisteredGauge("txpool/queued", nil)
|
||||
localGauge = metrics.NewRegisteredGauge("txpool/local", nil)
|
||||
slotsGauge = metrics.NewRegisteredGauge("txpool/slots", nil)
|
||||
OverflowPoolGauge = metrics.NewRegisteredGauge("txpool/overflowpool", nil)
|
||||
|
||||
reheapTimer = metrics.NewRegisteredTimer("txpool/reheap", nil)
|
||||
)
|
||||
@@ -133,10 +135,11 @@ type Config struct {
|
||||
PriceLimit uint64 // Minimum gas price to enforce for acceptance into the pool
|
||||
PriceBump uint64 // Minimum price bump percentage to replace an already existing transaction (nonce)
|
||||
|
||||
AccountSlots uint64 // Number of executable transaction slots guaranteed per account
|
||||
GlobalSlots uint64 // Maximum number of executable transaction slots for all accounts
|
||||
AccountQueue uint64 // Maximum number of non-executable transaction slots permitted per account
|
||||
GlobalQueue uint64 // Maximum number of non-executable transaction slots for all accounts
|
||||
AccountSlots uint64 // Number of executable transaction slots guaranteed per account
|
||||
GlobalSlots uint64 // Maximum number of executable transaction slots for all accounts
|
||||
AccountQueue uint64 // Maximum number of non-executable transaction slots permitted per account
|
||||
GlobalQueue uint64 // Maximum number of non-executable transaction slots for all accounts
|
||||
OverflowPoolSlots uint64 // Maximum number of transaction slots in overflow pool
|
||||
|
||||
Lifetime time.Duration // Maximum amount of time non-executable transaction are queued
|
||||
ReannounceTime time.Duration // Duration for announcing local pending transactions again
|
||||
@@ -150,10 +153,11 @@ var DefaultConfig = Config{
|
||||
PriceLimit: 1,
|
||||
PriceBump: 10,
|
||||
|
||||
AccountSlots: 16,
|
||||
GlobalSlots: 4096 + 1024, // urgent + floating queue capacity with 4:1 ratio
|
||||
AccountQueue: 64,
|
||||
GlobalQueue: 1024,
|
||||
AccountSlots: 16,
|
||||
GlobalSlots: 4096 + 1024, // urgent + floating queue capacity with 4:1 ratio
|
||||
AccountQueue: 64,
|
||||
GlobalQueue: 1024,
|
||||
OverflowPoolSlots: 0,
|
||||
|
||||
Lifetime: 3 * time.Hour,
|
||||
ReannounceTime: 10 * 365 * 24 * time.Hour,
|
||||
@@ -235,6 +239,8 @@ type LegacyPool struct {
|
||||
all *lookup // All transactions to allow lookups
|
||||
priced *pricedList // All transactions sorted by price
|
||||
|
||||
localBufferPool *TxOverflowPool // Local buffer transactions
|
||||
|
||||
reqResetCh chan *txpoolResetRequest
|
||||
reqPromoteCh chan *accountSet
|
||||
queueTxEventCh chan *types.Transaction
|
||||
@@ -272,6 +278,7 @@ func New(config Config, chain BlockChain) *LegacyPool {
|
||||
reorgDoneCh: make(chan chan struct{}),
|
||||
reorgShutdownCh: make(chan struct{}),
|
||||
initDoneCh: make(chan struct{}),
|
||||
localBufferPool: NewTxOverflowPoolHeap(config.OverflowPoolSlots),
|
||||
}
|
||||
pool.locals = newAccountSet(pool.signer)
|
||||
for _, addr := range config.Locals {
|
||||
@@ -408,7 +415,6 @@ func (pool *LegacyPool) loop() {
|
||||
if !pool.locals.contains(addr) {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, tx := range list.Flatten() {
|
||||
// Default ReannounceTime is 10 years, won't announce by default.
|
||||
if time.Since(tx.Time()) < pool.config.ReannounceTime {
|
||||
@@ -517,6 +523,17 @@ func (pool *LegacyPool) Stats() (int, int) {
|
||||
return pool.stats()
|
||||
}
|
||||
|
||||
func (pool *LegacyPool) statsOverflowPool() int {
|
||||
pool.mu.RLock()
|
||||
defer pool.mu.RUnlock()
|
||||
|
||||
if pool.localBufferPool == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return pool.localBufferPool.Size()
|
||||
}
|
||||
|
||||
// stats retrieves the current pool stats, namely the number of pending and the
|
||||
// number of queued (non-executable) transactions.
|
||||
func (pool *LegacyPool) stats() (int, int) {
|
||||
@@ -831,6 +848,8 @@ func (pool *LegacyPool) add(tx *types.Transaction, local bool) (replaced bool, e
|
||||
}
|
||||
}
|
||||
|
||||
pool.addToOverflowPool(drop, isLocal)
|
||||
|
||||
// Kick out the underpriced remote transactions.
|
||||
for _, tx := range drop {
|
||||
log.Trace("Discarding freshly underpriced transaction", "hash", tx.Hash(), "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap())
|
||||
@@ -887,6 +906,29 @@ func (pool *LegacyPool) add(tx *types.Transaction, local bool) (replaced bool, e
|
||||
return replaced, nil
|
||||
}
|
||||
|
||||
func (pool *LegacyPool) addToOverflowPool(drop types.Transactions, isLocal bool) {
|
||||
// calculate total number of slots in drop. Accordingly add them to OverflowPool (if there is space)
|
||||
availableSlotsOverflowPool := pool.availableSlotsOverflowPool()
|
||||
if availableSlotsOverflowPool > 0 {
|
||||
// transfer availableSlotsOverflowPool number of transactions slots from drop to OverflowPool
|
||||
currentSlotsUsed := 0
|
||||
for i, tx := range drop {
|
||||
txSlots := numSlots(tx)
|
||||
if currentSlotsUsed+txSlots <= availableSlotsOverflowPool {
|
||||
from, _ := types.Sender(pool.signer, tx)
|
||||
pool.localBufferPool.Add(tx)
|
||||
log.Debug("adding to OverflowPool", "transaction", tx.Hash().String(), "from", from.String())
|
||||
currentSlotsUsed += txSlots
|
||||
} else {
|
||||
log.Debug("not all got added to OverflowPool", "totalAdded", i+1)
|
||||
return
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.Debug("adding to OverflowPool unsuccessful", "availableSlotsOverflowPool", availableSlotsOverflowPool)
|
||||
}
|
||||
}
|
||||
|
||||
// isGapped reports whether the given transaction is immediately executable.
|
||||
func (pool *LegacyPool) isGapped(from common.Address, tx *types.Transaction) bool {
|
||||
// Short circuit if transaction falls within the scope of the pending list
|
||||
@@ -1333,7 +1375,6 @@ func (pool *LegacyPool) runReorg(done chan struct{}, reset *txpoolResetRequest,
|
||||
reorgDurationTimer.Update(time.Since(t0))
|
||||
}(time.Now())
|
||||
defer close(done)
|
||||
|
||||
var promoteAddrs []common.Address
|
||||
if dirtyAccounts != nil && reset == nil {
|
||||
// Only dirty accounts need to be promoted, unless we're resetting.
|
||||
@@ -1391,6 +1432,9 @@ func (pool *LegacyPool) runReorg(done chan struct{}, reset *txpoolResetRequest,
|
||||
pool.changesSinceReorg = 0 // Reset change counter
|
||||
pool.mu.Unlock()
|
||||
|
||||
// Transfer transactions from OverflowPool to MainPool for new block import
|
||||
pool.transferTransactions()
|
||||
|
||||
// Notify subsystems for newly added transactions
|
||||
for _, tx := range promoted {
|
||||
addr, _ := types.Sender(pool.signer, tx)
|
||||
@@ -2038,3 +2082,50 @@ func (t *lookup) RemotesBelowTip(threshold *big.Int) types.Transactions {
|
||||
func numSlots(tx *types.Transaction) int {
|
||||
return int((tx.Size() + txSlotSize - 1) / txSlotSize)
|
||||
}
|
||||
|
||||
// transferTransactions moves transactions from OverflowPool to MainPool
|
||||
func (pool *LegacyPool) transferTransactions() {
|
||||
// Fail fast if the overflow pool is empty
|
||||
if pool.localBufferPool.Size() == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
maxMainPoolSize := int(pool.config.GlobalSlots + pool.config.GlobalQueue)
|
||||
// Use pool.all.Slots() to get the total slots used by all transactions
|
||||
currentMainPoolSize := pool.all.Slots()
|
||||
if currentMainPoolSize >= maxMainPoolSize {
|
||||
return
|
||||
}
|
||||
|
||||
extraSlots := maxMainPoolSize - currentMainPoolSize
|
||||
extraTransactions := (extraSlots + 3) / 4 // Since a transaction can take up to 4 slots
|
||||
log.Debug("Will attempt to transfer from OverflowPool to MainPool", "transactions", extraTransactions)
|
||||
txs := pool.localBufferPool.Flush(extraTransactions)
|
||||
if len(txs) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
pool.Add(txs, true, false)
|
||||
}
|
||||
|
||||
func (pool *LegacyPool) availableSlotsOverflowPool() int {
|
||||
maxOverflowPoolSize := int(pool.config.OverflowPoolSlots)
|
||||
availableSlots := maxOverflowPoolSize - pool.localBufferPool.Size()
|
||||
if availableSlots > 0 {
|
||||
return availableSlots
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (pool *LegacyPool) PrintTxStats() {
|
||||
for _, l := range pool.pending {
|
||||
for _, transaction := range l.txs.items {
|
||||
from, _ := types.Sender(pool.signer, transaction)
|
||||
fmt.Println("from: ", from, " Pending:", transaction.Hash().String(), transaction.GasFeeCap(), transaction.GasTipCap())
|
||||
}
|
||||
}
|
||||
|
||||
pool.localBufferPool.PrintTxStats()
|
||||
fmt.Println("length of all: ", pool.all.Slots())
|
||||
fmt.Println("----------------------------------------------------")
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/trie"
|
||||
"github.com/holiman/uint256"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -1739,6 +1740,7 @@ func TestRepricingKeepsLocals(t *testing.T) {
|
||||
// Note, local transactions are never allowed to be dropped.
|
||||
func TestUnderpricing(t *testing.T) {
|
||||
t.Parallel()
|
||||
testTxPoolConfig.OverflowPoolSlots = 5
|
||||
|
||||
// Create the pool to test the pricing enforcement with
|
||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
||||
@@ -1931,6 +1933,8 @@ func TestUnderpricingDynamicFee(t *testing.T) {
|
||||
pool.config.GlobalSlots = 2
|
||||
pool.config.GlobalQueue = 2
|
||||
|
||||
pool.config.OverflowPoolSlots = 0
|
||||
|
||||
// Keep track of transaction events to ensure all executables get announced
|
||||
events := make(chan core.NewTxsEvent, 32)
|
||||
sub := pool.txFeed.Subscribe(events)
|
||||
@@ -1955,7 +1959,6 @@ func TestUnderpricingDynamicFee(t *testing.T) {
|
||||
// Import the batch and that both pending and queued transactions match up
|
||||
pool.addRemotes(txs) // Pend K0:0, K0:1; Que K1:1
|
||||
pool.addLocal(ltx) // +K2:0 => Pend K0:0, K0:1, K2:0; Que K1:1
|
||||
|
||||
pending, queued := pool.Stats()
|
||||
if pending != 3 {
|
||||
t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3)
|
||||
@@ -1995,9 +1998,9 @@ func TestUnderpricingDynamicFee(t *testing.T) {
|
||||
t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2)
|
||||
}
|
||||
if queued != 2 {
|
||||
t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2)
|
||||
t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1)
|
||||
}
|
||||
if err := validateEvents(events, 2); err != nil {
|
||||
if err := validateEvents(events, 2); err != nil { // todo make it 4...After this validateEvents the pending becomes 3?!
|
||||
t.Fatalf("additional event firing failed: %v", err)
|
||||
}
|
||||
if err := validatePoolInternals(pool); err != nil {
|
||||
@@ -2012,11 +2015,12 @@ func TestUnderpricingDynamicFee(t *testing.T) {
|
||||
if err := pool.addLocal(ltx); err != nil {
|
||||
t.Fatalf("failed to add new underpriced local transaction: %v", err)
|
||||
}
|
||||
|
||||
pending, queued = pool.Stats()
|
||||
if pending != 3 {
|
||||
if pending != 3 { // 3
|
||||
t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 3)
|
||||
}
|
||||
if queued != 1 {
|
||||
if queued != 1 { // 1
|
||||
t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1)
|
||||
}
|
||||
if err := validateEvents(events, 2); err != nil {
|
||||
@@ -2032,41 +2036,51 @@ func TestUnderpricingDynamicFee(t *testing.T) {
|
||||
func TestDualHeapEviction(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testTxPoolConfig.OverflowPoolSlots = 1
|
||||
pool, _ := setupPoolWithConfig(eip1559Config)
|
||||
defer pool.Close()
|
||||
|
||||
pool.config.GlobalSlots = 10
|
||||
pool.config.GlobalQueue = 10
|
||||
pool.config.GlobalSlots = 2
|
||||
pool.config.GlobalQueue = 2
|
||||
pool.config.OverflowPoolSlots = 1
|
||||
|
||||
var (
|
||||
highTip, highCap *types.Transaction
|
||||
baseFee int
|
||||
highCapValue int64
|
||||
highTipValue int64
|
||||
)
|
||||
|
||||
check := func(tx *types.Transaction, name string) {
|
||||
if pool.all.GetRemote(tx.Hash()) == nil {
|
||||
t.Fatalf("highest %s transaction evicted from the pool", name)
|
||||
t.Fatalf("highest %s transaction evicted from the pool, gasTip: %s, gasFeeCap: %s, hash: %s", name, highTip.GasTipCap().String(), highCap.GasFeeCap().String(), tx.Hash().String())
|
||||
}
|
||||
}
|
||||
|
||||
add := func(urgent bool) {
|
||||
for i := 0; i < 20; i++ {
|
||||
for i := 0; i < 4; i++ {
|
||||
var tx *types.Transaction
|
||||
// Create a test accounts and fund it
|
||||
key, _ := crypto.GenerateKey()
|
||||
testAddBalance(pool, crypto.PubkeyToAddress(key.PublicKey), big.NewInt(1000000000000))
|
||||
if urgent {
|
||||
tx = dynamicFeeTx(0, 100000, big.NewInt(int64(baseFee+1+i)), big.NewInt(int64(1+i)), key)
|
||||
highTip = tx
|
||||
if int64(1+i) > highTipValue || (int64(1+i) == highTipValue && int64(baseFee+1+i) > highTip.GasFeeCap().Int64()) {
|
||||
highTipValue = int64(1 + i)
|
||||
highTip = tx
|
||||
}
|
||||
} else {
|
||||
tx = dynamicFeeTx(0, 100000, big.NewInt(int64(baseFee+200+i)), big.NewInt(1), key)
|
||||
highCap = tx
|
||||
if int64(baseFee+200+i) > highCapValue {
|
||||
highCapValue = int64(baseFee + 200 + i)
|
||||
highCap = tx
|
||||
}
|
||||
}
|
||||
pool.addRemotesSync([]*types.Transaction{tx})
|
||||
}
|
||||
pending, queued := pool.Stats()
|
||||
if pending+queued != 20 {
|
||||
t.Fatalf("transaction count mismatch: have %d, want %d", pending+queued, 10)
|
||||
if pending+queued != 4 {
|
||||
t.Fatalf("transaction count mismatch: have %d, want %d, pending %d, queued %d, OverflowPool %d", pending+queued, 5, pending, queued, pool.localBufferPool.Size())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2231,6 +2245,50 @@ func TestReplacement(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTransferTransactions(t *testing.T) {
|
||||
t.Parallel()
|
||||
testTxPoolConfig.OverflowPoolSlots = 1
|
||||
pool, _ := setupPoolWithConfig(eip1559Config)
|
||||
defer pool.Close()
|
||||
|
||||
pool.config.GlobalSlots = 1
|
||||
pool.config.GlobalQueue = 2
|
||||
|
||||
// Create a number of test accounts and fund them
|
||||
keys := make([]*ecdsa.PrivateKey, 5)
|
||||
for i := 0; i < len(keys); i++ {
|
||||
keys[i], _ = crypto.GenerateKey()
|
||||
testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
|
||||
}
|
||||
|
||||
tx := dynamicFeeTx(0, 100000, big.NewInt(3), big.NewInt(2), keys[0])
|
||||
from, _ := types.Sender(pool.signer, tx)
|
||||
pool.addToOverflowPool([]*types.Transaction{tx}, true)
|
||||
pending, queue := pool.Stats()
|
||||
|
||||
assert.Equal(t, 0, pending, "pending transactions mismatched")
|
||||
assert.Equal(t, 0, queue, "queued transactions mismatched")
|
||||
assert.Equal(t, 1, pool.statsOverflowPool(), "OverflowPool size unexpected")
|
||||
|
||||
tx2 := dynamicFeeTx(0, 100000, big.NewInt(3), big.NewInt(2), keys[1])
|
||||
pool.addToOverflowPool([]*types.Transaction{tx2}, true)
|
||||
assert.Equal(t, 1, pool.statsOverflowPool(), "OverflowPool size unexpected")
|
||||
<-pool.requestPromoteExecutables(newAccountSet(pool.signer, from))
|
||||
pending, queue = pool.Stats()
|
||||
|
||||
assert.Equal(t, 0, pending, "pending transactions mismatched")
|
||||
assert.Equal(t, 1, queue, "queued transactions mismatched")
|
||||
assert.Equal(t, 0, pool.statsOverflowPool(), "OverflowPool size unexpected")
|
||||
|
||||
tx3 := dynamicFeeTx(0, 100000, big.NewInt(3), big.NewInt(2), keys[2])
|
||||
pool.addToOverflowPool([]*types.Transaction{tx3}, true)
|
||||
pending, queue = pool.Stats()
|
||||
|
||||
assert.Equal(t, 1, pending, "pending transactions mismatched")
|
||||
assert.Equal(t, 0, queue, "queued transactions mismatched")
|
||||
assert.Equal(t, 1, pool.statsOverflowPool(), "OverflowPool size unexpected")
|
||||
}
|
||||
|
||||
// Tests that the pool rejects replacement dynamic fee transactions that don't
|
||||
// meet the minimum price bump required.
|
||||
func TestReplacementDynamicFee(t *testing.T) {
|
||||
|
||||
171
core/txpool/legacypool/tx_overflowpool.go
Normal file
171
core/txpool/legacypool/tx_overflowpool.go
Normal file
@@ -0,0 +1,171 @@
|
||||
package legacypool
|
||||
|
||||
import (
|
||||
"container/heap"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
)
|
||||
|
||||
// txHeapItem implements the Interface interface (https://pkg.go.dev/container/heap#Interface) of heap so that it can be heapified
|
||||
type txHeapItem struct {
|
||||
tx *types.Transaction
|
||||
timestamp int64 // Unix timestamp (nanoseconds) of when the transaction was added
|
||||
index int
|
||||
}
|
||||
|
||||
type txHeap []*txHeapItem
|
||||
|
||||
func (h txHeap) Len() int { return len(h) }
|
||||
func (h txHeap) Less(i, j int) bool {
|
||||
return h[i].timestamp < h[j].timestamp
|
||||
}
|
||||
func (h txHeap) Swap(i, j int) {
|
||||
if i < 0 || j < 0 || i >= len(h) || j >= len(h) {
|
||||
return // Silently fail if indices are out of bounds
|
||||
}
|
||||
h[i], h[j] = h[j], h[i]
|
||||
if h[i] != nil {
|
||||
h[i].index = i
|
||||
}
|
||||
if h[j] != nil {
|
||||
h[j].index = j
|
||||
}
|
||||
}
|
||||
|
||||
func (h *txHeap) Push(x interface{}) {
|
||||
item, ok := x.(*txHeapItem)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
n := len(*h)
|
||||
item.index = n
|
||||
*h = append(*h, item)
|
||||
}
|
||||
|
||||
func (h *txHeap) Pop() interface{} {
|
||||
old := *h
|
||||
n := len(old)
|
||||
if n == 0 {
|
||||
return nil // Return nil if the heap is empty
|
||||
}
|
||||
item := old[n-1]
|
||||
old[n-1] = nil // avoid memory leak
|
||||
*h = old[0 : n-1]
|
||||
if item != nil {
|
||||
item.index = -1 // for safety
|
||||
}
|
||||
return item
|
||||
}
|
||||
|
||||
type TxOverflowPool struct {
|
||||
txHeap txHeap
|
||||
index map[common.Hash]*txHeapItem
|
||||
mu sync.RWMutex
|
||||
maxSize uint64
|
||||
totalSize int
|
||||
}
|
||||
|
||||
func NewTxOverflowPoolHeap(estimatedMaxSize uint64) *TxOverflowPool {
|
||||
return &TxOverflowPool{
|
||||
txHeap: make(txHeap, 0, estimatedMaxSize),
|
||||
index: make(map[common.Hash]*txHeapItem, estimatedMaxSize),
|
||||
maxSize: estimatedMaxSize,
|
||||
}
|
||||
}
|
||||
|
||||
func (tp *TxOverflowPool) Add(tx *types.Transaction) {
|
||||
tp.mu.Lock()
|
||||
defer tp.mu.Unlock()
|
||||
|
||||
if _, exists := tp.index[tx.Hash()]; exists {
|
||||
// Transaction already in pool, ignore
|
||||
return
|
||||
}
|
||||
|
||||
if uint64(len(tp.txHeap)) >= tp.maxSize {
|
||||
// Remove the oldest transaction to make space
|
||||
oldestItem, ok := heap.Pop(&tp.txHeap).(*txHeapItem)
|
||||
if !ok || oldestItem == nil {
|
||||
return
|
||||
}
|
||||
delete(tp.index, oldestItem.tx.Hash())
|
||||
tp.totalSize -= numSlots(oldestItem.tx)
|
||||
OverflowPoolGauge.Dec(1)
|
||||
}
|
||||
|
||||
item := &txHeapItem{
|
||||
tx: tx,
|
||||
timestamp: time.Now().UnixNano(),
|
||||
}
|
||||
heap.Push(&tp.txHeap, item)
|
||||
tp.index[tx.Hash()] = item
|
||||
tp.totalSize += numSlots(tx)
|
||||
OverflowPoolGauge.Inc(1)
|
||||
}
|
||||
|
||||
func (tp *TxOverflowPool) Get(hash common.Hash) (*types.Transaction, bool) {
|
||||
tp.mu.RLock()
|
||||
defer tp.mu.RUnlock()
|
||||
if item, ok := tp.index[hash]; ok {
|
||||
return item.tx, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (tp *TxOverflowPool) Remove(hash common.Hash) {
|
||||
tp.mu.Lock()
|
||||
defer tp.mu.Unlock()
|
||||
if item, ok := tp.index[hash]; ok {
|
||||
heap.Remove(&tp.txHeap, item.index)
|
||||
delete(tp.index, hash)
|
||||
tp.totalSize -= numSlots(item.tx)
|
||||
OverflowPoolGauge.Dec(1)
|
||||
}
|
||||
}
|
||||
|
||||
func (tp *TxOverflowPool) Flush(n int) []*types.Transaction {
|
||||
tp.mu.Lock()
|
||||
defer tp.mu.Unlock()
|
||||
if n > tp.txHeap.Len() {
|
||||
n = tp.txHeap.Len()
|
||||
}
|
||||
txs := make([]*types.Transaction, n)
|
||||
for i := 0; i < n; i++ {
|
||||
item, ok := heap.Pop(&tp.txHeap).(*txHeapItem)
|
||||
if !ok || item == nil {
|
||||
continue
|
||||
}
|
||||
txs[i] = item.tx
|
||||
delete(tp.index, item.tx.Hash())
|
||||
tp.totalSize -= numSlots(item.tx)
|
||||
}
|
||||
|
||||
OverflowPoolGauge.Dec(int64(n))
|
||||
return txs
|
||||
}
|
||||
|
||||
func (tp *TxOverflowPool) Len() int {
|
||||
tp.mu.RLock()
|
||||
defer tp.mu.RUnlock()
|
||||
return tp.txHeap.Len()
|
||||
}
|
||||
|
||||
func (tp *TxOverflowPool) Size() int {
|
||||
tp.mu.RLock()
|
||||
defer tp.mu.RUnlock()
|
||||
return tp.totalSize
|
||||
}
|
||||
|
||||
func (tp *TxOverflowPool) PrintTxStats() {
|
||||
tp.mu.RLock()
|
||||
defer tp.mu.RUnlock()
|
||||
for _, item := range tp.txHeap {
|
||||
tx := item.tx
|
||||
fmt.Printf("Hash: %s, Timestamp: %d, GasFeeCap: %s, GasTipCap: %s\n",
|
||||
tx.Hash().String(), item.timestamp, tx.GasFeeCap().String(), tx.GasTipCap().String())
|
||||
}
|
||||
}
|
||||
266
core/txpool/legacypool/tx_overflowpool_test.go
Normal file
266
core/txpool/legacypool/tx_overflowpool_test.go
Normal file
@@ -0,0 +1,266 @@
|
||||
package legacypool
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
rand2 "math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cometbft/cometbft/libs/rand"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
)
|
||||
|
||||
// Helper function to create a test transaction
|
||||
func createTestTx(nonce uint64, gasPrice *big.Int) *types.Transaction {
|
||||
to := common.HexToAddress("0x1234567890123456789012345678901234567890")
|
||||
return types.NewTransaction(nonce, to, big.NewInt(1000), 21000, gasPrice, nil)
|
||||
}
|
||||
|
||||
func TestNewTxOverflowPoolHeap(t *testing.T) {
|
||||
pool := NewTxOverflowPoolHeap(0)
|
||||
if pool == nil {
|
||||
t.Fatal("NewTxOverflowPoolHeap returned nil")
|
||||
}
|
||||
if pool.Len() != 0 {
|
||||
t.Errorf("New pool should be empty, got length %d", pool.Len())
|
||||
}
|
||||
}
|
||||
|
||||
func TestTxOverflowPoolHeapAdd(t *testing.T) {
|
||||
pool := NewTxOverflowPoolHeap(1)
|
||||
tx := createTestTx(1, big.NewInt(1000))
|
||||
|
||||
pool.Add(tx)
|
||||
if pool.Len() != 1 {
|
||||
t.Errorf("Pool should have 1 transaction, got %d", pool.Len())
|
||||
}
|
||||
|
||||
// Add the same transaction again
|
||||
pool.Add(tx)
|
||||
if pool.Len() != 1 {
|
||||
t.Errorf("Pool should still have 1 transaction after adding duplicate, got %d", pool.Len())
|
||||
}
|
||||
}
|
||||
|
||||
func TestTxOverflowPoolHeapGet(t *testing.T) {
|
||||
pool := NewTxOverflowPoolHeap(1)
|
||||
tx := createTestTx(1, big.NewInt(1000))
|
||||
pool.Add(tx)
|
||||
|
||||
gotTx, exists := pool.Get(tx.Hash())
|
||||
if !exists {
|
||||
t.Fatal("Get returned false for existing transaction")
|
||||
}
|
||||
if gotTx.Hash() != tx.Hash() {
|
||||
t.Errorf("Get returned wrong transaction. Want %v, got %v", tx.Hash(), gotTx.Hash())
|
||||
}
|
||||
|
||||
_, exists = pool.Get(common.Hash{})
|
||||
if exists {
|
||||
t.Error("Get returned true for non-existent transaction")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTxOverflowPoolHeapRemove(t *testing.T) {
|
||||
pool := NewTxOverflowPoolHeap(1)
|
||||
tx := createTestTx(1, big.NewInt(1000))
|
||||
pool.Add(tx)
|
||||
|
||||
pool.Remove(tx.Hash())
|
||||
if pool.Len() != 0 {
|
||||
t.Errorf("Pool should be empty after removing the only transaction, got length %d", pool.Len())
|
||||
}
|
||||
|
||||
// Try to remove non-existent transaction
|
||||
pool.Remove(common.Hash{})
|
||||
if pool.Len() != 0 {
|
||||
t.Error("Removing non-existent transaction should not affect pool size")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTxOverflowPoolHeapPopN(t *testing.T) {
|
||||
pool := NewTxOverflowPoolHeap(3)
|
||||
tx1 := createTestTx(1, big.NewInt(1000))
|
||||
tx2 := createTestTx(2, big.NewInt(2000))
|
||||
tx3 := createTestTx(3, big.NewInt(3000))
|
||||
|
||||
pool.Add(tx1)
|
||||
time.Sleep(time.Millisecond) // Ensure different timestamps
|
||||
pool.Add(tx2)
|
||||
time.Sleep(time.Millisecond)
|
||||
pool.Add(tx3)
|
||||
|
||||
popped := pool.Flush(2)
|
||||
if len(popped) != 2 {
|
||||
t.Fatalf("PopN(2) should return 2 transactions, got %d", len(popped))
|
||||
}
|
||||
if popped[0].Hash() != tx1.Hash() || popped[1].Hash() != tx2.Hash() {
|
||||
t.Error("PopN returned transactions in wrong order")
|
||||
}
|
||||
if pool.Len() != 1 {
|
||||
t.Errorf("Pool should have 1 transaction left, got %d", pool.Len())
|
||||
}
|
||||
|
||||
// Pop more than available
|
||||
popped = pool.Flush(2)
|
||||
if len(popped) != 1 {
|
||||
t.Fatalf("PopN(2) should return 1 transaction when only 1 is left, got %d", len(popped))
|
||||
}
|
||||
if popped[0].Hash() != tx3.Hash() {
|
||||
t.Error("PopN returned wrong transaction")
|
||||
}
|
||||
if pool.Len() != 0 {
|
||||
t.Errorf("Pool should be empty, got length %d", pool.Len())
|
||||
}
|
||||
}
|
||||
|
||||
func TestTxOverflowPoolHeapOrdering(t *testing.T) {
|
||||
pool := NewTxOverflowPoolHeap(3)
|
||||
tx1 := createTestTx(1, big.NewInt(1000))
|
||||
tx2 := createTestTx(2, big.NewInt(2000))
|
||||
tx3 := createTestTx(3, big.NewInt(3000))
|
||||
|
||||
pool.Add(tx2)
|
||||
time.Sleep(time.Millisecond) // Ensure different timestamps
|
||||
pool.Add(tx1)
|
||||
pool.Add(tx3) // Added immediately after tx1, should have same timestamp but higher sequence
|
||||
|
||||
popped := pool.Flush(3)
|
||||
if len(popped) != 3 {
|
||||
t.Fatalf("PopN(3) should return 3 transactions, got %d", len(popped))
|
||||
}
|
||||
if popped[0].Hash() != tx2.Hash() || popped[1].Hash() != tx1.Hash() || popped[2].Hash() != tx3.Hash() {
|
||||
t.Error("Transactions not popped in correct order (earliest timestamp first, then by sequence)")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTxOverflowPoolHeapLen(t *testing.T) {
|
||||
pool := NewTxOverflowPoolHeap(2)
|
||||
if pool.Len() != 0 {
|
||||
t.Errorf("New pool should have length 0, got %d", pool.Len())
|
||||
}
|
||||
|
||||
pool.Add(createTestTx(1, big.NewInt(1000)))
|
||||
if pool.Len() != 1 {
|
||||
t.Errorf("Pool should have length 1 after adding a transaction, got %d", pool.Len())
|
||||
}
|
||||
|
||||
pool.Add(createTestTx(2, big.NewInt(2000)))
|
||||
if pool.Len() != 2 {
|
||||
t.Errorf("Pool should have length 2 after adding another transaction, got %d", pool.Len())
|
||||
}
|
||||
|
||||
pool.Flush(1)
|
||||
if pool.Len() != 1 {
|
||||
t.Errorf("Pool should have length 1 after popping a transaction, got %d", pool.Len())
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to create a random test transaction
|
||||
func createRandomTestTx() *types.Transaction {
|
||||
nonce := uint64(rand.Intn(1000000))
|
||||
to := common.BytesToAddress(rand.Bytes(20))
|
||||
amount := new(big.Int).Rand(rand2.New(rand2.NewSource(rand.Int63())), big.NewInt(1e18))
|
||||
gasLimit := uint64(21000)
|
||||
gasPrice := new(big.Int).Rand(rand2.New(rand2.NewSource(rand.Int63())), big.NewInt(1e9))
|
||||
data := rand.Bytes(100)
|
||||
return types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, data)
|
||||
}
|
||||
|
||||
func createRandomTestTxs(n int) []*types.Transaction {
|
||||
txs := make([]*types.Transaction, n)
|
||||
for i := 0; i < n; i++ {
|
||||
txs[i] = createRandomTestTx()
|
||||
}
|
||||
return txs
|
||||
}
|
||||
|
||||
// goos: darwin
|
||||
// goarch: arm64
|
||||
// pkg: github.com/ethereum/go-ethereum/core/txpool/legacypool
|
||||
// BenchmarkTxOverflowPoolHeapAdd-8 813326 2858 ns/op
|
||||
func BenchmarkTxOverflowPoolHeapAdd(b *testing.B) {
|
||||
pool := NewTxOverflowPoolHeap(uint64(b.N))
|
||||
txs := createRandomTestTxs(b.N)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
pool.Add(txs[i])
|
||||
}
|
||||
}
|
||||
|
||||
// BenchmarkTxOverflowPoolHeapGet-8 32613938 35.63 ns/op
|
||||
func BenchmarkTxOverflowPoolHeapGet(b *testing.B) {
|
||||
pool := NewTxOverflowPoolHeap(1000)
|
||||
txs := createRandomTestTxs(1000)
|
||||
for _, tx := range txs {
|
||||
pool.Add(tx)
|
||||
}
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
pool.Get(txs[i%1000].Hash())
|
||||
}
|
||||
}
|
||||
|
||||
// BenchmarkTxOverflowPoolHeapRemove-8 3020841 417.8 ns/op
|
||||
func BenchmarkTxOverflowPoolHeapRemove(b *testing.B) {
|
||||
pool := NewTxOverflowPoolHeap(uint64(b.N))
|
||||
txs := createRandomTestTxs(b.N)
|
||||
for _, tx := range txs {
|
||||
pool.Add(tx)
|
||||
}
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
pool.Remove(txs[i].Hash())
|
||||
}
|
||||
}
|
||||
|
||||
// BenchmarkTxOverflowPoolHeapFlush-8 42963656 29.90 ns/op
|
||||
func BenchmarkTxOverflowPoolHeapFlush(b *testing.B) {
|
||||
pool := NewTxOverflowPoolHeap(1000)
|
||||
txs := createRandomTestTxs(1000)
|
||||
for _, tx := range txs {
|
||||
pool.Add(tx)
|
||||
}
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
pool.Flush(10)
|
||||
}
|
||||
}
|
||||
|
||||
// BenchmarkTxOverflowPoolHeapLen-8 79147188 20.07 ns/op
|
||||
func BenchmarkTxOverflowPoolHeapLen(b *testing.B) {
|
||||
pool := NewTxOverflowPoolHeap(1000)
|
||||
txs := createRandomTestTxs(1000)
|
||||
for _, tx := range txs {
|
||||
pool.Add(tx)
|
||||
}
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
pool.Len()
|
||||
}
|
||||
}
|
||||
|
||||
// BenchmarkTxOverflowPoolHeapAddRemove-8 902896 1546 ns/op
|
||||
func BenchmarkTxOverflowPoolHeapAddRemove(b *testing.B) {
|
||||
pool := NewTxOverflowPoolHeap(uint64(b.N))
|
||||
txs := createRandomTestTxs(b.N)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
pool.Add(txs[i])
|
||||
pool.Remove(txs[i].Hash())
|
||||
}
|
||||
}
|
||||
|
||||
// BenchmarkTxOverflowPoolHeapAddFlush-8 84417 14899 ns/op
|
||||
func BenchmarkTxOverflowPoolHeapAddFlush(b *testing.B) {
|
||||
pool := NewTxOverflowPoolHeap(uint64(b.N * 10))
|
||||
txs := createRandomTestTxs(b.N * 10)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
for j := 0; j < 10; j++ {
|
||||
pool.Add(txs[i*10+j])
|
||||
}
|
||||
pool.Flush(10)
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
|
||||
|
||||
package ethapi
|
||||
package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
)
|
||||
|
||||
43
core/types/transaction_options.go
Normal file
43
core/types/transaction_options.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
)
|
||||
|
||||
type AccountStorage struct {
|
||||
StorageRoot *common.Hash
|
||||
StorageSlots map[common.Hash]common.Hash
|
||||
}
|
||||
|
||||
func (a *AccountStorage) UnmarshalJSON(data []byte) error {
|
||||
var hash common.Hash
|
||||
if err := json.Unmarshal(data, &hash); err == nil {
|
||||
a.StorageRoot = &hash
|
||||
return nil
|
||||
}
|
||||
return json.Unmarshal(data, &a.StorageSlots)
|
||||
}
|
||||
|
||||
func (a AccountStorage) MarshalJSON() ([]byte, error) {
|
||||
if a.StorageRoot != nil {
|
||||
return json.Marshal(*a.StorageRoot)
|
||||
}
|
||||
return json.Marshal(a.StorageSlots)
|
||||
}
|
||||
|
||||
type KnownAccounts map[common.Address]AccountStorage
|
||||
|
||||
// It is known that marshaling is broken
|
||||
// https://github.com/golang/go/issues/55890
|
||||
|
||||
//go:generate go run github.com/fjl/gencodec -type TransactionOpts -out gen_tx_opts_json.go
|
||||
type TransactionOpts struct {
|
||||
KnownAccounts KnownAccounts `json:"knownAccounts"`
|
||||
BlockNumberMin *hexutil.Uint64 `json:"blockNumberMin,omitempty"`
|
||||
BlockNumberMax *hexutil.Uint64 `json:"blockNumberMax,omitempty"`
|
||||
TimestampMin *hexutil.Uint64 `json:"timestampMin,omitempty"`
|
||||
TimestampMax *hexutil.Uint64 `json:"timestampMax,omitempty"`
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package ethapi_test
|
||||
package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
)
|
||||
|
||||
func ptr(hash common.Hash) *common.Hash {
|
||||
@@ -23,15 +22,15 @@ func TestTransactionOptsJSONUnMarshalTrip(t *testing.T) {
|
||||
name string
|
||||
input string
|
||||
mustFail bool
|
||||
expected ethapi.TransactionOpts
|
||||
expected TransactionOpts
|
||||
}{
|
||||
{
|
||||
"StateRoot",
|
||||
`{"knownAccounts":{"0x6b3A8798E5Fb9fC5603F3aB5eA2e8136694e55d0":"0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563"}}`,
|
||||
false,
|
||||
ethapi.TransactionOpts{
|
||||
KnownAccounts: map[common.Address]ethapi.AccountStorage{
|
||||
common.HexToAddress("0x6b3A8798E5Fb9fC5603F3aB5eA2e8136694e55d0"): ethapi.AccountStorage{
|
||||
TransactionOpts{
|
||||
KnownAccounts: map[common.Address]AccountStorage{
|
||||
common.HexToAddress("0x6b3A8798E5Fb9fC5603F3aB5eA2e8136694e55d0"): AccountStorage{
|
||||
StorageRoot: ptr(common.HexToHash("0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563")),
|
||||
},
|
||||
},
|
||||
@@ -41,9 +40,9 @@ func TestTransactionOptsJSONUnMarshalTrip(t *testing.T) {
|
||||
"StorageSlots",
|
||||
`{"knownAccounts":{"0x6b3A8798E5Fb9fC5603F3aB5eA2e8136694e55d0":{"0xc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8":"0x0000000000000000000000000000000000000000000000000000000000000000"}}}`,
|
||||
false,
|
||||
ethapi.TransactionOpts{
|
||||
KnownAccounts: map[common.Address]ethapi.AccountStorage{
|
||||
common.HexToAddress("0x6b3A8798E5Fb9fC5603F3aB5eA2e8136694e55d0"): ethapi.AccountStorage{
|
||||
TransactionOpts{
|
||||
KnownAccounts: map[common.Address]AccountStorage{
|
||||
common.HexToAddress("0x6b3A8798E5Fb9fC5603F3aB5eA2e8136694e55d0"): AccountStorage{
|
||||
StorageRoot: nil,
|
||||
StorageSlots: map[common.Hash]common.Hash{
|
||||
common.HexToHash("0xc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a8"): common.HexToHash("0x"),
|
||||
@@ -56,15 +55,15 @@ func TestTransactionOptsJSONUnMarshalTrip(t *testing.T) {
|
||||
"EmptyObject",
|
||||
`{"knownAccounts":{}}`,
|
||||
false,
|
||||
ethapi.TransactionOpts{
|
||||
KnownAccounts: make(map[common.Address]ethapi.AccountStorage),
|
||||
TransactionOpts{
|
||||
KnownAccounts: make(map[common.Address]AccountStorage),
|
||||
},
|
||||
},
|
||||
{
|
||||
"EmptyStrings",
|
||||
`{"knownAccounts":{"":""}}`,
|
||||
true,
|
||||
ethapi.TransactionOpts{
|
||||
TransactionOpts{
|
||||
KnownAccounts: nil,
|
||||
},
|
||||
},
|
||||
@@ -72,7 +71,7 @@ func TestTransactionOptsJSONUnMarshalTrip(t *testing.T) {
|
||||
"BlockNumberMin",
|
||||
`{"blockNumberMin":"0x1"}`,
|
||||
false,
|
||||
ethapi.TransactionOpts{
|
||||
TransactionOpts{
|
||||
BlockNumberMin: u64Ptr(1),
|
||||
},
|
||||
},
|
||||
@@ -80,7 +79,7 @@ func TestTransactionOptsJSONUnMarshalTrip(t *testing.T) {
|
||||
"BlockNumberMax",
|
||||
`{"blockNumberMin":"0x1", "blockNumberMax":"0x2"}`,
|
||||
false,
|
||||
ethapi.TransactionOpts{
|
||||
TransactionOpts{
|
||||
BlockNumberMin: u64Ptr(1),
|
||||
BlockNumberMax: u64Ptr(2),
|
||||
},
|
||||
@@ -89,7 +88,7 @@ func TestTransactionOptsJSONUnMarshalTrip(t *testing.T) {
|
||||
"TimestampMin",
|
||||
`{"timestampMin":"0xffff"}`,
|
||||
false,
|
||||
ethapi.TransactionOpts{
|
||||
TransactionOpts{
|
||||
TimestampMin: u64Ptr(0xffff),
|
||||
},
|
||||
},
|
||||
@@ -97,7 +96,7 @@ func TestTransactionOptsJSONUnMarshalTrip(t *testing.T) {
|
||||
"TimestampMax",
|
||||
`{"timestampMax":"0xffffff"}`,
|
||||
false,
|
||||
ethapi.TransactionOpts{
|
||||
TransactionOpts{
|
||||
TimestampMax: u64Ptr(0xffffff),
|
||||
},
|
||||
},
|
||||
@@ -105,7 +104,7 @@ func TestTransactionOptsJSONUnMarshalTrip(t *testing.T) {
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
var opts ethapi.TransactionOpts
|
||||
var opts TransactionOpts
|
||||
err := json.Unmarshal([]byte(test.input), &opts)
|
||||
if test.mustFail && err == nil {
|
||||
t.Errorf("Test %s should fail", test.name)
|
||||
@@ -29,7 +29,6 @@ import (
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
)
|
||||
|
||||
@@ -737,7 +736,7 @@ func (ec *Client) SendTransaction(ctx context.Context, tx *types.Transaction) er
|
||||
//
|
||||
// If the transaction was a contract creation use the TransactionReceipt method to get the
|
||||
// contract address after the transaction has been mined.
|
||||
func (ec *Client) SendTransactionConditional(ctx context.Context, tx *types.Transaction, opts ethapi.TransactionOpts) error {
|
||||
func (ec *Client) SendTransactionConditional(ctx context.Context, tx *types.Transaction, opts types.TransactionOpts) error {
|
||||
data, err := tx.MarshalBinary()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -34,7 +34,6 @@ import (
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/eth"
|
||||
"github.com/ethereum/go-ethereum/eth/ethconfig"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
@@ -770,9 +769,9 @@ func sendTransactionConditional(ec *Client) error {
|
||||
}
|
||||
|
||||
root := common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
||||
return ec.SendTransactionConditional(context.Background(), tx, ethapi.TransactionOpts{
|
||||
KnownAccounts: map[common.Address]ethapi.AccountStorage{
|
||||
testAddr: ethapi.AccountStorage{
|
||||
return ec.SendTransactionConditional(context.Background(), tx, types.TransactionOpts{
|
||||
KnownAccounts: map[common.Address]types.AccountStorage{
|
||||
testAddr: types.AccountStorage{
|
||||
StorageRoot: &root,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -30,7 +30,6 @@ import (
|
||||
"github.com/ethereum/go-ethereum/eth/ethconfig"
|
||||
"github.com/ethereum/go-ethereum/eth/filters"
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
@@ -39,7 +38,7 @@ import (
|
||||
|
||||
// TransactionConditionalSender injects the conditional transaction into the pending pool for execution after verification.
|
||||
type TransactionConditionalSender interface {
|
||||
SendTransactionConditional(ctx context.Context, tx *types.Transaction, opts ethapi.TransactionOpts) error
|
||||
SendTransactionConditional(ctx context.Context, tx *types.Transaction, opts types.TransactionOpts) error
|
||||
}
|
||||
|
||||
// Client exposes the methods provided by the Ethereum RPC client.
|
||||
|
||||
@@ -2314,7 +2314,7 @@ func (s *TransactionAPI) SendRawTransaction(ctx context.Context, input hexutil.B
|
||||
|
||||
// SendRawTransactionConditional will add the signed transaction to the transaction pool.
|
||||
// The sender/bundler is responsible for signing the transaction
|
||||
func (s *TransactionAPI) SendRawTransactionConditional(ctx context.Context, input hexutil.Bytes, opts TransactionOpts) (common.Hash, error) {
|
||||
func (s *TransactionAPI) SendRawTransactionConditional(ctx context.Context, input hexutil.Bytes, opts types.TransactionOpts) (common.Hash, error) {
|
||||
tx := new(types.Transaction)
|
||||
if err := tx.UnmarshalBinary(input); err != nil {
|
||||
return common.Hash{}, err
|
||||
@@ -2324,7 +2324,7 @@ func (s *TransactionAPI) SendRawTransactionConditional(ctx context.Context, inpu
|
||||
if state == nil || err != nil {
|
||||
return common.Hash{}, err
|
||||
}
|
||||
if err := opts.Check(header.Number.Uint64(), header.Time, state); err != nil {
|
||||
if err := TxOptsCheck(opts, header.Number.Uint64(), header.Time, state); err != nil {
|
||||
return common.Hash{}, err
|
||||
}
|
||||
return SubmitTransaction(ctx, s.b, tx)
|
||||
|
||||
@@ -2,52 +2,15 @@ package ethapi
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
)
|
||||
|
||||
type AccountStorage struct {
|
||||
StorageRoot *common.Hash
|
||||
StorageSlots map[common.Hash]common.Hash
|
||||
}
|
||||
|
||||
func (a *AccountStorage) UnmarshalJSON(data []byte) error {
|
||||
var hash common.Hash
|
||||
if err := json.Unmarshal(data, &hash); err == nil {
|
||||
a.StorageRoot = &hash
|
||||
return nil
|
||||
}
|
||||
return json.Unmarshal(data, &a.StorageSlots)
|
||||
}
|
||||
|
||||
func (a AccountStorage) MarshalJSON() ([]byte, error) {
|
||||
if a.StorageRoot != nil {
|
||||
return json.Marshal(*a.StorageRoot)
|
||||
}
|
||||
return json.Marshal(a.StorageSlots)
|
||||
}
|
||||
|
||||
type KnownAccounts map[common.Address]AccountStorage
|
||||
|
||||
// It is known that marshaling is broken
|
||||
// https://github.com/golang/go/issues/55890
|
||||
|
||||
//go:generate go run github.com/fjl/gencodec -type TransactionOpts -out gen_tx_opts_json.go
|
||||
type TransactionOpts struct {
|
||||
KnownAccounts KnownAccounts `json:"knownAccounts"`
|
||||
BlockNumberMin *hexutil.Uint64 `json:"blockNumberMin,omitempty"`
|
||||
BlockNumberMax *hexutil.Uint64 `json:"blockNumberMax,omitempty"`
|
||||
TimestampMin *hexutil.Uint64 `json:"timestampMin,omitempty"`
|
||||
TimestampMax *hexutil.Uint64 `json:"timestampMax,omitempty"`
|
||||
}
|
||||
|
||||
const MaxNumberOfEntries = 1000
|
||||
|
||||
func (o *TransactionOpts) Check(blockNumber uint64, timeStamp uint64, statedb *state.StateDB) error {
|
||||
func TxOptsCheck(o types.TransactionOpts, blockNumber uint64, timeStamp uint64, statedb *state.StateDB) error {
|
||||
if o.BlockNumberMin != nil && blockNumber < uint64(*o.BlockNumberMin) {
|
||||
return errors.New("BlockNumberMin condition not met")
|
||||
}
|
||||
@@ -71,10 +34,10 @@ func (o *TransactionOpts) Check(blockNumber uint64, timeStamp uint64, statedb *s
|
||||
if counter > MaxNumberOfEntries {
|
||||
return errors.New("knownAccounts too large")
|
||||
}
|
||||
return o.CheckStorage(statedb)
|
||||
return TxOptsCheckStorage(o, statedb)
|
||||
}
|
||||
|
||||
func (o *TransactionOpts) CheckStorage(statedb *state.StateDB) error {
|
||||
func TxOptsCheckStorage(o types.TransactionOpts, statedb *state.StateDB) error {
|
||||
for address, accountStorage := range o.KnownAccounts {
|
||||
if accountStorage.StorageRoot != nil {
|
||||
rootHash := statedb.GetRoot(address)
|
||||
Reference in New Issue
Block a user