Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(eventindexer): add stats tracking #13810

Merged
merged 7 commits into from
May 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 87 additions & 43 deletions packages/eventindexer/TaikoL1.json
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,19 @@
"name": "RESOLVER_ZERO_ADDR",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "addressManager",
"type": "address"
}
],
"name": "AddressManagerChanged",
"type": "event"
},
{
"anonymous": false,
"inputs": [
Expand Down Expand Up @@ -313,11 +326,6 @@
"name": "mixHash",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "depositsRoot",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "txListHash",
Expand All @@ -343,11 +351,6 @@
"name": "beneficiary",
"type": "address"
},
{
"internalType": "uint8",
"name": "cacheTxListInfo",
"type": "uint8"
},
{
"internalType": "address",
"name": "treasury",
Expand Down Expand Up @@ -375,6 +378,12 @@
"internalType": "struct TaikoData.BlockMetadata",
"name": "meta",
"type": "tuple"
},
{
"indexed": false,
"internalType": "uint64",
"name": "blockFee",
"type": "uint64"
}
],
"name": "BlockProposed",
Expand Down Expand Up @@ -437,6 +446,12 @@
"internalType": "bytes32",
"name": "blockHash",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint64",
"name": "reward",
"type": "uint64"
}
],
"name": "BlockVerified",
Expand Down Expand Up @@ -524,6 +539,19 @@
"name": "OwnershipTransferred",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint64",
"name": "proofTimeTarget",
"type": "uint64"
}
],
"name": "ProofTimeTargetChanged",
"type": "event"
},
{
"inputs": [],
"name": "addressManager",
Expand Down Expand Up @@ -626,24 +654,19 @@
"type": "uint256"
},
{
"internalType": "uint256",
"internalType": "uint64",
"name": "blockMaxGasLimit",
"type": "uint256"
"type": "uint64"
},
{
"internalType": "uint256",
"internalType": "uint64",
"name": "maxTransactionsPerBlock",
"type": "uint256"
"type": "uint64"
},
{
"internalType": "uint256",
"internalType": "uint64",
"name": "maxBytesPerTxList",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "minTxGasLimit",
"type": "uint256"
"type": "uint64"
},
{
"internalType": "uint256",
Expand Down Expand Up @@ -695,11 +718,6 @@
"name": "minEthDepositAmount",
"type": "uint96"
},
{
"internalType": "uint64",
"name": "proofTimeTarget",
"type": "uint64"
},
{
"internalType": "uint8",
"name": "adjustmentQuotient",
Expand Down Expand Up @@ -822,12 +840,7 @@
"inputs": [
{
"internalType": "uint64",
"name": "provenAt",
"type": "uint64"
},
{
"internalType": "uint64",
"name": "proposedAt",
"name": "proofTime",
"type": "uint64"
}
],
Expand Down Expand Up @@ -878,6 +891,11 @@
"name": "proofTimeIssued",
"type": "uint64"
},
{
"internalType": "uint64",
"name": "proofTimeTarget",
"type": "uint64"
},
{
"internalType": "uint64",
"name": "lastVerifiedBlockId",
Expand Down Expand Up @@ -962,6 +980,11 @@
"name": "_initBlockFee",
"type": "uint64"
},
{
"internalType": "uint64",
"name": "_initProofTimeTarget",
"type": "uint64"
},
{
"internalType": "uint64",
"name": "_initProofTimeIssued",
Expand Down Expand Up @@ -1028,11 +1051,6 @@
"name": "mixHash",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "depositsRoot",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "txListHash",
Expand All @@ -1058,11 +1076,6 @@
"name": "beneficiary",
"type": "address"
},
{
"internalType": "uint8",
"name": "cacheTxListInfo",
"type": "uint8"
},
{
"internalType": "address",
"name": "treasury",
Expand Down Expand Up @@ -1172,6 +1185,37 @@
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newAddressManager",
"type": "address"
}
],
"name": "setAddressManager",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint64",
"name": "newProofTimeTarget",
"type": "uint64"
},
{
"internalType": "uint64",
"name": "newProofTimeIssued",
"type": "uint64"
}
],
"name": "setProofParams",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "state",
Expand Down Expand Up @@ -1233,7 +1277,7 @@
},
{
"internalType": "uint64",
"name": "__reserved91",
"name": "proofTimeTarget",
"type": "uint64"
}
],
Expand Down
8 changes: 4 additions & 4 deletions packages/eventindexer/abigen.sh
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
#/bin/sh

if [ ! -d "../protocol/artifacts" ]; then
echo "ABI not generated in protocol package yet. Please run npm install && npx hardhat compile in ../protocol"
if [ ! -d "../protocol/out" ]; then
echo "ABI not generated in protocol package yet. Please run npm install && pnpm run compile in ../protocol"
exit 1
fi

paths=("L1/TaikoL1.sol")
paths=("TaikoL1.sol")

names=("TaikoL1")

