From ca72e686b83d5f701a14e8531fee5412eb681e8c Mon Sep 17 00:00:00 2001 From: Sean McGary Date: Sat, 7 Sep 2024 22:15:16 -0500 Subject: [PATCH] On startup, load contracts --- .gitignore | 1 + cmd/sidecar/main.go | 3 ++ internal/config/config.go | 2 +- internal/contractManager/contractManager.go | 6 ++-- internal/contractStore/contractStore.go | 2 +- .../sqliteContractStore.go | 19 +++++++++++++ .../sqliteContractStore_test.go | 6 ++-- internal/indexer/indexer.go | 7 ++++- internal/indexer/transactionLogs.go | 9 ++++-- internal/logger/logger.go | 2 +- .../migrations/202409061249_bootstrapDb/up.go | 28 +++++++++---------- 11 files changed, 57 insertions(+), 28 deletions(-) diff --git a/.gitignore b/.gitignore index bb4953a6..63562ec6 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ block-lake/preprod-values.yaml /bin ./block-lake/preprod-values.yaml /scripts/runLocal +sidecar.db* diff --git a/cmd/sidecar/main.go b/cmd/sidecar/main.go index 7953dd15..b58768be 100644 --- a/cmd/sidecar/main.go +++ b/cmd/sidecar/main.go @@ -52,6 +52,9 @@ func main() { } contractStore := sqliteContractStore.NewSqliteContractStore(grm, l, cfg) + if err := contractStore.InitializeCoreContracts(); err != nil { + log.Fatalf("Failed to initialize core contracts: %v", err) + } cm := contractManager.NewContractManager(contractStore, etherscanClient, client, sdc, l) diff --git a/internal/config/config.go b/internal/config/config.go index 36f9784d..26039266 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -261,7 +261,7 @@ func (c *Config) GetGenesisBlockNumber() uint64 { case Environment_PreProd: return 1140406 case Environment_Testnet: - return 1140406 + return 1167044 case Environment_Mainnet: return 19492759 default: diff --git a/internal/contractManager/contractManager.go b/internal/contractManager/contractManager.go index ba02413e..16e45509 100644 --- a/internal/contractManager/contractManager.go +++ b/internal/contractManager/contractManager.go @@ -84,7 +84,6 @@ func (cm *ContractManager) CreateContract( bytecodeHash string, reindexContract bool, ) (*contractStore.Contract, error) { - // If the bytecode hash wasnt provided, fetch it if bytecodeHash == "" { cm.Logger.Sugar().Debugw("No bytecode hash provided for contract, fetching", @@ -112,6 +111,7 @@ func (cm *ContractManager) CreateContract( false, bytecodeHash, "", + false, ) if err != nil { cm.Logger.Sugar().Errorw("Failed to create new contract", @@ -122,9 +122,7 @@ func (cm *ContractManager) CreateContract( cm.Logger.Sugar().Debugf(fmt.Sprintf("Created new contract '%s'", contractAddress)) } - if !contract.CheckedForAbi || reindexContract { - contract = cm.FindAndSetContractAbi(contractAddress) - } + contract = cm.FindAndSetContractAbi(contractAddress) cm.FindAndSetLookalikeContract(contractAddress, bytecodeHash) diff --git a/internal/contractStore/contractStore.go b/internal/contractStore/contractStore.go index fac1e729..8821937c 100644 --- a/internal/contractStore/contractStore.go +++ b/internal/contractStore/contractStore.go @@ -12,7 +12,7 @@ var CoreContracts embed.FS type ContractStore interface { GetContractForAddress(address string) (*Contract, error) - FindOrCreateContract(address string, abiJson string, verified bool, bytecodeHash string, matchingContractAddress string) (*Contract, bool, error) + FindOrCreateContract(address string, abiJson string, verified bool, bytecodeHash string, matchingContractAddress string, checkedForAbi bool) (*Contract, bool, error) FindVerifiedContractWithMatchingBytecodeHash(bytecodeHash string, address string) (*Contract, error) FindOrCreateProxyContract(blockNumber uint64, contractAddress string, proxyContractAddress string) (*ProxyContract, bool, error) GetContractWithProxyContract(address string, atBlockNumber uint64) (*ContractsTree, error) diff --git a/internal/contractStore/sqliteContractStore/sqliteContractStore.go b/internal/contractStore/sqliteContractStore/sqliteContractStore.go index 670c4604..fe09dc91 100644 --- a/internal/contractStore/sqliteContractStore/sqliteContractStore.go +++ b/internal/contractStore/sqliteContractStore/sqliteContractStore.go @@ -68,6 +68,7 @@ func (s *SqliteContractStore) FindOrCreateContract( verified bool, bytecodeHash string, matchingContractAddress string, + checkedForAbi bool, ) (*contractStore.Contract, bool, error) { found := false upsertedContract, err := sqlite.WrapTxAndCommit[*contractStore.Contract](func(tx *gorm.DB) (*contractStore.Contract, error) { @@ -88,6 +89,7 @@ func (s *SqliteContractStore) FindOrCreateContract( Verified: verified, BytecodeHash: bytecodeHash, MatchingContractAddress: matchingContractAddress, + CheckedForAbi: checkedForAbi, } result = s.Db.Create(contract) @@ -295,6 +297,16 @@ func (s *SqliteContractStore) InitializeCoreContracts() error { return xerrors.Errorf("Failed to load core contracts: %w", err) } + contracts := make([]*contractStore.Contract, 0) + res := s.Db.Find(&contracts) + if res.Error != nil { + return xerrors.Errorf("Failed to fetch contracts: %w", res.Error) + } + if len(contracts) > 0 { + s.Logger.Sugar().Debugw("Core contracts already initialized") + return nil + } + for _, contract := range coreContracts.CoreContracts { _, _, err := s.FindOrCreateContract( contract.ContractAddress, @@ -302,10 +314,17 @@ func (s *SqliteContractStore) InitializeCoreContracts() error { true, contract.BytecodeHash, "", + true, ) if err != nil { return xerrors.Errorf("Failed to create core contract: %w", err) } + + _, err = s.SetContractCheckedForProxy(contract.ContractAddress) + if err != nil { + return xerrors.Errorf("Failed to create core contract: %w", err) + } + } for _, proxy := range coreContracts.ProxyContracts { _, _, err := s.FindOrCreateProxyContract( diff --git a/internal/contractStore/sqliteContractStore/sqliteContractStore_test.go b/internal/contractStore/sqliteContractStore/sqliteContractStore_test.go index f8bb29c1..5854b3d6 100644 --- a/internal/contractStore/sqliteContractStore/sqliteContractStore_test.go +++ b/internal/contractStore/sqliteContractStore/sqliteContractStore_test.go @@ -106,7 +106,7 @@ func Test_SqliteContractStore(t *testing.T) { MatchingContractAddress: "", } - createdContract, found, err := cs.FindOrCreateContract(contract.ContractAddress, contract.ContractAbi, contract.Verified, contract.BytecodeHash, contract.MatchingContractAddress) + createdContract, found, err := cs.FindOrCreateContract(contract.ContractAddress, contract.ContractAbi, contract.Verified, contract.BytecodeHash, contract.MatchingContractAddress, false) assert.Nil(t, err) assert.False(t, found) assert.Equal(t, contract.ContractAddress, createdContract.ContractAddress) @@ -126,7 +126,7 @@ func Test_SqliteContractStore(t *testing.T) { MatchingContractAddress: "", } - createdContract, found, err := cs.FindOrCreateContract(contract.ContractAddress, contract.ContractAbi, contract.Verified, contract.BytecodeHash, contract.MatchingContractAddress) + createdContract, found, err := cs.FindOrCreateContract(contract.ContractAddress, contract.ContractAbi, contract.Verified, contract.BytecodeHash, contract.MatchingContractAddress, false) assert.Nil(t, err) assert.True(t, found) assert.Equal(t, contract.ContractAddress, createdContract.ContractAddress) @@ -156,7 +156,7 @@ func Test_SqliteContractStore(t *testing.T) { BytecodeHash: "0x456", MatchingContractAddress: "", } - createdProxy, _, err := cs.FindOrCreateContract(newProxyContract.ContractAddress, newProxyContract.ContractAbi, newProxyContract.Verified, newProxyContract.BytecodeHash, newProxyContract.MatchingContractAddress) + createdProxy, _, err := cs.FindOrCreateContract(newProxyContract.ContractAddress, newProxyContract.ContractAbi, newProxyContract.Verified, newProxyContract.BytecodeHash, newProxyContract.MatchingContractAddress, false) assert.Nil(t, err) createdContracts = append(createdContracts, createdProxy) diff --git a/internal/indexer/indexer.go b/internal/indexer/indexer.go index 8d3c10ed..39496e3e 100644 --- a/internal/indexer/indexer.go +++ b/internal/indexer/indexer.go @@ -125,13 +125,18 @@ func (idx *Indexer) ParseInterestingTransactionsAndLogs(ctx context.Context, fet return nil, err } if parsedTransactionAndLogs == nil { - idx.Logger.Sugar().Debugw("Log line is nil", + idx.Logger.Sugar().Debugw("Transaction is nil", zap.String("txHash", tx.Hash.Value()), zap.Uint64("block", tx.BlockNumber.Value()), zap.Int("logIndex", i), ) continue } + idx.Logger.Sugar().Debugw("Parsed transaction and logs", + zap.String("txHash", tx.Hash.Value()), + zap.Uint64("block", tx.BlockNumber.Value()), + zap.Int("logCount", len(parsedTransactionAndLogs.Logs)), + ) // If there are interesting logs or if the tx/receipt is interesting, include it if len(parsedTransactionAndLogs.Logs) > 0 || idx.IsInterestingTransaction(tx, txReceipt) { parsedTransactions = append(parsedTransactions, parsedTransactionAndLogs) diff --git a/internal/indexer/transactionLogs.go b/internal/indexer/transactionLogs.go index 817a184a..8b6a3c90 100644 --- a/internal/indexer/transactionLogs.go +++ b/internal/indexer/transactionLogs.go @@ -47,7 +47,7 @@ func (idx *Indexer) ParseTransactionLogs( transaction *ethereum.EthereumTransaction, receipt *ethereum.EthereumTransactionReceipt, ) (*parser.ParsedTransaction, *IndexError) { - idx.Logger.Sugar().Debugf("ProcessingTransaction '%s'", transaction.Hash.Value()) + idx.Logger.Sugar().Debugw("ProcessingTransaction", zap.String("transactionHash", transaction.Hash.Value())) parsedTransaction := &parser.ParsedTransaction{ Logs: make([]*parser.DecodedLog, 0), Transaction: transaction, @@ -142,7 +142,10 @@ func (idx *Indexer) ParseTransactionLogs( logs := make([]*parser.DecodedLog, 0) // Attempt to decode each transaction log - idx.Logger.Sugar().Debugw(fmt.Sprintf("Decoding '%d' logs for transaction '%s'", len(receipt.Logs), transaction.Hash.Value())) + idx.Logger.Sugar().Debugw(fmt.Sprintf("Decoding '%d' logs for transaction", len(receipt.Logs)), + zap.String("transactionHash", transaction.Hash.Value()), + zap.Uint64("blockNumber", transaction.BlockNumber.Value()), + ) for i, lg := range receipt.Logs { if !idx.IsInterestingAddress(lg.Address.Value()) { @@ -169,7 +172,7 @@ func (idx *Indexer) ParseTransactionLogs( func (idx *Indexer) FindContractUpgradedLogs(parsedLogs []*parser.DecodedLog) []*parser.DecodedLog { contractUpgradedLogs := make([]*parser.DecodedLog, 0) for _, parsedLog := range parsedLogs { - if parsedLog.EventName == "Upgraded" { + if parsedLog.EventName == "Upgraded" && idx.IsInterestingAddress(parsedLog.Address) { contractUpgradedLogs = append(contractUpgradedLogs, parsedLog) } } diff --git a/internal/logger/logger.go b/internal/logger/logger.go index 5aabf690..300ba25a 100644 --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -18,7 +18,7 @@ func NewLogger(cfg *LoggerConfig, options ...zap.Option) (*zap.Logger, error) { c.EncoderConfig = zap.NewProductionEncoderConfig() if cfg.Debug { - c.Level = zap.NewAtomicLevelAt(zap.InfoLevel) + c.Level = zap.NewAtomicLevelAt(zap.DebugLevel) } else { c.Level = zap.NewAtomicLevelAt(zap.InfoLevel) } diff --git a/internal/sqlite/migrations/202409061249_bootstrapDb/up.go b/internal/sqlite/migrations/202409061249_bootstrapDb/up.go index 45d35bad..44d0375d 100644 --- a/internal/sqlite/migrations/202409061249_bootstrapDb/up.go +++ b/internal/sqlite/migrations/202409061249_bootstrapDb/up.go @@ -44,30 +44,30 @@ func (m *SqliteMigration) Up(grm *gorm.DB) error { transaction_index INTEGER NOT NULL, output_data TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - updated_at DATETIME, - deleted_at DATETIME, + updated_at DATETIME DEFAULT NULL, + deleted_at DATETIME DEFAULT NULL, UNIQUE(transaction_hash, log_index) )`, `CREATE TABLE IF NOT EXISTS contracts ( contract_address TEXT NOT NULL, contract_abi TEXT, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - updated_at DATETIME, - deleted_at DATETIME, bytecode_hash TEXT DEFAULT NULL, verified INTEGER DEFAULT false, + checked_for_proxy INTEGER DEFAULT 0, + checked_for_abi INTEGER DEFAULT 0, matching_contract_address TEXT DEFAULT NULL, - checked_for_proxy INTEGER DEFAULT 0 NOT NULL, - checked_for_abi INTEGER NOT NULL DEFAULT 0, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT NULL, + deleted_at DATETIME DEFAULT NULL, UNIQUE(contract_address) )`, `CREATE TABLE IF NOT EXISTS proxy_contracts ( block_number INTEGER NOT NULL, contract_address TEXT NOT NULL REFERENCES contracts(contract_address) ON DELETE CASCADE, proxy_contract_address TEXT NOT NULL, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, - updated_at DATETIME, - deleted_at DATETIME, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT NULL, + deleted_at DATETIME DEFAULT NULL, unique(contract_address, proxy_contract_address, block_number) )`, `CREATE TABLE IF NOT EXISTS operator_restaked_strategies ( @@ -75,11 +75,11 @@ func (m *SqliteMigration) Up(grm *gorm.DB) error { operator TEXT NOT NULL, avs TEXT NOT NULL, strategy TEXT NOT NULL, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - updated_at DATETIME, - deleted_at DATETIME, block_time DATETIME NOT NULL, - avs_directory_address TEXT + avs_directory_address TEXT, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT NULL, + deleted_at DATETIME DEFAULT NULL );`, }