mirror of
https://github.com/alexgo-io/gaze-indexer.git
synced 2026-04-30 20:52:01 +08:00
feat(btc): add btc indexer implementation
Co-authored-by: Gaze <gazenw@users.noreply.github.com>
This commit is contained in:
20
modules/bitcoin/internal/datagateway/bitcoin_data.go
Normal file
20
modules/bitcoin/internal/datagateway/bitcoin_data.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package datagateway
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gaze-network/indexer-network/core/types"
|
||||
)
|
||||
|
||||
type BitcoinDataGateway interface {
|
||||
BitcoinWriterDataDataGateway
|
||||
BitcoinReaderDataDataGateway
|
||||
}
|
||||
|
||||
type BitcoinWriterDataDataGateway interface {
|
||||
InsertBlock(context.Context, *types.Block) error
|
||||
}
|
||||
|
||||
type BitcoinReaderDataDataGateway interface {
|
||||
GetLatestBlockHeader(context.Context) (types.BlockHeader, error)
|
||||
}
|
||||
9
modules/bitcoin/internal/datagateway/indexer_info.go
Normal file
9
modules/bitcoin/internal/datagateway/indexer_info.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package datagateway
|
||||
|
||||
import "context"
|
||||
|
||||
type IndexerInformationDataGateway interface {
|
||||
GetCurrentDBVersion(ctx context.Context) (int, error)
|
||||
GetCurrentIndexerStats(ctx context.Context) (clientVersion string, network string, err error)
|
||||
UpdateIndexerStats(ctx context.Context, clientVersion string, network string) error
|
||||
}
|
||||
@@ -1,12 +1,15 @@
|
||||
package bitcoin
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"context"
|
||||
"slices"
|
||||
|
||||
"github.com/cockroachdb/errors"
|
||||
"github.com/gaze-network/indexer-network/core/indexers"
|
||||
"github.com/gaze-network/indexer-network/core/types"
|
||||
"github.com/gaze-network/indexer-network/modules/bitcoin/internal/datagateway"
|
||||
"github.com/gaze-network/indexer-network/pkg/logger"
|
||||
)
|
||||
|
||||
// Make sure to implement the BitcoinProcessor interface
|
||||
@@ -17,6 +20,42 @@ type Processor struct {
|
||||
}
|
||||
|
||||
func (p *Processor) Process(ctx context.Context, inputs []*types.Block) error {
|
||||
if len(inputs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Sort ASC by block height
|
||||
slices.SortFunc(inputs, func(t1, t2 *types.Block) int {
|
||||
return cmp.Compare(t1.Header.Height, t2.Header.Height)
|
||||
})
|
||||
|
||||
latestBlock, err := p.bitcoinDg.GetLatestBlockHeader(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to get latest indexed block header")
|
||||
}
|
||||
|
||||
// check if the given blocks are continue from the latest indexed block
|
||||
// return an error to prevent inserting out-of-order blocks or duplicate blocks
|
||||
if inputs[0].Header.Height != latestBlock.Height+1 {
|
||||
return errors.New("given blocks are not continue from the latest indexed block")
|
||||
}
|
||||
|
||||
// check if the given blocks are in sequence and not missing any block
|
||||
for i := 1; i < len(inputs); i++ {
|
||||
if inputs[i].Header.Height != inputs[i-1].Header.Height+1 {
|
||||
return errors.New("given blocks are not in sequence")
|
||||
}
|
||||
}
|
||||
|
||||
// Insert blocks
|
||||
for _, b := range inputs {
|
||||
err := p.bitcoinDg.InsertBlock(ctx, b)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to insert block, height: %d, hash: %s", b.Header.Height, b.Header.Hash)
|
||||
}
|
||||
logger.Info("Block inserted", "height", b.Header.Height, "hash", b.Header.Hash)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user