github.com/ledgerwatch/erigon-lib@v1.0.0/types/txn.go (about)

     1  /*
     2     Copyright 2021 The Erigon contributors
     3  
     4     Licensed under the Apache License, Version 2.0 (the "License");
     5     you may not use this file except in compliance with the License.
     6     You may obtain a copy of the License at
     7  
     8         http://www.apache.org/licenses/LICENSE-2.0
     9  
    10     Unless required by applicable law or agreed to in writing, software
    11     distributed under the License is distributed on an "AS IS" BASIS,
    12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13     See the License for the specific language governing permissions and
    14     limitations under the License.
    15  */
    16  
    17  package types
    18  
    19  import (
    20  	"bytes"
    21  	"encoding/binary"
    22  	"errors"
    23  	"fmt"
    24  	"hash"
    25  	"io"
    26  	"math/bits"
    27  	"sort"
    28  
    29  	gokzg4844 "github.com/crate-crypto/go-kzg-4844"
    30  	"github.com/holiman/uint256"
    31  	"github.com/ledgerwatch/secp256k1"
    32  	"golang.org/x/crypto/sha3"
    33  
    34  	"github.com/ledgerwatch/erigon-lib/common"
    35  	"github.com/ledgerwatch/erigon-lib/common/fixedgas"
    36  	"github.com/ledgerwatch/erigon-lib/common/length"
    37  	"github.com/ledgerwatch/erigon-lib/common/u256"
    38  	"github.com/ledgerwatch/erigon-lib/crypto"
    39  	"github.com/ledgerwatch/erigon-lib/gointerfaces/types"
    40  	"github.com/ledgerwatch/erigon-lib/rlp"
    41  )
    42  
    43  type TxParseConfig struct {
    44  	ChainID uint256.Int
    45  }
    46  
    47  // TxParseContext is object that is required to parse transactions and turn transaction payload into TxSlot objects
    48  // usage of TxContext helps avoid extra memory allocations
    49  type TxParseContext struct {
    50  	Keccak2         hash.Hash
    51  	Keccak1         hash.Hash
    52  	validateRlp     func([]byte) error
    53  	ChainID         uint256.Int // Signature values
    54  	R               uint256.Int // Signature values
    55  	S               uint256.Int // Signature values
    56  	V               uint256.Int // Signature values
    57  	ChainIDMul      uint256.Int
    58  	DeriveChainID   uint256.Int // pre-allocated variable to calculate Sub(&ctx.v, &ctx.chainIDMul)
    59  	cfg             TxParseConfig
    60  	buf             [65]byte // buffer needs to be enough for hashes (32 bytes) and for public key (65 bytes)
    61  	Sig             [65]byte
    62  	Sighash         [32]byte
    63  	withSender      bool
    64  	allowPreEip2s   bool // Allow s > secp256k1n/2; see EIP-2
    65  	chainIDRequired bool
    66  	IsProtected     bool
    67  }
    68  
    69  func NewTxParseContext(chainID uint256.Int) *TxParseContext {
    70  	if chainID.IsZero() {
    71  		panic("wrong chainID")
    72  	}
    73  	ctx := &TxParseContext{
    74  		withSender: true,
    75  		Keccak1:    sha3.NewLegacyKeccak256(),
    76  		Keccak2:    sha3.NewLegacyKeccak256(),
    77  	}
    78  
    79  	// behave as of London enabled
    80  	ctx.cfg.ChainID.Set(&chainID)
    81  	ctx.ChainIDMul.Mul(&chainID, u256.N2)
    82  	return ctx
    83  }
    84  
    85  // TxSlot contains information extracted from an Ethereum transaction, which is enough to manage it inside the transaction.
    86  // Also, it contains some auxillary information, like ephemeral fields, and indices within priority queues
    87  type TxSlot struct {
    88  	Rlp            []byte      // Is set to nil after flushing to db, frees memory, later we look for it in the db, if needed
    89  	Value          uint256.Int // Value transferred by the transaction
    90  	Tip            uint256.Int // Maximum tip that transaction is giving to miner/block proposer
    91  	FeeCap         uint256.Int // Maximum fee that transaction burns and gives to the miner/block proposer
    92  	SenderID       uint64      // SenderID - require external mapping to it's address
    93  	Nonce          uint64      // Nonce of the transaction
    94  	DataLen        int         // Length of transaction's data (for calculation of intrinsic gas)
    95  	DataNonZeroLen int
    96  	AlAddrCount    int      // Number of addresses in the access list
    97  	AlStorCount    int      // Number of storage keys in the access list
    98  	Gas            uint64   // Gas limit of the transaction
    99  	IDHash         [32]byte // Transaction hash for the purposes of using it as a transaction Id
   100  	Traced         bool     // Whether transaction needs to be traced throughout transaction pool code and generate debug printing
   101  	Creation       bool     // Set to true if "To" field of the transaction is not set
   102  	Type           byte     // Transaction type
   103  	Size           uint32   // Size of the payload
   104  
   105  	// EIP-4844: Shard Blob Transactions
   106  	BlobFeeCap  uint256.Int // max_fee_per_blob_gas
   107  	BlobHashes  []common.Hash
   108  	Blobs       [][]byte
   109  	Commitments []gokzg4844.KZGCommitment
   110  	Proofs      []gokzg4844.KZGProof
   111  }
   112  
   113  const (
   114  	LegacyTxType     byte = 0
   115  	AccessListTxType byte = 1 // EIP-2930
   116  	DynamicFeeTxType byte = 2 // EIP-1559
   117  	BlobTxType       byte = 3 // EIP-4844
   118  )
   119  
   120  var ErrParseTxn = fmt.Errorf("%w transaction", rlp.ErrParse)
   121  
   122  var ErrRejected = errors.New("rejected")
   123  var ErrAlreadyKnown = errors.New("already known")
   124  var ErrRlpTooBig = errors.New("txn rlp too big")
   125  
   126  // Set the RLP validate function
   127  func (ctx *TxParseContext) ValidateRLP(f func(txnRlp []byte) error) { ctx.validateRlp = f }
   128  
   129  // Set the with sender flag
   130  func (ctx *TxParseContext) WithSender(v bool) { ctx.withSender = v }
   131  
   132  // Set the AllowPreEIP2s flag
   133  func (ctx *TxParseContext) WithAllowPreEip2s(v bool) { ctx.allowPreEip2s = v }
   134  
   135  // Set ChainID-Required flag in the Parse context and return it
   136  func (ctx *TxParseContext) ChainIDRequired() *TxParseContext {
   137  	ctx.chainIDRequired = true
   138  	return ctx
   139  }
   140  
   141  func PeekTransactionType(serialized []byte) (byte, error) {
   142  	dataPos, _, legacy, err := rlp.Prefix(serialized, 0)
   143  	if err != nil {
   144  		return LegacyTxType, fmt.Errorf("%w: size Prefix: %s", ErrParseTxn, err) //nolint
   145  	}
   146  	if legacy {
   147  		return LegacyTxType, nil
   148  	}
   149  	return serialized[dataPos], nil
   150  }
   151  
   152  // ParseTransaction extracts all the information from the transactions's payload (RLP) necessary to build TxSlot.
   153  // It also performs syntactic validation of the transactions.
   154  // wrappedWithBlobs means that for blob (type 3) transactions the full version with blobs/commitments/proofs is expected
   155  // (see https://eips.ethereum.org/EIPS/eip-4844#networking).
   156  func (ctx *TxParseContext) ParseTransaction(payload []byte, pos int, slot *TxSlot, sender []byte, hasEnvelope, wrappedWithBlobs bool, validateHash func([]byte) error) (p int, err error) {
   157  	if len(payload) == 0 {
   158  		return 0, fmt.Errorf("%w: empty rlp", ErrParseTxn)
   159  	}
   160  	if ctx.withSender && len(sender) != 20 {
   161  		return 0, fmt.Errorf("%w: expect sender buffer of len 20", ErrParseTxn)
   162  	}
   163  
   164  	// Legacy transactions have list Prefix, whereas EIP-2718 transactions have string Prefix
   165  	// therefore we assign the first returned value of Prefix function (list) to legacy variable
   166  	dataPos, dataLen, legacy, err := rlp.Prefix(payload, pos)
   167  	if err != nil {
   168  		return 0, fmt.Errorf("%w: size Prefix: %s", ErrParseTxn, err) //nolint
   169  	}
   170  	// This handles the transactions coming from other Erigon peers of older versions, which add 0x80 (empty) transactions into packets
   171  	if dataLen == 0 {
   172  		return 0, fmt.Errorf("%w: transaction must be either 1 list or 1 string", ErrParseTxn)
   173  	}
   174  	if dataLen == 1 && !legacy {
   175  		if hasEnvelope {
   176  			return 0, fmt.Errorf("%w: expected envelope in the payload, got %x", ErrParseTxn, payload[dataPos:dataPos+dataLen])
   177  		}
   178  	}
   179  
   180  	p = dataPos
   181  
   182  	var wrapperDataPos, wrapperDataLen int
   183  
   184  	// If it is non-legacy transaction, the transaction type follows, and then the the list
   185  	if !legacy {
   186  		slot.Type = payload[p]
   187  		if slot.Type > BlobTxType {
   188  			return 0, fmt.Errorf("%w: unknown transaction type: %d", ErrParseTxn, slot.Type)
   189  		}
   190  		p++
   191  		if p >= len(payload) {
   192  			return 0, fmt.Errorf("%w: unexpected end of payload after txType", ErrParseTxn)
   193  		}
   194  		dataPos, dataLen, err = rlp.List(payload, p)
   195  		if err != nil {
   196  			return 0, fmt.Errorf("%w: envelope Prefix: %s", ErrParseTxn, err) //nolint
   197  		}
   198  		// For legacy transaction, the entire payload in expected to be in "rlp" field
   199  		// whereas for non-legacy, only the content of the envelope (start with position p)
   200  		slot.Rlp = payload[p-1 : dataPos+dataLen]
   201  
   202  		if slot.Type == BlobTxType && wrappedWithBlobs {
   203  			p = dataPos
   204  			wrapperDataPos = dataPos
   205  			wrapperDataLen = dataLen
   206  			dataPos, dataLen, err = rlp.List(payload, dataPos)
   207  			if err != nil {
   208  				return 0, fmt.Errorf("%w: wrapped blob tx: %s", ErrParseTxn, err) //nolint
   209  			}
   210  		}
   211  	} else {
   212  		slot.Type = LegacyTxType
   213  		slot.Rlp = payload[pos : dataPos+dataLen]
   214  	}
   215  
   216  	p, err = ctx.parseTransactionBody(payload, pos, p, slot, sender, validateHash)
   217  	if err != nil {
   218  		return p, err
   219  	}
   220  
   221  	if slot.Type == BlobTxType && wrappedWithBlobs {
   222  		if p != dataPos+dataLen {
   223  			return 0, fmt.Errorf("%w: unexpected leftover after blob tx body", ErrParseTxn)
   224  		}
   225  
   226  		dataPos, dataLen, err = rlp.List(payload, p)
   227  		if err != nil {
   228  			return 0, fmt.Errorf("%w: blobs len: %s", ErrParseTxn, err) //nolint
   229  		}
   230  		blobPos := dataPos
   231  		for blobPos < dataPos+dataLen {
   232  			blobPos, err = rlp.StringOfLen(payload, blobPos, fixedgas.BlobSize)
   233  			if err != nil {
   234  				return 0, fmt.Errorf("%w: blob: %s", ErrParseTxn, err) //nolint
   235  			}
   236  			slot.Blobs = append(slot.Blobs, payload[blobPos:blobPos+fixedgas.BlobSize])
   237  			blobPos += fixedgas.BlobSize
   238  		}
   239  		if blobPos != dataPos+dataLen {
   240  			return 0, fmt.Errorf("%w: extraneous space in blobs", ErrParseTxn)
   241  		}
   242  		p = blobPos
   243  
   244  		dataPos, dataLen, err = rlp.List(payload, p)
   245  		if err != nil {
   246  			return 0, fmt.Errorf("%w: commitments len: %s", ErrParseTxn, err) //nolint
   247  		}
   248  		commitmentPos := dataPos
   249  		for commitmentPos < dataPos+dataLen {
   250  			commitmentPos, err = rlp.StringOfLen(payload, commitmentPos, 48)
   251  			if err != nil {
   252  				return 0, fmt.Errorf("%w: commitment: %s", ErrParseTxn, err) //nolint
   253  			}
   254  			var commitment gokzg4844.KZGCommitment
   255  			copy(commitment[:], payload[commitmentPos:commitmentPos+48])
   256  			slot.Commitments = append(slot.Commitments, commitment)
   257  			commitmentPos += 48
   258  		}
   259  		if commitmentPos != dataPos+dataLen {
   260  			return 0, fmt.Errorf("%w: extraneous space in commitments", ErrParseTxn)
   261  		}
   262  		p = commitmentPos
   263  
   264  		dataPos, dataLen, err = rlp.List(payload, p)
   265  		if err != nil {
   266  			return 0, fmt.Errorf("%w: proofs len: %s", ErrParseTxn, err) //nolint
   267  		}
   268  		proofPos := dataPos
   269  		for proofPos < dataPos+dataLen {
   270  			proofPos, err = rlp.StringOfLen(payload, proofPos, 48)
   271  			if err != nil {
   272  				return 0, fmt.Errorf("%w: proof: %s", ErrParseTxn, err) //nolint
   273  			}
   274  			var proof gokzg4844.KZGProof
   275  			copy(proof[:], payload[proofPos:proofPos+48])
   276  			slot.Proofs = append(slot.Proofs, proof)
   277  			proofPos += 48
   278  		}
   279  		if proofPos != dataPos+dataLen {
   280  			return 0, fmt.Errorf("%w: extraneous space in proofs", ErrParseTxn)
   281  		}
   282  		p = proofPos
   283  
   284  		if p != wrapperDataPos+wrapperDataLen {
   285  			return 0, fmt.Errorf("%w: extraneous elements in blobs wrapper", ErrParseTxn)
   286  		}
   287  	}
   288  
   289  	slot.Size = uint32(p - pos)
   290  	return p, err
   291  }
   292  
   293  func (ctx *TxParseContext) parseTransactionBody(payload []byte, pos, p0 int, slot *TxSlot, sender []byte, validateHash func([]byte) error) (p int, err error) {
   294  	p = p0
   295  	legacy := slot.Type == LegacyTxType
   296  
   297  	// Compute transaction hash
   298  	ctx.Keccak1.Reset()
   299  	ctx.Keccak2.Reset()
   300  	if !legacy {
   301  		typeByte := []byte{slot.Type}
   302  		if _, err = ctx.Keccak1.Write(typeByte); err != nil {
   303  			return 0, fmt.Errorf("%w: computing IdHash (hashing type Prefix): %s", ErrParseTxn, err) //nolint
   304  		}
   305  		if _, err = ctx.Keccak2.Write(typeByte); err != nil {
   306  			return 0, fmt.Errorf("%w: computing signHash (hashing type Prefix): %s", ErrParseTxn, err) //nolint
   307  		}
   308  		dataPos, dataLen, err := rlp.List(payload, p)
   309  		if err != nil {
   310  			return 0, fmt.Errorf("%w: envelope Prefix: %s", ErrParseTxn, err) //nolint
   311  		}
   312  		// Hash the content of envelope, not the full payload
   313  		if _, err = ctx.Keccak1.Write(payload[p : dataPos+dataLen]); err != nil {
   314  			return 0, fmt.Errorf("%w: computing IdHash (hashing the envelope): %s", ErrParseTxn, err) //nolint
   315  		}
   316  		p = dataPos
   317  	}
   318  
   319  	if ctx.validateRlp != nil {
   320  		if err := ctx.validateRlp(slot.Rlp); err != nil {
   321  			return p, err
   322  		}
   323  	}
   324  
   325  	// Remember where signing hash data begins (it will need to be wrapped in an RLP list)
   326  	sigHashPos := p
   327  	if !legacy {
   328  		p, err = rlp.U256(payload, p, &ctx.ChainID)
   329  		if err != nil {
   330  			return 0, fmt.Errorf("%w: chainId len: %s", ErrParseTxn, err) //nolint
   331  		}
   332  		if ctx.ChainID.IsZero() { // zero indicates that the chain ID was not specified in the tx.
   333  			if ctx.chainIDRequired {
   334  				return 0, fmt.Errorf("%w: chainID is required", ErrParseTxn)
   335  			}
   336  			ctx.ChainID.Set(&ctx.cfg.ChainID)
   337  		}
   338  		if !ctx.ChainID.Eq(&ctx.cfg.ChainID) {
   339  			return 0, fmt.Errorf("%w: %s, %d (expected %d)", ErrParseTxn, "invalid chainID", ctx.ChainID.Uint64(), ctx.cfg.ChainID.Uint64())
   340  		}
   341  	}
   342  	// Next follows the nonce, which we need to parse
   343  	p, slot.Nonce, err = rlp.U64(payload, p)
   344  	if err != nil {
   345  		return 0, fmt.Errorf("%w: nonce: %s", ErrParseTxn, err) //nolint
   346  	}
   347  	// Next follows gas price or tip
   348  	p, err = rlp.U256(payload, p, &slot.Tip)
   349  	if err != nil {
   350  		return 0, fmt.Errorf("%w: tip: %s", ErrParseTxn, err) //nolint
   351  	}
   352  	// Next follows feeCap, but only for dynamic fee transactions, for legacy transaction, it is
   353  	// equal to tip
   354  	if slot.Type < DynamicFeeTxType {
   355  		slot.FeeCap = slot.Tip
   356  	} else {
   357  		p, err = rlp.U256(payload, p, &slot.FeeCap)
   358  		if err != nil {
   359  			return 0, fmt.Errorf("%w: feeCap: %s", ErrParseTxn, err) //nolint
   360  		}
   361  	}
   362  	// Next follows gas
   363  	p, slot.Gas, err = rlp.U64(payload, p)
   364  	if err != nil {
   365  		return 0, fmt.Errorf("%w: gas: %s", ErrParseTxn, err) //nolint
   366  	}
   367  	// Next follows the destination address (if present)
   368  	dataPos, dataLen, err := rlp.String(payload, p)
   369  	if err != nil {
   370  		return 0, fmt.Errorf("%w: to len: %s", ErrParseTxn, err) //nolint
   371  	}
   372  	if dataLen != 0 && dataLen != 20 {
   373  		return 0, fmt.Errorf("%w: unexpected length of to field: %d", ErrParseTxn, dataLen)
   374  	}
   375  
   376  	// Only note if To field is empty or not
   377  	slot.Creation = dataLen == 0
   378  	p = dataPos + dataLen
   379  	// Next follows value
   380  	p, err = rlp.U256(payload, p, &slot.Value)
   381  	if err != nil {
   382  		return 0, fmt.Errorf("%w: value: %s", ErrParseTxn, err) //nolint
   383  	}
   384  	// Next goes data, but we are only interesting in its length
   385  	dataPos, dataLen, err = rlp.String(payload, p)
   386  	if err != nil {
   387  		return 0, fmt.Errorf("%w: data len: %s", ErrParseTxn, err) //nolint
   388  	}
   389  	slot.DataLen = dataLen
   390  
   391  	// Zero and non-zero bytes are priced differently
   392  	slot.DataNonZeroLen = 0
   393  	for _, byt := range payload[dataPos : dataPos+dataLen] {
   394  		if byt != 0 {
   395  			slot.DataNonZeroLen++
   396  		}
   397  	}
   398  
   399  	p = dataPos + dataLen
   400  
   401  	// Next follows access list for non-legacy transactions, we are only interesting in number of addresses and storage keys
   402  	if !legacy {
   403  		dataPos, dataLen, err = rlp.List(payload, p)
   404  		if err != nil {
   405  			return 0, fmt.Errorf("%w: access list len: %s", ErrParseTxn, err) //nolint
   406  		}
   407  		tuplePos := dataPos
   408  		for tuplePos < dataPos+dataLen {
   409  			var tupleLen int
   410  			tuplePos, tupleLen, err = rlp.List(payload, tuplePos)
   411  			if err != nil {
   412  				return 0, fmt.Errorf("%w: tuple len: %s", ErrParseTxn, err) //nolint
   413  			}
   414  			var addrPos int
   415  			addrPos, err = rlp.StringOfLen(payload, tuplePos, 20)
   416  			if err != nil {
   417  				return 0, fmt.Errorf("%w: tuple addr len: %s", ErrParseTxn, err) //nolint
   418  			}
   419  			slot.AlAddrCount++
   420  			var storagePos, storageLen int
   421  			storagePos, storageLen, err = rlp.List(payload, addrPos+20)
   422  			if err != nil {
   423  				return 0, fmt.Errorf("%w: storage key list len: %s", ErrParseTxn, err) //nolint
   424  			}
   425  			skeyPos := storagePos
   426  			for skeyPos < storagePos+storageLen {
   427  				skeyPos, err = rlp.StringOfLen(payload, skeyPos, 32)
   428  				if err != nil {
   429  					return 0, fmt.Errorf("%w: tuple storage key len: %s", ErrParseTxn, err) //nolint
   430  				}
   431  				slot.AlStorCount++
   432  				skeyPos += 32
   433  			}
   434  			if skeyPos != storagePos+storageLen {
   435  				return 0, fmt.Errorf("%w: extraneous space in the tuple after storage key list", ErrParseTxn)
   436  			}
   437  			tuplePos += tupleLen
   438  		}
   439  		if tuplePos != dataPos+dataLen {
   440  			return 0, fmt.Errorf("%w: extraneous space in the access list after all tuples", ErrParseTxn)
   441  		}
   442  		p = dataPos + dataLen
   443  	}
   444  	if slot.Type == BlobTxType {
   445  		p, err = rlp.U256(payload, p, &slot.BlobFeeCap)
   446  		if err != nil {
   447  			return 0, fmt.Errorf("%w: blob fee cap: %s", ErrParseTxn, err) //nolint
   448  		}
   449  		dataPos, dataLen, err = rlp.List(payload, p)
   450  		if err != nil {
   451  			return 0, fmt.Errorf("%w: blob hashes len: %s", ErrParseTxn, err) //nolint
   452  		}
   453  		hashPos := dataPos
   454  		for hashPos < dataPos+dataLen {
   455  			var hash common.Hash
   456  			hashPos, err = rlp.ParseHash(payload, hashPos, hash[:])
   457  			if err != nil {
   458  				return 0, fmt.Errorf("%w: blob hash: %s", ErrParseTxn, err) //nolint
   459  			}
   460  			slot.BlobHashes = append(slot.BlobHashes, hash)
   461  		}
   462  		if hashPos != dataPos+dataLen {
   463  			return 0, fmt.Errorf("%w: extraneous space in the blob versioned hashes", ErrParseTxn)
   464  		}
   465  		p = dataPos + dataLen
   466  	}
   467  	// This is where the data for Sighash ends
   468  	// Next follows V of the signature
   469  	var vByte byte
   470  	sigHashEnd := p
   471  	sigHashLen := uint(sigHashEnd - sigHashPos)
   472  	var chainIDBits, chainIDLen int
   473  	if legacy {
   474  		p, err = rlp.U256(payload, p, &ctx.V)
   475  		if err != nil {
   476  			return 0, fmt.Errorf("%w: V: %s", ErrParseTxn, err) //nolint
   477  		}
   478  		ctx.IsProtected = ctx.V.Eq(u256.N27) || ctx.V.Eq(u256.N28)
   479  		// Compute chainId from V
   480  		if ctx.IsProtected {
   481  			// Do not add chain id and two extra zeros
   482  			vByte = byte(ctx.V.Uint64() - 27)
   483  			ctx.ChainID.Set(&ctx.cfg.ChainID)
   484  		} else {
   485  			ctx.ChainID.Sub(&ctx.V, u256.N35)
   486  			ctx.ChainID.Rsh(&ctx.ChainID, 1)
   487  			if !ctx.ChainID.Eq(&ctx.cfg.ChainID) {
   488  				return 0, fmt.Errorf("%w: %s, %d (expected %d)", ErrParseTxn, "invalid chainID", ctx.ChainID.Uint64(), ctx.cfg.ChainID.Uint64())
   489  			}
   490  
   491  			chainIDBits = ctx.ChainID.BitLen()
   492  			if chainIDBits <= 7 {
   493  				chainIDLen = 1
   494  			} else {
   495  				chainIDLen = common.BitLenToByteLen(chainIDBits) // It is always < 56 bytes
   496  				sigHashLen++                                     // For chainId len Prefix
   497  			}
   498  			sigHashLen += uint(chainIDLen) // For chainId
   499  			sigHashLen += 2                // For two extra zeros
   500  
   501  			ctx.DeriveChainID.Sub(&ctx.V, &ctx.ChainIDMul)
   502  			vByte = byte(ctx.DeriveChainID.Sub(&ctx.DeriveChainID, u256.N8).Uint64() - 27)
   503  		}
   504  	} else {
   505  		var v uint64
   506  		p, v, err = rlp.U64(payload, p)
   507  		if err != nil {
   508  			return 0, fmt.Errorf("%w: V: %s", ErrParseTxn, err) //nolint
   509  		}
   510  		if v > 1 {
   511  			return 0, fmt.Errorf("%w: V is loo large: %d", ErrParseTxn, v)
   512  		}
   513  		vByte = byte(v)
   514  		ctx.IsProtected = true
   515  	}
   516  
   517  	// Next follows R of the signature
   518  	p, err = rlp.U256(payload, p, &ctx.R)
   519  	if err != nil {
   520  		return 0, fmt.Errorf("%w: R: %s", ErrParseTxn, err) //nolint
   521  	}
   522  	// New follows S of the signature
   523  	p, err = rlp.U256(payload, p, &ctx.S)
   524  	if err != nil {
   525  		return 0, fmt.Errorf("%w: S: %s", ErrParseTxn, err) //nolint
   526  	}
   527  
   528  	// For legacy transactions, hash the full payload
   529  	if legacy {
   530  		if _, err = ctx.Keccak1.Write(payload[pos:p]); err != nil {
   531  			return 0, fmt.Errorf("%w: computing IdHash: %s", ErrParseTxn, err) //nolint
   532  		}
   533  	}
   534  	//ctx.keccak1.Sum(slot.IdHash[:0])
   535  	_, _ = ctx.Keccak1.(io.Reader).Read(slot.IDHash[:32])
   536  	if validateHash != nil {
   537  		if err := validateHash(slot.IDHash[:32]); err != nil {
   538  			return p, err
   539  		}
   540  	}
   541  
   542  	if !ctx.withSender {
   543  		return p, nil
   544  	}
   545  
   546  	if !crypto.TransactionSignatureIsValid(vByte, &ctx.R, &ctx.S, ctx.allowPreEip2s && legacy) {
   547  		return 0, fmt.Errorf("%w: invalid v, r, s: %d, %s, %s", ErrParseTxn, vByte, &ctx.R, &ctx.S)
   548  	}
   549  
   550  	// Computing sigHash (hash used to recover sender from the signature)
   551  	// Write len Prefix to the Sighash
   552  	if sigHashLen < 56 {
   553  		ctx.buf[0] = byte(sigHashLen) + 192
   554  		if _, err := ctx.Keccak2.Write(ctx.buf[:1]); err != nil {
   555  			return 0, fmt.Errorf("%w: computing signHash (hashing len Prefix): %s", ErrParseTxn, err) //nolint
   556  		}
   557  	} else {
   558  		beLen := common.BitLenToByteLen(bits.Len(sigHashLen))
   559  		binary.BigEndian.PutUint64(ctx.buf[1:], uint64(sigHashLen))
   560  		ctx.buf[8-beLen] = byte(beLen) + 247
   561  		if _, err := ctx.Keccak2.Write(ctx.buf[8-beLen : 9]); err != nil {
   562  			return 0, fmt.Errorf("%w: computing signHash (hashing len Prefix): %s", ErrParseTxn, err) //nolint
   563  		}
   564  	}
   565  	if _, err = ctx.Keccak2.Write(payload[sigHashPos:sigHashEnd]); err != nil {
   566  		return 0, fmt.Errorf("%w: computing signHash: %s", ErrParseTxn, err) //nolint
   567  	}
   568  	if legacy {
   569  		if chainIDLen > 0 {
   570  			if chainIDBits <= 7 {
   571  				ctx.buf[0] = byte(ctx.ChainID.Uint64())
   572  				if _, err := ctx.Keccak2.Write(ctx.buf[:1]); err != nil {
   573  					return 0, fmt.Errorf("%w: computing signHash (hashing legacy chainId): %s", ErrParseTxn, err) //nolint
   574  				}
   575  			} else {
   576  				binary.BigEndian.PutUint64(ctx.buf[1:9], ctx.ChainID[3])
   577  				binary.BigEndian.PutUint64(ctx.buf[9:17], ctx.ChainID[2])
   578  				binary.BigEndian.PutUint64(ctx.buf[17:25], ctx.ChainID[1])
   579  				binary.BigEndian.PutUint64(ctx.buf[25:33], ctx.ChainID[0])
   580  				ctx.buf[32-chainIDLen] = 128 + byte(chainIDLen)
   581  				if _, err = ctx.Keccak2.Write(ctx.buf[32-chainIDLen : 33]); err != nil {
   582  					return 0, fmt.Errorf("%w: computing signHash (hashing legacy chainId): %s", ErrParseTxn, err) //nolint
   583  				}
   584  			}
   585  			// Encode two zeros
   586  			ctx.buf[0] = 128
   587  			ctx.buf[1] = 128
   588  			if _, err := ctx.Keccak2.Write(ctx.buf[:2]); err != nil {
   589  				return 0, fmt.Errorf("%w: computing signHash (hashing zeros after legacy chainId): %s", ErrParseTxn, err) //nolint
   590  			}
   591  		}
   592  	}
   593  	// Squeeze Sighash
   594  	_, _ = ctx.Keccak2.(io.Reader).Read(ctx.Sighash[:32])
   595  	//ctx.keccak2.Sum(ctx.Sighash[:0])
   596  	binary.BigEndian.PutUint64(ctx.Sig[0:8], ctx.R[3])
   597  	binary.BigEndian.PutUint64(ctx.Sig[8:16], ctx.R[2])
   598  	binary.BigEndian.PutUint64(ctx.Sig[16:24], ctx.R[1])
   599  	binary.BigEndian.PutUint64(ctx.Sig[24:32], ctx.R[0])
   600  	binary.BigEndian.PutUint64(ctx.Sig[32:40], ctx.S[3])
   601  	binary.BigEndian.PutUint64(ctx.Sig[40:48], ctx.S[2])
   602  	binary.BigEndian.PutUint64(ctx.Sig[48:56], ctx.S[1])
   603  	binary.BigEndian.PutUint64(ctx.Sig[56:64], ctx.S[0])
   604  	ctx.Sig[64] = vByte
   605  	// recover sender
   606  	if _, err = secp256k1.RecoverPubkeyWithContext(secp256k1.DefaultContext, ctx.Sighash[:], ctx.Sig[:], ctx.buf[:0]); err != nil {
   607  		return 0, fmt.Errorf("%w: recovering sender from signature: %s", ErrParseTxn, err) //nolint
   608  	}
   609  	//apply keccak to the public key
   610  	ctx.Keccak2.Reset()
   611  	if _, err = ctx.Keccak2.Write(ctx.buf[1:65]); err != nil {
   612  		return 0, fmt.Errorf("%w: computing sender from public key: %s", ErrParseTxn, err) //nolint
   613  	}
   614  	// squeeze the hash of the public key
   615  	//ctx.keccak2.Sum(ctx.buf[:0])
   616  	_, _ = ctx.Keccak2.(io.Reader).Read(ctx.buf[:32])
   617  	//take last 20 bytes as address
   618  	copy(sender, ctx.buf[12:32])
   619  
   620  	return p, nil
   621  }
   622  
   623  type PeerID *types.H512
   624  
   625  type Hashes []byte // flatten list of 32-byte hashes
   626  
   627  func (h Hashes) At(i int) []byte { return h[i*length.Hash : (i+1)*length.Hash] }
   628  func (h Hashes) Len() int        { return len(h) / length.Hash }
   629  func (h Hashes) Less(i, j int) bool {
   630  	return bytes.Compare(h[i*length.Hash:(i+1)*length.Hash], h[j*length.Hash:(j+1)*length.Hash]) < 0
   631  }
   632  func (h Hashes) Swap(i, j int) {
   633  	ii := i * length.Hash
   634  	jj := j * length.Hash
   635  	for k := 0; k < length.Hash; k++ {
   636  		h[ii], h[jj] = h[jj], h[ii]
   637  		ii++
   638  		jj++
   639  	}
   640  }
   641  
   642  // DedupCopy sorts hashes, and creates deduplicated copy
   643  func (h Hashes) DedupCopy() Hashes {
   644  	if len(h) == 0 {
   645  		return h
   646  	}
   647  	sort.Sort(h)
   648  	unique := 1
   649  	for i := length.Hash; i < len(h); i += length.Hash {
   650  		if !bytes.Equal(h[i:i+length.Hash], h[i-length.Hash:i]) {
   651  			unique++
   652  		}
   653  	}
   654  	c := make(Hashes, unique*length.Hash)
   655  	copy(c[:], h[0:length.Hash])
   656  	dest := length.Hash
   657  	for i := dest; i < len(h); i += length.Hash {
   658  		if !bytes.Equal(h[i:i+length.Hash], h[i-length.Hash:i]) {
   659  			copy(c[dest:dest+length.Hash], h[i:i+length.Hash])
   660  			dest += length.Hash
   661  		}
   662  	}
   663  	return c
   664  }
   665  
   666  type Announcements struct {
   667  	ts     []byte
   668  	sizes  []uint32
   669  	hashes []byte
   670  }
   671  
   672  func (a *Announcements) Append(t byte, size uint32, hash []byte) {
   673  	a.ts = append(a.ts, t)
   674  	a.sizes = append(a.sizes, size)
   675  	a.hashes = append(a.hashes, hash...)
   676  }
   677  
   678  func (a *Announcements) AppendOther(other Announcements) {
   679  	a.ts = append(a.ts, other.ts...)
   680  	a.sizes = append(a.sizes, other.sizes...)
   681  	a.hashes = append(a.hashes, other.hashes...)
   682  }
   683  
   684  func (a *Announcements) Reset() {
   685  	a.ts = a.ts[:0]
   686  	a.sizes = a.sizes[:0]
   687  	a.hashes = a.hashes[:0]
   688  }
   689  
   690  func (a Announcements) At(i int) (byte, uint32, []byte) {
   691  	return a.ts[i], a.sizes[i], a.hashes[i*length.Hash : (i+1)*length.Hash]
   692  }
   693  func (a Announcements) Len() int { return len(a.ts) }
   694  func (a Announcements) Less(i, j int) bool {
   695  	return bytes.Compare(a.hashes[i*length.Hash:(i+1)*length.Hash], a.hashes[j*length.Hash:(j+1)*length.Hash]) < 0
   696  }
   697  func (a Announcements) Swap(i, j int) {
   698  	a.ts[i], a.ts[j] = a.ts[j], a.ts[i]
   699  	a.sizes[i], a.sizes[j] = a.sizes[j], a.sizes[i]
   700  	ii := i * length.Hash
   701  	jj := j * length.Hash
   702  	for k := 0; k < length.Hash; k++ {
   703  		a.hashes[ii], a.hashes[jj] = a.hashes[jj], a.hashes[ii]
   704  		ii++
   705  		jj++
   706  	}
   707  }
   708  
   709  // DedupCopy sorts hashes, and creates deduplicated copy
   710  func (a Announcements) DedupCopy() Announcements {
   711  	if len(a.ts) == 0 {
   712  		return a
   713  	}
   714  	sort.Sort(a)
   715  	unique := 1
   716  	for i := length.Hash; i < len(a.hashes); i += length.Hash {
   717  		if !bytes.Equal(a.hashes[i:i+length.Hash], a.hashes[i-length.Hash:i]) {
   718  			unique++
   719  		}
   720  	}
   721  	c := Announcements{
   722  		ts:     make([]byte, unique),
   723  		sizes:  make([]uint32, unique),
   724  		hashes: make([]byte, unique*length.Hash),
   725  	}
   726  	copy(c.hashes, a.hashes[0:length.Hash])
   727  	c.ts[0] = a.ts[0]
   728  	c.sizes[0] = a.sizes[0]
   729  	dest := length.Hash
   730  	j := 1
   731  	origin := length.Hash
   732  	for i := 1; i < len(a.ts); i++ {
   733  		if !bytes.Equal(a.hashes[origin:origin+length.Hash], a.hashes[origin-length.Hash:origin]) {
   734  			copy(c.hashes[dest:dest+length.Hash], a.hashes[origin:origin+length.Hash])
   735  			c.ts[j] = a.ts[i]
   736  			c.sizes[j] = a.sizes[i]
   737  			dest += length.Hash
   738  			j++
   739  		}
   740  		origin += length.Hash
   741  	}
   742  	return c
   743  }
   744  
   745  func (a Announcements) DedupHashes() Hashes {
   746  	if len(a.ts) == 0 {
   747  		return Hashes{}
   748  	}
   749  	sort.Sort(a)
   750  	unique := 1
   751  	for i := length.Hash; i < len(a.hashes); i += length.Hash {
   752  		if !bytes.Equal(a.hashes[i:i+length.Hash], a.hashes[i-length.Hash:i]) {
   753  			unique++
   754  		}
   755  	}
   756  	c := make(Hashes, unique*length.Hash)
   757  	copy(c[:], a.hashes[0:length.Hash])
   758  	dest := length.Hash
   759  	j := 1
   760  	origin := length.Hash
   761  	for i := 1; i < len(a.ts); i++ {
   762  		if !bytes.Equal(a.hashes[origin:origin+length.Hash], a.hashes[origin-length.Hash:origin]) {
   763  			copy(c[dest:dest+length.Hash], a.hashes[origin:origin+length.Hash])
   764  			dest += length.Hash
   765  			j++
   766  		}
   767  		origin += length.Hash
   768  	}
   769  	return c
   770  }
   771  
   772  func (a Announcements) Hashes() Hashes {
   773  	return Hashes(a.hashes)
   774  }
   775  
   776  func (a Announcements) Copy() Announcements {
   777  	if len(a.ts) == 0 {
   778  		return a
   779  	}
   780  	c := Announcements{
   781  		ts:     common.Copy(a.ts),
   782  		sizes:  make([]uint32, len(a.sizes)),
   783  		hashes: common.Copy(a.hashes),
   784  	}
   785  	copy(c.sizes, a.sizes)
   786  	return c
   787  }
   788  
   789  type Addresses []byte // flatten list of 20-byte addresses
   790  
   791  // AddressAt returns an address at the given index in the flattened list.
   792  // Use this method if you want to reduce memory allocations
   793  func (h Addresses) AddressAt(i int) common.Address {
   794  	return *(*[20]byte)(h[i*length.Addr : (i+1)*length.Addr])
   795  }
   796  
   797  func (h Addresses) At(i int) []byte { return h[i*length.Addr : (i+1)*length.Addr] }
   798  func (h Addresses) Len() int        { return len(h) / length.Addr }
   799  
   800  type TxSlots struct {
   801  	Txs     []*TxSlot
   802  	Senders Addresses
   803  	IsLocal []bool
   804  }
   805  
   806  func (s *TxSlots) Valid() error {
   807  	if len(s.Txs) != len(s.IsLocal) {
   808  		return fmt.Errorf("TxSlots: expect equal len of isLocal=%d and txs=%d", len(s.IsLocal), len(s.Txs))
   809  	}
   810  	if len(s.Txs) != s.Senders.Len() {
   811  		return fmt.Errorf("TxSlots: expect equal len of senders=%d and txs=%d", s.Senders.Len(), len(s.Txs))
   812  	}
   813  	return nil
   814  }
   815  
   816  var zeroAddr = make([]byte, 20)
   817  
   818  // Resize internal arrays to len=targetSize, shrinks if need. It rely on `append` algorithm to realloc
   819  func (s *TxSlots) Resize(targetSize uint) {
   820  	for uint(len(s.Txs)) < targetSize {
   821  		s.Txs = append(s.Txs, nil)
   822  	}
   823  	for uint(s.Senders.Len()) < targetSize {
   824  		s.Senders = append(s.Senders, addressesGrowth...)
   825  	}
   826  	for uint(len(s.IsLocal)) < targetSize {
   827  		s.IsLocal = append(s.IsLocal, false)
   828  	}
   829  	//todo: set nil to overflow txs
   830  	oldLen := uint(len(s.Txs))
   831  	s.Txs = s.Txs[:targetSize]
   832  	for i := oldLen; i < targetSize; i++ {
   833  		s.Txs[i] = nil
   834  	}
   835  	s.Senders = s.Senders[:length.Addr*targetSize]
   836  	for i := oldLen; i < targetSize; i++ {
   837  		copy(s.Senders.At(int(i)), zeroAddr)
   838  	}
   839  	s.IsLocal = s.IsLocal[:targetSize]
   840  	for i := oldLen; i < targetSize; i++ {
   841  		s.IsLocal[i] = false
   842  	}
   843  }
   844  func (s *TxSlots) Append(slot *TxSlot, sender []byte, isLocal bool) {
   845  	n := len(s.Txs)
   846  	s.Resize(uint(len(s.Txs) + 1))
   847  	s.Txs[n] = slot
   848  	s.IsLocal[n] = isLocal
   849  	copy(s.Senders.At(n), sender)
   850  }
   851  
   852  type TxsRlp struct {
   853  	Txs     [][]byte
   854  	Senders Addresses
   855  	IsLocal []bool
   856  }
   857  
   858  // Resize internal arrays to len=targetSize, shrinks if need. It rely on `append` algorithm to realloc
   859  func (s *TxsRlp) Resize(targetSize uint) {
   860  	for uint(len(s.Txs)) < targetSize {
   861  		s.Txs = append(s.Txs, nil)
   862  	}
   863  	for uint(s.Senders.Len()) < targetSize {
   864  		s.Senders = append(s.Senders, addressesGrowth...)
   865  	}
   866  	for uint(len(s.IsLocal)) < targetSize {
   867  		s.IsLocal = append(s.IsLocal, false)
   868  	}
   869  	//todo: set nil to overflow txs
   870  	s.Txs = s.Txs[:targetSize]
   871  	s.Senders = s.Senders[:length.Addr*targetSize]
   872  	s.IsLocal = s.IsLocal[:targetSize]
   873  }
   874  
   875  var addressesGrowth = make([]byte, length.Addr)
   876  
   877  func EncodeSenderLengthForStorage(nonce uint64, balance uint256.Int) uint {
   878  	var structLength uint = 1 // 1 byte for fieldset
   879  	if !balance.IsZero() {
   880  		structLength += uint(balance.ByteLen()) + 1
   881  	}
   882  	if nonce > 0 {
   883  		structLength += uint(common.BitLenToByteLen(bits.Len64(nonce))) + 1
   884  	}
   885  	return structLength
   886  }
   887  
   888  // Encode the details of txn sender into the given "buffer" byte-slice that should be big enough
   889  func EncodeSender(nonce uint64, balance uint256.Int, buffer []byte) {
   890  	var fieldSet = 0 // start with first bit set to 0
   891  	var pos = 1
   892  	if nonce > 0 {
   893  		fieldSet = 1
   894  		nonceBytes := common.BitLenToByteLen(bits.Len64(nonce))
   895  		buffer[pos] = byte(nonceBytes)
   896  		var nonce = nonce
   897  		for i := nonceBytes; i > 0; i-- {
   898  			buffer[pos+i] = byte(nonce)
   899  			nonce >>= 8
   900  		}
   901  		pos += nonceBytes + 1
   902  	}
   903  
   904  	// Encoding balance
   905  	if !balance.IsZero() {
   906  		fieldSet |= 2
   907  		balanceBytes := balance.ByteLen()
   908  		buffer[pos] = byte(balanceBytes)
   909  		pos++
   910  		balance.WriteToSlice(buffer[pos : pos+balanceBytes])
   911  		pos += balanceBytes //nolint
   912  	}
   913  
   914  	buffer[0] = byte(fieldSet)
   915  }
   916  
   917  // Decode the sender's balance and nonce from encoded byte-slice
   918  func DecodeSender(enc []byte) (nonce uint64, balance uint256.Int, err error) {
   919  	if len(enc) == 0 {
   920  		return
   921  	}
   922  
   923  	var fieldSet = enc[0]
   924  	var pos = 1
   925  
   926  	if fieldSet&1 > 0 {
   927  		decodeLength := int(enc[pos])
   928  
   929  		if len(enc) < pos+decodeLength+1 {
   930  			return nonce, balance, fmt.Errorf(
   931  				"malformed CBOR for Account.Nonce: %s, Length %d",
   932  				enc[pos+1:], decodeLength)
   933  		}
   934  
   935  		nonce = bytesToUint64(enc[pos+1 : pos+decodeLength+1])
   936  		pos += decodeLength + 1
   937  	}
   938  
   939  	if fieldSet&2 > 0 {
   940  		decodeLength := int(enc[pos])
   941  
   942  		if len(enc) < pos+decodeLength+1 {
   943  			return nonce, balance, fmt.Errorf(
   944  				"malformed CBOR for Account.Nonce: %s, Length %d",
   945  				enc[pos+1:], decodeLength)
   946  		}
   947  
   948  		(&balance).SetBytes(enc[pos+1 : pos+decodeLength+1])
   949  	}
   950  	return
   951  }
   952  
   953  func bytesToUint64(buf []byte) (x uint64) {
   954  	for i, b := range buf {
   955  		x = x<<8 + uint64(b)
   956  		if i == 7 {
   957  			return
   958  		}
   959  	}
   960  	return
   961  }
   962  
   963  // nolint
   964  func (tx *TxSlot) PrintDebug(prefix string) {
   965  	fmt.Printf("%s: senderID=%d,nonce=%d,tip=%d,v=%d\n", prefix, tx.SenderID, tx.Nonce, tx.Tip, tx.Value.Uint64())
   966  	//fmt.Printf("%s: senderID=%d,nonce=%d,tip=%d,hash=%x\n", prefix, tx.senderID, tx.nonce, tx.tip, tx.IdHash)
   967  }
   968  
   969  // AccessList is an EIP-2930 access list.
   970  type AccessList []AccessTuple
   971  
   972  // AccessTuple is the element type of an access list.
   973  type AccessTuple struct {
   974  	Address     common.Address `json:"address"`
   975  	StorageKeys []common.Hash  `json:"storageKeys"`
   976  }
   977  
   978  // StorageKeys returns the total number of storage keys in the access list.
   979  func (al AccessList) StorageKeys() int {
   980  	sum := 0
   981  	for _, tuple := range al {
   982  		sum += len(tuple.StorageKeys)
   983  	}
   984  	return sum
   985  }