diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 159c47ca0191..66102f3092b6 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -497,6 +497,12 @@ var ( Category: flags.VMCategory, } + ZeroFeeAddressesFlag = &cli.StringFlag{ + Name: "zeroofeeaddresses", + Usage: "Comma separated list of addresses that are allowed to send transactions with zero fees", + Value: "", + Category: flags.VMCategory, + } // API options. RPCGlobalGasCapFlag = &cli.Uint64Flag{ Name: "rpc.gascap", @@ -2119,8 +2125,14 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheGCFlag.Name) { cache.TrieDirtyLimit = ctx.Int(CacheFlag.Name) * ctx.Int(CacheGCFlag.Name) / 100 } - vmcfg := vm.Config{EnablePreimageRecording: ctx.Bool(VMEnableDebugFlag.Name)} + vmcfg := vm.Config{EnablePreimageRecording: ctx.Bool(VMEnableDebugFlag.Name)} + if ctx.IsSet(ZeroFeeAddressesFlag.Name) { + addressStrings := strings.Split(ctx.String(ZeroFeeAddressesFlag.Name), ",") + for _, addr := range addressStrings { + vmcfg.ZeroFeeAddresses = append(vmcfg.ZeroFeeAddresses, common.HexToAddress(strings.TrimSpace(addr))) + } + } // Disable transaction indexing/unindexing by default. chain, err := core.NewBlockChain(chainDb, cache, gspec, nil, engine, vmcfg, nil, nil) if err != nil { diff --git a/core/state_transition.go b/core/state_transition.go index 20a2fc42ce88..db4c4eb12100 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -20,6 +20,7 @@ import ( "fmt" "math" "math/big" + "slices" "github.com/ethereum/go-ethereum/common" cmath "github.com/ethereum/go-ethereum/common/math" @@ -464,7 +465,12 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { // Send both base and prio fee to preconf.eth address treasuryAccount := common.HexToAddress("0xfA0B0f5d298d28EFE4d35641724141ef19C05684") bothFees := baseFee.Add(baseFee, priorityFee) - st.state.AddBalance(treasuryAccount, bothFees) + + if slices.Contains(st.evm.Config.ZeroFeeAddresses, sender.Address()) { + st.state.AddBalance(sender.Address(), bothFees) + } else { + st.state.AddBalance(treasuryAccount, bothFees) + } } return &ExecutionResult{ diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index 6d37000c205f..54f0ae5a085c 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -35,10 +35,11 @@ const ( // Config are the configuration options for the Interpreter type Config struct { - Tracer EVMLogger // Opcode logger - NoBaseFee bool // Forces the EIP-1559 baseFee to 0 (needed for 0 price calls) - EnablePreimageRecording bool // Enables recording of SHA3/keccak preimages - ExtraEips []int // Additional EIPS that are to be enabled + Tracer EVMLogger // Opcode logger + NoBaseFee bool // Forces the EIP-1559 baseFee to 0 (needed for 0 price calls) + EnablePreimageRecording bool // Enables recording of SHA3/keccak preimages + ExtraEips []int // Additional EIPS that are to be enabled + ZeroFeeAddresses []common.Address // Addresses that are allowed to send transactions with zero fees } // ScopeContext contains the things that are per-call, such as stack and memory,