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

Fix/deleting challenges #33

Merged
merged 6 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
10 changes: 6 additions & 4 deletions challenger/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@ To configure the Challenger, fill in the values in the `~/.opinit/challenger.jso
"bech32_prefix": "init",
"rpc_address": "tcp://localhost:27657",
},
// L1StartHeight is the height to start the l1 node. If it is 0, it will finds the optimal height and sets it automatically.
// However, if you do not want to use this feature, set it to a non-zero value.
// There is no need for modification under normal circumstances, because it
// is automatically determined when you set the l2 start height,
// DisableAutoSetL1Height is the flag to disable the automatic setting of the l1 height.
// If it is false, it will finds the optimal height and sets l1_start_height automatically
// from l2 start height and l1_start_height is ignored.
// It can be useful when you don't want to use TxSearch.
"disable_auto_set_l1_height": false,
// L1StartHeight is the height to start the l1 node.
"l1_start_height": 0,
// L2StartHeight is the height to start the l2 node. If it is 0, it will start from the latest height.
// If the latest height stored in the db is not 0, this config is ignored.
Expand Down
32 changes: 25 additions & 7 deletions challenger/challenger.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"strconv"
"sync"
"time"

"github.com/pkg/errors"

Expand Down Expand Up @@ -101,14 +102,29 @@ func (c *Challenger) Initialize(ctx context.Context) error {
return err
}

err = c.host.Initialize(ctx, hostProcessedHeight, c.child, bridgeInfo, c)
var initialBlockTime time.Time
hostInitialBlockTime, err := c.host.Initialize(ctx, hostProcessedHeight, c.child, bridgeInfo, c)
if err != nil {
return err
}
err = c.child.Initialize(ctx, childProcessedHeight, processedOutputIndex+1, c.host, bridgeInfo, c)
if initialBlockTime.Before(hostInitialBlockTime) {
initialBlockTime = hostInitialBlockTime
}

childInitialBlockTime, err := c.child.Initialize(ctx, childProcessedHeight, processedOutputIndex+1, c.host, bridgeInfo, c)
if err != nil {
return err
}
if initialBlockTime.Before(childInitialBlockTime) {
initialBlockTime = childInitialBlockTime
}
if !initialBlockTime.IsZero() {
err := c.DeleteFutureChallenges(initialBlockTime)
if err != nil {
return err
}
}

beer-1 marked this conversation as resolved.
Show resolved Hide resolved
c.RegisterQuerier()

c.pendingChallenges, err = c.loadPendingChallenges()
Expand Down Expand Up @@ -206,7 +222,9 @@ func (c *Challenger) getProcessedHeights(ctx context.Context, bridgeId uint64) (
}
}

if c.cfg.L1StartHeight == 0 {
if c.cfg.DisableAutoSetL1Height {
l1ProcessedHeight = c.cfg.L1StartHeight
} else {
// get the bridge start height from the host
l1ProcessedHeight, err = c.host.QueryCreateBridgeHeight(ctx, bridgeId)
if err != nil {
Expand All @@ -233,14 +251,14 @@ func (c *Challenger) getProcessedHeights(ctx context.Context, bridgeId uint64) (
if depositTxHeight > l1ProcessedHeight {
l1ProcessedHeight = depositTxHeight
}
if outputL1BlockNumber < l1ProcessedHeight {
if outputL1BlockNumber != 0 && outputL1BlockNumber < l1ProcessedHeight {
l1ProcessedHeight = outputL1BlockNumber
}
}
} else {
l1ProcessedHeight = c.cfg.L1StartHeight
}
l1ProcessedHeight--
if l1ProcessedHeight > 0 {
l1ProcessedHeight--
}

return l1ProcessedHeight, l2ProcessedHeight, processedOutputIndex, err
}
16 changes: 12 additions & 4 deletions challenger/child/child.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,28 @@ func NewChildV1(
}
}

func (ch *Child) Initialize(ctx context.Context, processedHeight int64, startOutputIndex uint64, host hostNode, bridgeInfo opchildtypes.BridgeInfo, challenger challenger) error {
func (ch *Child) Initialize(ctx context.Context, processedHeight int64, startOutputIndex uint64, host hostNode, bridgeInfo opchildtypes.BridgeInfo, challenger challenger) (time.Time, error) {
_, err := ch.BaseChild.Initialize(ctx, processedHeight, startOutputIndex, bridgeInfo)
if err != nil {
return err
return time.Time{}, err
}
ch.host = host
ch.challenger = challenger
ch.registerHandlers()

err = ch.eventHandler.Initialize(bridgeInfo.BridgeConfig.SubmissionInterval)
if err != nil {
return err
return time.Time{}, err
}
return nil

var blockTime time.Time
if ch.Node().HeightInitialized() {
blockTime, err = ch.Node().QueryBlockTime(ctx, ch.Node().GetHeight())
if err != nil {
return time.Time{}, err
}
}
return blockTime, nil
}

func (ch *Child) registerHandlers() {
Expand Down
89 changes: 81 additions & 8 deletions challenger/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package challenger
import (
"fmt"
"slices"
"time"

challengertypes "github.com/initia-labs/opinit-bots/challenger/types"
"github.com/initia-labs/opinit-bots/node"
Expand Down Expand Up @@ -84,17 +85,43 @@ func (c *Challenger) loadChallenges() (challenges []challengertypes.Challenge, e
return
}

func (c *Challenger) DeleteFutureChallenges(initialBlockTime time.Time) error {
deletingKeys := make([][]byte, 0)
iterErr := c.db.PrefixedReverseIterate(challengertypes.ChallengeKey, func(key []byte, _ []byte) (stop bool, err error) {
ts, _, err := challengertypes.ParseChallenge(key)
if err != nil {
return true, err
}
if !ts.After(initialBlockTime) {
return true, nil
}

deletingKeys = append(deletingKeys, key)
return false, nil
})
if iterErr != nil {
return iterErr
}

for _, key := range deletingKeys {
err := c.db.Delete(key)
if err != nil {
return err
}
}
return nil
}

func ResetHeights(db types.DB) error {
dbs := []types.DB{
db.WithPrefix([]byte(types.HostName)),
db.WithPrefix([]byte(types.ChildName)),
dbNames := []string{
types.HostName,
types.ChildName,
}

for _, db := range dbs {
if err := node.DeleteSyncInfo(db); err != nil {
for _, dbName := range dbNames {
if err := ResetHeight(db, dbName); err != nil {
return err
}
fmt.Printf("reset height to 0 for node %s\n", string(db.GetPrefix()))
}
return nil
}
Expand All @@ -105,10 +132,56 @@ func ResetHeight(db types.DB, nodeName string) error {
return errors.New("unknown node name")
}
nodeDB := db.WithPrefix([]byte(nodeName))
err := node.DeleteSyncInfo(nodeDB)
if err != nil {

if err := DeletePendingEvents(db); err != nil {
return err
}

if err := DeletePendingChallenges(db); err != nil {
return err
}

beer-1 marked this conversation as resolved.
Show resolved Hide resolved
if err := node.DeleteSyncInfo(nodeDB); err != nil {
return err
}
fmt.Printf("reset height to 0 for node %s\n", string(nodeDB.GetPrefix()))
return nil
}

func DeletePendingEvents(db types.DB) error {
deletingKeys := make([][]byte, 0)
iterErr := db.PrefixedIterate(challengertypes.PendingEventKey, func(key []byte, _ []byte) (stop bool, err error) {
deletingKeys = append(deletingKeys, key)
return false, nil
})
if iterErr != nil {
return iterErr
}

for _, key := range deletingKeys {
err := db.Delete(key)
if err != nil {
return err
}
}
return nil
}

func DeletePendingChallenges(db types.DB) error {
deletingKeys := make([][]byte, 0)
iterErr := db.PrefixedIterate(challengertypes.PendingChallengeKey, func(key []byte, _ []byte) (stop bool, err error) {
deletingKeys = append(deletingKeys, key)
return false, nil
})
if iterErr != nil {
return iterErr
}

for _, key := range deletingKeys {
err := db.Delete(key)
if err != nil {
return err
}
}
return nil
}
beer-1 marked this conversation as resolved.
Show resolved Hide resolved
16 changes: 12 additions & 4 deletions challenger/host/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ func NewHostV1(
}
}

func (h *Host) Initialize(ctx context.Context, processedHeight int64, child childNode, bridgeInfo opchildtypes.BridgeInfo, challenger challenger) error {
func (h *Host) Initialize(ctx context.Context, processedHeight int64, child childNode, bridgeInfo opchildtypes.BridgeInfo, challenger challenger) (time.Time, error) {
err := h.BaseHost.Initialize(ctx, processedHeight, bridgeInfo)
if err != nil {
return err
return time.Time{}, err
}
h.child = child
h.challenger = challenger
Expand All @@ -67,9 +67,17 @@ func (h *Host) Initialize(ctx context.Context, processedHeight int64, child chil

err = h.eventHandler.Initialize(bridgeInfo.BridgeConfig.SubmissionInterval)
if err != nil {
return err
return time.Time{}, err
}
return nil

var blockTime time.Time
if h.Node().HeightInitialized() {
blockTime, err = h.Node().QueryBlockTime(ctx, h.Node().GetHeight())
if err != nil {
return time.Time{}, err
}
}
return blockTime, nil
beer-1 marked this conversation as resolved.
Show resolved Hide resolved
}

func (h *Host) registerHandlers() {
Expand Down
15 changes: 9 additions & 6 deletions challenger/types/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@ type Config struct {
// L2Node is the configuration for the l2 node.
L2Node NodeConfig `json:"l2_node"`

// L1StartHeight is the height to start the l1 node. If it is 0, it will finds the optimal height and sets it automatically.
// However, if you do not want to use this feature, set it to a non-zero value.
// There is no need for modification under normal circumstances, because it
// is automatically determined when you set the l2 start height,
// DisableAutoSetL1Height is the flag to disable the automatic setting of the l1 height.
// If it is false, it will finds the optimal height and sets l1_start_height automatically
// from l2 start height and l1_start_height is ignored.
// It can be useful when you don't want to use TxSearch.
DisableAutoSetL1Height bool `json:"disable_auto_set_l1_height"`
// L1StartHeight is the height to start the l1 node.
L1StartHeight int64 `json:"l1_start_height"`
// L2StartHeight is the height to start the l2 node. If it is 0, it will start from the latest height.
// If the latest height stored in the db is not 0, this config is ignored.
Expand All @@ -65,8 +67,9 @@ func DefaultConfig() *Config {
Bech32Prefix: "init",
RPCAddress: "tcp://localhost:27657",
},
L1StartHeight: 0,
L2StartHeight: 0,
DisableAutoSetL1Height: false,
L1StartHeight: 0,
L2StartHeight: 0,
}
}

Expand Down
25 changes: 20 additions & 5 deletions challenger/types/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,18 @@ func PrefixedPendingChallenge(id ChallengeId) []byte {
PrefixedEventTypeId(id.Type, id.Id)...)
}

func PrefixedTimeEventTypeId(eventTime time.Time, id ChallengeId) []byte {
return append(append(dbtypes.FromUint64Key(types.MustInt64ToUint64(eventTime.UnixNano())), dbtypes.Splitter),
PrefixedEventTypeId(id.Type, id.Id)...)
func PrefixedTimeEvent(eventTime time.Time) []byte {
return append(dbtypes.FromUint64Key(types.MustInt64ToUint64(eventTime.UnixNano())), dbtypes.Splitter)
}

func PrefixedChallenge(eventTime time.Time, id ChallengeId) []byte {
func PrefixedChallengeEventTime(eventTime time.Time) []byte {
return append(append(ChallengeKey, dbtypes.Splitter),
PrefixedTimeEventTypeId(eventTime, id)...)
PrefixedTimeEvent(eventTime)...)
}

func PrefixedChallenge(eventTime time.Time, id ChallengeId) []byte {
return append(PrefixedChallengeEventTime(eventTime),
PrefixedEventTypeId(id.Type, id.Id)...)
}

func ParsePendingEvent(key []byte) (ChallengeId, error) {
Expand All @@ -53,3 +57,14 @@ func ParsePendingEvent(key []byte) (ChallengeId, error) {
idBz := key[len(key)-8:]
return ChallengeId{Type: EventType(typeBz[0]), Id: dbtypes.ToUint64Key(idBz)}, nil
}

func ParseChallenge(key []byte) (time.Time, ChallengeId, error) {
if len(key) < 19 {
return time.Time{}, ChallengeId{}, errors.New("invalid key bytes")
}

timeBz := key[len(key)-19 : len(key)-11]
typeBz := key[len(key)-10 : len(key)-9]
idBz := key[len(key)-8:]
return time.Unix(0, types.MustUint64ToInt64(dbtypes.ToUint64Key(timeBz))), ChallengeId{Type: EventType(typeBz[0]), Id: dbtypes.ToUint64Key(idBz)}, nil
}
12 changes: 6 additions & 6 deletions db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ func (db *LevelDB) PrefixedIterate(prefix []byte, cb func(key, value []byte) (st
iter := db.db.NewIterator(util.BytesPrefix(db.PrefixedKey(prefix)), nil)
defer iter.Release()
for iter.Next() {
key := db.UnprefixedKey(iter.Key())
if stop, err := cb(key, iter.Value()); err != nil {
key := db.UnprefixedKey(bytes.Clone(iter.Key()))
if stop, err := cb(key, bytes.Clone(iter.Value())); err != nil {
return err
} else if stop {
break
Expand All @@ -106,8 +106,8 @@ func (db *LevelDB) PrefixedReverseIterate(prefix []byte, cb func(key, value []by
defer iter.Release()
if iter.Last() {
for {
key := db.UnprefixedKey(iter.Key())
if stop, err := cb(key, iter.Value()); err != nil {
key := db.UnprefixedKey(bytes.Clone(iter.Key()))
if stop, err := cb(key, bytes.Clone(iter.Value())); err != nil {
return err
} else if stop {
break
Expand All @@ -128,8 +128,8 @@ func (db *LevelDB) SeekPrevInclusiveKey(prefix []byte, key []byte) (k []byte, v
iter := db.db.NewIterator(util.BytesPrefix(db.PrefixedKey(prefix)), nil)
defer iter.Release()
if iter.Seek(db.PrefixedKey(key)) || iter.Valid() && iter.Prev() || iter.Last() && iter.Valid() {
k = db.UnprefixedKey(iter.Key())
v = iter.Value()
k = db.UnprefixedKey(bytes.Clone(iter.Key()))
v = bytes.Clone(iter.Value())
} else {
err = dbtypes.ErrNotFound
}
Expand Down
10 changes: 6 additions & 4 deletions executor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,12 @@ To configure the Executor, fill in the values in the `~/.opinit/executor.json` f
"max_chunk_size": 300000,
// MaxSubmissionTime is the maximum time to submit a batch.
"max_submission_time": 3600,
// L1StartHeight is the height to start the l1 node. If it is 0, it will finds the optimal height and sets it automatically.
// However, if you do not want to use this feature, set it to a non-zero value.
// There is no need for modification under normal circumstances, because it
// is automatically determined when you set the l2 start height,
// DisableAutoSetL1Height is the flag to disable the automatic setting of the l1 height.
// If it is false, it will finds the optimal height and sets l1_start_height automatically
// from l2 start height and l1_start_height is ignored.
// It can be useful when you don't want to use TxSearch.
"disable_auto_set_l1_height": false,
// L1StartHeight is the height to start the l1 node.
"l1_start_height": 0,
// L2StartHeight is the height to start the l2 node. If it is 0, it will start from the latest height.
// If the latest height stored in the db is not 0, this config is ignored.
Expand Down
Loading
Loading