Skip to content

Commit

Permalink
Merge pull request #22 from Layr-Labs/sm-stakerSharesPt2
Browse files Browse the repository at this point in the history
Adding support for StakerShares M1/M2 migration
  • Loading branch information
seanmcgary authored Sep 10, 2024
2 parents 84b31f2 + 8277da9 commit 6ed7085
Show file tree
Hide file tree
Showing 12 changed files with 883 additions and 79 deletions.
134 changes: 134 additions & 0 deletions cmd/debugger/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package main

import (
"context"
"fmt"
"github.com/Layr-Labs/go-sidecar/internal/clients/ethereum"
"github.com/Layr-Labs/go-sidecar/internal/clients/etherscan"
"github.com/Layr-Labs/go-sidecar/internal/config"
"github.com/Layr-Labs/go-sidecar/internal/contractManager"
"github.com/Layr-Labs/go-sidecar/internal/contractStore/sqliteContractStore"
"github.com/Layr-Labs/go-sidecar/internal/eigenState/avsOperators"
"github.com/Layr-Labs/go-sidecar/internal/eigenState/operatorShares"
"github.com/Layr-Labs/go-sidecar/internal/eigenState/stakerDelegations"
"github.com/Layr-Labs/go-sidecar/internal/eigenState/stakerShares"
"github.com/Layr-Labs/go-sidecar/internal/eigenState/stateManager"
"github.com/Layr-Labs/go-sidecar/internal/fetcher"
"github.com/Layr-Labs/go-sidecar/internal/indexer"
"github.com/Layr-Labs/go-sidecar/internal/logger"
"github.com/Layr-Labs/go-sidecar/internal/metrics"
"github.com/Layr-Labs/go-sidecar/internal/pipeline"
"github.com/Layr-Labs/go-sidecar/internal/sidecar"
"github.com/Layr-Labs/go-sidecar/internal/sqlite"
"github.com/Layr-Labs/go-sidecar/internal/sqlite/migrations"
sqliteBlockStore "github.com/Layr-Labs/go-sidecar/internal/storage/sqlite"
"go.uber.org/zap"
"log"
)

