fix:Log events are not found

This commit is contained in:
rrhlrmrr 2025-04-02 16:33:44 +09:00
parent a9e6c8daae
commit 0b83e096a8
2 changed files with 151 additions and 0 deletions

View file

@ -17,6 +17,7 @@
package catalyst
import (
"context"
"crypto/rand"
"crypto/sha256"
"errors"
@ -256,9 +257,23 @@ func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal, timestamp u
return err
}
c.lastBlockTime = payload.Timestamp
if err := c.syncLogProcessing(); err != nil {
log.Warn("Failed to process logs", "err", err)
}
return nil
}
func (c *SimulatedBeacon) syncLogProcessing() error {
blockHash := c.eth.BlockChain().CurrentBlock().Hash()
blockNumber := c.eth.BlockChain().CurrentBlock().Number.Uint64()
ctx := context.Background()
_, err := c.eth.APIBackend.GetLogs(ctx, blockHash, blockNumber)
return err
}
// loop runs the block production loop for non-zero period configuration
func (c *SimulatedBeacon) loop() {
timer := time.NewTimer(0)
@ -307,6 +322,11 @@ func (c *SimulatedBeacon) Commit() common.Hash {
if err := c.sealBlock(withdrawals, uint64(time.Now().Unix())); err != nil {
log.Warn("Error performing sealing work", "err", err)
}
// 로그 이벤트 처리를 보장하기 위해 블록체인 이벤트를 동기화합니다
// 이는 로그 필터가 새로운 로그를 즉시 사용할 수 있도록 합니다
c.syncLogProcessing()
return c.eth.BlockChain().CurrentBlock().Hash()
}

View file

@ -0,0 +1,131 @@
package simulated
import (
"context"
"math/big"
"testing"
"time"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
)
// TestLogEventsImmediateAvailability verifies that the fix for issue #31518
// ensures log events are immediately available after transaction commitment.
func TestLogEventsImmediateAvailability(t *testing.T) {
// Generate a random private key instead of using a hardcoded one
key, err := crypto.GenerateKey()
if err != nil {
t.Fatalf("Failed to generate random key: %v", err)
}
addr := crypto.PubkeyToAddress(key.PublicKey)
// Create a simulated backend with initial allocation
balance := new(big.Int).Mul(big.NewInt(1000), big.NewInt(params.Ether))
sim := NewBackend(types.GenesisAlloc{addr: {Balance: balance}})
defer sim.Close()
// Create a client to interact with the simulated backend
client := sim.Client()
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// Deploy a simple contract that emits logs
contractCode := []byte{
// PUSH1 1, PUSH1 0, PUSH1 0, LOG0 - Simple bytecode that emits a log
0x60, 0x01, 0x60, 0x00, 0x60, 0x00, 0xa0,
// PUSH1 0, PUSH1 0, RETURN - Return empty
0x60, 0x00, 0x60, 0x00, 0xf3,
}
// Get the nonce for the sender
nonce, err := client.PendingNonceAt(ctx, addr)
if err != nil {
t.Fatalf("Failed to get nonce: %v", err)
}
// Get the current gas price
gasPrice, err := client.SuggestGasPrice(ctx)
if err != nil {
t.Fatalf("Failed to get gas price: %v", err)
}
// Create the contract creation transaction
tx := types.NewContractCreation(
nonce,
big.NewInt(0),
500000, // Gas limit
gasPrice,
contractCode,
)
// Sign the transaction
chainID, err := client.ChainID(ctx)
if err != nil {
t.Fatalf("Failed to get chain ID: %v", err)
}
signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(chainID), key)
if err != nil {
t.Fatalf("Failed to sign transaction: %v", err)
}
// Set up a filter to catch logs
query := ethereum.FilterQuery{
FromBlock: big.NewInt(0),
Topics: [][]common.Hash{},
}
// Send the transaction
t.Log("Sending contract creation transaction")
err = client.SendTransaction(ctx, signedTx)
if err != nil {
t.Fatalf("Failed to send transaction: %v", err)
}
// Commit the transaction - this should emit logs
t.Log("Committing block")
sim.Commit()
// Check for the transaction receipt
receipt, err := client.TransactionReceipt(ctx, signedTx.Hash())
if err != nil {
t.Fatalf("Failed to get transaction receipt: %v", err)
}
if receipt.Status != types.ReceiptStatusSuccessful {
t.Fatal("Transaction failed")
}
// Update the filter query to include the contract address
query.Addresses = []common.Address{receipt.ContractAddress}
// Check for logs immediately without any sleep or wait
t.Log("Checking for logs immediately after commit")
logs, err := client.FilterLogs(ctx, query)
if err != nil {
t.Fatalf("Error filtering logs: %v", err)
}
// Verify logs are found immediately
if len(logs) == 0 {
t.Fatal("No logs found immediately after commit")
}
t.Logf("Success: Found %d logs immediately after commit", len(logs))
// Additional verification - check log details
for i, log := range logs {
t.Logf("Log #%d - BlockNumber: %d, TxHash: %s, Index: %d",
i, log.BlockNumber, log.TxHash.Hex(), log.Index)
if log.BlockNumber != receipt.BlockNumber.Uint64() {
t.Errorf("Log block number mismatch: expected %d, got %d",
receipt.BlockNumber.Uint64(), log.BlockNumber)
}
if log.TxHash != signedTx.Hash() {
t.Errorf("Log transaction hash mismatch: expected %s, got %s",
signedTx.Hash().Hex(), log.TxHash.Hex())
}
}
}