blockbook/bchain/coins/btc/bitcoinparser.go
Sai Raj 49ca2ba2cf Self restart on repeated error and package name
- Adding self restart when repeated error occurs with backend rpc connection

- renamed package name to reflect correctly
2024-07-01 22:20:48 -04:00

123 lines
3.8 KiB
Go

package btc
import (
"encoding/json"
"math/big"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/ranchimall/blockbook/bchain"
"github.com/ranchimall/blockbook/common"
)
// BitcoinParser handle
type BitcoinParser struct {
*BitcoinLikeParser
}
// NewBitcoinParser returns new BitcoinParser instance
func NewBitcoinParser(params *chaincfg.Params, c *Configuration) *BitcoinParser {
p := &BitcoinParser{
BitcoinLikeParser: NewBitcoinLikeParser(params, c),
}
p.VSizeSupport = true
return p
}
// GetChainParams contains network parameters for the main Bitcoin network,
// the regression test Bitcoin network, the test Bitcoin network and
// the simulation test Bitcoin network, in this order
func GetChainParams(chain string) *chaincfg.Params {
if !chaincfg.IsRegistered(&chaincfg.MainNetParams) {
chaincfg.RegisterBitcoinParams()
}
switch chain {
case "test":
return &chaincfg.TestNet3Params
case "regtest":
return &chaincfg.RegressionNetParams
case "signet":
return &chaincfg.SigNetParams
}
return &chaincfg.MainNetParams
}
// ScriptPubKey contains data about output script
type ScriptPubKey struct {
// Asm string `json:"asm"`
Hex string `json:"hex,omitempty"`
// Type string `json:"type"`
Addresses []string `json:"addresses"` // removed from Bitcoind 22.0.0
Address string `json:"address"` // used in Bitcoind 22.0.0
}
// Vout contains data about tx output
type Vout struct {
ValueSat big.Int
JsonValue common.JSONNumber `json:"value"`
N uint32 `json:"n"`
ScriptPubKey ScriptPubKey `json:"scriptPubKey"`
}
// Tx is blockchain transaction
// unnecessary fields are commented out to avoid overhead
type Tx struct {
Hex string `json:"hex"`
Txid string `json:"txid"`
Version int32 `json:"version"`
LockTime uint32 `json:"locktime"`
VSize int64 `json:"vsize,omitempty"`
Vin []bchain.Vin `json:"vin"`
Vout []Vout `json:"vout"`
BlockHeight uint32 `json:"blockHeight,omitempty"`
// BlockHash string `json:"blockhash,omitempty"`
Confirmations uint32 `json:"confirmations,omitempty"`
Time int64 `json:"time,omitempty"`
Blocktime int64 `json:"blocktime,omitempty"`
CoinSpecificData interface{} `json:"-"`
}
// ParseTxFromJson parses JSON message containing transaction and returns Tx struct
// Bitcoind version 22.0.0 removed ScriptPubKey.Addresses from the API and replaced it by a single Address
func (p *BitcoinParser) ParseTxFromJson(msg json.RawMessage) (*bchain.Tx, error) {
var bitcoinTx Tx
var tx bchain.Tx
err := json.Unmarshal(msg, &bitcoinTx)
if err != nil {
return nil, err
}
// it is necessary to copy bitcoinTx to Tx to make it compatible
tx.Hex = bitcoinTx.Hex
tx.Txid = bitcoinTx.Txid
tx.Version = bitcoinTx.Version
tx.LockTime = bitcoinTx.LockTime
tx.VSize = bitcoinTx.VSize
tx.Vin = bitcoinTx.Vin
tx.BlockHeight = bitcoinTx.BlockHeight
tx.Confirmations = bitcoinTx.Confirmations
tx.Time = bitcoinTx.Time
tx.Blocktime = bitcoinTx.Blocktime
tx.CoinSpecificData = bitcoinTx.CoinSpecificData
tx.Vout = make([]bchain.Vout, len(bitcoinTx.Vout))
for i := range bitcoinTx.Vout {
bitcoinVout := &bitcoinTx.Vout[i]
vout := &tx.Vout[i]
// convert vout.JsonValue to big.Int and clear it, it is only temporary value used for unmarshal
vout.ValueSat, err = p.AmountToBigInt(bitcoinVout.JsonValue)
if err != nil {
return nil, err
}
vout.N = bitcoinVout.N
vout.ScriptPubKey.Hex = bitcoinVout.ScriptPubKey.Hex
// convert single Address to Addresses if Addresses are empty
if len(bitcoinVout.ScriptPubKey.Addresses) == 0 {
vout.ScriptPubKey.Addresses = []string{bitcoinVout.ScriptPubKey.Address}
} else {
vout.ScriptPubKey.Addresses = bitcoinVout.ScriptPubKey.Addresses
}
}
return &tx, nil
}