mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
Custom tx validator logic WIP
This commit is contained in:
parent
577be37e0e
commit
65e11e1ee1
4 changed files with 82 additions and 0 deletions
|
|
@ -54,4 +54,7 @@ var (
|
|||
// ErrFutureReplacePending is returned if a future transaction replaces a pending
|
||||
// one. Future transactions should only be able to replace other future transactions.
|
||||
ErrFutureReplacePending = errors.New("future transaction tries to replace pending")
|
||||
|
||||
// FIXME add proper explanation (Kirill)
|
||||
ErrCustomValidationFailed = errors.New("tranaction failed custom validation")
|
||||
)
|
||||
|
|
|
|||
|
|
@ -134,6 +134,8 @@ type Config struct {
|
|||
GlobalQueue uint64 // Maximum number of non-executable transaction slots for all accounts
|
||||
|
||||
Lifetime time.Duration // Maximum amount of time non-executable transaction are queued
|
||||
|
||||
CustomValidationEnabled bool
|
||||
}
|
||||
|
||||
// DefaultConfig contains the default configurations for the transaction pool.
|
||||
|
|
@ -150,6 +152,8 @@ var DefaultConfig = Config{
|
|||
GlobalQueue: 1024,
|
||||
|
||||
Lifetime: 3 * time.Hour,
|
||||
|
||||
CustomValidationEnabled: false,
|
||||
}
|
||||
|
||||
// sanitize checks the provided user configurations and changes anything that's
|
||||
|
|
@ -605,6 +609,17 @@ func (pool *LegacyPool) validateTxBasics(tx *types.Transaction, local bool) erro
|
|||
return nil
|
||||
}
|
||||
|
||||
// FIXME add proper explanation (Kirill)
|
||||
func (pool *LegacyPool) validateTxWithCustomValidator(tx *types.Transaction, local bool) error {
|
||||
if pool.config.CustomValidationEnabled {
|
||||
opts := &txpool.CustomValidationOptions{}
|
||||
if err := txpool.ValidateTransactionWithCustomValidator(tx, pool.currentHead.Load(), pool.signer, opts); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateTx checks whether a transaction is valid according to the consensus
|
||||
// rules and adheres to some heuristic limits of the local node (price and size).
|
||||
func (pool *LegacyPool) validateTx(tx *types.Transaction, local bool) error {
|
||||
|
|
@ -981,6 +996,14 @@ func (pool *LegacyPool) Add(txs []*types.Transaction, local, sync bool) []error
|
|||
invalidTxMeter.Mark(1)
|
||||
continue
|
||||
}
|
||||
|
||||
// FIXME kirill
|
||||
if err := pool.validateTxWithCustomValidator(tx, local); err != nil {
|
||||
errs[i] = err
|
||||
log.Trace("Discarding invalid transaction", "hash", tx.Hash(), "err", err)
|
||||
invalidTxMeter.Mark(1)
|
||||
continue
|
||||
}
|
||||
// Accumulate all unknown transactions for deeper processing
|
||||
news = append(news, tx)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1536,6 +1536,52 @@ func TestMinGasPriceEnforced(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestCustomTxValidationEnforced(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Create the pool to test the pricing enforcement with
|
||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
||||
blockchain := newTestBlockChain(eip1559Config, 10000000, statedb, new(event.Feed))
|
||||
|
||||
txPoolConfig := DefaultConfig
|
||||
if txPoolConfig.CustomValidationEnabled {
|
||||
t.Fatalf("Custom validation should be disabled by default")
|
||||
}
|
||||
|
||||
txPoolConfig.NoLocals = true
|
||||
pool := New(txPoolConfig, blockchain)
|
||||
pool.Init(new(big.Int).SetUint64(txPoolConfig.PriceLimit), blockchain.CurrentBlock(), makeAddressReserver())
|
||||
defer pool.Close()
|
||||
|
||||
key, _ := crypto.GenerateKey()
|
||||
testAddBalance(pool, crypto.PubkeyToAddress(key.PublicKey), big.NewInt(1000000))
|
||||
|
||||
tx := pricedTransaction(0, 100000, big.NewInt(3), key)
|
||||
pool.SetGasTip(big.NewInt(tx.GasPrice().Int64()))
|
||||
|
||||
// yo := pool.Add([]*types.Transaction{tx}, true, false)[0]
|
||||
// t.Fatal(yo)
|
||||
if err := pool.Add([]*types.Transaction{tx}, true, false)[0]; err != nil {
|
||||
t.Fatalf("TxValidation enforced in default config despite being disabled by default")
|
||||
}
|
||||
|
||||
// Modifying local config to enable custom validation
|
||||
poolWithCustomValidationConfig := DefaultConfig
|
||||
poolWithCustomValidationConfig.CustomValidationEnabled = true
|
||||
poolWithCustomValidationConfig.NoLocals = true
|
||||
|
||||
poolWithCustomValidation := New(poolWithCustomValidationConfig, blockchain)
|
||||
poolWithCustomValidation.Init(new(big.Int).SetUint64(poolWithCustomValidationConfig.PriceLimit), blockchain.CurrentBlock(), makeAddressReserver())
|
||||
defer poolWithCustomValidation.Close()
|
||||
|
||||
testAddBalance(poolWithCustomValidation, crypto.PubkeyToAddress(key.PublicKey), big.NewInt(1000000))
|
||||
poolWithCustomValidation.SetGasTip(big.NewInt(tx.GasPrice().Int64()))
|
||||
|
||||
if err := poolWithCustomValidation.Add([]*types.Transaction{tx}, true, false)[0]; !errors.Is(err, txpool.ErrCustomValidationFailed) {
|
||||
t.Fatalf("Custom TxValidation not enforced")
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that setting the transaction pool gas price to a higher value correctly
|
||||
// discards everything cheaper (legacy & dynamic fee) than that and moves any
|
||||
// gapped transactions back from the pending pool to the queue.
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ type ValidationOptions struct {
|
|||
MinTip *big.Int // Minimum gas tip needed to allow a transaction into the caller pool
|
||||
}
|
||||
|
||||
type CustomValidationOptions struct {
|
||||
}
|
||||
|
||||
// ValidateTransaction is a helper method to check whether a transaction is valid
|
||||
// according to the consensus rules, but does not check state-dependent validation
|
||||
// (balance, nonce, etc).
|
||||
|
|
@ -245,3 +248,10 @@ func ValidateTransactionWithState(tx *types.Transaction, signer types.Signer, op
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// FIXME add proper explanation (Kirill)
|
||||
func ValidateTransactionWithCustomValidator(tx *types.Transaction, head *types.Header, signer types.Signer, opts *CustomValidationOptions) error {
|
||||
// Ensure transactions not implemented by the calling pool are rejected
|
||||
return ErrCustomValidationFailed
|
||||
// return nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue