Skip to content

Commit

Permalink
Block: use generic atomics (#12461)
Browse files Browse the repository at this point in the history
Cherry pick #11512 into `release/2.61`

Co-authored-by: Alex Sharov <[email protected]>
  • Loading branch information
yperbasis and AskAlexSharov authored Oct 24, 2024
1 parent 34d42e1 commit 7a65be6
Show file tree
Hide file tree
Showing 12 changed files with 73 additions and 123 deletions.
12 changes: 8 additions & 4 deletions cmd/evm/internal/t8ntool/transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,8 @@ func getTransaction(txJson jsonrpc.RPCTransaction) (types.Transaction, error) {
commonTx.S.SetFromBig(txJson.S.ToInt())
if txJson.Type == types.LegacyTxType || txJson.Type == types.AccessListTxType {
legacyTx := types.LegacyTx{
CommonTx: commonTx,
//it's ok to copy here - because it's constructor of object - no parallel access yet
CommonTx: commonTx, //nolint
GasPrice: gasPrice,
}

Expand All @@ -432,7 +433,8 @@ func getTransaction(txJson jsonrpc.RPCTransaction) (types.Transaction, error) {
}

return &types.AccessListTx{
LegacyTx: legacyTx,
//it's ok to copy here - because it's constructor of object - no parallel access yet
LegacyTx: legacyTx, //nolint
ChainID: chainId,
AccessList: *txJson.Accesses,
}, nil
Expand All @@ -454,7 +456,8 @@ func getTransaction(txJson jsonrpc.RPCTransaction) (types.Transaction, error) {
}

dynamicFeeTx := types.DynamicFeeTransaction{
CommonTx: commonTx,
//it's ok to copy here - because it's constructor of object - no parallel access yet
CommonTx: commonTx, //nolint
ChainID: chainId,
Tip: tip,
FeeCap: feeCap,
Expand All @@ -471,7 +474,8 @@ func getTransaction(txJson jsonrpc.RPCTransaction) (types.Transaction, error) {
}

return &types.SetCodeTransaction{
DynamicFeeTransaction: dynamicFeeTx,
// it's ok to copy here - because it's constructor of object - no parallel access yet
DynamicFeeTransaction: dynamicFeeTx, //nolint
Authorizations: auths,
}, nil
} else {
Expand Down
20 changes: 6 additions & 14 deletions core/types/access_list_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import (
rlp2 "github.com/ledgerwatch/erigon-lib/rlp"
types2 "github.com/ledgerwatch/erigon-lib/types"

"github.com/ledgerwatch/erigon/common/u256"
"github.com/ledgerwatch/erigon/rlp"
)

Expand Down Expand Up @@ -446,19 +445,11 @@ func (tx *AccessListTx) WithSignature(signer Signer, sig []byte) (Transaction, e
cpy.ChainID = signer.ChainID()
return cpy, nil
}
func (tx *AccessListTx) FakeSign(address libcommon.Address) Transaction {
cpy := tx.copy()
cpy.R.Set(u256.Num1)
cpy.S.Set(u256.Num1)
cpy.V.Set(u256.Num4)
cpy.from.Store(address)
return cpy
}

// Hash computes the hash (but not for signatures!)
func (tx *AccessListTx) Hash() libcommon.Hash {
if hash := tx.hash.Load(); hash != nil {
return *hash.(*libcommon.Hash)
return *hash
}
hash := prefixedRlpHash(AccessListTxType, []interface{}{
tx.ChainID,
Expand Down Expand Up @@ -503,15 +494,16 @@ func (tx *AccessListTx) GetChainID() *uint256.Int {
var zeroAddr = libcommon.Address{}

func (tx *AccessListTx) Sender(signer Signer) (libcommon.Address, error) {
if sc := tx.from.Load(); sc != nil {
if sc.(libcommon.Address) != zeroAddr { // Sender address can never be zero in a transaction with a valid signer
return sc.(libcommon.Address), nil
if from := tx.from.Load(); from != nil {
if *from != zeroAddr { // Sender address can never be zero in a transaction with a valid signer
return *from, nil
}
}

addr, err := signer.Sender(tx)
if err != nil {
return libcommon.Address{}, err
}
tx.from.Store(addr)
tx.from.Store(&addr)
return addr, nil
}
11 changes: 5 additions & 6 deletions core/types/blob_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,23 +81,22 @@ func (stx *BlobTx) AsMessage(s Signer, baseFee *big.Int, rules *chain.Rules) (Me
}

func (stx *BlobTx) Sender(signer Signer) (libcommon.Address, error) {
if sc := stx.from.Load(); sc != nil {
zeroAddr := libcommon.Address{}
if sc.(libcommon.Address) != zeroAddr { // Sender address can never be zero in a transaction with a valid signer
return sc.(libcommon.Address), nil
if from := stx.from.Load(); from != nil {
if *from != zeroAddr { // Sender address can never be zero in a transaction with a valid signer
return *from, nil
}
}
addr, err := signer.Sender(stx)
if err != nil {
return libcommon.Address{}, err
}
stx.from.Store(addr)
stx.from.Store(&addr)
return addr, nil
}

func (stx *BlobTx) Hash() libcommon.Hash {
if hash := stx.hash.Load(); hash != nil {
return *hash.(*libcommon.Hash)
return *hash
}
hash := prefixedRlpHash(BlobTxType, []interface{}{
stx.ChainID,
Expand Down
9 changes: 2 additions & 7 deletions core/types/blob_tx_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,7 @@ func (c KZGCommitment) ComputeVersionedHash() libcommon.Hash {

// validateBlobTransactionWrapper implements validate_blob_transaction_wrapper from EIP-4844
func (txw *BlobTxWrapper) ValidateBlobTransactionWrapper() error {
blobTx := txw.Tx
l1 := len(blobTx.BlobVersionedHashes)
l1 := len(txw.Tx.BlobVersionedHashes)
if l1 == 0 {
return fmt.Errorf("a blob tx must contain at least one blob")
}
Expand All @@ -278,7 +277,7 @@ func (txw *BlobTxWrapper) ValidateBlobTransactionWrapper() error {
if err != nil {
return fmt.Errorf("error during proof verification: %v", err)
}
for i, h := range blobTx.BlobVersionedHashes {
for i, h := range txw.Tx.BlobVersionedHashes {
if computed := txw.Commitments[i].ComputeVersionedHash(); computed != h {
return fmt.Errorf("versioned hash %d supposedly %s but does not match computed %s", i, h, computed)
}
Expand Down Expand Up @@ -311,10 +310,6 @@ func (txw *BlobTxWrapper) WithSignature(signer Signer, sig []byte) (Transaction,
return txw.Tx.WithSignature(signer, sig)
}

func (txw *BlobTxWrapper) FakeSign(address libcommon.Address) Transaction {
return txw.Tx.FakeSign(address)
}

func (txw *BlobTxWrapper) Hash() libcommon.Hash { return txw.Tx.Hash() }

func (txw *BlobTxWrapper) SigningHash(chainID *big.Int) libcommon.Hash {
Expand Down
54 changes: 24 additions & 30 deletions core/types/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -681,8 +681,8 @@ type Block struct {
requests Requests

// caches
hash atomic.Value
size atomic.Value
hash atomic.Pointer[libcommon.Hash]
size atomic.Uint64
}

// Copy transaction senders from body into the transactions
Expand Down Expand Up @@ -1062,7 +1062,7 @@ func NewBlock(header *Header, txs []Transaction, uncles []*Header, receipts []*R
// in this case no reason to copy parts, or re-calculate headers fields - they are all stored in DB
func NewBlockFromStorage(hash libcommon.Hash, header *Header, txs []Transaction, uncles []*Header, withdrawals []*Withdrawal, requests Requests) *Block {
b := &Block{header: header, transactions: txs, uncles: uncles, withdrawals: withdrawals, requests: requests}
b.hash.Store(hash)
b.hash.Store(&hash)
return b
}

Expand Down Expand Up @@ -1136,7 +1136,7 @@ func (bb *Block) DecodeRLP(s *rlp.Stream) error {
if err != nil {
return err
}
bb.size.Store(common.StorageSize(rlp.ListSize(size)))
bb.size.Store(rlp.ListSize(size))

// decode header
var h Header
Expand Down Expand Up @@ -1166,7 +1166,7 @@ func (bb *Block) DecodeRLP(s *rlp.Stream) error {
return s.ListEnd()
}

func (bb Block) payloadSize() (payloadSize int, txsLen, unclesLen, withdrawalsLen, requestsLen int) {
func (bb *Block) payloadSize() (payloadSize int, txsLen, unclesLen, withdrawalsLen, requestsLen int) {
// size of Header
headerLen := bb.header.EncodingSize()
payloadSize += rlp2.ListPrefixLen(headerLen) + headerLen
Expand Down Expand Up @@ -1195,13 +1195,13 @@ func (bb Block) payloadSize() (payloadSize int, txsLen, unclesLen, withdrawalsLe
return payloadSize, txsLen, unclesLen, withdrawalsLen, requestsLen
}

func (bb Block) EncodingSize() int {
func (bb *Block) EncodingSize() int {
payloadSize, _, _, _, _ := bb.payloadSize()
return payloadSize
}

// EncodeRLP serializes b into the Ethereum RLP block format.
func (bb Block) EncodeRLP(w io.Writer) error {
func (bb *Block) EncodeRLP(w io.Writer) error {
payloadSize, txsLen, unclesLen, withdrawalsLen, _ /* requestsLen */ := bb.payloadSize()
var b [33]byte
// prefix
Expand Down Expand Up @@ -1324,12 +1324,12 @@ func (b *Body) RawBody() *RawBody {
// Size returns the true RLP encoded storage size of the block, either by encoding
// and returning it, or returning a previously cached value.
func (b *Block) Size() common.StorageSize {
if size := b.size.Load(); size != nil {
return size.(common.StorageSize)
if size := b.size.Load(); size > 0 {
return common.StorageSize(size)
}
c := writeCounter(0)
rlp.Encode(&c, b)
b.size.Store(common.StorageSize(c))
b.size.Store(uint64(c))
return common.StorageSize(c)
}

Expand Down Expand Up @@ -1412,7 +1412,8 @@ func CopyTxs(in Transactions) Transactions {
if txWrapper, ok := tx.(*BlobTxWrapper); ok {
blobTx := out[i].(*BlobTx)
out[i] = &BlobTxWrapper{
Tx: *blobTx,
// it's ok to copy here - because it's constructor of object - no parallel access yet
Tx: *blobTx, //nolint
Commitments: txWrapper.Commitments.copy(),
Blobs: txWrapper.Blobs.copy(),
Proofs: txWrapper.Proofs.copy(),
Expand Down Expand Up @@ -1446,27 +1447,20 @@ func (b *Block) Copy() *Block {
}
}

var hashValue atomic.Value
if value := b.hash.Load(); value != nil {
hash := value.(libcommon.Hash)
hashCopy := libcommon.BytesToHash(hash.Bytes())
hashValue.Store(hashCopy)
}

var sizeValue atomic.Value
if size := b.size.Load(); size != nil {
sizeValue.Store(size)
}

return &Block{
newB := &Block{
header: CopyHeader(b.header),
uncles: uncles,
transactions: CopyTxs(b.transactions),
withdrawals: withdrawals,
requests: requests,
hash: hashValue,
size: sizeValue,
}
if h := b.hash.Load(); h != nil {
hashCopy := *h
newB.hash.Store(&hashCopy)
}
szCopy := b.size.Load()
newB.size.Store(szCopy)
return newB
}

// WithSeal returns a new block with the data from b but the header replaced with
Expand All @@ -1487,11 +1481,11 @@ func (b *Block) WithSeal(header *Header) *Block {
// The hash is computed on the first call and cached thereafter.
func (b *Block) Hash() libcommon.Hash {
if hash := b.hash.Load(); hash != nil {
return hash.(libcommon.Hash)
return *hash
}
v := b.header.Hash()
b.hash.Store(v)
return v
h := b.header.Hash()
b.hash.Store(&h)
return h
}

type Blocks []*Block
Expand Down
21 changes: 5 additions & 16 deletions core/types/dynamic_fee_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import (
rlp2 "github.com/ledgerwatch/erigon-lib/rlp"
types2 "github.com/ledgerwatch/erigon-lib/types"

"github.com/ledgerwatch/erigon/common/u256"
"github.com/ledgerwatch/erigon/rlp"
)

Expand Down Expand Up @@ -167,15 +166,6 @@ func (tx *DynamicFeeTransaction) WithSignature(signer Signer, sig []byte) (Trans
return cpy, nil
}

func (tx *DynamicFeeTransaction) FakeSign(address libcommon.Address) Transaction {
cpy := tx.copy()
cpy.R.Set(u256.Num1)
cpy.S.Set(u256.Num1)
cpy.V.Set(u256.Num4)
cpy.from.Store(address)
return cpy
}

// MarshalBinary returns the canonical encoding of the transaction.
// For legacy transactions, it returns the RLP encoding. For EIP-2718 typed
// transactions, it returns the type and payload.
Expand Down Expand Up @@ -371,7 +361,7 @@ func (tx *DynamicFeeTransaction) AsMessage(s Signer, baseFee *big.Int, rules *ch
// Hash computes the hash (but not for signatures!)
func (tx *DynamicFeeTransaction) Hash() libcommon.Hash {
if hash := tx.hash.Load(); hash != nil {
return *hash.(*libcommon.Hash)
return *hash
}
hash := prefixedRlpHash(DynamicFeeTxType, []interface{}{
tx.ChainID,
Expand Down Expand Up @@ -417,17 +407,16 @@ func (tx *DynamicFeeTransaction) GetChainID() *uint256.Int {
}

func (tx *DynamicFeeTransaction) Sender(signer Signer) (libcommon.Address, error) {
if sc := tx.from.Load(); sc != nil {
zeroAddr := libcommon.Address{}
if sc.(libcommon.Address) != zeroAddr { // Sender address can never be zero in a transaction with a valid signer
return sc.(libcommon.Address), nil
if from := tx.from.Load(); from != nil {
if *from != zeroAddr { // Sender address can never be zero in a transaction with a valid signer
return *from, nil
}
}
addr, err := signer.Sender(tx)
if err != nil {
return libcommon.Address{}, err
}
tx.from.Store(addr)
tx.from.Store(&addr)
return addr, nil
}

Expand Down
10 changes: 5 additions & 5 deletions core/types/encdec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,21 +183,21 @@ func (tr *TRand) RandTransaction() Transaction {
switch txType {
case LegacyTxType:
return &LegacyTx{
CommonTx: commonTx,
CommonTx: commonTx, //nolint
GasPrice: uint256.NewInt(*tr.RandUint64()),
}
case AccessListTxType:
return &AccessListTx{
LegacyTx: LegacyTx{
CommonTx: commonTx,
CommonTx: commonTx, //nolint
GasPrice: uint256.NewInt(*tr.RandUint64()),
},
ChainID: uint256.NewInt(*tr.RandUint64()),
AccessList: tr.RandAccessList(tr.RandIntInRange(1, 5)),
}
case DynamicFeeTxType:
return &DynamicFeeTransaction{
CommonTx: commonTx,
CommonTx: commonTx, //nolint
ChainID: uint256.NewInt(*tr.RandUint64()),
Tip: uint256.NewInt(*tr.RandUint64()),
FeeCap: uint256.NewInt(*tr.RandUint64()),
Expand All @@ -207,7 +207,7 @@ func (tr *TRand) RandTransaction() Transaction {
r := *tr.RandUint64()
return &BlobTx{
DynamicFeeTransaction: DynamicFeeTransaction{
CommonTx: commonTx,
CommonTx: commonTx, //nolint
ChainID: uint256.NewInt(*tr.RandUint64()),
Tip: uint256.NewInt(*tr.RandUint64()),
FeeCap: uint256.NewInt(*tr.RandUint64()),
Expand All @@ -219,7 +219,7 @@ func (tr *TRand) RandTransaction() Transaction {
case SetCodeTxType:
return &SetCodeTransaction{
DynamicFeeTransaction: DynamicFeeTransaction{
CommonTx: commonTx,
CommonTx: commonTx, //nolint
ChainID: uint256.NewInt(*tr.RandUint64()),
Tip: uint256.NewInt(*tr.RandUint64()),
FeeCap: uint256.NewInt(*tr.RandUint64()),
Expand Down
Loading

0 comments on commit 7a65be6

Please sign in to comment.