Skip to content

Commit

Permalink
skip events scanners
Browse files Browse the repository at this point in the history
  • Loading branch information
pablomendezroyo committed Dec 20, 2024
1 parent b01f0d2 commit ed3d7c7
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 4 deletions.
4 changes: 2 additions & 2 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ func main() {

// Initialize domain services
eventsWatcherService := services.NewEventsWatcherService(veboAdapter, csModuleAdapter, csFeeDistributorAdapter, notifierAdapter)
distributionLogUpdatedScannerService := services.NewDistributionLogUpdatedEventScanner(storageAdapter, notifierAdapter, executionAdapter, csFeeDistributorImplAdapter, networkConfig.CsFeeDistributorBlockDeployment)
validatorExitRequestScannerService := services.NewValidatorExitRequestEventScanner(storageAdapter, notifierAdapter, veboAdapter, executionAdapter, beaconchainAdapter, networkConfig.VeboBlockDeployment)
distributionLogUpdatedScannerService := services.NewDistributionLogUpdatedEventScanner(storageAdapter, notifierAdapter, executionAdapter, csFeeDistributorImplAdapter, networkConfig.CsFeeDistributorBlockDeployment, networkConfig.CSModuleTxReceipt)
validatorExitRequestScannerService := services.NewValidatorExitRequestEventScanner(storageAdapter, notifierAdapter, veboAdapter, executionAdapter, beaconchainAdapter, networkConfig.VeboBlockDeployment, networkConfig.CSModuleTxReceipt)
validatorEjectorService := services.NewValidatorEjectorService(storageAdapter, notifierAdapter, exitValidatorAdapter, beaconchainAdapter)
pendingHashesLoaderService := services.NewPendingHashesLoader(storageAdapter, notifierAdapter, ipfsAdapter, networkConfig.MinGenesisTime)
// relaysCheckerService := services.NewRelayCronService(relaysAllowedAdapter, relaysUsedAdapter, notifierAdapter)
Expand Down
44 changes: 44 additions & 0 deletions internal/adapters/execution/execution_adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"net/http"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
)

Expand Down Expand Up @@ -158,3 +159,46 @@ func (e *ExecutionAdapter) IsSyncing() (bool, error) {
// If result is a map or object, the node is syncing
return true, nil
}

// GetTransactionReceipt retrieves the transaction receipt for a given transaction hash.
func (e *ExecutionAdapter) GetTransactionReceipt(txHash common.Hash) (map[string]interface{}, error) {
// Create the request payload for eth_getTransactionReceipt
payload := map[string]interface{}{
"jsonrpc": "2.0",
"method": "eth_getTransactionReceipt",
"params": []interface{}{txHash},
"id": 1,
}

// Marshal the payload to JSON
jsonPayload, err := json.Marshal(payload)
if err != nil {
return nil, fmt.Errorf("failed to marshal request payload for eth_getTransactionReceipt: %w", err)
}

// Send the request to the execution client
resp, err := http.Post(e.rpcURL, "application/json", bytes.NewBuffer(jsonPayload))
if err != nil {
return nil, fmt.Errorf("failed to send request to execution client at %s: %w", e.rpcURL, err)
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected status code %d received from execution client", resp.StatusCode)
}

// Parse the response
var result struct {
Result map[string]interface{} `json:"result"`
}
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return nil, fmt.Errorf("failed to decode response from execution client: %w", err)
}

// Check if the result is null
if result.Result == nil {
return nil, nil // Returning nil to indicate no receipt is available
}

return result.Result, nil
}
20 changes: 20 additions & 0 deletions internal/adapters/execution/execution_adapter_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"lido-events/internal/adapters/execution"

"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -81,3 +82,22 @@ func TestIsSyncingIntegration(t *testing.T) {
t.Log("The Ethereum node is not syncing.")
}
}

