Skip to content

Commit 1153701

Browse files
committed
internal/ethapi: disable sending of non eip155 replay protected tx ethereum#22339
1 parent 08dbbe7 commit 1153701

File tree

8 files changed

+44
-8
lines changed

8 files changed

+44
-8
lines changed

cmd/XDC/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ var (
161161
utils.IPCDisabledFlag,
162162
utils.IPCPathFlag,
163163
utils.RPCGlobalTxFeeCap,
164+
utils.AllowUnprotectedTxs,
164165
}
165166

166167
metricsFlags = []cli.Flag{

cmd/utils/flags.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,11 @@ var (
546546
Usage: "Comma separated list of JavaScript files to preload into the console",
547547
Category: flags.APICategory,
548548
}
549+
AllowUnprotectedTxs = &cli.BoolFlag{
550+
Name: "rpc.allow-unprotected-txs",
551+
Usage: "Allow for unprotected (non EIP155 signed) transactions to be submitted via RPC",
552+
Category: flags.APICategory,
553+
}
549554

550555
// Network Settings
551556
MaxPeersFlag = &cli.IntFlag{
@@ -1014,6 +1019,9 @@ func setHTTP(ctx *cli.Context, cfg *node.Config) {
10141019
if ctx.IsSet(HTTPIdleTimeoutFlag.Name) {
10151020
cfg.HTTPTimeouts.IdleTimeout = ctx.Duration(HTTPIdleTimeoutFlag.Name)
10161021
}
1022+
if ctx.IsSet(AllowUnprotectedTxs.Name) {
1023+
cfg.AllowUnprotectedTxs = ctx.Bool(AllowUnprotectedTxs.Name)
1024+
}
10171025
cfg.HTTPCors = SplitAndTrim(ctx.String(HTTPCORSDomainFlag.Name))
10181026
cfg.HTTPModules = SplitAndTrim(ctx.String(HTTPApiFlag.Name))
10191027
cfg.HTTPVirtualHosts = SplitAndTrim(ctx.String(HTTPVirtualHostsFlag.Name))

eth/api_backend.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,10 @@ import (
5454

5555
// EthAPIBackend implements ethapi.Backend for full nodes
5656
type EthAPIBackend struct {
57-
eth *Ethereum
58-
gpo *gasprice.Oracle
59-
XDPoS *XDPoS.XDPoS
57+
allowUnprotectedTxs bool
58+
eth *Ethereum
59+
gpo *gasprice.Oracle
60+
XDPoS *XDPoS.XDPoS
6061
}
6162

6263
func (b *EthAPIBackend) ChainConfig() *params.ChainConfig {
@@ -369,6 +370,10 @@ func (b *EthAPIBackend) EventMux() *event.TypeMux {
369370
return b.eth.EventMux()
370371
}
371372

373+
func (b *EthAPIBackend) UnprotectedAllowed() bool {
374+
return b.allowUnprotectedTxs
375+
}
376+
372377
func (b *EthAPIBackend) RPCGasCap() uint64 {
373378
return b.eth.config.RPCGasCap
374379
}

eth/backend.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,22 @@ func New(stack *node.Node, config *ethconfig.Config, XDCXServ *XDCx.XDCX, lendin
245245
eth.miner.SetExtra(makeExtraData(config.ExtraData))
246246

247247
if eth.chainConfig.XDPoS != nil {
248-
eth.ApiBackend = &EthAPIBackend{eth, nil, eth.engine.(*XDPoS.XDPoS)}
248+
eth.ApiBackend = &EthAPIBackend{
249+
allowUnprotectedTxs: stack.Config().AllowUnprotectedTxs,
250+
eth: eth,
251+
gpo: nil,
252+
XDPoS: eth.engine.(*XDPoS.XDPoS),
253+
}
249254
} else {
250-
eth.ApiBackend = &EthAPIBackend{eth, nil, nil}
255+
eth.ApiBackend = &EthAPIBackend{
256+
allowUnprotectedTxs: stack.Config().AllowUnprotectedTxs,
257+
eth: eth,
258+
gpo: nil,
259+
XDPoS: nil,
260+
}
261+
}
262+
if eth.ApiBackend.allowUnprotectedTxs {
263+
log.Info("Unprotected transactions allowed")
251264
}
252265
eth.ApiBackend.gpo = gasprice.NewOracle(eth.ApiBackend, config.GPO, config.GasPrice)
253266

internal/ethapi/api.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2304,6 +2304,10 @@ func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (c
23042304
if err := checkTxFee(tx.GasPrice(), tx.Gas(), b.RPCTxFeeCap()); err != nil {
23052305
return common.Hash{}, err
23062306
}
2307+
if !b.UnprotectedAllowed() && !tx.Protected() {
2308+
// Ensure only eip155 signed transactions are submitted if EIP155Required is set.
2309+
return common.Hash{}, errors.New("only replay-protected (EIP-155) transactions allowed over RPC")
2310+
}
23072311
if err := b.SendTx(ctx, tx); err != nil {
23082312
return common.Hash{}, err
23092313
}

internal/ethapi/backend.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,10 @@ type Backend interface {
5151
BlobBaseFee(ctx context.Context) *big.Int
5252
ChainDb() ethdb.Database
5353
AccountManager() *accounts.Manager
54-
RPCGasCap() uint64 // global gas cap for eth_call over rpc: DoS protection
55-
RPCTxFeeCap() float64 // global tx fee cap for all transaction related APIs
54+
RPCGasCap() uint64 // global gas cap for eth_call over rpc: DoS protection
55+
RPCTxFeeCap() float64 // global tx fee cap for all transaction related APIs
56+
UnprotectedAllowed() bool // allows only for EIP155 transactions.
57+
5658
XDCxService() *XDCx.XDCX
5759
LendingService() *XDCxlending.Lending
5860

node/config.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ type Config struct {
171171
oldGethResourceWarning bool
172172

173173
AnnounceTxs bool `toml:",omitempty"`
174+
175+
// AllowUnprotectedTxs allows non EIP-155 protected transactions to be send over RPC.
176+
AllowUnprotectedTxs bool `toml:",omitempty"`
174177
}
175178

176179
// IPCEndpoint resolves an IPC endpoint based on a configured value, taking into

node/rpcstack_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ func baseRpcRequest(t *testing.T, url, bodyStr string, extraHeaders ...string) *
258258

259259
// Create the request.
260260
body := bytes.NewReader([]byte(bodyStr))
261-
req, err := http.NewRequest("POST", url, body)
261+
req, err := http.NewRequest(http.MethodPost, url, body)
262262
if err != nil {
263263
t.Fatal("could not create http request:", err)
264264
}

0 commit comments

Comments
 (0)