mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 21:31:37 +00:00
This commit is contained in:
parent
eaaeea0cad
commit
4881c9445a
9 changed files with 144 additions and 64 deletions
|
|
@ -2045,7 +2045,7 @@ func (bc *BlockChain) insertSidechain(block *types.Block, it *insertIterator) (i
|
|||
// Import all the pruned blocks to make the state available
|
||||
var (
|
||||
blocks []*types.Block
|
||||
memory common.StorageSize
|
||||
memory uint64
|
||||
)
|
||||
for i := len(hashes) - 1; i >= 0; i-- {
|
||||
// Append the next block to our batch
|
||||
|
|
|
|||
|
|
@ -623,7 +623,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
|
|||
return core.ErrTxTypeNotSupported
|
||||
}
|
||||
// Reject transactions over defined size to prevent DOS attacks
|
||||
if uint64(tx.Size()) > txMaxSize {
|
||||
if tx.Size() > txMaxSize {
|
||||
return ErrOversizedData
|
||||
}
|
||||
// Get current block number
|
||||
|
|
|
|||
|
|
@ -325,7 +325,7 @@ func (b *Block) DecodeRLP(s *rlp.Stream) error {
|
|||
return err
|
||||
}
|
||||
b.header, b.uncles, b.transactions = eb.Header, eb.Uncles, eb.Txs
|
||||
b.size.Store(common.StorageSize(rlp.ListSize(size)))
|
||||
b.size.Store(rlp.ListSize(size))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -412,17 +412,17 @@ func (b *Block) HashNoValidator() common.Hash {
|
|||
|
||||
// Size returns the true RLP encoded storage size of the block, either by encoding
|
||||
// and returning it, or returning a previsouly cached value.
|
||||
func (b *Block) Size() common.StorageSize {
|
||||
func (b *Block) Size() uint64 {
|
||||
if size := b.size.Load(); size != nil {
|
||||
return size.(common.StorageSize)
|
||||
return size.(uint64)
|
||||
}
|
||||
c := writeCounter(0)
|
||||
rlp.Encode(&c, b)
|
||||
b.size.Store(common.StorageSize(c))
|
||||
return common.StorageSize(c)
|
||||
b.size.Store(uint64(c))
|
||||
return uint64(c)
|
||||
}
|
||||
|
||||
type writeCounter common.StorageSize
|
||||
type writeCounter uint64
|
||||
|
||||
func (c *writeCounter) Write(b []byte) (int, error) {
|
||||
*c += writeCounter(len(b))
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ func TestBlockEncoding(t *testing.T) {
|
|||
check("Hash", block.Hash().String(), common.HexToHash("e8d9d473fdeddd3079988fa7be58f582b7b2800e90917d4bb6f11155ce4dba30").String())
|
||||
check("Nonce", block.Nonce(), uint64(0xa13a5a8c8f2bb1c4))
|
||||
check("Time", block.Time(), uint64(1426516743))
|
||||
check("Size", block.Size(), common.StorageSize(len(blockEnc)))
|
||||
check("Size", block.Size(), uint64(len(blockEnc)))
|
||||
|
||||
ourBlockEnc, err := rlp.EncodeToBytes(&block)
|
||||
if err != nil {
|
||||
|
|
@ -85,7 +85,7 @@ func TestEIP2718BlockEncoding(t *testing.T) {
|
|||
check("Root", block.Root(), common.HexToHash("ef1552a40b7165c3cd773806b9e0c165b75356e0314bf0706f279c729f51e017"))
|
||||
check("Nonce", block.Nonce(), uint64(0xa13a5a8c8f2bb1c4))
|
||||
check("Time", block.Time(), uint64(1426516743))
|
||||
check("Size", block.Size(), common.StorageSize(len(blockEnc)))
|
||||
check("Size", block.Size(), uint64(len(blockEnc)))
|
||||
|
||||
// Create legacy tx.
|
||||
to := common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87")
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ func (tx *Transaction) DecodeRLP(s *rlp.Stream) error {
|
|||
var inner LegacyTx
|
||||
err := s.Decode(&inner)
|
||||
if err == nil {
|
||||
tx.setDecoded(&inner, int(rlp.ListSize(size)))
|
||||
tx.setDecoded(&inner, rlp.ListSize(size))
|
||||
}
|
||||
return err
|
||||
default:
|
||||
|
|
@ -157,7 +157,7 @@ func (tx *Transaction) DecodeRLP(s *rlp.Stream) error {
|
|||
}
|
||||
inner, err := tx.decodeTyped(b)
|
||||
if err == nil {
|
||||
tx.setDecoded(inner, len(b))
|
||||
tx.setDecoded(inner, uint64(len(b)))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
@ -173,7 +173,7 @@ func (tx *Transaction) UnmarshalBinary(b []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tx.setDecoded(&data, len(b))
|
||||
tx.setDecoded(&data, uint64(len(b)))
|
||||
return nil
|
||||
}
|
||||
// It's an EIP2718 typed transaction envelope.
|
||||
|
|
@ -181,7 +181,7 @@ func (tx *Transaction) UnmarshalBinary(b []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tx.setDecoded(inner, len(b))
|
||||
tx.setDecoded(inner, uint64(len(b)))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -205,11 +205,11 @@ func (tx *Transaction) decodeTyped(b []byte) (TxData, error) {
|
|||
}
|
||||
|
||||
// setDecoded sets the inner transaction and size after decoding.
|
||||
func (tx *Transaction) setDecoded(inner TxData, size int) {
|
||||
func (tx *Transaction) setDecoded(inner TxData, size uint64) {
|
||||
tx.inner = inner
|
||||
tx.time = time.Now()
|
||||
if size > 0 {
|
||||
tx.size.Store(common.StorageSize(size))
|
||||
tx.size.Store(size)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -407,16 +407,26 @@ func (tx *Transaction) Hash() common.Hash {
|
|||
return h
|
||||
}
|
||||
|
||||
// Size returns the true RLP encoded storage size of the transaction, either by
|
||||
// encoding and returning it, or returning a previously cached value.
|
||||
func (tx *Transaction) Size() common.StorageSize {
|
||||
// Size returns the true encoded storage size of the transaction, either by encoding
|
||||
// and returning it, or returning a previously cached value.
|
||||
func (tx *Transaction) Size() uint64 {
|
||||
if size := tx.size.Load(); size != nil {
|
||||
return size.(common.StorageSize)
|
||||
return size.(uint64)
|
||||
}
|
||||
|
||||
// Cache miss, encode and cache.
|
||||
// Note we rely on the assumption that all tx.inner values are RLP-encoded
|
||||
c := writeCounter(0)
|
||||
rlp.Encode(&c, &tx.inner)
|
||||
tx.size.Store(common.StorageSize(c))
|
||||
return common.StorageSize(c)
|
||||
size := uint64(c)
|
||||
|
||||
// For typed transactions, the encoding also includes the leading type byte.
|
||||
if tx.Type() != LegacyTxType {
|
||||
size++
|
||||
}
|
||||
|
||||
tx.size.Store(size)
|
||||
return size
|
||||
}
|
||||
|
||||
func (tx *Transaction) EffectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
|
||||
|
|
|
|||
|
|
@ -51,55 +51,58 @@ type txJSON struct {
|
|||
}
|
||||
|
||||
// MarshalJSON marshals as JSON with a hash.
|
||||
func (t *Transaction) MarshalJSON() ([]byte, error) {
|
||||
func (tx *Transaction) MarshalJSON() ([]byte, error) {
|
||||
var enc txJSON
|
||||
// These are set for all tx types.
|
||||
enc.Hash = t.Hash()
|
||||
enc.Type = hexutil.Uint64(t.Type())
|
||||
enc.Hash = tx.Hash()
|
||||
enc.Type = hexutil.Uint64(tx.Type())
|
||||
|
||||
// Other fields are set conditionally depending on tx type.
|
||||
switch tx := t.inner.(type) {
|
||||
// Other fields are set conditionally depending on itx type.
|
||||
switch itx := tx.inner.(type) {
|
||||
case *LegacyTx:
|
||||
enc.Nonce = (*hexutil.Uint64)(&tx.Nonce)
|
||||
enc.Gas = (*hexutil.Uint64)(&tx.Gas)
|
||||
enc.GasPrice = (*hexutil.Big)(tx.GasPrice)
|
||||
enc.Value = (*hexutil.Big)(tx.Value)
|
||||
enc.Data = (*hexutil.Bytes)(&tx.Data)
|
||||
enc.To = t.To()
|
||||
enc.V = (*hexutil.Big)(tx.V)
|
||||
enc.R = (*hexutil.Big)(tx.R)
|
||||
enc.S = (*hexutil.Big)(tx.S)
|
||||
enc.Nonce = (*hexutil.Uint64)(&itx.Nonce)
|
||||
enc.To = tx.To()
|
||||
enc.Gas = (*hexutil.Uint64)(&itx.Gas)
|
||||
enc.GasPrice = (*hexutil.Big)(itx.GasPrice)
|
||||
enc.Value = (*hexutil.Big)(itx.Value)
|
||||
enc.Data = (*hexutil.Bytes)(&itx.Data)
|
||||
enc.V = (*hexutil.Big)(itx.V)
|
||||
enc.R = (*hexutil.Big)(itx.R)
|
||||
enc.S = (*hexutil.Big)(itx.S)
|
||||
|
||||
case *AccessListTx:
|
||||
enc.ChainID = (*hexutil.Big)(tx.ChainID)
|
||||
enc.AccessList = &tx.AccessList
|
||||
enc.Nonce = (*hexutil.Uint64)(&tx.Nonce)
|
||||
enc.Gas = (*hexutil.Uint64)(&tx.Gas)
|
||||
enc.GasPrice = (*hexutil.Big)(tx.GasPrice)
|
||||
enc.Value = (*hexutil.Big)(tx.Value)
|
||||
enc.Data = (*hexutil.Bytes)(&tx.Data)
|
||||
enc.To = t.To()
|
||||
enc.V = (*hexutil.Big)(tx.V)
|
||||
enc.R = (*hexutil.Big)(tx.R)
|
||||
enc.S = (*hexutil.Big)(tx.S)
|
||||
enc.ChainID = (*hexutil.Big)(itx.ChainID)
|
||||
enc.Nonce = (*hexutil.Uint64)(&itx.Nonce)
|
||||
enc.To = tx.To()
|
||||
enc.Gas = (*hexutil.Uint64)(&itx.Gas)
|
||||
enc.GasPrice = (*hexutil.Big)(itx.GasPrice)
|
||||
enc.Value = (*hexutil.Big)(itx.Value)
|
||||
enc.Data = (*hexutil.Bytes)(&itx.Data)
|
||||
enc.AccessList = &itx.AccessList
|
||||
enc.V = (*hexutil.Big)(itx.V)
|
||||
enc.R = (*hexutil.Big)(itx.R)
|
||||
enc.S = (*hexutil.Big)(itx.S)
|
||||
|
||||
case *DynamicFeeTx:
|
||||
enc.ChainID = (*hexutil.Big)(tx.ChainID)
|
||||
enc.AccessList = &tx.AccessList
|
||||
enc.Nonce = (*hexutil.Uint64)(&tx.Nonce)
|
||||
enc.Gas = (*hexutil.Uint64)(&tx.Gas)
|
||||
enc.MaxFeePerGas = (*hexutil.Big)(tx.GasFeeCap)
|
||||
enc.MaxPriorityFeePerGas = (*hexutil.Big)(tx.GasTipCap)
|
||||
enc.Value = (*hexutil.Big)(tx.Value)
|
||||
enc.Data = (*hexutil.Bytes)(&tx.Data)
|
||||
enc.To = t.To()
|
||||
enc.V = (*hexutil.Big)(tx.V)
|
||||
enc.R = (*hexutil.Big)(tx.R)
|
||||
enc.S = (*hexutil.Big)(tx.S)
|
||||
enc.ChainID = (*hexutil.Big)(itx.ChainID)
|
||||
enc.Nonce = (*hexutil.Uint64)(&itx.Nonce)
|
||||
enc.To = tx.To()
|
||||
enc.Gas = (*hexutil.Uint64)(&itx.Gas)
|
||||
enc.MaxFeePerGas = (*hexutil.Big)(itx.GasFeeCap)
|
||||
enc.MaxPriorityFeePerGas = (*hexutil.Big)(itx.GasTipCap)
|
||||
enc.Value = (*hexutil.Big)(itx.Value)
|
||||
enc.Data = (*hexutil.Bytes)(&itx.Data)
|
||||
enc.AccessList = &itx.AccessList
|
||||
enc.V = (*hexutil.Big)(itx.V)
|
||||
enc.R = (*hexutil.Big)(itx.R)
|
||||
enc.S = (*hexutil.Big)(itx.S)
|
||||
}
|
||||
|
||||
return json.Marshal(&enc)
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals from JSON.
|
||||
func (t *Transaction) UnmarshalJSON(input []byte) error {
|
||||
func (tx *Transaction) UnmarshalJSON(input []byte) error {
|
||||
var dec txJSON
|
||||
if err := json.Unmarshal(input, &dec); err != nil {
|
||||
return err
|
||||
|
|
@ -268,8 +271,7 @@ func (t *Transaction) UnmarshalJSON(input []byte) error {
|
|||
}
|
||||
|
||||
// Now set the inner transaction.
|
||||
t.setDecoded(inner, 0)
|
||||
tx.setDecoded(inner, 0)
|
||||
|
||||
// TODO: check hash here?
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -541,3 +541,71 @@ func assertEqual(orig *Transaction, cpy *Transaction) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestTransactionSizes(t *testing.T) {
|
||||
signer := NewLondonSigner(big.NewInt(123))
|
||||
key, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||
to := common.HexToAddress("0x01")
|
||||
for i, txdata := range []TxData{
|
||||
&AccessListTx{
|
||||
ChainID: big.NewInt(123),
|
||||
Nonce: 0,
|
||||
To: nil,
|
||||
Value: big.NewInt(1000),
|
||||
Gas: 21000,
|
||||
GasPrice: big.NewInt(100000),
|
||||
},
|
||||
&LegacyTx{
|
||||
Nonce: 1,
|
||||
GasPrice: big.NewInt(500),
|
||||
Gas: 1000000,
|
||||
To: &to,
|
||||
Value: big.NewInt(1),
|
||||
},
|
||||
&AccessListTx{
|
||||
ChainID: big.NewInt(123),
|
||||
Nonce: 1,
|
||||
GasPrice: big.NewInt(500),
|
||||
Gas: 1000000,
|
||||
To: &to,
|
||||
Value: big.NewInt(1),
|
||||
AccessList: AccessList{
|
||||
AccessTuple{
|
||||
Address: common.HexToAddress("0x01"),
|
||||
StorageKeys: []common.Hash{common.HexToHash("0x01")},
|
||||
}},
|
||||
},
|
||||
&DynamicFeeTx{
|
||||
ChainID: big.NewInt(123),
|
||||
Nonce: 1,
|
||||
Gas: 1000000,
|
||||
To: &to,
|
||||
Value: big.NewInt(1),
|
||||
GasTipCap: big.NewInt(500),
|
||||
GasFeeCap: big.NewInt(500),
|
||||
},
|
||||
} {
|
||||
tx, err := SignNewTx(key, signer, txdata)
|
||||
if err != nil {
|
||||
t.Fatalf("test %d: %v", i, err)
|
||||
}
|
||||
bin, _ := tx.MarshalBinary()
|
||||
|
||||
// Check initial calc
|
||||
if have, want := int(tx.Size()), len(bin); have != want {
|
||||
t.Errorf("test %d: size wrong, have %d want %d", i, have, want)
|
||||
}
|
||||
// Check cached version too
|
||||
if have, want := int(tx.Size()), len(bin); have != want {
|
||||
t.Errorf("test %d: (cached) size wrong, have %d want %d", i, have, want)
|
||||
}
|
||||
// Check unmarshalled version too
|
||||
utx := new(Transaction)
|
||||
if err := utx.UnmarshalBinary(bin); err != nil {
|
||||
t.Fatalf("test %d: failed to unmarshal tx: %v", i, err)
|
||||
}
|
||||
if have, want := int(utx.Size()), len(bin); have != want {
|
||||
t.Errorf("test %d: (unmarshalled) size wrong, have %d want %d", i, have, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -381,7 +381,7 @@ func (q *queue) Results(block bool) []*fetchResult {
|
|||
size += receipt.Size()
|
||||
}
|
||||
for _, tx := range result.Transactions {
|
||||
size += tx.Size()
|
||||
size += common.StorageSize(tx.Size())
|
||||
}
|
||||
q.resultSize = common.StorageSize(blockCacheSizeWeight)*size +
|
||||
(1-common.StorageSize(blockCacheSizeWeight))*q.resultSize
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ func (pm *ProtocolManager) txsyncLoop() {
|
|||
pack.txs = pack.txs[:0]
|
||||
for i := 0; i < len(s.txs) && size < txsyncPackSize; i++ {
|
||||
pack.txs = append(pack.txs, s.txs[i])
|
||||
size += s.txs[i].Size()
|
||||
size += common.StorageSize(s.txs[i].Size())
|
||||
}
|
||||
// Remove the transactions that will be sent.
|
||||
s.txs = s.txs[:copy(s.txs, s.txs[len(pack.txs):])]
|
||||
|
|
|
|||
Loading…
Reference in a new issue