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

Add unit-test for chainsync reorg capabilities #440

Open
wants to merge 91 commits into
base: feat/optimism
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
930bbe1
feat: add gnosiskeyper command
jannikluhn Jan 22, 2024
9879b8d
Fix linting error
jannikluhn Jan 31, 2024
f8f8b91
chore(op): add initial op-shutter keyper
ezdac Dec 1, 2023
01cf53c
chore(op): fix chain init
ezdac Dec 4, 2023
f3a9e4e
chore(op): add initial sync client
ezdac Dec 6, 2023
1044380
chore(op): allow private repo fetching in Dockerfile
ezdac Dec 6, 2023
a7f37b2
fix(op): use correct database defintion for optimism keyper
ezdac Dec 7, 2023
a384cbd
feat(op): add bootstrap command
ezdac Dec 11, 2023
6d1c20d
chore(op): bump shop-contracts version
ezdac Dec 12, 2023
0751cf4
chore(op): insert TM keyperset in database
ezdac Dec 21, 2023
6d63d88
fix(op): append unsafe head service to l2client services
ezdac Dec 22, 2023
59060e5
fix: chain init and tendermint config option
ezdac Dec 21, 2023
a60999c
chore: update dependencies
ezdac Jan 3, 2024
e4a5f7d
fix(op): missing assignment to optimism-keyper field
ezdac Jan 3, 2024
7616a5e
chore(op): remove lib shadow
ezdac Jan 4, 2024
82e9b15
feat(op): allow to retrieve keyperset by index for op-bootstrap
ezdac Jan 5, 2024
4a63d52
chore(op): improve sync client
ezdac Jan 10, 2024
8cd3b1a
chore(p2p): use fallback defaults from lib
ezdac Jan 22, 2024
0905f13
fix(p2p): bootstrap context
ezdac Jan 22, 2024
8f00e9e
fix(op): nil-deref in pubkey syncer
ezdac Jan 22, 2024
552f781
feat(op): added AtBlockNumber to events
ezdac Jan 24, 2024
f361ac8
chore(op): add uint64 converter to block-number
ezdac Jan 24, 2024
e991ab5
fix(op): 'latest' RPC call-opt always fixed to concrete number
ezdac Jan 30, 2024
5865514
chore(op): remove private repo access for dockerfile
ezdac Jan 30, 2024
72bf764
chore!: move syncer to medley
ezdac Jan 30, 2024
f0a0a8b
chore: satisfy linter
ezdac Jan 30, 2024
4a8c206
fix: runner defer executed too early
ezdac Jan 31, 2024
4136f93
chore!: refactor ServiceFn and pass runner
ezdac Jan 31, 2024
631ca13
fix: P2P integration test
ezdac Jan 31, 2024
249876f
chore!: add arg to retry.ExponentialBackoff option
ezdac Jan 31, 2024
c37dacd
chore: remove old documentation
ezdac Jan 31, 2024
715ff9a
chore: update pre-commit dependencies
ezdac Jan 31, 2024
d8143b6
chore: update pre-commit version
ezdac Jan 31, 2024
3948370
Monitor main chain in gnosis keyper
jannikluhn Feb 5, 2024
c22cfda
Send trigger at each block
jannikluhn Jan 29, 2024
c63b310
Implement sequencer syncer
jannikluhn Feb 7, 2024
1178aab
Store tx_pointer in db
jannikluhn Feb 8, 2024
1b73c2a
Store index of transaction submitted events
jannikluhn Feb 8, 2024
d736f49
Trigger key generation according to tx pointer
jannikluhn Feb 12, 2024
f00c663
Ensure encrypted gas limit is not exceeded
jannikluhn Feb 13, 2024
2d19961
Add extra data field to messages
jannikluhn Feb 12, 2024
d92c56d
Support multiple handlers for single topic
jannikluhn Feb 13, 2024
e17e466
Intercept outgoing messages
jannikluhn Feb 14, 2024
e389bbd
Fix typo in log message
jannikluhn Feb 16, 2024
3a426c3
Allow inserting the same share multiple times
jannikluhn Feb 16, 2024
0bd3f2f
Extend gnosis keyper tables
jannikluhn Feb 16, 2024
57df4d8
Fix tx trigger updating
jannikluhn Feb 16, 2024
0808f14
Integrate gnosis message interceptors and handlers
jannikluhn Feb 16, 2024
bffe04e
Fix block identity preimage
jannikluhn Feb 16, 2024
8ca5f26
Implement gnosis message handlers and interceptors
jannikluhn Feb 16, 2024
598c4a2
Implement slot decryption signatures
jannikluhn Feb 16, 2024
ca87e05
Add basic watcher command
jannikluhn Feb 17, 2024
4b5f240
Show latency
jannikluhn Feb 17, 2024
11c4ae6
Use DHT to find peers
jannikluhn Mar 14, 2024
4b160de
Trigger decryption based on slots not blocks
jannikluhn Mar 28, 2024
db250a4
Trigger in new slots instead of blocks
jannikluhn Apr 4, 2024
aa66bfc
Simplify message validation function
jannikluhn Apr 4, 2024
14961a1
Add Gnosis config section
jannikluhn Apr 4, 2024
a50cc4f
Publish eon keys via publisher contract
jannikluhn Apr 7, 2024
21311d0
Publish eon keys from db on startup
jannikluhn Apr 8, 2024
7812fcb
Improve log messages
jannikluhn Apr 9, 2024
4e536e5
Update shcrypto
jannikluhn Apr 24, 2024
ad464c7
Trigger decryption based on blocks and slots
jannikluhn Apr 26, 2024
8c5e715
Replace eon with keyper set index in shares msg
jannikluhn Apr 26, 2024
2f6b7b3
Sync validator registry
jannikluhn May 7, 2024
7cc9556
Only generate keys for registered proposers
jannikluhn May 7, 2024
53dcd36
Fix slot decryption signature computation
jannikluhn May 14, 2024
c3ef527
Update tx pointer age on skipped slots
jannikluhn May 19, 2024
cef8e4d
Fix eon column in tx pointer table
jannikluhn May 19, 2024
dcc826b
Fix is proposer check
jannikluhn May 19, 2024
39fd356
Improve logs
jannikluhn May 19, 2024
5c981ef
Fix slot identity preimage
jannikluhn May 19, 2024
ca187b3
Improve contract syncing
jannikluhn May 19, 2024
7ad00c2
Fix validator API request
jannikluhn May 19, 2024
f0fa129
Fix lint errors
jannikluhn May 19, 2024
d99963c
Ignore missing row error
jannikluhn May 20, 2024
6914783
Fix eon/keyper config index mixup
jannikluhn May 20, 2024
2f059d7
Use correct key for dkg result
jannikluhn May 20, 2024
8889ed9
Query decryption key shares by keyper config index
jannikluhn May 20, 2024
912e468
Use 52 byte epoch ids in JSON tests
jannikluhn May 20, 2024
ee9d7a6
Do not consider eon in sequencer syncer
jannikluhn May 20, 2024
07ceb38
Sort identity preimages in messages
jannikluhn May 22, 2024
d9d079e
Enable validator registration signature check
jannikluhn May 22, 2024
acb6f1b
chore(op): add initial op-shutter keyper
ezdac May 10, 2024
2c8842e
feat(chainsync): sync contract event handler with latest head
ezdac May 10, 2024
d44c6bd
fix(op): one-off error in decryption-trigger on new block
ezdac May 10, 2024
74d780f
feat(chainsync): allow not fetching past active events
ezdac May 10, 2024
65dcfe7
feat: consider reorgs in chainsync
ezdac May 10, 2024
cdb0a9e
fix(chainsync): sync all blocks from start to latest head
ezdac May 10, 2024
b1a10bd
chore(chainsync): add unit test for reorgs
ezdac May 10, 2024
80f095d
fix: lint
ezdac May 31, 2024
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
8 changes: 4 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ repos:
require_serial: true

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v4.5.0
hooks:
- id: check-added-large-files
args: ["--maxkb=1000"]
Expand All @@ -33,7 +33,7 @@ repos:
- id: trailing-whitespace