// TestGetTransactionReceiptIntegration tests retrieving the transaction receipt
func TestGetTransactionReceiptIntegration(t *testing.T) {
adapter, err := setupExecutionAdapter(t)
assert.NoError(t, err)

// Specify a transaction hash to test
txHash := common.HexToHash("0x1475719ecbb73b28bc531bb54b37695df1bf6b71c6d2bf1d28b4efa404867e26")

// Call the GetTransactionReceipt method
receipt, err := adapter.GetTransactionReceipt(txHash)
assert.NoError(t, err)

// Ensure receipt is not nil
assert.NotNil(t, receipt, "Expected a non-nil transaction receipt")

// Log the receipt for debugging
t.Logf("Transaction receipt: %+v", receipt)
}
3 changes: 3 additions & 0 deletions internal/application/ports/execution_port.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package ports

import "github.com/ethereum/go-ethereum/common"

type ExecutionPort interface {
GetMostRecentBlockNumber() (uint64, error)
GetBlockTimestampByNumber(blockNumber uint64) (uint64, error)
IsSyncing() (bool, error)
GetTransactionReceipt(txHash common.Hash) (map[string]interface{}, error)
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"lido-events/internal/logger"
"sync"
"time"

"github.com/ethereum/go-ethereum/common"
)

type DistributionLogUpdatedEventScanner struct {
Expand All @@ -16,16 +18,18 @@ type DistributionLogUpdatedEventScanner struct {
executionPort ports.ExecutionPort
csFeeDistributorImplPort ports.CsFeeDistributorImplPort
csFeeDistributorBlockDeployment uint64
csModuleTxReceipt common.Hash
servicePrefix string
}

func NewDistributionLogUpdatedEventScanner(storagePort ports.StoragePort, notifierPort ports.NotifierPort, executionPort ports.ExecutionPort, csFeeDistributorImplPort ports.CsFeeDistributorImplPort, csFeeDistributorBlockDeployment uint64) *DistributionLogUpdatedEventScanner {
func NewDistributionLogUpdatedEventScanner(storagePort ports.StoragePort, notifierPort ports.NotifierPort, executionPort ports.ExecutionPort, csFeeDistributorImplPort ports.CsFeeDistributorImplPort, csFeeDistributorBlockDeployment uint64, csModuleTxReceipt common.Hash) *DistributionLogUpdatedEventScanner {
return &DistributionLogUpdatedEventScanner{
storagePort,
notifierPort,
executionPort,
csFeeDistributorImplPort,
csFeeDistributorBlockDeployment,
csModuleTxReceipt,
"DistributionLogUpdatedEventScanner",
}
}
Expand Down Expand Up @@ -70,6 +74,17 @@ func (ds *DistributionLogUpdatedEventScanner) runScan(ctx context.Context) {
return
}

// Skip if tx receipt not found (nil). This means that the node does not store log receipts and there are no logs at all
receipt, err := ds.executionPort.GetTransactionReceipt(ds.csModuleTxReceipt)
if err != nil {
logger.ErrorWithPrefix(ds.servicePrefix, "Error getting transaction receipt for csModule deployment: %v", err)
return
}
if receipt == nil {
logger.WarnWithPrefix(ds.servicePrefix, "Transaction receipt for csModule deployment not found, skipping ValidatorExitRequest event scan. This means that the node does not store log receipts and there are no logs at all")
return
}

// Retrieve start and end blocks for scanning
start, err := ds.storagePort.GetDistributionLogLastProcessedBlock()
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"lido-events/internal/logger"
"sync"
"time"

"github.com/ethereum/go-ethereum/common"
)

type ValidatorExitRequestEventScanner struct {
Expand All @@ -18,17 +20,19 @@ type ValidatorExitRequestEventScanner struct {
executionPort ports.ExecutionPort
beaconchainPort ports.Beaconchain
veboBlockDeployment uint64
csModuleTxReceipt common.Hash
servicePrefix string
}

func NewValidatorExitRequestEventScanner(storagePort ports.StoragePort, notifierPort ports.NotifierPort, veboPort ports.VeboPort, executionPort ports.ExecutionPort, beaconchainPort ports.Beaconchain, veboBlockDeployment uint64) *ValidatorExitRequestEventScanner {
func NewValidatorExitRequestEventScanner(storagePort ports.StoragePort, notifierPort ports.NotifierPort, veboPort ports.VeboPort, executionPort ports.ExecutionPort, beaconchainPort ports.Beaconchain, veboBlockDeployment uint64, csModuleTxReceipt common.Hash) *ValidatorExitRequestEventScanner {
return &ValidatorExitRequestEventScanner{
storagePort,
notifierPort,
veboPort,
executionPort,
beaconchainPort,
veboBlockDeployment,
csModuleTxReceipt,
"ValidatorExitRequestEventScanner",
}
}
Expand Down Expand Up @@ -82,6 +86,22 @@ func (vs *ValidatorExitRequestEventScanner) runScan(ctx context.Context) {
return
}

// Skip if tx receipt not found (nil). This means that the node does not store log receipts and there are no logs at all
receipt, err := vs.executionPort.GetTransactionReceipt(vs.csModuleTxReceipt)
if err != nil {
logger.ErrorWithPrefix(vs.servicePrefix, "Error getting transaction receipt for csModule deployment: %v", err)
return
}
if receipt == nil {
logger.WarnWithPrefix(vs.servicePrefix, "Transaction receipt for csModule deployment not found, skipping ValidatorExitRequest event scan. This means that the node does not store log receipts and there are no logs at all")
// notify the user to switch to an execution client that does store the log receipts
message := "- 🚨 The node does not store log receipts and there are no logs at all. ValidatorExitRequest events cannot be scanned. We highly recommend switching to a Execution Client that does store the log receipts"
if err := vs.notifierPort.SendNotification(message); err != nil {
logger.ErrorWithPrefix(vs.servicePrefix, "Error sending notification: %v", err)
}
return
}

// Retrieve start and end blocks for scanning
start, err := vs.storagePort.GetValidatorExitRequestLastProcessedBlock()
if err != nil {
Expand Down
5 changes: 5 additions & 0 deletions internal/config/config_loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ type Config struct {
VeboBlockDeployment uint64
CsFeeDistributorBlockDeployment uint64

// tx receipts
CSModuleTxReceipt common.Hash

// Lido specifics
LidoKeysApiUrl string
ProxyApiPort uint64
Expand Down Expand Up @@ -161,6 +164,7 @@ func LoadNetworkConfig() (Config, error) {
VeboBlockDeployment: uint64(30701),
CsFeeDistributorBlockDeployment: uint64(1774650),
CSModuleAddress: common.HexToAddress("0x4562c3e63c2e586cD1651B958C22F88135aCAd4f"),
CSModuleTxReceipt: common.HexToHash("0x1475719ecbb73b28bc531bb54b37695df1bf6b71c6d2bf1d28b4efa404867e26"),
LidoKeysApiUrl: "https://keys-api-holesky.testnet.fi",
ProxyApiPort: proxyApiPort,
MinGenesisTime: uint64(1695902400),
Expand Down Expand Up @@ -198,6 +202,7 @@ func LoadNetworkConfig() (Config, error) {
VeboBlockDeployment: uint64(17172556),
CsFeeDistributorBlockDeployment: uint64(20935463),
CSModuleAddress: common.HexToAddress("0xdA7dE2ECdDfccC6c3AF10108Db212ACBBf9EA83F"),
CSModuleTxReceipt: common.HexToHash("0x85d995eba9763907fdf35cd2034144dd9d53ce32cbec21349d4b12823c6860c5"),
LidoKeysApiUrl: "https://keys-api.lido.fi",
ProxyApiPort: proxyApiPort,
MinGenesisTime: uint64(1606824023),
Expand Down

0 comments on commit ed3d7c7

Please sign in to comment.