Skip to content

Commit

Permalink
Merge branch 'ethereum:master' into gethintegration
Browse files Browse the repository at this point in the history
  • Loading branch information
GrapeBaBa authored Jan 16, 2025
2 parents 7c7bfe0 + 4d94bd8 commit 427928f
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 6 deletions.
2 changes: 1 addition & 1 deletion core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -1619,7 +1619,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool, makeWitness
return nil, 0, nil
}
// Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss)
SenderCacher.RecoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number(), chain[0].Time()), chain)
SenderCacher().RecoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number(), chain[0].Time()), chain)

var (
stats = insertStats{startTime: mclock.Now()}
Expand Down
13 changes: 11 additions & 2 deletions core/sender_cacher.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,21 @@ package core

import (
"runtime"
"sync"

"github.com/ethereum/go-ethereum/core/types"
)

// SenderCacher is a concurrent transaction sender recoverer and cacher.
var SenderCacher = newTxSenderCacher(runtime.NumCPU())
// senderCacherOnce is used to ensure that the SenderCacher is initialized only once.
var senderCacherOnce = sync.OnceValue(func() *txSenderCacher {
return newTxSenderCacher(runtime.NumCPU())
})

// SenderCacher returns the singleton instance of SenderCacher, initializing it if called for the first time.
// This function is thread-safe and ensures that initialization happens only once.
func SenderCacher() *txSenderCacher {
return senderCacherOnce()
}

// txSenderCacherRequest is a request for recovering transaction senders with a
// specific signature scheme and caching it into the transactions themselves.
Expand Down
8 changes: 8 additions & 0 deletions core/tracing/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ All notable changes to the tracing interface will be documented in this file.
- `GasChangeReason` has been extended with the following reasons which will be enabled only post-Verkle. There shouldn't be any gas changes with those reasons prior to the fork.
- `GasChangeWitnessContractCollisionCheck` flags the event of adding to the witness when checking for contract address collision.

## [v1.14.12]

This release contains a change in behavior for `OnCodeChange` hook.

### `OnCodeChange` change

The `OnCodeChange` hook is now called when the code of a contract is removed due to a selfdestruct. Previously, no code change was emitted on such occasions.

## [v1.14.4]

This release contained only minor extensions to the tracing interface.
Expand Down
3 changes: 2 additions & 1 deletion core/txpool/legacypool/legacypool.go
Original file line number Diff line number Diff line change
Expand Up @@ -1440,7 +1440,7 @@ func (pool *LegacyPool) reset(oldHead, newHead *types.Header) {

// Inject any transactions discarded due to reorgs
log.Debug("Reinjecting stale transactions", "count", len(reinject))
core.SenderCacher.Recover(pool.signer, reinject)
core.SenderCacher().Recover(pool.signer, reinject)
pool.addTxsLocked(reinject, false)
}

Expand Down Expand Up @@ -1994,6 +1994,7 @@ func (pool *LegacyPool) Clear() {
pool.priced = newPricedList(pool.all)
pool.pending = make(map[common.Address]*list)
pool.queue = make(map[common.Address]*list)
pool.pendingNonces = newNoncer(pool.currentState)

if !pool.config.NoLocals && pool.config.Journal != "" {
pool.journal = newTxJournal(pool.config.Journal)
Expand Down
51 changes: 49 additions & 2 deletions ethclient/simulated/backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,15 @@ package simulated
import (
"context"
"crypto/ecdsa"
"crypto/sha256"
"math/big"
"math/rand"
"testing"
"time"

"github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/holiman/uint256"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
Expand All @@ -34,8 +38,10 @@ import (
var _ bind.ContractBackend = (Client)(nil)

var (
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
testAddr = crypto.PubkeyToAddress(testKey.PublicKey)
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
testAddr = crypto.PubkeyToAddress(testKey.PublicKey)
testKey2, _ = crypto.HexToECDSA("7ee346e3f7efc685250053bfbafbfc880d58dc6145247053d4fb3cb0f66dfcb2")
testAddr2 = crypto.PubkeyToAddress(testKey2.PublicKey)
)

func simTestBackend(testAddr common.Address) *Backend {
Expand All @@ -46,6 +52,46 @@ func simTestBackend(testAddr common.Address) *Backend {
)
}

func newBlobTx(sim *Backend, key *ecdsa.PrivateKey) (*types.Transaction, error) {
client := sim.Client()

testBlob := &kzg4844.Blob{0x00}
testBlobCommit, _ := kzg4844.BlobToCommitment(testBlob)
testBlobProof, _ := kzg4844.ComputeBlobProof(testBlob, testBlobCommit)
testBlobVHash := kzg4844.CalcBlobHashV1(sha256.New(), &testBlobCommit)

head, _ := client.HeaderByNumber(context.Background(), nil) // Should be child's, good enough
gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(params.GWei))
gasPriceU256, _ := uint256.FromBig(gasPrice)
gasTipCapU256, _ := uint256.FromBig(big.NewInt(params.GWei))

addr := crypto.PubkeyToAddress(key.PublicKey)
chainid, _ := client.ChainID(context.Background())
nonce, err := client.PendingNonceAt(context.Background(), addr)
if err != nil {
return nil, err
}

chainidU256, _ := uint256.FromBig(chainid)
tx := types.NewTx(&types.BlobTx{
ChainID: chainidU256,
GasTipCap: gasTipCapU256,
GasFeeCap: gasPriceU256,
BlobFeeCap: uint256.NewInt(1),
Gas: 21000,
Nonce: nonce,
To: addr,
AccessList: nil,
BlobHashes: []common.Hash{testBlobVHash},
Sidecar: &types.BlobTxSidecar{
Blobs: []kzg4844.Blob{*testBlob},
Commitments: []kzg4844.Commitment{testBlobCommit},
Proofs: []kzg4844.Proof{testBlobProof},
},
})
return types.SignTx(tx, types.LatestSignerForChainID(chainid), key)
}

func newTx(sim *Backend, key *ecdsa.PrivateKey) (*types.Transaction, error) {
client := sim.Client()

Expand All @@ -66,6 +112,7 @@ func newTx(sim *Backend, key *ecdsa.PrivateKey) (*types.Transaction, error) {
Gas: 21000,
To: &addr,
})

return types.SignTx(tx, types.LatestSignerForChainID(chainid), key)
}

Expand Down
102 changes: 102 additions & 0 deletions ethclient/simulated/rollback_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package simulated

import (
"context"
"crypto/ecdsa"
"math/big"
"testing"
"time"

"github.com/ethereum/go-ethereum/core/types"
)

// TestTransactionRollbackBehavior tests that calling Rollback on the simulated backend doesn't prevent subsequent
// addition of new transactions
func TestTransactionRollbackBehavior(t *testing.T) {
sim := NewBackend(
types.GenesisAlloc{
testAddr: {Balance: big.NewInt(10000000000000000)},
testAddr2: {Balance: big.NewInt(10000000000000000)},
},
)
defer sim.Close()
client := sim.Client()

btx0 := testSendSignedTx(t, testKey, sim, true)
tx0 := testSendSignedTx(t, testKey2, sim, false)
tx1 := testSendSignedTx(t, testKey2, sim, false)

sim.Rollback()

if pendingStateHasTx(client, btx0) || pendingStateHasTx(client, tx0) || pendingStateHasTx(client, tx1) {
t.Fatalf("all transactions were not rolled back")
}

btx2 := testSendSignedTx(t, testKey, sim, true)
tx2 := testSendSignedTx(t, testKey2, sim, false)
tx3 := testSendSignedTx(t, testKey2, sim, false)

sim.Commit()

if !pendingStateHasTx(client, btx2) || !pendingStateHasTx(client, tx2) || !pendingStateHasTx(client, tx3) {
t.Fatalf("all post-rollback transactions were not included")
}
}

// testSendSignedTx sends a signed transaction to the simulated backend.
// It does not commit the block.
func testSendSignedTx(t *testing.T, key *ecdsa.PrivateKey, sim *Backend, isBlobTx bool) *types.Transaction {
t.Helper()
client := sim.Client()
ctx := context.Background()

var (
err error
signedTx *types.Transaction
)
if isBlobTx {
signedTx, err = newBlobTx(sim, key)
} else {
signedTx, err = newTx(sim, key)
}
if err != nil {
t.Fatalf("failed to create transaction: %v", err)
}

if err = client.SendTransaction(ctx, signedTx); err != nil {
t.Fatalf("failed to send transaction: %v", err)
}

return signedTx
}

// pendingStateHasTx returns true if a given transaction was successfully included as of the latest pending state.
func pendingStateHasTx(client Client, tx *types.Transaction) bool {
ctx := context.Background()

var (
receipt *types.Receipt
err error
)

// Poll for receipt with timeout
deadline := time.Now().Add(2 * time.Second)
for time.Now().Before(deadline) {
receipt, err = client.TransactionReceipt(ctx, tx.Hash())
if err == nil && receipt != nil {
break
}
time.Sleep(100 * time.Millisecond)
}

if err != nil {
return false
}
if receipt == nil {
return false
}
if receipt.Status != types.ReceiptStatusSuccessful {
return false
}
return true
}

0 comments on commit 427928f

Please sign in to comment.