- repo: https://github.com/pre-commit/mirrors-prettier
rev: v3.0.1
rev: v3.1.0
hooks:
- id: prettier
additional_dependencies:
Expand All @@ -59,12 +59,12 @@ repos:
]

- repo: https://github.com/pre-commit/mirrors-eslint
rev: "v8.4.1"
rev: "v8.56.0"
hooks:
- id: eslint

- repo: https://github.com/shutter-network/pre-commit-go-hooks
rev: "7a66f5523b34139615a0c95f2b8a441dbc1778dc"
rev: "53239641ec106cda9a7acf9150c98be8d5ffa1ec"
hooks:
- id: shfmt
args: ["-i", "4"]
Expand Down
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ golangci-lint 1.55.2
java temurin-17.0.5+8
nodejs 18.17.0
postgres 14.2
pre-commit 3.3.3
pre-commit 3.6.0
protoc 22.3
shfmt 3.7.0
solidity 0.8.9
Expand Down
26 changes: 26 additions & 0 deletions docker/build-src/optimism/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
FROM golang:1.21 as builder
ENV GOMODCACHE=/root/.cache/mod

# Fetch go modules separately to improve cache usage
RUN mkdir /gomod
COPY /rolling-shutter/go.* /gomod/
WORKDIR /gomod
RUN --mount=type=cache,target=/root/.cache go mod download

