fix: add content to inscription transfers

This commit is contained in:
Gaze
2024-05-31 12:08:09 +07:00
parent ef575dea85
commit d6c3f90d8c
10 changed files with 82 additions and 56 deletions

View File

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

View File

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

View File

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

View File

@@ -6,6 +6,7 @@ type InscriptionTransfer struct {
InscriptionId ordinals.InscriptionId
BlockHeight uint64
TxIndex uint32
Content []byte
OldSatPoint ordinals.SatPoint
NewSatPoint ordinals.SatPoint
NewPkScript []byte

View File

@@ -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) {

View File

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

View File

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

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

View File

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

View File

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