From 70704f03988b35037dda6236108c830fd7771e36 Mon Sep 17 00:00:00 2001 From: Sean McGary Date: Thu, 19 Dec 2024 14:46:28 -0600 Subject: [PATCH] Concat all contracts together --- pkg/contractManager/contractManager.go | 4 +++ pkg/contractStore/contractStore.go | 13 +++++++++ pkg/contractStore/coreContracts/testnet.json | 6 ++-- .../postgresContractStore.go | 29 +++++++++++++++++++ pkg/indexer/transactionLogs.go | 21 ++++++++++---- 5 files changed, 64 insertions(+), 9 deletions(-) diff --git a/pkg/contractManager/contractManager.go b/pkg/contractManager/contractManager.go index 9c007f12..89cf96d8 100644 --- a/pkg/contractManager/contractManager.go +++ b/pkg/contractManager/contractManager.go @@ -29,6 +29,10 @@ func NewContractManager( } } +func (cm *ContractManager) GetContractWithImplementations(contractAddress string) ([]*contractStore.Contract, error) { + return cm.ContractStore.GetProxyContractWithImplementations(contractAddress) +} + func (cm *ContractManager) GetContractWithProxy( contractAddress string, blockNumber uint64, diff --git a/pkg/contractStore/contractStore.go b/pkg/contractStore/contractStore.go index 5d5ff5b9..502e9bfe 100644 --- a/pkg/contractStore/contractStore.go +++ b/pkg/contractStore/contractStore.go @@ -16,6 +16,7 @@ type ContractStore interface { FindOrCreateProxyContract(blockNumber uint64, contractAddress string, proxyContractAddress string) (*ProxyContract, bool, error) GetContractWithProxyContract(address string, atBlockNumber uint64) (*ContractsTree, error) SetContractCheckedForProxy(address string) (*Contract, error) + GetProxyContractWithImplementations(contractAddress string) ([]*Contract, error) InitializeCoreContracts() error } @@ -61,6 +62,18 @@ type ContractWithProxyContract struct { ProxyContractVerified string } +func CombineAbis(contracts []*Contract) (string, error) { + abisToCombine := make([]string, 0) + + for _, contract := range contracts { + strippedContractAbi := contract.ContractAbi[1 : len(contract.ContractAbi)-1] + abisToCombine = append(abisToCombine, strippedContractAbi) + } + + combinedAbi := fmt.Sprintf("[%s]", strings.Join(abisToCombine, ",")) + return combinedAbi, nil +} + func (c *ContractWithProxyContract) CombineAbis() (string, error) { if c.ProxyContractAbi == "" { return c.ContractAbi, nil diff --git a/pkg/contractStore/coreContracts/testnet.json b/pkg/contractStore/coreContracts/testnet.json index d0270560..e9fb9860 100644 --- a/pkg/contractStore/coreContracts/testnet.json +++ b/pkg/contractStore/coreContracts/testnet.json @@ -149,17 +149,17 @@ }, { "contract_address": "0x78469728304326cbc65f8f95fa756b0b73164462", "proxy_contract_address": "0xe03d546ada84b5624b50aa22ff8b87badef44ee2", - "block_number": 2969349 + "block_number": 2969816 }, { "contract_address": "0x30770d7e3e71112d7a6b7259542d1f680a70e315", "proxy_contract_address": "0x35b7743633acdaeb18a4894469fcdbf23e13f304", - "block_number": 2969355 + "block_number": 2969816 }, { "contract_address": "0xa44151489861fe9e3055d95adc98fbd462b948e7", "proxy_contract_address": "0xf435ef8bb9520d15b5128a519ae04d1e6e04a6e0", - "block_number": 2969352 + "block_number": 2969816 } ] } diff --git a/pkg/contractStore/postgresContractStore/postgresContractStore.go b/pkg/contractStore/postgresContractStore/postgresContractStore.go index 89af8ac5..c466451c 100644 --- a/pkg/contractStore/postgresContractStore/postgresContractStore.go +++ b/pkg/contractStore/postgresContractStore/postgresContractStore.go @@ -123,6 +123,35 @@ func (s *PostgresContractStore) FindOrCreateProxyContract( return upsertedContract, found, err } +func (s *PostgresContractStore) GetProxyContractWithImplementations(contractAddress string) ([]*contractStore.Contract, error) { + contractAddress = strings.ToLower(contractAddress) + contracts := make([]*contractStore.Contract, 0) + + query := `select + c.contract_address, + c.contract_abi, + c.bytecode_hash + from contracts as c + where c.contract_address = @contractAddress + or c.contract_address in ( + select proxy_contract_address from proxy_contracts where contract_address = @contractAddress + ) + ` + result := s.Db.Raw(query, + sql.Named("contractAddress", contractAddress), + ).Scan(&contracts) + + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + s.Logger.Sugar().Debug(fmt.Sprintf("Proxy contract not found '%s'", contractAddress)) + return nil, result.Error + } + return nil, result.Error + } + + return contracts, nil +} + func (s *PostgresContractStore) GetContractWithProxyContract(address string, atBlockNumber uint64) (*contractStore.ContractsTree, error) { address = strings.ToLower(address) diff --git a/pkg/indexer/transactionLogs.go b/pkg/indexer/transactionLogs.go index f147d574..59dc3fd8 100644 --- a/pkg/indexer/transactionLogs.go +++ b/pkg/indexer/transactionLogs.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "github.com/Layr-Labs/sidecar/pkg/clients/ethereum" + "github.com/Layr-Labs/sidecar/pkg/contractStore" "github.com/Layr-Labs/sidecar/pkg/parser" "github.com/Layr-Labs/sidecar/pkg/utils" "github.com/ethereum/go-ethereum/accounts/abi" @@ -68,7 +69,7 @@ func (idx *Indexer) ParseTransactionLogs( // the log address would be different than the transaction address var a *abi.ABI if idx.IsInterestingAddress(contractAddress.Value()) { - contract, err := idx.ContractManager.GetContractWithProxy(contractAddress.Value(), transaction.BlockNumber.Value()) + foundContracts, err := idx.ContractManager.GetContractWithImplementations(contractAddress.Value()) if err != nil { idx.Logger.Sugar().Errorw(fmt.Sprintf("Failed to get contract for address %s", contractAddress), zap.Error(err)) return nil, NewIndexError(IndexError_FailedToFindContract, err). @@ -79,7 +80,7 @@ func (idx *Indexer) ParseTransactionLogs( } // if the contract is interesting but not found, throw an error to stop processing - if contract == nil { + if foundContracts == nil { idx.Logger.Sugar().Errorw("No contract found for address", zap.String("hash", transaction.Hash.Value())) return nil, NewIndexError(IndexError_FailedToFindContract, err). WithMessage("No contract found for address"). @@ -88,7 +89,15 @@ func (idx *Indexer) ParseTransactionLogs( WithMetadata("contractAddress", contractAddress.Value()) } - contractAbi := contract.CombineAbis() + contractAbi, err := contractStore.CombineAbis(foundContracts) + if err != nil { + idx.Logger.Sugar().Errorw("Failed to combine ABIs", zap.Error(err)) + return nil, NewIndexError(IndexError_FailedToCombineAbis, err). + WithMessage("Failed to combine ABIs"). + WithBlockNumber(transaction.BlockNumber.Value()). + WithTransactionHash(transaction.Hash.Value()). + WithMetadata("contractAddress", contractAddress.Value()) + } // If the ABI is empty, return an error if contractAbi == "" { @@ -171,16 +180,16 @@ func (idx *Indexer) DecodeLogWithAbi( } else { idx.Logger.Sugar().Debugw("Log address does not match contract address", zap.String("logAddress", logAddress.String()), zap.String("contractAddress", txReceipt.GetTargetAddress().Value())) // Find/create the log address and attempt to determine if it is a proxy address - foundContract, err := idx.ContractManager.GetContractWithProxy(logAddress.String(), txReceipt.BlockNumber.Value()) + foundContracts, err := idx.ContractManager.GetContractWithImplementations(logAddress.String()) if err != nil { return idx.DecodeLog(nil, lg) } - if foundContract == nil { + if foundContracts == nil { idx.Logger.Sugar().Debugw("No contract found for address", zap.String("address", logAddress.String())) return idx.DecodeLog(nil, lg) } - contractAbi := foundContract.CombineAbis() + contractAbi, err := contractStore.CombineAbis(foundContracts) if err != nil { idx.Logger.Sugar().Errorw("Failed to combine ABIs", zap.Error(err), zap.String("contractAddress", logAddress.String())) return idx.DecodeLog(nil, lg)