for (( i = 0; i < ${#paths[@]}; ++i ));
do
jq .abi ../protocol/artifacts/contracts/${paths[i]}/${names[i]}.json > ${names[i]}.json
jq .abi ../protocol/out/${paths[i]}/${names[i]}.json > ${names[i]}.json
lower=$(echo "${names[i]}" | tr '[:upper:]' '[:lower:]')
abigen --abi ${names[i]}.json \
--pkg $lower \
Expand Down
12 changes: 12 additions & 0 deletions packages/eventindexer/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ func Run(
log.Fatal(err)
}

statRepository, err := repo.NewStatRepository(db)
if err != nil {
log.Fatal(err)
}

blockRepository, err := repo.NewBlockRepository(db)
if err != nil {
log.Fatal(err)
Expand Down Expand Up @@ -123,6 +128,7 @@ func Run(
i, err := indexer.NewService(indexer.NewServiceOpts{
EventRepo: eventRepository,
BlockRepo: blockRepository,
StatRepo: statRepository,
EthClient: l1EthClient,
RPCClient: l1RpcClient,
SrcTaikoAddress: common.HexToAddress(os.Getenv("L1_TAIKO_ADDRESS")),
Expand Down Expand Up @@ -233,8 +239,14 @@ func newHTTPServer(db eventindexer.DB, l1EthClient *ethclient.Client) (*http.Ser
return nil, err
}

statRepo, err := repo.NewStatRepository(db)
if err != nil {
return nil, err
}

srv, err := http.NewServer(http.NewServerOpts{
EventRepo: eventRepo,
StatRepo: statRepo,
Echo: echo.New(),
CorsOrigins: strings.Split(os.Getenv("CORS_ORIGINS"), ","),
})
Expand Down
439 changes: 374 additions & 65 deletions packages/eventindexer/contracts/taikol1/TaikoL1.go

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions packages/eventindexer/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import "github.com/cyberhorsey/errors"
var (
ErrNoEthClient = errors.Validation.NewWithKeyAndDetail("ERR_NO_ETH_CLIENT", "EthClient is required")
ErrNoEventRepository = errors.Validation.NewWithKeyAndDetail("ERR_NO_EVENT_REPOSITORY", "EventRepository is required")
ErrNoStatRepository = errors.Validation.NewWithKeyAndDetail("ERR_NO_STAT_REPOSITORY", "StatRepository is required")
ErrNoBlockRepository = errors.Validation.NewWithKeyAndDetail(
"ERR_NO_BLOCK_REPOSITORY",
"BlockRepository is required",
Expand Down
1 change: 1 addition & 0 deletions packages/eventindexer/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
var (
EventNameBlockProven = "BlockProven"
EventNameBlockProposed = "BlockProposed"
EventNameBlockVerified = "BlockVerified"
)

// Event represents a stored EVM event. The fields will be serialized
Expand Down
19 changes: 19 additions & 0 deletions packages/eventindexer/http/get_stats.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package http

import (
"net/http"

"github.com/cyberhorsey/webutils"
"github.com/labstack/echo/v4"
)

func (srv *Server) GetStats(c echo.Context) error {
stats, err := srv.statRepo.Find(
c.Request().Context(),
)
if err != nil {
return webutils.LogAndRenderErrors(c, http.StatusUnprocessableEntity, err)
}

return c.JSON(http.StatusOK, stats)
}
58 changes: 58 additions & 0 deletions packages/eventindexer/http/get_stats_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package http

import (
"context"
"net/http"
"net/http/httptest"
"testing"

"github.com/cyberhorsey/webutils/testutils"
"github.com/labstack/echo/v4"
"github.com/stretchr/testify/assert"
"github.com/taikoxyz/taiko-mono/packages/eventindexer"
)

func Test_GetStats(t *testing.T) {
srv := newTestServer("")

var proofTime uint64 = 5

var proofReward uint64 = 7

_, err := srv.statRepo.Save(context.Background(), eventindexer.SaveStatOpts{
ProofTime: &proofTime,
ProofReward: &proofReward,
})

assert.Equal(t, nil, err)

tests := []struct {
name string
address string
wantStatus int
wantBodyRegexpMatches []string
}{
{
"success",
"0x123",
http.StatusOK,
[]string{`{"id":1,"averageProofTime":5,"averageProofReward":7,"numProofs":1}`},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
req := testutils.NewUnauthenticatedRequest(
echo.GET,
"/stats",
nil,
)

rec := httptest.NewRecorder()

srv.ServeHTTP(rec, req)

testutils.AssertStatusAndBody(t, rec, tt.wantStatus, tt.wantBodyRegexpMatches)
})
}
}
1 change: 1 addition & 0 deletions packages/eventindexer/http/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ func (srv *Server) configureRoutes() {
srv.echo.GET("/uniqueProvers", srv.GetUniqueProvers)
srv.echo.GET("/uniqueProposers", srv.GetUniqueProposers)
srv.echo.GET("/eventByAddress", srv.GetCountByAddressAndEventName)
srv.echo.GET("/stats", srv.GetStats)
}
Loading