Skip to content

Commit

Permalink
feat: enable inscription parsing on Bitcoin mainnet (#3425)
Browse files Browse the repository at this point in the history
* remove non withness function

* update tests

* changelog
  • Loading branch information
lumtis authored Jan 29, 2025
1 parent 10f735b commit 21884ab
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 249 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* [3357](https://github.com/zeta-chain/node/pull/3357) - cosmos-sdk v.50.x upgrade
* [3358](https://github.com/zeta-chain/node/pull/3358) - register aborted CCTX for Bitcoin inbound that carries insufficient depositor fee
* [3368](https://github.com/zeta-chain/node/pull/3368) - cli command to fetch inbound ballot from inbound hash added to zetatools.
* [3425](https://github.com/zeta-chain/node/pull/3425) - enable inscription parsing on Bitcoin mainnet

### Refactor

Expand Down
107 changes: 1 addition & 106 deletions zetaclient/chains/bitcoin/observer/inbound.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ func (ob *Observer) GetInboundVoteFromBtcEvent(event *BTCInboundEvent) *types.Ms
}

// GetBtcEvent returns a valid BTCInboundEvent or nil
// it uses witness data to extract the sender address, except for mainnet
// it uses witness data to extract the sender address
func GetBtcEvent(
ctx context.Context,
rpc RPC,
Expand All @@ -296,114 +296,9 @@ func GetBtcEvent(
netParams *chaincfg.Params,
feeCalculator common.DepositorFeeCalculator,
) (*BTCInboundEvent, error) {
if netParams.Name == chaincfg.MainNetParams.Name {
return GetBtcEventWithoutWitness(ctx, rpc, tx, tssAddress, blockNumber, logger, netParams, feeCalculator)
}

return GetBtcEventWithWitness(ctx, rpc, tx, tssAddress, blockNumber, logger, netParams, feeCalculator)
}

// GetBtcEventWithoutWitness either returns a valid BTCInboundEvent or nil
// Note: the caller should retry the tx on error (e.g., GetSenderAddressByVin failed)
// TODO(revamp): simplify this function
func GetBtcEventWithoutWitness(
ctx context.Context,
rpc RPC,
tx btcjson.TxRawResult,
tssAddress string,
blockNumber uint64,
logger zerolog.Logger,
netParams *chaincfg.Params,
feeCalculator common.DepositorFeeCalculator,
) (*BTCInboundEvent, error) {
var (
found bool
value float64
depositorFee float64
memo []byte
status = types.InboundStatus_SUCCESS
)

// prepare logger fields
lf := map[string]any{
logs.FieldMethod: "GetBtcEventWithoutWitness",
logs.FieldTx: tx.Txid,
}

if len(tx.Vout) >= 2 {
// 1st vout must have tss address as receiver with p2wpkh scriptPubKey
vout0 := tx.Vout[0]
script := vout0.ScriptPubKey.Hex
if len(script) == 44 && script[:4] == "0014" {
// P2WPKH output: 0x00 + 20 bytes of pubkey hash
receiver, err := common.DecodeScriptP2WPKH(vout0.ScriptPubKey.Hex, netParams)
if err != nil { // should never happen
return nil, err
}

// skip irrelevant tx to us
if receiver != tssAddress {
return nil, nil
}

// calculate depositor fee
depositorFee, err = feeCalculator(ctx, rpc, &tx, netParams)
if err != nil {
return nil, errors.Wrapf(err, "error calculating depositor fee for inbound %s", tx.Txid)
}

// deduct depositor fee
// to allow developers to track failed deposit caused by insufficient depositor fee,
// the error message will be forwarded to zetacore to register a failed CCTX
value, err = DeductDepositorFee(vout0.Value, depositorFee)
if err != nil {
value = 0
status = types.InboundStatus_INSUFFICIENT_DEPOSITOR_FEE
logger.Error().Err(err).Fields(lf).Msgf("unable to deduct depositor fee")
}

// 2nd vout must be a valid OP_RETURN memo
vout1 := tx.Vout[1]
memo, found, err = common.DecodeOpReturnMemo(vout1.ScriptPubKey.Hex)
if err != nil {
lf["memo"] = vout1.ScriptPubKey.Hex
logger.Error().Err(err).Fields(lf).Msgf("unable to decode OP_RETURN memo")
return nil, nil
}
}
}
// event found, get sender address
if found {
if len(tx.Vin) == 0 { // should never happen
return nil, fmt.Errorf("GetBtcEvent: no input found for inbound: %s", tx.Txid)
}

// get sender address by input (vin)
fromAddress, err := GetSenderAddressByVin(ctx, rpc, tx.Vin[0], netParams)
if err != nil {
return nil, errors.Wrapf(err, "error getting sender address for inbound: %s", tx.Txid)
}

// skip this tx and move on (e.g., due to unknown script type)
// we don't know whom to refund if this tx gets reverted in zetacore
if fromAddress == "" {
return nil, nil
}

return &BTCInboundEvent{
FromAddress: fromAddress,
ToAddress: tssAddress,
Value: value,
DepositorFee: depositorFee,
MemoBytes: memo,
BlockNumber: blockNumber,
TxHash: tx.Txid,
Status: status,
}, nil
}
return nil, nil
}

// GetSenderAddressByVin get the sender address from the transaction input (vin)
func GetSenderAddressByVin(
ctx context.Context,
Expand Down
Loading

0 comments on commit 21884ab

Please sign in to comment.