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: sync delegations #21

Merged
merged 12 commits into from
Oct 21, 2024
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
2 changes: 1 addition & 1 deletion config/config-local.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
db:
username: root
password: example
address: "mongodb://localhost:27017"
gusin13 marked this conversation as resolved.
Show resolved Hide resolved
address: "mongodb://localhost:27019/?replicaSet=RS&directConnection=true"
db-name: babylon-staking-indexer
btc:
endpoint: localhost:18332
Expand Down
2 changes: 1 addition & 1 deletion contrib/images/babylon-staking-indexer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.21-alpine AS builder
FROM golang:1.22.3-alpine AS builder

ARG VERSION="HEAD"

Expand Down Expand Up @@ -31,13 +31,13 @@
make build

# Final minimal image with binary only
FROM alpine:3.16 as run

Check warning on line 34 in contrib/images/babylon-staking-indexer/Dockerfile

View workflow job for this annotation

GitHub Actions / docker_pipeline / docker_build (linux/amd64, ubuntu-24.04)

The 'as' keyword should match the case of the 'from' keyword

FromAsCasing: 'as' and 'FROM' keywords' casing do not match More info: https://docs.docker.com/go/dockerfile/rule/from-as-casing/

Check warning on line 34 in contrib/images/babylon-staking-indexer/Dockerfile

View workflow job for this annotation

GitHub Actions / docker_pipeline / docker_build (linux/amd64, ubuntu-24.04)

The 'as' keyword should match the case of the 'from' keyword

FromAsCasing: 'as' and 'FROM' keywords' casing do not match More info: https://docs.docker.com/go/dockerfile/rule/from-as-casing/

Check warning on line 34 in contrib/images/babylon-staking-indexer/Dockerfile

View workflow job for this annotation

GitHub Actions / docker_pipeline / docker_build (linux/arm64, ubuntu-24.04-arm64)

The 'as' keyword should match the case of the 'from' keyword

FromAsCasing: 'as' and 'FROM' keywords' casing do not match More info: https://docs.docker.com/go/dockerfile/rule/from-as-casing/

Check warning on line 34 in contrib/images/babylon-staking-indexer/Dockerfile

View workflow job for this annotation

GitHub Actions / docker_pipeline / docker_build (linux/arm64, ubuntu-24.04-arm64)

The 'as' keyword should match the case of the 'from' keyword

FromAsCasing: 'as' and 'FROM' keywords' casing do not match More info: https://docs.docker.com/go/dockerfile/rule/from-as-casing/

RUN addgroup --gid 1138 -S babylon-staking-indexer && adduser --uid 1138 -S babylon-staking-indexer -G babylon-staking-indexer
RUN apk add bash curl jq

# Label should match your github repo
LABEL org.opencontainers.image.source="https://github.com/babylonlabs-io/babylon-staking-indexer:${VERSION}"

Check warning on line 40 in contrib/images/babylon-staking-indexer/Dockerfile

View workflow job for this annotation

GitHub Actions / docker_pipeline / docker_build (linux/amd64, ubuntu-24.04)

Variables should be defined before their use

UndefinedVar: Usage of undefined variable '$VERSION' More info: https://docs.docker.com/go/dockerfile/rule/undefined-var/

Check warning on line 40 in contrib/images/babylon-staking-indexer/Dockerfile

View workflow job for this annotation

GitHub Actions / docker_pipeline / docker_build (linux/amd64, ubuntu-24.04)

Variables should be defined before their use

UndefinedVar: Usage of undefined variable '$VERSION' More info: https://docs.docker.com/go/dockerfile/rule/undefined-var/

Check warning on line 40 in contrib/images/babylon-staking-indexer/Dockerfile

View workflow job for this annotation

GitHub Actions / docker_pipeline / docker_build (linux/arm64, ubuntu-24.04-arm64)

Variables should be defined before their use

UndefinedVar: Usage of undefined variable '$VERSION' More info: https://docs.docker.com/go/dockerfile/rule/undefined-var/

Check warning on line 40 in contrib/images/babylon-staking-indexer/Dockerfile

View workflow job for this annotation

GitHub Actions / docker_pipeline / docker_build (linux/arm64, ubuntu-24.04-arm64)

Variables should be defined before their use

UndefinedVar: Usage of undefined variable '$VERSION' More info: https://docs.docker.com/go/dockerfile/rule/undefined-var/


