From d91781ec41f09d9201e9ce4d4c0e4d1370f1d391 Mon Sep 17 00:00:00 2001 From: Seri Choi Date: Thu, 13 Feb 2025 13:33:28 -0500 Subject: [PATCH] successful test --- pkg/contractManager/contractManager.go | 64 +++++++++++++++++ pkg/indexer/indexer.go | 2 +- pkg/indexer/indexer_test.go | 99 ++++++++++++++++++-------- 3 files changed, 136 insertions(+), 29 deletions(-) diff --git a/pkg/contractManager/contractManager.go b/pkg/contractManager/contractManager.go index 9c007f12..e73458ba 100644 --- a/pkg/contractManager/contractManager.go +++ b/pkg/contractManager/contractManager.go @@ -1,6 +1,7 @@ package contractManager import ( + "context" "fmt" "github.com/Layr-Labs/sidecar/internal/metrics" "github.com/Layr-Labs/sidecar/pkg/clients/ethereum" @@ -43,3 +44,66 @@ func (cm *ContractManager) GetContractWithProxy( return contract, nil } + +func (cm *ContractManager) CreateProxyContract( + contractAddress string, + proxyContractAddress string, + blockNumber uint64, +) (*contractStore.ProxyContract, error) { + proxyContract, found, err := cm.ContractStore.FindOrCreateProxyContract(blockNumber, contractAddress, proxyContractAddress) + if err != nil { + cm.Logger.Sugar().Errorw("Failed to create proxy contract", + zap.Error(err), + zap.String("contractAddress", contractAddress), + zap.String("proxyContractAddress", proxyContractAddress), + ) + return nil, err + } else { + if found { + cm.Logger.Sugar().Debugw("Found existing proxy contract", + zap.String("contractAddress", contractAddress), + zap.String("proxyContractAddress", proxyContractAddress), + ) + } else { + cm.Logger.Sugar().Debugw("Created proxy contract", + zap.String("contractAddress", contractAddress), + zap.String("proxyContractAddress", proxyContractAddress), + ) + } + } + + bytecode, err := cm.EthereumClient.GetCode(context.Background(), proxyContractAddress) + if err != nil { + cm.Logger.Sugar().Errorw("Failed to get proxy contract bytecode", + zap.Error(err), + zap.String("proxyContractAddress", proxyContractAddress), + ) + return nil, err + } + + bytecodeHash := ethereum.HashBytecode(bytecode) + cm.Logger.Sugar().Debug("Fetched proxy contract bytecode", + zap.String("proxyContractAddress", proxyContractAddress), + zap.String("bytecodeHash", bytecodeHash), + ) + + _, _, err = cm.ContractStore.FindOrCreateContract( + proxyContractAddress, + "", + false, + bytecodeHash, + "", + false, + ) + if err != nil { + cm.Logger.Sugar().Errorw("Failed to create new contract for proxy contract", + zap.Error(err), + zap.String("proxyContractAddress", proxyContractAddress), + ) + return nil, err + } else { + cm.Logger.Sugar().Debugf("Created new contract for proxy contract", zap.String("proxyContractAddress", proxyContractAddress)) + } + + return proxyContract, nil +} diff --git a/pkg/indexer/indexer.go b/pkg/indexer/indexer.go index a9899eed..1fe6d2ec 100644 --- a/pkg/indexer/indexer.go +++ b/pkg/indexer/indexer.go @@ -196,7 +196,7 @@ func (idx *Indexer) IndexContractUpgrade(ctx context.Context, blockNumber uint64 return nil } - _, _, err := idx.ContractStore.FindOrCreateProxyContract(blockNumber, upgradedLog.Address, newProxiedAddress) + _, err := idx.ContractManager.CreateProxyContract(upgradedLog.Address, newProxiedAddress, blockNumber) if err != nil { idx.Logger.Sugar().Errorw("Failed to create proxy contract", zap.Error(err)) return err diff --git a/pkg/indexer/indexer_test.go b/pkg/indexer/indexer_test.go index 53015636..5eac39d6 100644 --- a/pkg/indexer/indexer_test.go +++ b/pkg/indexer/indexer_test.go @@ -2,6 +2,7 @@ package indexer import ( "context" + "database/sql" "log" "testing" @@ -9,6 +10,7 @@ import ( "github.com/Layr-Labs/sidecar/pkg/clients/ethereum" "github.com/Layr-Labs/sidecar/pkg/contractCaller/multicallContractCaller" "github.com/Layr-Labs/sidecar/pkg/contractManager" + "github.com/Layr-Labs/sidecar/pkg/contractStore" "github.com/Layr-Labs/sidecar/pkg/contractStore/postgresContractStore" "github.com/Layr-Labs/sidecar/pkg/fetcher" "github.com/Layr-Labs/sidecar/pkg/parser" @@ -38,6 +40,19 @@ func Test_Indexer(t *testing.T) { l.Sugar().Fatal("Failed to setup metrics sink", zap.Error(err)) } + contract := &contractStore.Contract{ + ContractAddress: "0x123", + ContractAbi: "[]", + Verified: true, + BytecodeHash: "0x123", + MatchingContractAddress: "", + } + proxyContract := &contractStore.ProxyContract{ + BlockNumber: 1, + ContractAddress: contract.ContractAddress, + ProxyContractAddress: "0x456", + } + sdc, err := metrics.NewMetricsSink(&metrics.MetricsSinkConfig{}, metricsClients) if err != nil { l.Sugar().Fatal("Failed to setup metrics sink", zap.Error(err)) @@ -57,35 +72,63 @@ func Test_Indexer(t *testing.T) { cm := contractManager.NewContractManager(contractStore, client, sdc, l) t.Run("Test indexing contract upgrades", func(t *testing.T) { - contractAddress := "0x055733000064333caddbc92763c58bf0192ffebf" - blockNumber := uint64(2969816) - - upgradedLog := &parser.DecodedLog{ - LogIndex: 0, - Address: contractAddress, - EventName: "Upgraded", - Arguments: []parser.Argument{ - { - Name: "implementation", - Type: "address", - Value: common.HexToAddress("0xa504276dfdee6210c26c55385d1f793bf52089a0"), - Indexed: true, - }, - }, - } - + // Create a contract + _, found, err := contractStore.FindOrCreateContract(contract.ContractAddress, contract.ContractAbi, contract.Verified, contract.BytecodeHash, contract.MatchingContractAddress, false) + assert.Nil(t, err) + assert.False(t, found) + + // Create a proxy contract + _, found, err = contractStore.FindOrCreateProxyContract(uint64(proxyContract.BlockNumber), proxyContract.ContractAddress, proxyContract.ProxyContractAddress) + assert.Nil(t, err) + assert.False(t, found) + + // Check if contract and proxy contract exist + var contractCount int + contractAddress := contract.ContractAddress + res := grm.Raw(`select count(*) from contracts where contract_address=@contractAddress`, sql.Named("contractAddress", contractAddress)).Scan(&contractCount) + assert.Nil(t, res.Error) + assert.Equal(t, 1, contractCount) + + proxyContractAddress := proxyContract.ContractAddress + res = grm.Raw(`select count(*) from contracts where contract_address=@proxyContractAddress`, sql.Named("proxyContractAddress", proxyContractAddress)).Scan(&contractCount) + assert.Nil(t, res.Error) + assert.Equal(t, 1, contractCount) + + var proxyContractCount int + res = grm.Raw(`select count(*) from proxy_contracts where contract_address=@contractAddress`, sql.Named("contractAddress", contractAddress)).Scan(&proxyContractCount) + assert.Nil(t, res.Error) + assert.Equal(t, 1, proxyContractCount) + + // An upgrade event + upgradedLog := &parser.DecodedLog{ + LogIndex: 0, + Address: contract.ContractAddress, + EventName: "Upgraded", + Arguments: []parser.Argument{ + { + Name: "implementation", + Type: "address", + Value: common.HexToAddress("0x789"), + Indexed: true, + }, + }, + } + + // Perform the upgrade idxr := NewIndexer(mds, contractStore, cm, client, fetchr, mccc, grm, l, cfg) - - - // Get initial state - - // Perform the upgrade - err = idxr.IndexContractUpgrade(context.Background(), blockNumber, upgradedLog) - assert.Nil(t, err) - - // Verify database state after upgrade - }) - + err = idxr.IndexContractUpgrade(context.Background(), 5, upgradedLog) + assert.Nil(t, err) + + // Verify database state after upgrade + newProxyContractAddress := upgradedLog.Arguments[0].Value.(common.Address).Hex() + res = grm.Raw(`select count(*) from contracts where contract_address=@newProxyContractAddress`, sql.Named("newProxyContractAddress", newProxyContractAddress)).Scan(&contractCount) + assert.Nil(t, res.Error) + assert.Equal(t, 1, contractCount) + + res = grm.Raw(`select count(*) from proxy_contracts where contract_address=@contractAddress`, sql.Named("contractAddress", contractAddress)).Scan(&proxyContractCount) + assert.Nil(t, res.Error) + assert.Equal(t, 2, proxyContractCount) + }) t.Cleanup(func() { postgres.TeardownTestDatabase(dbName, cfg, grm, l) })