From fd47aec81d0b168b2e1d80447896aedf54d4a79c Mon Sep 17 00:00:00 2001 From: Ethen Pociask Date: Wed, 8 Nov 2023 01:42:02 -0800 Subject: [PATCH] [indexer.api.supply_view] add withdrawal suppply calculations --- indexer/api-ts/generated.ts | 1 + indexer/api/api_test.go | 3 ++ indexer/api/models/models.go | 3 +- indexer/api/routes/deposits.go | 25 ------------- indexer/api/routes/supply.go | 35 +++++++++++++++++++ indexer/database/bridge_transfers.go | 12 ++++++- .../e2e_tests/bridge_transfers_e2e_test.go | 11 ++++-- 7 files changed, 61 insertions(+), 29 deletions(-) create mode 100644 indexer/api/routes/supply.go diff --git a/indexer/api-ts/generated.ts b/indexer/api-ts/generated.ts index 9651a114df01..7f9473cc5534 100644 --- a/indexer/api-ts/generated.ts +++ b/indexer/api-ts/generated.ts @@ -53,4 +53,5 @@ export interface WithdrawalResponse { } export interface BridgeSupplyView { l1DepositSum: number /* float64 */; + l2WithdrawalSum: number /* float64 */; } diff --git a/indexer/api/api_test.go b/indexer/api/api_test.go index 1424c35b60c3..4bfbc38907af 100644 --- a/indexer/api/api_test.go +++ b/indexer/api/api_test.go @@ -99,6 +99,9 @@ func (mbv *MockBridgeTransfersView) L2BridgeWithdrawalsByAddress(address common. func (mbv *MockBridgeTransfersView) L1BridgeDepositSum() (float64, error) { return 69, nil } +func (mbv *MockBridgeTransfersView) L2BridgeWithdrawalSum() (float64, error) { + return 420, nil +} func TestHealthz(t *testing.T) { logger := testlog.Logger(t, log.LvlInfo) diff --git a/indexer/api/models/models.go b/indexer/api/models/models.go index 307abab575de..b3e0964204bf 100644 --- a/indexer/api/models/models.go +++ b/indexer/api/models/models.go @@ -50,7 +50,8 @@ type WithdrawalResponse struct { } type BridgeSupplyView struct { - L1DepositSum float64 `json:"l1DepositSum"` + L1DepositSum float64 `json:"l1DepositSum"` + L2WithdrawalSum float64 `json:"l2WithdrawalSum"` } // FIXME make a pure function that returns a struct instead of newWithdrawalResponse diff --git a/indexer/api/routes/deposits.go b/indexer/api/routes/deposits.go index b7833ef6c95a..5bf6229a25a7 100644 --- a/indexer/api/routes/deposits.go +++ b/indexer/api/routes/deposits.go @@ -76,28 +76,3 @@ func (h Routes) L1DepositsHandler(w http.ResponseWriter, r *http.Request) { h.logger.Error("Error writing response", "err", err) } } - -// SupplyView ... Handles /api/v0/supply GET requests -func (h Routes) SupplyView(w http.ResponseWriter, r *http.Request) { - sum, err := h.view.L1BridgeDepositSum() - if err != nil { - http.Error(w, "Internal server error reading deposits", http.StatusInternalServerError) - h.logger.Error("Unable to read deposits from DB", "err", err.Error()) - return - } - - view := models.BridgeSupplyView{ - L1DepositSum: sum, - } - - // TODO - Add support for: - // - L2DepositSum - // - L1WithdrawalProvenSum - // - L1WithdrawalFinalizedSum - // - L2WithdrawalInitiatedSum - - err = jsonResponse(w, view, http.StatusOK) - if err != nil { - h.logger.Error("Error writing response", "err", err) - } -} diff --git a/indexer/api/routes/supply.go b/indexer/api/routes/supply.go new file mode 100644 index 000000000000..7f0ece832234 --- /dev/null +++ b/indexer/api/routes/supply.go @@ -0,0 +1,35 @@ +package routes + +import ( + "net/http" + + "github.com/ethereum-optimism/optimism/indexer/api/models" +) + +// SupplyView ... Handles /api/v0/supply GET requests +func (h Routes) SupplyView(w http.ResponseWriter, r *http.Request) { + + depositSum, err := h.view.L1BridgeDepositSum() + if err != nil { + http.Error(w, "internal server error reading deposits", http.StatusInternalServerError) + h.logger.Error("unable to read deposits from DB", "err", err.Error()) + return + } + + withdrawalSum, err := h.view.L2BridgeWithdrawalSum() + if err != nil { + http.Error(w, "internal server error reading withdrawals", http.StatusInternalServerError) + h.logger.Error("unable to read withdrawals from DB", "err", err.Error()) + return + } + + view := models.BridgeSupplyView{ + L1DepositSum: depositSum, + L2WithdrawalSum: withdrawalSum, + } + + err = jsonResponse(w, view, http.StatusOK) + if err != nil { + h.logger.Error("error writing response", "err", err) + } +} diff --git a/indexer/database/bridge_transfers.go b/indexer/database/bridge_transfers.go index 94cb435d1578..6704accf5911 100644 --- a/indexer/database/bridge_transfers.go +++ b/indexer/database/bridge_transfers.go @@ -66,6 +66,7 @@ type BridgeTransfersView interface { L1BridgeDepositsByAddress(common.Address, string, int) (*L1BridgeDepositsResponse, error) L2BridgeWithdrawal(common.Hash) (*L2BridgeWithdrawal, error) + L2BridgeWithdrawalSum() (float64, error) L2BridgeWithdrawalWithFilter(BridgeTransfer) (*L2BridgeWithdrawal, error) L2BridgeWithdrawalsByAddress(common.Address, string, int) (*L2BridgeWithdrawalsResponse, error) } @@ -139,7 +140,6 @@ type L1BridgeDepositsResponse struct { // L1BridgeDepositSum ... returns the sum of all l1 bridge deposit mints in gwei func (db *bridgeTransfersDB) L1BridgeDepositSum() (float64, error) { - // (1) Fetch the sum of all deposits in gwei var sum float64 result := db.gorm.Model(&L1TransactionDeposit{}).Select("sum(amount)").Scan(&sum) if result.Error != nil { @@ -246,6 +246,16 @@ func (db *bridgeTransfersDB) L2BridgeWithdrawal(txWithdrawalHash common.Hash) (* return &withdrawal, nil } +func (db *bridgeTransfersDB) L2BridgeWithdrawalSum() (float64, error) { + var sum float64 + result := db.gorm.Model(&L2TransactionWithdrawal{}).Select("sum(amount)").Scan(&sum) + if result.Error != nil { + return 0, result.Error + } + + return sum, nil +} + // L2BridgeWithdrawalWithFilter queries for a bridge withdrawal with set fields in the `BridgeTransfer` filter func (db *bridgeTransfersDB) L2BridgeWithdrawalWithFilter(filter BridgeTransfer) (*L2BridgeWithdrawal, error) { var withdrawal L2BridgeWithdrawal diff --git a/indexer/e2e_tests/bridge_transfers_e2e_test.go b/indexer/e2e_tests/bridge_transfers_e2e_test.go index bd2c0fd0e845..9f26940bb7f0 100644 --- a/indexer/e2e_tests/bridge_transfers_e2e_test.go +++ b/indexer/e2e_tests/bridge_transfers_e2e_test.go @@ -468,6 +468,8 @@ func TestClientBridgeFunctions(t *testing.T) { } mintSum := bigint.Zero + withdrawSum := bigint.Zero + actors := []actor{ { addr: aliceAddr, @@ -512,6 +514,8 @@ func TestClientBridgeFunctions(t *testing.T) { return l2Header != nil && l2Header.Number.Uint64() >= l2ToL1WithdrawReceipt.BlockNumber.Uint64(), nil })) + withdrawSum = new(big.Int).Add(withdrawSum, l2ToL1MessagePasserWithdrawTx.Value()) + // (3.d) Ensure that withdrawal and deposit txs are retrievable via API deposits, err := testSuite.Client.GetAllDepositsByAddress(actor.addr) require.NoError(t, err) @@ -529,7 +533,10 @@ func TestClientBridgeFunctions(t *testing.T) { assessment, err := testSuite.Client.GetSupplyAssessment() require.NoError(t, err) - asFloat, _ := mintSum.Float64() - require.Equal(t, asFloat, assessment.L1DepositSum) + mintFloat, _ := mintSum.Float64() + require.Equal(t, mintFloat, assessment.L1DepositSum) + + withdrawFloat, _ := withdrawSum.Float64() + require.Equal(t, withdrawFloat, assessment.L2WithdrawalSum) }