# Build binary
COPY / /src
WORKDIR /src/rolling-shutter


RUN go env
RUN --mount=type=cache,target=/root/.cache CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GOFLAGS=-v make build

FROM scratch as runner

COPY --from=builder /src/rolling-shutter/bin/rolling-shutter /rolling-shutter

# Use 'uclibc' flavor to avoid https://github.com/docker-library/busybox/issues/155#issuecomment-1344375664
RUN --mount=from=busybox:uclibc,src=/bin,dst=/bin mkdir -p /etc/ssl
COPY --from=builder /etc/ssl/certs /etc/ssl/certs

ENTRYPOINT ["/rolling-shutter"]
1 change: 0 additions & 1 deletion rolling-shutter/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,6 @@ func (ShutterApp) decodeTx(tx []byte) (signer common.Address, msg *shmsg.Message
}

msg, err = shmsg.GetMessage(signedMsg)

if err != nil {
return
}
Expand Down
11 changes: 7 additions & 4 deletions rolling-shutter/app/messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"math/big"

"github.com/ethereum/go-ethereum/common"
bn256 "github.com/ethereum/go-ethereum/crypto/bn256/cloudflare"
"github.com/ethereum/go-ethereum/crypto/bls12381"
"github.com/pkg/errors"

"github.com/shutter-network/shutter/shlib/shcrypto"
Expand Down Expand Up @@ -54,14 +54,17 @@ func ParsePolyEvalMsg(msg *shmsg.PolyEval, sender common.Address) (*PolyEval, er

// ParsePolyCommitmentMsg converts a shmsg.PolyCommitmentMsg to an app.PolyCommitmentMsg.
func ParsePolyCommitmentMsg(msg *shmsg.PolyCommitment, sender common.Address) (*PolyCommitment, error) {
g2 := bls12381.NewG2()
gammas := shcrypto.Gammas{}
for _, g := range msg.Gammas {
g2 := new(bn256.G2)
_, err := g2.Unmarshal(g)
p, err := g2.FromBytes(g)
if err != nil {
return nil, err
}
gammas = append(gammas, g2)
if !g2.IsOnCurve(p) {
return nil, errors.Errorf("invalid gamma value %x", g)
}
gammas = append(gammas, p)
}
return &PolyCommitment{
Sender: sender,
Expand Down
51 changes: 51 additions & 0 deletions rolling-shutter/chainobserver/db/keyper/extend.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package database

import (
"github.com/ethereum/go-ethereum/common"
"github.com/pkg/errors"

"github.com/shutter-network/rolling-shutter/rolling-shutter/shdb"
)

// GetIndex returns the index of the given address in the KeyperSet.
func (s *KeyperSet) GetIndex(address common.Address) (uint64, error) {
encodedAddress := shdb.EncodeAddress(address)
for i, m := range s.Keypers {
if m == encodedAddress {
return uint64(i), nil
}
}
return 0, errors.Errorf("keyper %s not found", address.String())
}

// Contains checks if the given address is present in the KeyperSet.
// It returns true if the address is found, otherwise false.
func (s *KeyperSet) Contains(address common.Address) bool {
encodedAddress := shdb.EncodeAddress(address)
for _, m := range s.Keypers {
if m == encodedAddress {
return true
}
}
return false
}

// GetSubset returns a subset of addresses from the KeyperSet based on the given indices.
// The return value is ordered according to the order of the given indices. If indices contains
// duplicates, the return value will do so as well. If at least one of the given indices is out of
// range, an error is returned.
func (s *KeyperSet) GetSubset(indices []uint64) ([]common.Address, error) {
subset := []common.Address{}
for _, i := range indices {
if i >= uint64(len(s.Keypers)) {
return nil, errors.Errorf("keyper index %d out of range (size %d)", i, len(s.Keypers))
}
addressStr := s.Keypers[i]
address, err := shdb.DecodeAddress(addressStr)
if err != nil {
return nil, err
}
subset = append(subset, address)
}
return subset, nil
}
75 changes: 75 additions & 0 deletions rolling-shutter/chainobserver/db/keyper/extend_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package database

import (
"testing"

"github.com/ethereum/go-ethereum/common"
"gotest.tools/v3/assert"

"github.com/shutter-network/rolling-shutter/rolling-shutter/shdb"
)

func makeTestKeyperSet() KeyperSet {
return KeyperSet{
KeyperConfigIndex: 0,
ActivationBlockNumber: 0,
Keypers: []string{
shdb.EncodeAddress(common.HexToAddress("0x0000000000000000000000000000000000000000")),
shdb.EncodeAddress(common.HexToAddress("0x5555555555555555555555555555555555555555")),
shdb.EncodeAddress(common.HexToAddress("0xaAaAaAaaAaAaAaaAaAAAAAAAAaaaAaAaAaaAaaAa")),
},
Threshold: 2,
}
}

func TestKeyperSetGetIndex(t *testing.T) {
keyperSet := makeTestKeyperSet()
addresses, err := shdb.DecodeAddresses(keyperSet.Keypers)
assert.NilError(t, err)

for i, address := range addresses {
index, err := keyperSet.GetIndex(address)
assert.NilError(t, err)
assert.Equal(t, uint64(i), index)
}
_, err = keyperSet.GetIndex(common.HexToAddress("0xffffffffffffffffffffffffffffffffffffffff"))
assert.ErrorContains(t, err, "keyper 0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF not found")
}

func TestKeyperSetContains(t *testing.T) {
keyperSet := makeTestKeyperSet()
addresses, err := shdb.DecodeAddresses(keyperSet.Keypers)
assert.NilError(t, err)

for _, address := range addresses {
assert.Assert(t, keyperSet.Contains(address))
}
assert.Assert(t, !keyperSet.Contains(common.HexToAddress("0xffffffffffffffffffffffffffffffffffffffff")))
}

func TestKeyperSetSubset(t *testing.T) {
keyperSet := makeTestKeyperSet()
testCases := []struct {
indices []uint64
valid bool
}{
{indices: []uint64{0, 1, 2}, valid: true},
{indices: []uint64{}, valid: true},
{indices: []uint64{1, 0}, valid: true},
{indices: []uint64{0, 0}, valid: true},
{indices: []uint64{0, 0, 0, 0}, valid: true},
{indices: []uint64{3}, valid: false},
}

for _, tc := range testCases {
subset, err := keyperSet.GetSubset(tc.indices)
if tc.valid {
assert.Assert(t, len(subset) == len(tc.indices))
for _, i := range tc.indices {
assert.Assert(t, shdb.EncodeAddress(subset[i]) == keyperSet.Keypers[tc.indices[i]])
}
} else {
assert.Assert(t, err != nil)
}
}
}
30 changes: 30 additions & 0 deletions rolling-shutter/chainobserver/db/keyper/keyper.sqlc.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,7 @@ SELECT * FROM keyper_set WHERE keyper_config_index=$1;
SELECT * FROM keyper_set
WHERE activation_block_number <= $1
ORDER BY activation_block_number DESC LIMIT 1;

-- name: GetKeyperSets :many
SELECT * FROM keyper_set
ORDER BY activation_block_number ASC;
4 changes: 2 additions & 2 deletions rolling-shutter/chainobserver/observer.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func (c *ChainObserver) Start(ctx context.Context, runner service.Runner) error
log.Info().Uint64("from-block", fromBlock).Uint64("from-log-index", fromLogIndex).
Msg("starting event syncing")
syncer := eventsyncer.New(c.Client, finalityOffset, eventTypes, fromBlock, fromLogIndex)
handleSyncLoop := func(ctx context.Context) error {
handleSyncLoop := func(ctx context.Context, _ service.Runner) error {
for {
select {
case <-ctx.Done():
Expand All @@ -102,5 +102,5 @@ func (c *ChainObserver) Start(ctx context.Context, runner service.Runner) error
}
}
}
return runner.StartService(syncer, service.ServiceFn{Fn: handleSyncLoop})
return runner.StartService(syncer, service.Function{Func: handleSyncLoop})
}
4 changes: 4 additions & 0 deletions rolling-shutter/cmd/bootstrap/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ chain's genesis config.`,
return cmd
}

// TODO: deprecate this command and split this up in 2 stages:
// 1. gather initial keyperset information e.g. from contracts
// (could be different from optimism, rollupshutter,snapshot)
// 2. send the batch-config / new block seen message based on that info.
func bootstrap(config *Config) error {
ctx := context.Background()
ethereumClient, err := ethclient.DialContext(ctx, config.EthereumURL)
Expand Down
Loading