feat(btc): add btc indexer implementation

Co-authored-by: Gaze <gazenw@users.noreply.github.com>
This commit is contained in:
Gaze
2024-04-10 02:21:52 +07:00
parent 88f4335446
commit 25ce73bf29
3 changed files with 68 additions and 0 deletions

View 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)
}

View 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
}

View File

@@ -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
}