# Copy over binaries from the build-env
Expand Down
8 changes: 4 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
version: "3.9"
services:
babylon-staking-indexer:
image: babylonlabs/babylon-staking-indexer:latest
image: babylonlabs-io/babylon-staking-indexer:latest
container_name: babylon-staking-indexer
environment:
- CONFIG=/home/babylon-staking-indexer/config.yml
depends_on:
- mongodb
- indexer-mongodb
- rabbitmq
volumes:
- ./config/config-docker.yml:/home/babylon-staking-indexer/config.yml:Z
mongodb:
indexer-mongodb:
image: mongo:latest
container_name: indexer-mongodb
hostname: indexer-mongodb
ports:
- "27017:27017"
- "27019:27017"
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
module github.com/babylonlabs-io/babylon-staking-indexer

go 1.23.2
go 1.22.3

require (
github.com/babylonlabs-io/babylon v0.12.1
github.com/babylonlabs-io/staking-queue-client v0.4.1
github.com/btcsuite/btcd v0.24.2
github.com/cometbft/cometbft v0.38.7
github.com/cosmos/cosmos-sdk v0.50.6
github.com/cosmos/gogoproto v1.7.0
github.com/go-chi/chi/v5 v5.1.0
github.com/spf13/viper v1.19.0
)
Expand Down Expand Up @@ -62,10 +64,8 @@ require (
github.com/cosmos/btcutil v1.0.5 // indirect
github.com/cosmos/cosmos-db v1.0.2 // indirect
github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect
github.com/cosmos/cosmos-sdk v0.50.6 // indirect
github.com/cosmos/go-bip39 v1.0.0 // indirect
github.com/cosmos/gogogateway v1.2.0 // indirect
github.com/cosmos/gogoproto v1.7.0 // indirect
github.com/cosmos/iavl v1.1.2 // indirect
github.com/cosmos/ibc-go/modules/capability v1.0.0 // indirect
github.com/cosmos/ibc-go/v8 v8.3.0 // indirect
Expand Down
79 changes: 79 additions & 0 deletions internal/db/delegation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package db

import (
"context"
"errors"

"github.com/babylonlabs-io/babylon-staking-indexer/internal/db/model"
"github.com/babylonlabs-io/babylon-staking-indexer/internal/types"
"go.mongodb.org/mongo-driver/mongo"
)

func (db *Database) SaveNewBTCDelegation(
ctx context.Context, delegationDoc *model.BTCDelegationDetails,
) error {
_, err := db.client.Database(db.dbName).
Collection(model.BTCDelegationDetailsCollection).
InsertOne(ctx, delegationDoc)
if err != nil {
var writeErr mongo.WriteException
if errors.As(err, &writeErr) {
for _, e := range writeErr.WriteErrors {
if mongo.IsDuplicateKeyError(e) {
return &DuplicateKeyError{
Key: delegationDoc.StakingTxHashHex,
Message: "delegation already exists",
}
}
}
}
return err
}
return nil
}

func (db *Database) UpdateBTCDelegationState(
ctx context.Context, stakingTxHash string, newState types.DelegationState,
) error {
filter := map[string]interface{}{"_id": stakingTxHash}
update := map[string]interface{}{"$set": map[string]string{"state": newState.String()}}

res := db.client.Database(db.dbName).
Collection(model.BTCDelegationDetailsCollection).
FindOneAndUpdate(ctx, filter, update)

if res.Err() != nil {
if errors.Is(res.Err(), mongo.ErrNoDocuments) {
return &NotFoundError{
Key: stakingTxHash,
Message: "BTC delegation not found when updating state",
}
}
return res.Err()
}

return nil
}

func (db *Database) GetBTCDelegationByStakingTxHash(
ctx context.Context, stakingTxHash string,
) (*model.BTCDelegationDetails, error) {
filter := map[string]interface{}{"_id": stakingTxHash}
res := db.client.Database(db.dbName).
Collection(model.BTCDelegationDetailsCollection).
FindOne(ctx, filter)

var delegationDoc model.BTCDelegationDetails
err := res.Decode(&delegationDoc)
if err != nil {
if errors.Is(err, mongo.ErrNoDocuments) {
return nil, &NotFoundError{
Key: stakingTxHash,
Message: "BTC delegation not found when getting by staking tx hash",
}
}
return nil, err
}

return &delegationDoc, nil
}
30 changes: 30 additions & 0 deletions internal/db/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/babylonlabs-io/babylon-staking-indexer/internal/clients/bbnclient"
"github.com/babylonlabs-io/babylon-staking-indexer/internal/db/model"
"github.com/babylonlabs-io/babylon-staking-indexer/internal/types"
)

