Skip to content

Commit

Permalink
Feat/withdrawal api by address (#41)
Browse files Browse the repository at this point in the history
* save withdrawals by address

* change query params

* db iteration bug fix

* fix db iteration bug

* change cmd name

* go mod tidy

* cleanup go.mod

* change offset to real index

* add next

---------

Co-authored-by: beer-1 <[email protected]>
  • Loading branch information
sh-cha and beer-1 authored Nov 12, 2024
1 parent e03e229 commit 05f8a32
Show file tree
Hide file tree
Showing 19 changed files with 366 additions and 118 deletions.
10 changes: 5 additions & 5 deletions challenger/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func (c *Challenger) deletePendingChallenge(challenge challengertypes.Challenge)
}

func (c *Challenger) loadPendingChallenges() (challenges []challengertypes.Challenge, err error) {
iterErr := c.db.PrefixedIterate(challengertypes.PendingChallengeKey, func(_, value []byte) (stop bool, err error) {
iterErr := c.db.PrefixedIterate(challengertypes.PendingChallengeKey, nil, func(_, value []byte) (stop bool, err error) {
challenge := challengertypes.Challenge{}
err = challenge.Unmarshal(value)
if err != nil {
Expand All @@ -66,7 +66,7 @@ func (c *Challenger) saveChallenge(challenge challengertypes.Challenge) (types.R
}

func (c *Challenger) loadChallenges() (challenges []challengertypes.Challenge, err error) {
iterErr := c.db.PrefixedReverseIterate(challengertypes.ChallengeKey, func(_, value []byte) (stop bool, err error) {
iterErr := c.db.PrefixedReverseIterate(challengertypes.ChallengeKey, nil, func(_, value []byte) (stop bool, err error) {
challenge := challengertypes.Challenge{}
err = challenge.Unmarshal(value)
if err != nil {
Expand All @@ -87,7 +87,7 @@ func (c *Challenger) loadChallenges() (challenges []challengertypes.Challenge, e

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) {
iterErr := c.db.PrefixedReverseIterate(challengertypes.ChallengeKey, nil, func(key []byte, _ []byte) (stop bool, err error) {
ts, _, err := challengertypes.ParseChallenge(key)
if err != nil {
return true, err
Expand Down Expand Up @@ -150,7 +150,7 @@ func ResetHeight(db types.DB, nodeName string) error {

func DeletePendingEvents(db types.DB) error {
deletingKeys := make([][]byte, 0)
iterErr := db.PrefixedIterate(challengertypes.PendingEventKey, func(key []byte, _ []byte) (stop bool, err error) {
iterErr := db.PrefixedIterate(challengertypes.PendingEventKey, nil, func(key []byte, _ []byte) (stop bool, err error) {
deletingKeys = append(deletingKeys, key)
return false, nil
})
Expand All @@ -169,7 +169,7 @@ func DeletePendingEvents(db types.DB) error {

func DeletePendingChallenges(db types.DB) error {
deletingKeys := make([][]byte, 0)
iterErr := db.PrefixedIterate(challengertypes.PendingChallengeKey, func(key []byte, _ []byte) (stop bool, err error) {
iterErr := db.PrefixedIterate(challengertypes.PendingChallengeKey, nil, func(key []byte, _ []byte) (stop bool, err error) {
deletingKeys = append(deletingKeys, key)
return false, nil
})
Expand Down
2 changes: 1 addition & 1 deletion challenger/eventhandler/pending_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func (ch *ChallengeEventHandler) SetPendingEvents(events []challengertypes.Chall
}

func (ch *ChallengeEventHandler) loadPendingEvents() (events []challengertypes.ChallengeEvent, err error) {
iterErr := ch.db.PrefixedIterate(challengertypes.PendingEventKey, func(key, value []byte) (stop bool, err error) {
iterErr := ch.db.PrefixedIterate(challengertypes.PendingEventKey, nil, func(key, value []byte) (stop bool, err error) {
id, err := challengertypes.ParsePendingEvent(key)
if err != nil {
return true, err
Expand Down
2 changes: 1 addition & 1 deletion challenger/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import challengertypes "github.com/initia-labs/opinit-bots/challenger/types"

func (c *Challenger) QueryChallenges(page uint64) (challenges []challengertypes.Challenge, err error) {
i := uint64(0)
iterErr := c.db.PrefixedIterate(challengertypes.ChallengeKey, func(_, value []byte) (stop bool, err error) {
iterErr := c.db.PrefixedIterate(challengertypes.ChallengeKey, nil, func(_, value []byte) (stop bool, err error) {
i++
if i >= (page+1)*100 {
return true, nil
Expand Down
39 changes: 39 additions & 0 deletions cmd/opinitd/db.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package main

import (
"fmt"

"github.com/initia-labs/opinit-bots/bot"
bottypes "github.com/initia-labs/opinit-bots/bot/types"
"github.com/initia-labs/opinit-bots/db"
"github.com/initia-labs/opinit-bots/executor"
"github.com/spf13/cobra"
)

// migration015Cmd handles the one-time migration of withdrawal data for v0.1.5
// TODO: Remove this command in the future
func migration015Cmd(ctx *cmdContext) *cobra.Command {
cmd := &cobra.Command{
Use: "migrate",
Args: cobra.ExactArgs(1),
Short: "Run database migrations",
Long: `Run database migrations
v0.1.5: Store the sequence number so that it can be accessed by address
`,
RunE: func(cmd *cobra.Command, args []string) error {
version := args[0]
switch version {
case "v0.1.5":
// Run migration for v0.1.5
db, err := db.NewDB(bot.GetDBPath(ctx.homePath, bottypes.BotTypeExecutor))
if err != nil {
return err
}
return executor.Migration015(db)
default:
return fmt.Errorf("unknown migration version: %s", version)
}
},
}
return cmd
}
1 change: 1 addition & 0 deletions cmd/opinitd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ func NewRootCmd() *cobra.Command {
resetDBCmd(ctx),
resetHeightsCmd(ctx),
resetHeightCmd(ctx),
migration015Cmd(ctx),
version.NewVersionCommand(),
)
return rootCmd
Expand Down
47 changes: 31 additions & 16 deletions db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,36 +87,45 @@ func (db *LevelDB) Close() error {
// PrefixedIterate iterates over the key-value pairs in the database with prefixing the keys.
//
// @dev: `LevelDB.prefix + prefix` is used as the prefix for the iteration.
func (db *LevelDB) PrefixedIterate(prefix []byte, cb func(key, value []byte) (stop bool, err error)) error {
func (db *LevelDB) PrefixedIterate(prefix []byte, start []byte, cb func(key, value []byte) (stop bool, err error)) error {
iter := db.db.NewIterator(util.BytesPrefix(db.PrefixedKey(prefix)), nil)
defer iter.Release()
for iter.Next() {
if start != nil {
iter.Seek(db.PrefixedKey(start))
} else {
iter.First()
}

for iter.Valid() {
key := db.UnprefixedKey(bytes.Clone(iter.Key()))
if stop, err := cb(key, bytes.Clone(iter.Value())); err != nil {
return err
} else if stop {
break
}
iter.Next()
}
return iter.Error()
}

func (db *LevelDB) PrefixedReverseIterate(prefix []byte, cb func(key, value []byte) (stop bool, err error)) error {
func (db *LevelDB) PrefixedReverseIterate(prefix []byte, start []byte, cb func(key, value []byte) (stop bool, err error)) error {
iter := db.db.NewIterator(util.BytesPrefix(db.PrefixedKey(prefix)), nil)
defer iter.Release()
if iter.Last() {
for {
key := db.UnprefixedKey(bytes.Clone(iter.Key()))
if stop, err := cb(key, bytes.Clone(iter.Value())); err != nil {
return err
} else if stop {
break
}

if !iter.Prev() {
break
}
if start != nil {
iter.Seek(db.PrefixedKey(start))
} else {
iter.Last()
}

for iter.Valid() {
key := db.UnprefixedKey(bytes.Clone(iter.Key()))
if stop, err := cb(key, bytes.Clone(iter.Value())); err != nil {
return err
} else if stop {
break
}

iter.Prev()
}
return iter.Error()
}
Expand All @@ -127,7 +136,13 @@ func (db *LevelDB) PrefixedReverseIterate(prefix []byte, cb func(key, value []by
func (db *LevelDB) SeekPrevInclusiveKey(prefix []byte, key []byte) (k []byte, v []byte, err error) {
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() {
if ok := iter.Seek(db.PrefixedKey(key)); ok || iter.Last() {
// if the valid key is not found, the iterator will be at the last key
// if the key is found, the iterator will be at the key
// or the previous key if the key is not found
if ok && !bytes.Equal(db.PrefixedKey(key), iter.Key()) {
iter.Prev()
}
k = db.UnprefixedKey(bytes.Clone(iter.Key()))
v = bytes.Clone(iter.Value())
} else {
Expand Down
7 changes: 6 additions & 1 deletion executor/child/child.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,19 @@ type Child struct {
lastFinalizedDepositL1BlockHeight int64
lastFinalizedDepositL1Sequence uint64
lastOutputTime time.Time

batchKVs []types.RawKV
addressIndexMap map[string]uint64
}

func NewChildV1(
cfg nodetypes.NodeConfig,
db types.DB, logger *zap.Logger,
) *Child {
return &Child{
BaseChild: childprovider.NewBaseChildV1(cfg, db, logger),
BaseChild: childprovider.NewBaseChildV1(cfg, db, logger),
batchKVs: make([]types.RawKV, 0),
addressIndexMap: make(map[string]uint64),
}
}

Expand Down
13 changes: 7 additions & 6 deletions executor/child/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ import (

btypes "github.com/initia-labs/opinit-bots/node/broadcaster/types"
nodetypes "github.com/initia-labs/opinit-bots/node/types"
"github.com/initia-labs/opinit-bots/types"
"golang.org/x/exp/maps"
)

func (ch *Child) beginBlockHandler(ctx context.Context, args nodetypes.BeginBlockArgs) (err error) {
blockHeight := args.Block.Header.Height
ch.EmptyMsgQueue()
ch.EmptyProcessedMsgs()
ch.batchKVs = ch.batchKVs[:0]
maps.Clear(ch.addressIndexMap)

if ch.Merkle() == nil {
return errors.New("merkle is not initialized")
Expand All @@ -34,13 +36,12 @@ func (ch *Child) beginBlockHandler(ctx context.Context, args nodetypes.BeginBloc

func (ch *Child) endBlockHandler(_ context.Context, args nodetypes.EndBlockArgs) error {
blockHeight := args.Block.Header.Height
batchKVs := make([]types.RawKV, 0)
treeKVs, storageRoot, err := ch.handleTree(blockHeight, args.LatestHeight, args.BlockID, args.Block.Header)
if err != nil {
return err
}

batchKVs = append(batchKVs, treeKVs...)
ch.batchKVs = append(ch.batchKVs, treeKVs...)
if storageRoot != nil {
workingTreeIndex, err := ch.GetWorkingTreeIndex()
if err != nil {
Expand All @@ -53,7 +54,7 @@ func (ch *Child) endBlockHandler(_ context.Context, args nodetypes.EndBlockArgs)
}

// update the sync info
batchKVs = append(batchKVs, ch.Node().SyncInfoToRawKV(blockHeight))
ch.batchKVs = append(ch.batchKVs, ch.Node().SyncInfoToRawKV(blockHeight))

// if has key, then process the messages
if ch.host.HasKey() {
Expand All @@ -76,10 +77,10 @@ func (ch *Child) endBlockHandler(_ context.Context, args nodetypes.EndBlockArgs)
if err != nil {
return err
}
batchKVs = append(batchKVs, msgKVs...)
ch.batchKVs = append(ch.batchKVs, msgKVs...)
}

err = ch.DB().RawBatchSet(batchKVs...)
err = ch.DB().RawBatchSet(ch.batchKVs...)
if err != nil {
return err
}
Expand Down
34 changes: 28 additions & 6 deletions executor/child/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,36 @@ func (ch Child) QueryWithdrawal(sequence uint64) (executortypes.QueryWithdrawalR
BridgeId: ch.BridgeId(),
OutputIndex: outputIndex,
WithdrawalProofs: proofs,
Sender: withdrawal.From,
From: withdrawal.From,
To: withdrawal.To,
Sequence: sequence,
Amount: amount.String(),
Amount: amount,
Version: []byte{ch.Version()},
StorageRoot: outputRoot,
LatestBlockHash: treeExtraData.BlockHash,
BlockNumber: treeExtraData.BlockNumber,
Receiver: withdrawal.To,
WithdrawalHash: withdrawal.WithdrawalHash,
LastBlockHash: treeExtraData.BlockHash,
// BlockNumber: treeExtraData.BlockNumber,
// WithdrawalHash: withdrawal.WithdrawalHash,
}, nil
}

func (ch Child) QueryWithdrawals(address string, offset uint64, limit uint64, descOrder bool) (executortypes.QueryWithdrawalsResponse, error) {
sequences, next, total, err := ch.GetSequencesByAddress(address, offset, limit, descOrder)
if err != nil {
return executortypes.QueryWithdrawalsResponse{}, err
}
withdrawals := make([]executortypes.QueryWithdrawalResponse, 0)
for _, sequence := range sequences {
withdrawal, err := ch.QueryWithdrawal(sequence)
if err != nil {
return executortypes.QueryWithdrawalsResponse{}, err
}
withdrawals = append(withdrawals, withdrawal)
}

res := executortypes.QueryWithdrawalsResponse{
Withdrawals: withdrawals,
Next: next,
Total: total,
}
return res, nil
}
Loading

0 comments on commit 05f8a32

Please sign in to comment.