mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-02-26 15:47:21 +00:00
Some tests involving transactions near the txMaxSize limit were flaky. This was due to ECDSA signatures occasionally having leading zeros, which are omitted during RLP encoding — making the final transaction size 1 byte smaller than expected. To address this, a new helper function pricedDataTransactionWithFixedSignature was added. It ensures both r and s are exactly 32 bytes (i.e., no leading zeros), producing transactions with deterministic size.
This commit is contained in:
parent
24771fdba4
commit
e4a8ecb947
1 changed files with 27 additions and 5 deletions
|
|
@ -108,11 +108,33 @@ func pricedTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ec
|
|||
return tx
|
||||
}
|
||||
|
||||
func pricedDataTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ecdsa.PrivateKey, bytes uint64) *types.Transaction {
|
||||
data := make([]byte, bytes)
|
||||
crand.Read(data)
|
||||
// pricedDataTransaction generates a signed transaction with fixed-size data,
|
||||
// and ensures that the resulting signature components (r and s) are exactly 32 bytes each,
|
||||
// producing transactions with deterministic size.
|
||||
//
|
||||
// This avoids variability in transaction size caused by leading zeros being omitted in
|
||||
// RLP encoding of r/s. Since r and s are derived from ECDSA, they occasionally have leading
|
||||
// zeros and thus can be shorter than 32 bytes.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// r: 0 leading zeros, bytesSize: 32, bytes: [221 ... 101]
|
||||
// s: 1 leading zeros, bytesSize: 31, bytes: [0 75 ... 47]
|
||||
func pricedDataTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ecdsa.PrivateKey, dataBytes uint64) *types.Transaction {
|
||||
var tx *types.Transaction
|
||||
|
||||
tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(0), gaslimit, gasprice, data), types.HomesteadSigner{}, key)
|
||||
// 10 attempts is statistically sufficient since leading zeros in ECDSA signatures are rare and randomly distributed.
|
||||
var retryTimes = 10
|
||||
for i := 0; i < retryTimes; i++ {
|
||||
data := make([]byte, dataBytes)
|
||||
crand.Read(data)
|
||||
|
||||
tx, _ = types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(0), gaslimit, gasprice, data), types.HomesteadSigner{}, key)
|
||||
_, r, s := tx.RawSignatureValues()
|
||||
if len(r.Bytes()) == 32 && len(s.Bytes()) == 32 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return tx
|
||||
}
|
||||
|
||||
|
|
@ -1239,7 +1261,7 @@ func TestAllowedTxSize(t *testing.T) {
|
|||
const largeDataLength = txMaxSize - 200 // enough to have a 5 bytes RLP encoding of the data length number
|
||||
txWithLargeData := pricedDataTransaction(0, pool.currentHead.Load().GasLimit, big.NewInt(1), key, largeDataLength)
|
||||
maxTxLengthWithoutData := txWithLargeData.Size() - largeDataLength // 103 bytes
|
||||
maxTxDataLength := txMaxSize - maxTxLengthWithoutData // 131072 - 103 = 130953 bytes
|
||||
maxTxDataLength := txMaxSize - maxTxLengthWithoutData // 131072 - 103 = 130969 bytes
|
||||
|
||||
// Try adding a transaction with maximal allowed size
|
||||
tx := pricedDataTransaction(0, pool.currentHead.Load().GasLimit, big.NewInt(1), key, maxTxDataLength)
|
||||
|
|
|
|||
Loading…
Reference in a new issue