func main() {
ctx := context.Background()
cfg := config.NewConfig()

fmt.Printf("Config: %+v\n", cfg)

l, _ := logger.NewLogger(&logger.LoggerConfig{Debug: cfg.Debug})

sdc, err := metrics.InitStatsdClient(cfg.StatsdUrl)
if err != nil {
l.Sugar().Fatal("Failed to setup statsd client", zap.Error(err))
}

etherscanClient := etherscan.NewEtherscanClient(cfg, l)
client := ethereum.NewClient(cfg.EthereumRpcConfig.BaseUrl, l)

db := sqlite.NewSqlite(cfg.SqliteConfig.GetSqlitePath())

grm, err := sqlite.NewGormSqliteFromSqlite(db)
if err != nil {
l.Error("Failed to create gorm instance", zap.Error(err))
panic(err)
}

migrator := migrations.NewSqliteMigrator(grm, l)
if err = migrator.MigrateAll(); err != nil {
log.Fatalf("Failed to migrate: %v", err)
}

contractStore := sqliteContractStore.NewSqliteContractStore(grm, l, cfg)
if err := contractStore.InitializeCoreContracts(); err != nil {
log.Fatalf("Failed to initialize core contracts: %v", err)
}

cm := contractManager.NewContractManager(contractStore, etherscanClient, client, sdc, l)

mds := sqliteBlockStore.NewSqliteBlockStore(grm, l, cfg)
if err != nil {
log.Fatalln(err)
}

sm := stateManager.NewEigenStateManager(l, grm)

if _, err := avsOperators.NewAvsOperators(sm, grm, cfg.Network, cfg.Environment, l, cfg); err != nil {
l.Sugar().Fatalw("Failed to create AvsOperatorsModel", zap.Error(err))
}
if _, err := operatorShares.NewOperatorSharesModel(sm, grm, cfg.Network, cfg.Environment, l, cfg); err != nil {
l.Sugar().Fatalw("Failed to create OperatorSharesModel", zap.Error(err))
}
if _, err := stakerDelegations.NewStakerDelegationsModel(sm, grm, cfg.Network, cfg.Environment, l, cfg); err != nil {
l.Sugar().Fatalw("Failed to create StakerDelegationsModel", zap.Error(err))
}
if _, err := stakerShares.NewStakerSharesModel(sm, grm, cfg.Network, cfg.Environment, l, cfg); err != nil {
l.Sugar().Fatalw("Failed to create StakerSharesModel", zap.Error(err))
}

fetchr := fetcher.NewFetcher(client, cfg, l)

idxr := indexer.NewIndexer(mds, contractStore, etherscanClient, cm, client, fetchr, l, cfg)

p := pipeline.NewPipeline(fetchr, idxr, mds, sm, l)

// Create new sidecar instance
sidecar := sidecar.NewSidecar(&sidecar.SidecarConfig{
GenesisBlockNumber: cfg.GetGenesisBlockNumber(),
}, cfg, mds, p, sm, l, client)

// RPC channel to notify the RPC server to shutdown gracefully
rpcChannel := make(chan bool)
err = sidecar.WithRpcServer(ctx, mds, sm, rpcChannel)
if err != nil {
l.Sugar().Fatalw("Failed to start RPC server", zap.Error(err))
}

block, err := fetchr.FetchBlock(ctx, 1215893)
if err != nil {
l.Sugar().Fatalw("Failed to fetch block", zap.Error(err))
}

transactionHash := "0xf6775c38af1d2802bcbc2b7c8959c0d5b48c63a14bfeda0261ba29d76c68c423"
transaction := &ethereum.EthereumTransaction{}

for _, tx := range block.Block.Transactions {
if tx.Hash.Value() == transactionHash {
transaction = tx
break
}
}

logIndex := 4
receipt := block.TxReceipts[transaction.Hash.Value()]
var interestingLog *ethereum.EthereumEventLog

for _, log := range receipt.Logs {
if log.LogIndex.Value() == uint64(logIndex) {
fmt.Printf("Log: %+v\n", log)
interestingLog = log
}
}

decodedLog, err := idxr.DecodeLogWithAbi(nil, receipt, interestingLog)
if err != nil {
l.Sugar().Fatalw("Failed to decode log", zap.Error(err))
}
l.Sugar().Infof("Decoded log: %+v", decodedLog)
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ require (
github.com/klauspost/compress v1.17.9 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-sqlite3 v1.14.22 // indirect
github.com/mattn/go-sqlite3 v1.14.23 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mmcloughlin/addchain v0.4.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/mattn/go-sqlite3 v1.14.23 h1:gbShiuAP1W5j9UOksQ06aiiqPMxYecovVGwmTxWtuw0=
github.com/mattn/go-sqlite3 v1.14.23/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
Expand Down
33 changes: 20 additions & 13 deletions internal/eigenState/operatorShares/operatorShares.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ import (
"github.com/Layr-Labs/go-sidecar/internal/eigenState/stateManager"
"github.com/Layr-Labs/go-sidecar/internal/eigenState/types"
"github.com/Layr-Labs/go-sidecar/internal/storage"
"github.com/Layr-Labs/go-sidecar/internal/types/numbers"
"github.com/Layr-Labs/go-sidecar/internal/utils"
"github.com/holiman/uint256"
"github.com/wealdtech/go-merkletree/v2"
"github.com/wealdtech/go-merkletree/v2/keccak256"
orderedmap "github.com/wk8/go-ordered-map/v2"
"go.uber.org/zap"
"golang.org/x/xerrors"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"math/big"
"slices"
"sort"
"strings"
Expand All @@ -37,14 +38,15 @@ type OperatorShares struct {
type AccumulatedStateChange struct {
Operator string
Strategy string
Shares *uint256.Int
Shares *big.Int
BlockNumber uint64
IsNegative bool
}

type OperatorSharesDiff struct {
Operator string
Strategy string
Shares *uint256.Int
Shares *big.Int
BlockNumber uint64
IsNew bool
}
Expand Down Expand Up @@ -136,21 +138,21 @@ func (osm *OperatorSharesModel) GetStateTransitions() (types.StateTransitions[Ac
operator := strings.ToLower(arguments[0].Value.(string))

sharesStr := outputData.Shares.String()
shares, err := uint256.FromDecimal(sharesStr)
if err != nil {
osm.logger.Sugar().Errorw("Failed to convert shares to uint256",
zap.Error(err),
shares, success := numbers.NewBig257().SetString(sharesStr, 10)
if !success {
osm.logger.Sugar().Errorw("Failed to convert shares to big.Int",
zap.String("shares", sharesStr),
zap.String("transactionHash", log.TransactionHash),
zap.Uint64("transactionIndex", log.TransactionIndex),
zap.Uint64("blockNumber", log.BlockNumber),
)
return nil, xerrors.Errorf("Failed to convert shares to uint256: %s", sharesStr)
return nil, xerrors.Errorf("Failed to convert shares to big.Int: %s", sharesStr)
}

isNegative := false
// All shares are emitted as ABS(shares), so we need to negate the shares if the event is a decrease
if log.EventName == "OperatorSharesDecreased" {
shares = shares.Neg(shares)
isNegative = true
}

slotId := NewSlotId(operator, outputData.Strategy)
Expand All @@ -161,10 +163,15 @@ func (osm *OperatorSharesModel) GetStateTransitions() (types.StateTransitions[Ac
Strategy: outputData.Strategy,
Shares: shares,
BlockNumber: log.BlockNumber,
IsNegative: isNegative,
}
osm.stateAccumulator[log.BlockNumber][slotId] = record
} else {
record.Shares = record.Shares.Add(record.Shares, shares)
if isNegative {
record.Shares = record.Shares.Sub(record.Shares, shares)
} else {
record.Shares = record.Shares.Add(record.Shares, shares)
}
}

return record, nil
Expand Down Expand Up @@ -305,9 +312,9 @@ func (osm *OperatorSharesModel) prepareState(blockNumber uint64) ([]OperatorShar
}

if existingRecord, ok := mappedRecords[slotId]; ok {
existingShares, err := uint256.FromDecimal(existingRecord.Shares)
if err != nil {
osm.logger.Sugar().Errorw("Failed to convert existing shares to uint256", zap.Error(err))
existingShares, success := numbers.NewBig257().SetString(existingRecord.Shares, 10)
if !success {
osm.logger.Sugar().Errorw("Failed to convert existing shares to big.Int")
continue
}
prepared.Shares = existingShares.Add(existingShares, newState.Shares)
Expand Down
40 changes: 38 additions & 2 deletions internal/eigenState/operatorShares/operatorShares_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package operatorShares

import (
"database/sql"
"fmt"
"github.com/Layr-Labs/go-sidecar/internal/config"
"github.com/Layr-Labs/go-sidecar/internal/eigenState/stateManager"
"github.com/Layr-Labs/go-sidecar/internal/logger"
Expand All @@ -13,6 +12,7 @@ import (
"go.uber.org/zap"
"gorm.io/gorm"
"math/big"
"strings"
"testing"
"time"
)
Expand Down Expand Up @@ -129,7 +129,43 @@ func Test_OperatorSharesState(t *testing.T) {

stateRoot, err := model.GenerateStateRoot(blockNumber)
assert.Nil(t, err)
fmt.Printf("StateRoot: %s\n", stateRoot)
assert.True(t, len(stateRoot) > 0)

teardown(model)
})
t.Run("Should handle state transition for operator shares decreased", func(t *testing.T) {
esm := stateManager.NewEigenStateManager(l, grm)
blockNumber := uint64(200)
log := storage.TransactionLog{
TransactionHash: "some hash",
TransactionIndex: big.NewInt(100).Uint64(),
BlockNumber: blockNumber,
Address: cfg.GetContractsMapForEnvAndNetwork().DelegationManager,
Arguments: `[{"Name": "operator", "Type": "address", "Value": "0x32f766cf7BC7dEE7F65573587BECd7AdB2a5CC7f"}, {"Name": "staker", "Type": "address", "Value": ""}, {"Name": "strategy", "Type": "address", "Value": ""}, {"Name": "shares", "Type": "uint256", "Value": ""}]`,
EventName: "OperatorSharesDecreased",
LogIndex: big.NewInt(400).Uint64(),
OutputData: `{"shares": 1670000000000000000000, "staker": "0x32f766cf7bc7dee7f65573587becd7adb2a5cc7f", "strategy": "0x80528d6e9a2babfc766965e0e26d5ab08d9cfaf9"}`,
CreatedAt: time.Time{},
UpdatedAt: time.Time{},
DeletedAt: time.Time{},
}

model, err := NewOperatorSharesModel(esm, grm, cfg.Network, cfg.Environment, l, cfg)
assert.Nil(t, err)

err = model.InitBlockProcessing(blockNumber)
assert.Nil(t, err)

stateChange, err := model.HandleStateChange(&log)
assert.Nil(t, err)
assert.NotNil(t, stateChange)

stateChangeTyped := stateChange.(*AccumulatedStateChange)

assert.Equal(t, "1670000000000000000000", stateChangeTyped.Shares.String())
assert.Equal(t, true, stateChangeTyped.IsNegative)
assert.Equal(t, strings.ToLower("0x32f766cf7BC7dEE7F65573587BECd7AdB2a5CC7f"), stateChangeTyped.Operator)
assert.Equal(t, "0x80528d6e9a2babfc766965e0e26d5ab08d9cfaf9", stateChangeTyped.Strategy)

teardown(model)
})
Expand Down
Loading

0 comments on commit 6ed7085

Please sign in to comment.