Add custom handling of unknown input txs during BitcoinType block import
This commit is contained in:
parent
d77fb35bb5
commit
341bf331c1
@ -7,6 +7,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gogo/protobuf/proto"
|
"github.com/gogo/protobuf/proto"
|
||||||
|
"github.com/golang/glog"
|
||||||
"github.com/juju/errors"
|
"github.com/juju/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -26,6 +27,16 @@ func (p *BaseParser) ParseTx(b []byte) (*Tx, error) {
|
|||||||
return nil, errors.New("ParseTx: not implemented")
|
return nil, errors.New("ParseTx: not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAddrDescForUnknownInput returns nil AddressDescriptor
|
||||||
|
func (p *BaseParser) GetAddrDescForUnknownInput(block *Block, tx *Tx, input int) AddressDescriptor {
|
||||||
|
var iTxid string
|
||||||
|
if len(tx.Vin) > input {
|
||||||
|
iTxid = tx.Vin[input].Txid
|
||||||
|
}
|
||||||
|
glog.Warningf("height %d, tx %v, input tx %v not found in txAddresses", block.Height, tx.Txid, iTxid)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
const zeros = "0000000000000000000000000000000000000000"
|
const zeros = "0000000000000000000000000000000000000000"
|
||||||
|
|
||||||
// AmountToBigInt converts amount in json.Number (string) to big.Int
|
// AmountToBigInt converts amount in json.Number (string) to big.Int
|
||||||
|
|||||||
@ -3,7 +3,12 @@ package liquid
|
|||||||
import (
|
import (
|
||||||
"blockbook/bchain"
|
"blockbook/bchain"
|
||||||
"blockbook/bchain/coins/btc"
|
"blockbook/bchain/coins/btc"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
vlq "github.com/bsm/go-vlq"
|
||||||
|
"github.com/golang/glog"
|
||||||
|
|
||||||
|
"github.com/martinboehm/btcd/txscript"
|
||||||
"github.com/martinboehm/btcd/wire"
|
"github.com/martinboehm/btcd/wire"
|
||||||
"github.com/martinboehm/btcutil/chaincfg"
|
"github.com/martinboehm/btcutil/chaincfg"
|
||||||
)
|
)
|
||||||
@ -27,15 +32,19 @@ func init() {
|
|||||||
// LiquidParser handle
|
// LiquidParser handle
|
||||||
type LiquidParser struct {
|
type LiquidParser struct {
|
||||||
*btc.BitcoinParser
|
*btc.BitcoinParser
|
||||||
baseparser *bchain.BaseParser
|
baseparser *bchain.BaseParser
|
||||||
|
origOutputScriptToAddressesFunc btc.OutputScriptToAddressesFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewLiquidParser returns new LiquidParser instance
|
// NewLiquidParser returns new LiquidParser instance
|
||||||
func NewLiquidParser(params *chaincfg.Params, c *btc.Configuration) *LiquidParser {
|
func NewLiquidParser(params *chaincfg.Params, c *btc.Configuration) *LiquidParser {
|
||||||
return &LiquidParser{
|
p := &LiquidParser{
|
||||||
BitcoinParser: btc.NewBitcoinParser(params, c),
|
BitcoinParser: btc.NewBitcoinParser(params, c),
|
||||||
baseparser: &bchain.BaseParser{},
|
baseparser: &bchain.BaseParser{},
|
||||||
}
|
}
|
||||||
|
p.origOutputScriptToAddressesFunc = p.OutputScriptToAddressesFunc
|
||||||
|
p.OutputScriptToAddressesFunc = p.outputScriptToAddresses
|
||||||
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetChainParams contains network parameters for the main GameCredits network,
|
// GetChainParams contains network parameters for the main GameCredits network,
|
||||||
@ -62,3 +71,36 @@ func (p *LiquidParser) PackTx(tx *bchain.Tx, height uint32, blockTime int64) ([]
|
|||||||
func (p *LiquidParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) {
|
func (p *LiquidParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) {
|
||||||
return p.baseparser.UnpackTx(buf)
|
return p.baseparser.UnpackTx(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAddrDescForUnknownInput processes inputs that were not found in txAddresses - they are bitcoin transactions
|
||||||
|
// create a special script for the input in the form OP_INVALIDOPCODE <txid> <vout varint>
|
||||||
|
func (p *LiquidParser) GetAddrDescForUnknownInput(block *bchain.Block, tx *bchain.Tx, input int) bchain.AddressDescriptor {
|
||||||
|
var iTxid string
|
||||||
|
s := make([]byte, 0, 40)
|
||||||
|
if len(tx.Vin) > input {
|
||||||
|
iTxid = tx.Vin[input].Txid
|
||||||
|
btxID, err := p.PackTxid(iTxid)
|
||||||
|
if err == nil {
|
||||||
|
buf := make([]byte, vlq.MaxLen64)
|
||||||
|
l := vlq.PutInt(buf, int64(tx.Vin[input].Vout))
|
||||||
|
s = append(s, txscript.OP_INVALIDOPCODE)
|
||||||
|
s = append(s, btxID...)
|
||||||
|
s = append(s, buf[:l]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
glog.Info("height ", block.Height, ", tx ", tx.Txid, ", encountered Bitcoin tx ", iTxid)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// outputScriptToAddresses converts ScriptPubKey to bitcoin addresses
|
||||||
|
func (p *LiquidParser) outputScriptToAddresses(script []byte) ([]string, bool, error) {
|
||||||
|
// minimum length of the special script OP_INVALIDOPCODE <txid> <index varint> is 34 bytes (1 byte opcode, 32 bytes tx, 1 byte vout)
|
||||||
|
if len(script) > 33 && script[0] == txscript.OP_INVALIDOPCODE {
|
||||||
|
txid, _ := p.UnpackTxid(script[1:33])
|
||||||
|
vout, _ := vlq.Int(script[33:])
|
||||||
|
return []string{
|
||||||
|
"Bitcoin tx " + txid + ":" + strconv.Itoa(int(vout)),
|
||||||
|
}, false, nil
|
||||||
|
}
|
||||||
|
return p.origOutputScriptToAddressesFunc(script)
|
||||||
|
}
|
||||||
|
|||||||
@ -256,6 +256,7 @@ type BlockChainParser interface {
|
|||||||
ParseTxFromJson(json.RawMessage) (*Tx, error)
|
ParseTxFromJson(json.RawMessage) (*Tx, error)
|
||||||
PackTx(tx *Tx, height uint32, blockTime int64) ([]byte, error)
|
PackTx(tx *Tx, height uint32, blockTime int64) ([]byte, error)
|
||||||
UnpackTx(buf []byte) (*Tx, uint32, error)
|
UnpackTx(buf []byte) (*Tx, uint32, error)
|
||||||
|
GetAddrDescForUnknownInput(block *Block, tx *Tx, input int) AddressDescriptor
|
||||||
// blocks
|
// blocks
|
||||||
PackBlockHash(hash string) ([]byte, error)
|
PackBlockHash(hash string) ([]byte, error)
|
||||||
UnpackBlockHash(buf []byte) (string, error)
|
UnpackBlockHash(buf []byte) (string, error)
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/bsm/go-vlq"
|
vlq "github.com/bsm/go-vlq"
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"github.com/juju/errors"
|
"github.com/juju/errors"
|
||||||
"github.com/tecbot/gorocksdb"
|
"github.com/tecbot/gorocksdb"
|
||||||
@ -490,7 +490,8 @@ func (d *RocksDB) processAddressesBitcoinType(block *bchain.Block, addresses add
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if ita == nil {
|
if ita == nil {
|
||||||
glog.Warningf("rocksdb: height %d, tx %v, input tx %v not found in txAddresses", block.Height, tx.Txid, input.Txid)
|
// allow parser to process unknown input, some coins may implement special handling, default is to log warning
|
||||||
|
tai.AddrDesc = d.chainParser.GetAddrDescForUnknownInput(block, tx, i)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
txAddressesMap[stxID] = ita
|
txAddressesMap[stxID] = ita
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user