Skip to content

Commit e311ecd

Browse files
authored
fix flaky TestAllowedTxSize (#699)
for more info, https://github.com/ethereum/go-ethereum/pull/31836/files
1 parent 07869cb commit e311ecd

File tree

1 file changed

+28
-6
lines changed

1 file changed

+28
-6
lines changed

mempool/txpool/legacypool/legacypool_test.go

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,33 @@ func pricedTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ec
109109
return tx
110110
}
111111

112-
func pricedDataTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ecdsa.PrivateKey, bytes uint64) *types.Transaction {
113-
data := make([]byte, bytes)
114-
crand.Read(data)
115-
116-
tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(0), gaslimit, gasprice, data), types.HomesteadSigner{}, key)
112+
// pricedDataTransaction generates a signed transaction with fixed-size data,
113+
// and ensures that the resulting signature components (r and s) are exactly 32 bytes each,
114+
// producing transactions with deterministic size.
115+
//
116+
// This avoids variability in transaction size caused by leading zeros being omitted in
117+
// RLP encoding of r/s. Since r and s are derived from ECDSA, they occasionally have leading
118+
// zeros and thus can be shorter than 32 bytes.
119+
//
120+
// For example:
121+
//
122+
// r: 0 leading zeros, bytesSize: 32, bytes: [221 ... 101]
123+
// s: 1 leading zeros, bytesSize: 31, bytes: [0 75 ... 47]
124+
func pricedDataTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ecdsa.PrivateKey, dataBytes uint64) *types.Transaction {
125+
var tx *types.Transaction
126+
127+
// 10 attempts is statistically sufficient since leading zeros in ECDSA signatures are rare and randomly distributed.
128+
var retryTimes = 10
129+
for i := 0; i < retryTimes; i++ {
130+
data := make([]byte, dataBytes)
131+
crand.Read(data)
132+
133+
tx, _ = types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(0), gaslimit, gasprice, data), types.HomesteadSigner{}, key)
134+
_, r, s := tx.RawSignatureValues()
135+
if len(r.Bytes()) == 32 && len(s.Bytes()) == 32 {
136+
break
137+
}
138+
}
117139
return tx
118140
}
119141

@@ -1240,7 +1262,7 @@ func TestAllowedTxSize(t *testing.T) {
12401262
const largeDataLength = txMaxSize - 200 // enough to have a 5 bytes RLP encoding of the data length number
12411263
txWithLargeData := pricedDataTransaction(0, pool.currentHead.Load().GasLimit, big.NewInt(1), key, largeDataLength)
12421264
maxTxLengthWithoutData := txWithLargeData.Size() - largeDataLength // 103 bytes
1243-
maxTxDataLength := txMaxSize - maxTxLengthWithoutData // 131072 - 103 = 130953 bytes
1265+
maxTxDataLength := txMaxSize - maxTxLengthWithoutData // 131072 - 103 = 130969 bytes
12441266

12451267
// Try adding a transaction with maximal allowed size
12461268
tx := pricedDataTransaction(0, pool.currentHead.Load().GasLimit, big.NewInt(1), key, maxTxDataLength)

0 commit comments

Comments
 (0)