Skip to content

Commit 2f6b7b3

Browse files
committed
Sync validator registry
1 parent 8c5e715 commit 2f6b7b3

File tree

15 files changed

+680
-5
lines changed

15 files changed

+680
-5
lines changed

rolling-shutter/go.mod

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ require (
3737
github.com/spf13/cobra v1.6.1
3838
github.com/spf13/pflag v1.0.5
3939
github.com/spf13/viper v1.13.0
40+
github.com/stretchr/testify v1.8.4
41+
github.com/supranational/blst v0.3.11
4042
github.com/tendermint/go-amino v0.16.0
4143
github.com/tendermint/tendermint v0.37.0-rc2
4244
go.opentelemetry.io/otel v1.21.0
@@ -197,6 +199,7 @@ require (
197199
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect
198200
github.com/pelletier/go-toml v1.9.5 // indirect
199201
github.com/petermattis/goid v0.0.0-20230808133559-b036b712a89b // indirect
202+
github.com/pmezard/go-difflib v1.0.0 // indirect
200203
github.com/polydawn/refmt v0.89.0 // indirect
201204
github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 // indirect
202205
github.com/prometheus/common v0.44.0 // indirect
@@ -217,7 +220,6 @@ require (
217220
github.com/spf13/cast v1.5.1 // indirect
218221
github.com/spf13/jwalterweatherman v1.1.0 // indirect
219222
github.com/subosito/gotenv v1.4.2 // indirect
220-
github.com/supranational/blst v0.3.11 // indirect
221223
github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect
222224
github.com/tendermint/tm-db v0.6.7 // indirect
223225
github.com/tklauser/go-sysconf v0.3.12 // indirect

rolling-shutter/keyperimpl/gnosis/config.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@ func (c *Config) Init() {
3838
}
3939

4040
type Config struct {
41-
InstanceID uint64 `shconfig:",required"`
42-
DatabaseURL string `shconfig:",required" comment:"If it's empty, we use the standard PG_ environment variables"`
41+
InstanceID uint64 `shconfig:",required"`
42+
DatabaseURL string `shconfig:",required" comment:"If it's empty, we use the standard PG_ environment variables"`
43+
BeaconAPIURL string `shconfig:",required"`
4344

4445
HTTPEnabled bool
4546
HTTPListenAddress string
@@ -80,6 +81,7 @@ func (c *Config) SetExampleValues() error {
8081
}
8182
c.InstanceID = 42
8283
c.DatabaseURL = "postgres://pguser:pgpassword@localhost:5432/shutter"
84+
c.BeaconAPIURL = "http://localhost:5052"
8385

8486
return nil
8587
}
@@ -151,6 +153,7 @@ type GnosisContractsConfig struct {
151153
KeyBroadcastContract common.Address `shconfig:",required"`
152154
EonKeyPublish common.Address `shconfig:",required"`
153155
Sequencer common.Address `shconfig:",required"`
156+
ValidatorRegistry common.Address `shconfig:",required"`
154157
}
155158

156159
func NewGnosisContractsConfig() *GnosisContractsConfig {
@@ -159,6 +162,7 @@ func NewGnosisContractsConfig() *GnosisContractsConfig {
159162
KeyBroadcastContract: common.Address{},
160163
EonKeyPublish: common.Address{},
161164
Sequencer: common.Address{},
165+
ValidatorRegistry: common.Address{},
162166
}
163167
}
164168

rolling-shutter/keyperimpl/gnosis/database/gnosiskeyper.sqlc.gen.go

Lines changed: 102 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rolling-shutter/keyperimpl/gnosis/database/models.sqlc.gen.go

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rolling-shutter/keyperimpl/gnosis/database/sql/queries/gnosiskeyper.sql

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,34 @@ SELECT * FROM slot_decryption_signatures
7272
WHERE eon = $1 AND slot = $2 AND tx_pointer = $3 AND identities_hash = $4
7373
ORDER BY keyper_index ASC
7474
LIMIT $5;
75+
76+
-- name: InsertValidatorRegistration :exec
77+
INSERT INTO validator_registrations (
78+
block_number,
79+
block_hash,
80+
tx_index,
81+
log_index,
82+
validator_index,
83+
nonce,
84+
is_registration
85+
) VALUES ($1, $2, $3, $4, $5, $6, $7);
86+
87+
-- name: IsValidatorRegistered :one
88+
SELECT is_registration FROM validator_registrations
89+
WHERE validator_index = $1 AND block_number < $1
90+
ORDER BY block_number DESC, tx_index DESC, log_index DESC
91+
LIMIT 1;
92+
93+
-- name: SetValidatorRegistrationsSyncedUntil :exec
94+
INSERT INTO validator_registrations_synced_until (block_hash, block_number) VALUES ($1, $2)
95+
ON CONFLICT (enforce_one_row) DO UPDATE
96+
SET block_hash = $1, block_number = $2;
97+
98+
-- name: GetValidatorRegistrationsSyncedUntil :one
99+
SELECT * FROM validator_registrations_synced_until LIMIT 1;
100+
101+
-- name: GetValidatorRegistrationNonceBefore :one
102+
SELECT nonce FROM validator_registrations
103+
WHERE validator_index = $1 AND block_number <= $2 AND tx_index <= $3 AND log_index <= $4
104+
ORDER BY block_number DESC, tx_index DESC, log_index DESC
105+
LIMIT 1;

rolling-shutter/keyperimpl/gnosis/database/sql/schemas/gnosiskeyper.sql

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,22 @@ CREATE TABLE slot_decryption_signatures(
4848
identities_hash bytea NOT NULL,
4949
signature bytea NOT NULL,
5050
PRIMARY KEY (eon, slot, keyper_index)
51+
);
52+
53+
CREATE TABLE validator_registrations(
54+
block_number bigint NOT NULL CHECK (block_number >= 0),
55+
block_hash bytea NOT NULL,
56+
tx_index bigint NOT NULL CHECK (tx_index >= 0),
57+
log_index bigint NOT NULL CHECK (log_index >= 0),
58+
validator_index bigint NOT NULL CHECK (validator_index >= 0),
59+
nonce bigint NOT NULL CHECK (nonce >= 0),
60+
is_registration bool NOT NULL,
61+
PRIMARY KEY (block_number, tx_index, log_index)
62+
);
63+
CREATE INDEX idx_validator_index ON validator_registrations (validator_index);
64+
65+
CREATE TABLE validator_registrations_synced_until(
66+
enforce_one_row bool PRIMARY KEY DEFAULT true,
67+
block_hash bytea NOT NULL,
68+
block_number bigint NOT NULL CHECK (block_number >= 0)
5169
);

rolling-shutter/keyperimpl/gnosis/keyper.go

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/pkg/errors"
1212
"github.com/rs/zerolog/log"
1313
sequencerBindings "github.com/shutter-network/gnosh-contracts/gnoshcontracts/sequencer"
14+
validatorRegistryBindings "github.com/shutter-network/gnosh-contracts/gnoshcontracts/validatorregistry"
1415
"golang.org/x/exp/slog"
1516

1617
obskeyper "github.com/shutter-network/rolling-shutter/rolling-shutter/chainobserver/db/keyper"
@@ -19,6 +20,7 @@ import (
1920
"github.com/shutter-network/rolling-shutter/rolling-shutter/keyper/epochkghandler"
2021
"github.com/shutter-network/rolling-shutter/rolling-shutter/keyper/kprconfig"
2122
"github.com/shutter-network/rolling-shutter/rolling-shutter/keyperimpl/gnosis/database"
23+
"github.com/shutter-network/rolling-shutter/rolling-shutter/medley/beaconapiclient"
2224
"github.com/shutter-network/rolling-shutter/rolling-shutter/medley/broker"
2325
"github.com/shutter-network/rolling-shutter/rolling-shutter/medley/chainsync"
2426
syncevent "github.com/shutter-network/rolling-shutter/rolling-shutter/medley/chainsync/event"
@@ -45,6 +47,7 @@ type Keyper struct {
4547
client *ethclient.Client
4648
chainSyncClient *chainsync.Client
4749
sequencerSyncer *SequencerSyncer
50+
validatorSyncer *ValidatorSyncer
4851
eonKeyPublisher *eonkeypublisher.EonKeyPublisher
4952
latestTriggeredSlot *uint64
5053

@@ -91,6 +94,32 @@ func (kpr *Keyper) Start(ctx context.Context, runner service.Runner) error {
9194
if err != nil {
9295
return errors.Wrap(err, "failed to connect to database")
9396
}
97+
beaconAPIClient, err := beaconapiclient.New(kpr.config.BeaconAPIURL)
98+
if err != nil {
99+
return errors.Wrap(err, "failed to initialize beacon API client")
100+
}
101+
102+
validatorSyncerClient, err := ethclient.DialContext(ctx, kpr.config.Gnosis.Node.EthereumURL)
103+
if err != nil {
104+
return errors.Wrap(err, "failed to dial ethereum node")
105+
}
106+
chainID, err := validatorSyncerClient.ChainID(ctx)
107+
if err != nil {
108+
return errors.Wrap(err, "failed to get chain ID")
109+
}
110+
validatorRegistryContract, err := validatorRegistryBindings.NewValidatorregistry(
111+
kpr.config.Gnosis.Contracts.ValidatorRegistry,
112+
validatorSyncerClient,
113+
)
114+
if err != nil {
115+
return errors.Wrap(err, "failed to instantiate validator registry contract")
116+
}
117+
kpr.validatorSyncer = &ValidatorSyncer{
118+
Contract: validatorRegistryContract,
119+
DBPool: kpr.dbpool,
120+
BeaconAPIClient: beaconAPIClient,
121+
ChainID: chainID.Uint64(),
122+
}
94123

95124
messageSender, err := p2p.New(kpr.config.P2P)
96125
if err != nil {
@@ -213,8 +242,6 @@ func (kpr *Keyper) ensureSequencerSyncing(ctx context.Context, eon uint64) error
213242
GenesisSlotTimestamp: kpr.config.Gnosis.GenesisSlotTimestamp,
214243
SecondsPerSlot: kpr.config.Gnosis.SecondsPerSlot,
215244
}
216-
217-
// TODO: perform an initial sync without blocking and/or set start block
218245
}
219246

220247
if eon < kpr.sequencerSyncer.StartEon {

rolling-shutter/keyperimpl/gnosis/newblock.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ func (kpr *Keyper) processNewBlock(ctx context.Context, ev *syncevent.LatestBloc
1313
return err
1414
}
1515
}
16+
err := kpr.validatorSyncer.Sync(ctx, ev.Header)
17+
if err != nil {
18+
return err
19+
}
1620
slot := medley.BlockTimestampToSlot(
1721
ev.Header.Time,
1822
kpr.config.Gnosis.GenesisSlotTimestamp,

0 commit comments

Comments
 (0)