Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
95dd5008
Unverified
Commit
95dd5008
authored
Oct 14, 2023
by
Ethen Pociask
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[indexer.api.supply_view] feat(indexer) Obervability for Bridge Supplies
parent
8644925c
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
90 additions
and
2 deletions
+90
-2
api.go
indexer/api/api.go
+4
-0
api_test.go
indexer/api/api_test.go
+5
-0
models.go
indexer/api/models/models.go
+4
-0
deposits.go
indexer/api/routes/deposits.go
+25
-0
client.go
indexer/client/client.go
+20
-0
bridge_transfers.go
indexer/database/bridge_transfers.go
+13
-0
bridge_transfers_e2e_test.go
indexer/e2e_tests/bridge_transfers_e2e_test.go
+18
-1
20230523_create_schema.sql
indexer/migrations/20230523_create_schema.sql
+1
-1
No files found.
indexer/api/api.go
View file @
95dd5008
...
@@ -43,6 +43,8 @@ const (
...
@@ -43,6 +43,8 @@ const (
HealthPath
=
"/healthz"
HealthPath
=
"/healthz"
DepositsPath
=
"/api/v0/deposits/"
DepositsPath
=
"/api/v0/deposits/"
WithdrawalsPath
=
"/api/v0/withdrawals/"
WithdrawalsPath
=
"/api/v0/withdrawals/"
SupplyPath
=
"/api/v0/supply"
)
)
// chiMetricsMiddleware ... Injects a metrics recorder into request processing middleware
// chiMetricsMiddleware ... Injects a metrics recorder into request processing middleware
...
@@ -70,6 +72,8 @@ func NewApi(logger log.Logger, bv database.BridgeTransfersView, serverConfig con
...
@@ -70,6 +72,8 @@ func NewApi(logger log.Logger, bv database.BridgeTransfersView, serverConfig con
apiRouter
.
Get
(
fmt
.
Sprintf
(
DepositsPath
+
addressParam
,
ethereumAddressRegex
),
h
.
L1DepositsHandler
)
apiRouter
.
Get
(
fmt
.
Sprintf
(
DepositsPath
+
addressParam
,
ethereumAddressRegex
),
h
.
L1DepositsHandler
)
apiRouter
.
Get
(
fmt
.
Sprintf
(
WithdrawalsPath
+
addressParam
,
ethereumAddressRegex
),
h
.
L2WithdrawalsHandler
)
apiRouter
.
Get
(
fmt
.
Sprintf
(
WithdrawalsPath
+
addressParam
,
ethereumAddressRegex
),
h
.
L2WithdrawalsHandler
)
apiRouter
.
Get
(
SupplyPath
,
h
.
SupplyView
)
return
&
API
{
log
:
logger
,
router
:
apiRouter
,
metricsRegistry
:
mr
,
serverConfig
:
serverConfig
,
metricsConfig
:
metricsConfig
}
return
&
API
{
log
:
logger
,
router
:
apiRouter
,
metricsRegistry
:
mr
,
serverConfig
:
serverConfig
,
metricsConfig
:
metricsConfig
}
}
}
...
...
indexer/api/api_test.go
View file @
95dd5008
...
@@ -93,6 +93,11 @@ func (mbv *MockBridgeTransfersView) L2BridgeWithdrawalsByAddress(address common.
...
@@ -93,6 +93,11 @@ func (mbv *MockBridgeTransfersView) L2BridgeWithdrawalsByAddress(address common.
},
},
},
nil
},
nil
}
}
func
(
mbv
*
MockBridgeTransfersView
)
L1BridgeDepositSum
()
(
float64
,
error
)
{
return
69
,
nil
}
func
TestHealthz
(
t
*
testing
.
T
)
{
func
TestHealthz
(
t
*
testing
.
T
)
{
logger
:=
testlog
.
Logger
(
t
,
log
.
LvlInfo
)
logger
:=
testlog
.
Logger
(
t
,
log
.
LvlInfo
)
api
:=
NewApi
(
logger
,
&
MockBridgeTransfersView
{},
apiConfig
,
metricsConfig
)
api
:=
NewApi
(
logger
,
&
MockBridgeTransfersView
{},
apiConfig
,
metricsConfig
)
...
...
indexer/api/models/models.go
View file @
95dd5008
...
@@ -43,3 +43,7 @@ type WithdrawalResponse struct {
...
@@ -43,3 +43,7 @@ type WithdrawalResponse struct {
HasNextPage
bool
`json:"hasNextPage"`
HasNextPage
bool
`json:"hasNextPage"`
Items
[]
WithdrawalItem
`json:"items"`
Items
[]
WithdrawalItem
`json:"items"`
}
}
type
BridgeSupplyView
struct
{
L1DepositSum
float64
`json:"l1DepositSum"`
}
indexer/api/routes/deposits.go
View file @
95dd5008
...
@@ -76,3 +76,28 @@ func (h Routes) L1DepositsHandler(w http.ResponseWriter, r *http.Request) {
...
@@ -76,3 +76,28 @@ func (h Routes) L1DepositsHandler(w http.ResponseWriter, r *http.Request) {
h
.
logger
.
Error
(
"Error writing response"
,
"err"
,
err
)
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
)
}
}
indexer/client/client.go
View file @
95dd5008
...
@@ -23,6 +23,7 @@ const (
...
@@ -23,6 +23,7 @@ const (
healthz
=
"get_health"
healthz
=
"get_health"
deposits
=
"get_deposits"
deposits
=
"get_deposits"
withdrawals
=
"get_withdrawals"
withdrawals
=
"get_withdrawals"
sum
=
"get_sum"
)
)
// Option ... Provides configuration through callback injection
// Option ... Provides configuration through callback injection
...
@@ -164,6 +165,25 @@ func (c *Client) GetAllDepositsByAddress(l1Address common.Address) ([]models.Dep
...
@@ -164,6 +165,25 @@ func (c *Client) GetAllDepositsByAddress(l1Address common.Address) ([]models.Dep
}
}
// GetSupplyAssessment ... Returns an assessment of the current supply
// on both L1 and L2. This includes the individual sums of
// (L1/L2) deposits and withdrawals
func
(
c
*
Client
)
GetSupplyAssessment
()
(
*
models
.
BridgeSupplyView
,
error
)
{
url
:=
c
.
cfg
.
BaseURL
+
api
.
SupplyPath
resp
,
err
:=
c
.
doRecordRequest
(
sum
,
url
)
if
err
!=
nil
{
return
nil
,
err
}
var
bsv
*
models
.
BridgeSupplyView
if
err
:=
json
.
Unmarshal
(
resp
,
&
bsv
);
err
!=
nil
{
return
nil
,
err
}
return
bsv
,
nil
}
// GetAllWithdrawalsByAddress ... Gets all withdrawals provided a L2 address
// GetAllWithdrawalsByAddress ... Gets all withdrawals provided a L2 address
func
(
c
*
Client
)
GetAllWithdrawalsByAddress
(
l2Address
common
.
Address
)
([]
models
.
WithdrawalItem
,
error
)
{
func
(
c
*
Client
)
GetAllWithdrawalsByAddress
(
l2Address
common
.
Address
)
([]
models
.
WithdrawalItem
,
error
)
{
var
withdrawals
[]
models
.
WithdrawalItem
var
withdrawals
[]
models
.
WithdrawalItem
...
...
indexer/database/bridge_transfers.go
View file @
95dd5008
...
@@ -59,6 +59,7 @@ type L2BridgeWithdrawalWithTransactionHashes struct {
...
@@ -59,6 +59,7 @@ type L2BridgeWithdrawalWithTransactionHashes struct {
type
BridgeTransfersView
interface
{
type
BridgeTransfersView
interface
{
L1BridgeDeposit
(
common
.
Hash
)
(
*
L1BridgeDeposit
,
error
)
L1BridgeDeposit
(
common
.
Hash
)
(
*
L1BridgeDeposit
,
error
)
L1BridgeDepositSum
()
(
float64
,
error
)
L1BridgeDepositWithFilter
(
BridgeTransfer
)
(
*
L1BridgeDeposit
,
error
)
L1BridgeDepositWithFilter
(
BridgeTransfer
)
(
*
L1BridgeDeposit
,
error
)
L1BridgeDepositsByAddress
(
common
.
Address
,
string
,
int
)
(
*
L1BridgeDepositsResponse
,
error
)
L1BridgeDepositsByAddress
(
common
.
Address
,
string
,
int
)
(
*
L1BridgeDepositsResponse
,
error
)
...
@@ -128,6 +129,18 @@ type L1BridgeDepositsResponse struct {
...
@@ -128,6 +129,18 @@ type L1BridgeDepositsResponse struct {
HasNextPage
bool
HasNextPage
bool
}
}
// 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
{
return
0
,
result
.
Error
}
return
sum
,
nil
}
// L1BridgeDepositsByAddress retrieves a list of deposits initiated by the specified address,
// L1BridgeDepositsByAddress retrieves a list of deposits initiated by the specified address,
// coupled with the L1/L2 transaction hashes that complete the bridge transaction.
// coupled with the L1/L2 transaction hashes that complete the bridge transaction.
func
(
db
*
bridgeTransfersDB
)
L1BridgeDepositsByAddress
(
address
common
.
Address
,
cursor
string
,
limit
int
)
(
*
L1BridgeDepositsResponse
,
error
)
{
func
(
db
*
bridgeTransfersDB
)
L1BridgeDepositsByAddress
(
address
common
.
Address
,
cursor
string
,
limit
int
)
(
*
L1BridgeDepositsResponse
,
error
)
{
...
...
indexer/e2e_tests/bridge_transfers_e2e_test.go
View file @
95dd5008
...
@@ -8,6 +8,7 @@ import (
...
@@ -8,6 +8,7 @@ import (
"testing"
"testing"
"time"
"time"
"github.com/ethereum-optimism/optimism/indexer/bigint"
e2etest_utils
"github.com/ethereum-optimism/optimism/indexer/e2e_tests/utils"
e2etest_utils
"github.com/ethereum-optimism/optimism/indexer/e2e_tests/utils"
op_e2e
"github.com/ethereum-optimism/optimism/op-e2e"
op_e2e
"github.com/ethereum-optimism/optimism/op-e2e"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/transactions"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/transactions"
...
@@ -447,7 +448,7 @@ func TestE2EBridgeTransfersCursoredWithdrawals(t *testing.T) {
...
@@ -447,7 +448,7 @@ func TestE2EBridgeTransfersCursoredWithdrawals(t *testing.T) {
}
}
}
}
func
TestClient
GetWithdrawal
s
(
t
*
testing
.
T
)
{
func
TestClient
BridgeFunction
s
(
t
*
testing
.
T
)
{
testSuite
:=
createE2ETestSuite
(
t
)
testSuite
:=
createE2ETestSuite
(
t
)
// (1) Generate contract bindings for the L1 and L2 standard bridges
// (1) Generate contract bindings for the L1 and L2 standard bridges
...
@@ -459,12 +460,14 @@ func TestClientGetWithdrawals(t *testing.T) {
...
@@ -459,12 +460,14 @@ func TestClientGetWithdrawals(t *testing.T) {
// (2) Create test actors that will deposit and withdraw using the standard bridge
// (2) Create test actors that will deposit and withdraw using the standard bridge
aliceAddr
:=
testSuite
.
OpCfg
.
Secrets
.
Addresses
()
.
Alice
aliceAddr
:=
testSuite
.
OpCfg
.
Secrets
.
Addresses
()
.
Alice
bobAddr
:=
testSuite
.
OpCfg
.
Secrets
.
Addresses
()
.
Bob
bobAddr
:=
testSuite
.
OpCfg
.
Secrets
.
Addresses
()
.
Bob
malAddr
:=
testSuite
.
OpCfg
.
Secrets
.
Addresses
()
.
Mallory
type
actor
struct
{
type
actor
struct
{
addr
common
.
Address
addr
common
.
Address
priv
*
ecdsa
.
PrivateKey
priv
*
ecdsa
.
PrivateKey
}
}
mintSum
:=
bigint
.
Zero
actors
:=
[]
actor
{
actors
:=
[]
actor
{
{
{
addr
:
aliceAddr
,
addr
:
aliceAddr
,
...
@@ -474,6 +477,10 @@ func TestClientGetWithdrawals(t *testing.T) {
...
@@ -474,6 +477,10 @@ func TestClientGetWithdrawals(t *testing.T) {
addr
:
bobAddr
,
addr
:
bobAddr
,
priv
:
testSuite
.
OpCfg
.
Secrets
.
Bob
,
priv
:
testSuite
.
OpCfg
.
Secrets
.
Bob
,
},
},
{
addr
:
malAddr
,
priv
:
testSuite
.
OpCfg
.
Secrets
.
Mallory
,
},
}
}
// (3) Iterate over each actor and deposit / withdraw
// (3) Iterate over each actor and deposit / withdraw
...
@@ -491,6 +498,8 @@ func TestClientGetWithdrawals(t *testing.T) {
...
@@ -491,6 +498,8 @@ func TestClientGetWithdrawals(t *testing.T) {
_
,
err
=
wait
.
ForReceiptOK
(
context
.
Background
(),
testSuite
.
L1Client
,
depositTx
.
Hash
())
_
,
err
=
wait
.
ForReceiptOK
(
context
.
Background
(),
testSuite
.
L1Client
,
depositTx
.
Hash
())
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
mintSum
=
new
(
big
.
Int
)
.
Add
(
mintSum
,
depositTx
.
Value
())
// (3.b) Initiate withdrawal transaction via L2ToL1MessagePasser contract
// (3.b) Initiate withdrawal transaction via L2ToL1MessagePasser contract
l2ToL1MessagePasserWithdrawTx
,
err
:=
l2ToL1MessagePasser
.
Receive
(
l2Opts
)
l2ToL1MessagePasserWithdrawTx
,
err
:=
l2ToL1MessagePasser
.
Receive
(
l2Opts
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
...
@@ -513,6 +522,14 @@ func TestClientGetWithdrawals(t *testing.T) {
...
@@ -513,6 +522,14 @@ func TestClientGetWithdrawals(t *testing.T) {
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
require
.
Len
(
t
,
withdrawals
,
1
)
require
.
Len
(
t
,
withdrawals
,
1
)
require
.
Equal
(
t
,
l2ToL1MessagePasserWithdrawTx
.
Hash
()
.
String
(),
withdrawals
[
0
]
.
TransactionHash
)
require
.
Equal
(
t
,
l2ToL1MessagePasserWithdrawTx
.
Hash
()
.
String
(),
withdrawals
[
0
]
.
TransactionHash
)
}
}
// (4) Ensure that supply assessment is correct
assessment
,
err
:=
testSuite
.
Client
.
GetSupplyAssessment
()
require
.
NoError
(
t
,
err
)
asFloat
,
_
:=
mintSum
.
Float64
()
require
.
Equal
(
t
,
asFloat
,
assessment
.
L1DepositSum
)
}
}
indexer/migrations/20230523_create_schema.sql
View file @
95dd5008
...
@@ -94,7 +94,7 @@ CREATE TABLE IF NOT EXISTS l1_transaction_deposits (
...
@@ -94,7 +94,7 @@ CREATE TABLE IF NOT EXISTS l1_transaction_deposits (
-- transaction data. NOTE: `to_address` is the recipient of funds transferred in value field of the
-- transaction data. NOTE: `to_address` is the recipient of funds transferred in value field of the
-- L2 deposit transaction and not the amount minted on L1 from the source address. Hence the `amount`
-- L2 deposit transaction and not the amount minted on L1 from the source address. Hence the `amount`
-- column in this table does NOT indic
i
ate the amount transferred to the recipient but instead funds
-- column in this table does NOT indicate the amount transferred to the recipient but instead funds
-- bridged from L1 into `from_address`.
-- bridged from L1 into `from_address`.
from_address
VARCHAR
NOT
NULL
,
from_address
VARCHAR
NOT
NULL
,
to_address
VARCHAR
NOT
NULL
,
to_address
VARCHAR
NOT
NULL
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment