mirror of
https://github.com/alexgo-io/gaze-brc20-indexer.git
synced 2026-04-30 20:43:11 +08:00
fix: add content to inscription transfers
This commit is contained in:
@@ -7,13 +7,15 @@ SELECT * FROM "brc20_indexed_blocks" WHERE "height" = $1;
|
||||
-- name: GetLatestProcessorStats :one
|
||||
SELECT * FROM "brc20_processor_stats" ORDER BY "block_height" DESC LIMIT 1;
|
||||
|
||||
-- name: GetInscriptionsInOutPoints :many
|
||||
SELECT "brc20_inscription_transfers".* FROM (
|
||||
-- name: GetInscriptionTransfersInOutPoints :many
|
||||
SELECT "it".*, "ie"."content" FROM (
|
||||
SELECT
|
||||
unnest(@tx_hash_arr::text[]) AS "tx_hash",
|
||||
unnest(@tx_out_idx_arr::int[]) AS "tx_out_idx"
|
||||
) "inputs"
|
||||
INNER JOIN "brc20_inscription_transfers" ON "inputs"."tx_hash" = "brc20_inscription_transfers"."new_satpoint_tx_hash" AND "inputs"."tx_out_idx" = "brc20_inscription_transfers"."new_satpoint_out_idx";
|
||||
INNER JOIN "brc20_inscription_transfers" it ON "inputs"."tx_hash" = "it"."new_satpoint_tx_hash" AND "inputs"."tx_out_idx" = "it"."new_satpoint_out_idx"
|
||||
LEFT JOIN "brc20_inscription_entries" ie ON "it"."inscription_id" = "ie"."id";
|
||||
;
|
||||
|
||||
-- name: GetInscriptionEntriesByIds :many
|
||||
WITH "states" AS (
|
||||
|
||||
@@ -26,7 +26,7 @@ type BRC20ReaderDataGateway interface {
|
||||
GetLatestBlock(ctx context.Context) (types.BlockHeader, error)
|
||||
GetIndexedBlockByHeight(ctx context.Context, height int64) (*entity.IndexedBlock, error)
|
||||
GetProcessorStats(ctx context.Context) (*entity.ProcessorStats, error)
|
||||
GetInscriptionIdsInOutPoints(ctx context.Context, outPoints []wire.OutPoint) (map[ordinals.SatPoint][]ordinals.InscriptionId, error)
|
||||
GetInscriptionTransfersInOutPoints(ctx context.Context, outPoints []wire.OutPoint) (map[ordinals.SatPoint][]*entity.InscriptionTransfer, error)
|
||||
GetInscriptionEntryById(ctx context.Context, id ordinals.InscriptionId) (*ordinals.InscriptionEntry, error)
|
||||
}
|
||||
|
||||
|
||||
@@ -6,24 +6,25 @@ import (
|
||||
)
|
||||
|
||||
type OriginOld struct {
|
||||
Content []byte
|
||||
OldSatPoint ordinals.SatPoint
|
||||
}
|
||||
type OriginNew struct {
|
||||
Cursed bool
|
||||
CursedForBRC20 bool
|
||||
Fee uint64
|
||||
Hidden bool
|
||||
Inscription ordinals.Inscription
|
||||
Parent *ordinals.InscriptionId
|
||||
Pointer *uint64
|
||||
Fee uint64
|
||||
Cursed bool
|
||||
CursedForBRC20 bool
|
||||
Hidden bool
|
||||
Reinscription bool
|
||||
Unbound bool
|
||||
Inscription ordinals.Inscription
|
||||
}
|
||||
|
||||
type Flotsam struct {
|
||||
Offset uint64
|
||||
InscriptionId ordinals.InscriptionId
|
||||
Tx *types.Transaction
|
||||
OriginOld *OriginOld // OriginOld and OriginNew are mutually exclusive
|
||||
OriginNew *OriginNew // OriginOld and OriginNew are mutually exclusive
|
||||
Offset uint64
|
||||
InscriptionId ordinals.InscriptionId
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ type InscriptionTransfer struct {
|
||||
InscriptionId ordinals.InscriptionId
|
||||
BlockHeight uint64
|
||||
TxIndex uint32
|
||||
Content []byte
|
||||
OldSatPoint ordinals.SatPoint
|
||||
NewSatPoint ordinals.SatPoint
|
||||
NewPkScript []byte
|
||||
|
||||
@@ -67,44 +67,29 @@ func (r *Repository) GetProcessorStats(ctx context.Context) (*entity.ProcessorSt
|
||||
return &stats, nil
|
||||
}
|
||||
|
||||
func (r *Repository) GetInscriptionIdsInOutPoints(ctx context.Context, outPoints []wire.OutPoint) (map[ordinals.SatPoint][]ordinals.InscriptionId, error) {
|
||||
func (r *Repository) GetInscriptionTransfersInOutPoints(ctx context.Context, outPoints []wire.OutPoint) (map[ordinals.SatPoint][]*entity.InscriptionTransfer, error) {
|
||||
txHashArr := lo.Map(outPoints, func(outPoint wire.OutPoint, _ int) string {
|
||||
return outPoint.Hash.String()
|
||||
})
|
||||
txOutIdxArr := lo.Map(outPoints, func(outPoint wire.OutPoint, _ int) int32 {
|
||||
return int32(outPoint.Index)
|
||||
})
|
||||
models, err := r.queries.GetInscriptionsInOutPoints(ctx, gen.GetInscriptionsInOutPointsParams{
|
||||
models, err := r.queries.GetInscriptionTransfersInOutPoints(ctx, gen.GetInscriptionTransfersInOutPointsParams{
|
||||
TxHashArr: txHashArr,
|
||||
TxOutIdxArr: txOutIdxArr,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
inscriptionIds := make(map[ordinals.SatPoint][]ordinals.InscriptionId)
|
||||
results := make(map[ordinals.SatPoint][]*entity.InscriptionTransfer)
|
||||
for _, model := range models {
|
||||
// sanity check
|
||||
if !model.NewSatpointTxHash.Valid || !model.NewSatpointOutIdx.Valid || !model.NewSatpointOffset.Valid {
|
||||
return nil, errors.New("invalid satpoint: missing required satpoint fields")
|
||||
}
|
||||
txHash, err := chainhash.NewHashFromStr(model.NewSatpointTxHash.String)
|
||||
inscriptionTransfer, err := mapInscriptionTransferModelToType(model)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "invalid satpoint: cannot parse txHash")
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
satPoint := ordinals.SatPoint{
|
||||
OutPoint: wire.OutPoint{
|
||||
Hash: *txHash,
|
||||
Index: uint32(model.NewSatpointOutIdx.Int32),
|
||||
},
|
||||
Offset: uint64(model.NewSatpointOffset.Int64),
|
||||
}
|
||||
inscriptionId, err := ordinals.NewInscriptionIdFromString(model.InscriptionID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "invalid inscription id")
|
||||
}
|
||||
inscriptionIds[satPoint] = append(inscriptionIds[satPoint], inscriptionId)
|
||||
results[inscriptionTransfer.NewSatPoint] = append(results[inscriptionTransfer.NewSatPoint], &inscriptionTransfer)
|
||||
}
|
||||
return inscriptionIds, nil
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func (r *Repository) GetInscriptionEntryById(ctx context.Context, id ordinals.InscriptionId) (*ordinals.InscriptionEntry, error) {
|
||||
|
||||
@@ -139,29 +139,46 @@ func (q *Queries) GetInscriptionEntriesByIds(ctx context.Context, inscriptionIds
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getInscriptionsInOutPoints = `-- name: GetInscriptionsInOutPoints :many
|
||||
SELECT brc20_inscription_transfers.inscription_id, brc20_inscription_transfers.block_height, brc20_inscription_transfers.tx_index, brc20_inscription_transfers.old_satpoint_tx_hash, brc20_inscription_transfers.old_satpoint_out_idx, brc20_inscription_transfers.old_satpoint_offset, brc20_inscription_transfers.new_satpoint_tx_hash, brc20_inscription_transfers.new_satpoint_out_idx, brc20_inscription_transfers.new_satpoint_offset, brc20_inscription_transfers.new_pkscript, brc20_inscription_transfers.new_output_value, brc20_inscription_transfers.sent_as_fee FROM (
|
||||
const getInscriptionTransfersInOutPoints = `-- name: GetInscriptionTransfersInOutPoints :many
|
||||
SELECT it.inscription_id, it.block_height, it.tx_index, it.old_satpoint_tx_hash, it.old_satpoint_out_idx, it.old_satpoint_offset, it.new_satpoint_tx_hash, it.new_satpoint_out_idx, it.new_satpoint_offset, it.new_pkscript, it.new_output_value, it.sent_as_fee, "ie"."content" FROM (
|
||||
SELECT
|
||||
unnest($1::text[]) AS "tx_hash",
|
||||
unnest($2::int[]) AS "tx_out_idx"
|
||||
) "inputs"
|
||||
INNER JOIN "brc20_inscription_transfers" ON "inputs"."tx_hash" = "brc20_inscription_transfers"."new_satpoint_tx_hash" AND "inputs"."tx_out_idx" = "brc20_inscription_transfers"."new_satpoint_out_idx"
|
||||
INNER JOIN "brc20_inscription_transfers" it ON "inputs"."tx_hash" = "it"."new_satpoint_tx_hash" AND "inputs"."tx_out_idx" = "it"."new_satpoint_out_idx"
|
||||
LEFT JOIN "brc20_inscription_entries" ie ON "it"."inscription_id" = "ie"."id"
|
||||
`
|
||||
|
||||
type GetInscriptionsInOutPointsParams struct {
|
||||
type GetInscriptionTransfersInOutPointsParams struct {
|
||||
TxHashArr []string
|
||||
TxOutIdxArr []int32
|
||||
}
|
||||
|
||||
func (q *Queries) GetInscriptionsInOutPoints(ctx context.Context, arg GetInscriptionsInOutPointsParams) ([]Brc20InscriptionTransfer, error) {
|
||||
rows, err := q.db.Query(ctx, getInscriptionsInOutPoints, arg.TxHashArr, arg.TxOutIdxArr)
|
||||
type GetInscriptionTransfersInOutPointsRow struct {
|
||||
InscriptionID string
|
||||
BlockHeight int32
|
||||
TxIndex int32
|
||||
OldSatpointTxHash pgtype.Text
|
||||
OldSatpointOutIdx pgtype.Int4
|
||||
OldSatpointOffset pgtype.Int8
|
||||
NewSatpointTxHash pgtype.Text
|
||||
NewSatpointOutIdx pgtype.Int4
|
||||
NewSatpointOffset pgtype.Int8
|
||||
NewPkscript string
|
||||
NewOutputValue int64
|
||||
SentAsFee bool
|
||||
Content []byte
|
||||
}
|
||||
|
||||
func (q *Queries) GetInscriptionTransfersInOutPoints(ctx context.Context, arg GetInscriptionTransfersInOutPointsParams) ([]GetInscriptionTransfersInOutPointsRow, error) {
|
||||
rows, err := q.db.Query(ctx, getInscriptionTransfersInOutPoints, arg.TxHashArr, arg.TxOutIdxArr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Brc20InscriptionTransfer
|
||||
var items []GetInscriptionTransfersInOutPointsRow
|
||||
for rows.Next() {
|
||||
var i Brc20InscriptionTransfer
|
||||
var i GetInscriptionTransfersInOutPointsRow
|
||||
if err := rows.Scan(
|
||||
&i.InscriptionID,
|
||||
&i.BlockHeight,
|
||||
@@ -175,6 +192,7 @@ func (q *Queries) GetInscriptionsInOutPoints(ctx context.Context, arg GetInscrip
|
||||
&i.NewPkscript,
|
||||
&i.NewOutputValue,
|
||||
&i.SentAsFee,
|
||||
&i.Content,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ func mapInscriptionEntryTypeToParams(src ordinals.InscriptionEntry, blockHeight
|
||||
}, nil
|
||||
}
|
||||
|
||||
func mapInscriptionTransferModelToType(src gen.Brc20InscriptionTransfer) (entity.InscriptionTransfer, error) {
|
||||
func mapInscriptionTransferModelToType(src gen.GetInscriptionTransfersInOutPointsRow) (entity.InscriptionTransfer, error) {
|
||||
inscriptionId, err := ordinals.NewInscriptionIdFromString(src.InscriptionID)
|
||||
if err != nil {
|
||||
return entity.InscriptionTransfer{}, errors.Wrap(err, "invalid inscription id")
|
||||
@@ -225,6 +225,7 @@ func mapInscriptionTransferModelToType(src gen.Brc20InscriptionTransfer) (entity
|
||||
InscriptionId: inscriptionId,
|
||||
BlockHeight: uint64(src.BlockHeight),
|
||||
TxIndex: uint32(src.TxIndex),
|
||||
Content: src.Content,
|
||||
OldSatPoint: oldSatPoint,
|
||||
NewSatPoint: newSatPoint,
|
||||
NewPkScript: newPkScript,
|
||||
|
||||
11
modules/brc20/processor_brc20.go
Normal file
11
modules/brc20/processor_brc20.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package brc20
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gaze-network/indexer-network/modules/brc20/internal/entity"
|
||||
)
|
||||
|
||||
func (p *Processor) processBRC20States(ctx context.Context, transfers []*entity.InscriptionTransfer) error {
|
||||
panic("not implemented")
|
||||
}
|
||||
@@ -29,7 +29,7 @@ func (p *Processor) processInscriptionTx(ctx context.Context, tx *types.Transact
|
||||
Index: txIn.PreviousOutIndex,
|
||||
}
|
||||
})
|
||||
inscriptionIdsInOutPoints, err := p.getInscriptionIdsInOutPoints(ctx, inputOutPoints)
|
||||
transfersInOutPoints, err := p.getInscriptionTransfersInOutPoints(ctx, inputOutPoints)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to get inscriptions in outpoints")
|
||||
}
|
||||
@@ -40,7 +40,7 @@ func (p *Processor) processInscriptionTx(ctx context.Context, tx *types.Transact
|
||||
Index: uint32(outIndex),
|
||||
}, uint64(txOut.Value))
|
||||
}
|
||||
if len(envelopes) == 0 && len(inscriptionIdsInOutPoints) == 0 {
|
||||
if len(envelopes) == 0 && len(transfersInOutPoints) == 0 {
|
||||
// no inscription activity, skip
|
||||
return nil
|
||||
}
|
||||
@@ -73,23 +73,24 @@ func (p *Processor) processInscriptionTx(ctx context.Context, tx *types.Transact
|
||||
continue
|
||||
}
|
||||
|
||||
inscriptionIdsInOutPoint := inscriptionIdsInOutPoints[inputOutPoint]
|
||||
for satPoint, inscriptionIds := range inscriptionIdsInOutPoint {
|
||||
transfersInOutPoint := transfersInOutPoints[inputOutPoint]
|
||||
for satPoint, transfers := range transfersInOutPoint {
|
||||
offset := totalInputValue + satPoint.Offset
|
||||
for _, inscriptionId := range inscriptionIds {
|
||||
for _, transfer := range transfers {
|
||||
floatingInscriptions = append(floatingInscriptions, &entity.Flotsam{
|
||||
Offset: offset,
|
||||
InscriptionId: inscriptionId,
|
||||
InscriptionId: transfer.InscriptionId,
|
||||
Tx: tx,
|
||||
OriginOld: &entity.OriginOld{
|
||||
OldSatPoint: satPoint,
|
||||
Content: transfer.Content,
|
||||
},
|
||||
})
|
||||
if _, ok := inscribeOffsets[offset]; !ok {
|
||||
inscribeOffsets[offset] = &struct {
|
||||
inscriptionId ordinals.InscriptionId
|
||||
count int
|
||||
}{inscriptionId, 0}
|
||||
}{transfer.InscriptionId, 0}
|
||||
}
|
||||
inscribeOffsets[offset].count++
|
||||
}
|
||||
@@ -296,6 +297,7 @@ func (p *Processor) updateInscriptionLocation(ctx context.Context, newSatPoint o
|
||||
InscriptionId: flotsam.InscriptionId,
|
||||
BlockHeight: uint64(flotsam.Tx.BlockHeight), // use flotsam's tx to track tx that initiated the transfer
|
||||
TxIndex: flotsam.Tx.Index, // use flotsam's tx to track tx that initiated the transfer
|
||||
Content: flotsam.OriginOld.Content,
|
||||
OldSatPoint: flotsam.OriginOld.OldSatPoint,
|
||||
NewSatPoint: newSatPoint,
|
||||
NewPkScript: txOut.PkScript,
|
||||
@@ -341,6 +343,7 @@ func (p *Processor) updateInscriptionLocation(ctx context.Context, newSatPoint o
|
||||
InscriptionId: flotsam.InscriptionId,
|
||||
BlockHeight: uint64(flotsam.Tx.BlockHeight), // use flotsam's tx to track tx that initiated the transfer
|
||||
TxIndex: flotsam.Tx.Index, // use flotsam's tx to track tx that initiated the transfer
|
||||
Content: origin.Inscription.Content,
|
||||
OldSatPoint: ordinals.SatPoint{},
|
||||
NewSatPoint: newSatPoint,
|
||||
NewPkScript: txOut.PkScript,
|
||||
@@ -436,17 +439,17 @@ func (p *Processor) getOutPointValues(ctx context.Context, outPoints []wire.OutP
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (p *Processor) getInscriptionIdsInOutPoints(ctx context.Context, outPoints []wire.OutPoint) (map[wire.OutPoint]map[ordinals.SatPoint][]ordinals.InscriptionId, error) {
|
||||
inscriptionIds, err := p.brc20Dg.GetInscriptionIdsInOutPoints(ctx, outPoints)
|
||||
func (p *Processor) getInscriptionTransfersInOutPoints(ctx context.Context, outPoints []wire.OutPoint) (map[wire.OutPoint]map[ordinals.SatPoint][]*entity.InscriptionTransfer, error) {
|
||||
transfers, err := p.brc20Dg.GetInscriptionTransfersInOutPoints(ctx, outPoints)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get inscriptions by outpoint")
|
||||
}
|
||||
result := make(map[wire.OutPoint]map[ordinals.SatPoint][]ordinals.InscriptionId)
|
||||
for satPoint, inscriptionIds := range inscriptionIds {
|
||||
result := make(map[wire.OutPoint]map[ordinals.SatPoint][]*entity.InscriptionTransfer)
|
||||
for satPoint, transfer := range transfers {
|
||||
if _, ok := result[satPoint.OutPoint]; !ok {
|
||||
result[satPoint.OutPoint] = make(map[ordinals.SatPoint][]ordinals.InscriptionId)
|
||||
result[satPoint.OutPoint] = make(map[ordinals.SatPoint][]*entity.InscriptionTransfer)
|
||||
}
|
||||
result[satPoint.OutPoint][satPoint] = append(result[satPoint.OutPoint][satPoint], inscriptionIds...)
|
||||
result[satPoint.OutPoint][satPoint] = append(result[satPoint.OutPoint][satPoint], transfer...)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@@ -43,7 +43,11 @@ func (p *Processor) Process(ctx context.Context, blocks []*types.Block) error {
|
||||
return int(t1.NewSatPoint.Offset) - int(t2.NewSatPoint.Offset)
|
||||
})
|
||||
|
||||
// TODO: add brc20 processing
|
||||
// process brc20 states
|
||||
if err := p.processBRC20States(ctx, p.newInscriptionTransfers); err != nil {
|
||||
return errors.Wrap(err, "failed to process brc20 states")
|
||||
}
|
||||
|
||||
if err := p.flushBlock(ctx, block.Header); err != nil {
|
||||
return errors.Wrap(err, "failed to flush block")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user