type DbInterface interface {
Expand Down Expand Up @@ -73,4 +74,33 @@ type DbInterface interface {
SaveCheckpointParams(
ctx context.Context, params *bbnclient.CheckpointParams,
) error
/**
* SaveNewBTCDelegation saves a new BTC delegation to the database.
* If the BTC delegation already exists, DuplicateKeyError will be returned.
* @param ctx The context
* @param delegationDoc The BTC delegation details
* @return An error if the operation failed
*/
SaveNewBTCDelegation(
ctx context.Context, delegationDoc *model.BTCDelegationDetails,
) error
/**
* SaveBTCDelegationStateUpdate saves a BTC delegation state update to the database.
* @param ctx The context
* @param delegationDoc The BTC delegation details
* @return An error if the operation failed
*/
UpdateBTCDelegationState(
ctx context.Context, stakingTxHash string, newState types.DelegationState,
) error
/**
* GetBTCDelegationByStakingTxHash retrieves the BTC delegation details by the staking tx hash.
* If the BTC delegation does not exist, a NotFoundError will be returned.
* @param ctx The context
* @param stakingTxHash The staking tx hash
* @return The BTC delegation details or an error
*/
GetBTCDelegationByStakingTxHash(
ctx context.Context, stakingTxHash string,
) (*model.BTCDelegationDetails, error)
}
31 changes: 27 additions & 4 deletions internal/db/model/delegation.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,33 @@ package model

import (
"github.com/babylonlabs-io/babylon-staking-indexer/internal/types"
bbntypes "github.com/babylonlabs-io/babylon/x/btcstaking/types"
)

type DelegationDocument struct {
StakingTxHashHex string `bson:"_id"` // Primary key
State types.DelegationState `bson:"state"`
// TODO: Placeholder for more fields
type BTCDelegationDetails struct {
StakingTxHashHex string `bson:"_id"` // Primary key
ParamsVersion string `bson:"params_version"`
FinalityProviderBtcPksHex []string `bson:"finality_provider_btc_pks_hex"`
StakerBtcPkHex string `bson:"staker_btc_pk_hex"`
StakingTime string `bson:"staking_time"`
StakingAmount string `bson:"staking_amount"`
UnbondingTime string `bson:"unbonding_time"`
UnbondingTx string `bson:"unbonding_tx"`
State types.DelegationState `bson:"state"`
}

func FromEventBTCDelegationCreated(
event *bbntypes.EventBTCDelegationCreated,
) *BTCDelegationDetails {
return &BTCDelegationDetails{
StakingTxHashHex: event.StakingTxHash, // babylon returns a hex string
ParamsVersion: event.ParamsVersion,
FinalityProviderBtcPksHex: event.FinalityProviderBtcPksHex,
StakerBtcPkHex: event.StakerBtcPkHex,
StakingTime: event.StakingTime,
StakingAmount: event.StakingAmount,
UnbondingTime: event.UnbondingTime,
UnbondingTx: event.UnbondingTx,
State: types.DelegationState(event.NewState),
}
}
4 changes: 2 additions & 2 deletions internal/db/model/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (

const (
FinalityProviderDetailsCollection = "finality_provider_details"
DelegationCollection = "delegation"
BTCDelegationDetailsCollection = "btc_delegation_details"
GlobalParamsCollection = "global_params"
)

Expand All @@ -26,7 +26,7 @@ type index struct {

var collections = map[string][]index{
FinalityProviderDetailsCollection: {{Indexes: map[string]int{}}},
DelegationCollection: {{Indexes: map[string]int{}}},
BTCDelegationDetailsCollection: {{Indexes: map[string]int{}}},
GlobalParamsCollection: {{Indexes: map[string]int{}}},
}

Expand Down
1 change: 1 addition & 0 deletions internal/db/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,6 @@ func (db *Database) SaveCheckpointParams(
if err != nil {
return fmt.Errorf("failed to save checkpoint params: %w", err)
}

return nil
}
Loading