Make AddressDescriptor as type,expose DB/mempool methods working with it
This commit is contained in:
parent
1a931d8a65
commit
676aabfaa6
@ -79,7 +79,7 @@ func GetChainParams(chain string) *chaincfg.Params {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetAddrDescFromAddress returns internal address representation of given address
|
// GetAddrDescFromAddress returns internal address representation of given address
|
||||||
func (p *BCashParser) GetAddrDescFromAddress(address string) ([]byte, error) {
|
func (p *BCashParser) GetAddrDescFromAddress(address string) (bchain.AddressDescriptor, error) {
|
||||||
return p.addressToOutputScript(address)
|
return p.addressToOutputScript(address)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -205,6 +205,11 @@ func (c *blockChainWithMetrics) GetMempoolTransactions(address string) (v []stri
|
|||||||
return c.b.GetMempoolTransactions(address)
|
return c.b.GetMempoolTransactions(address)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *blockChainWithMetrics) GetMempoolTransactionsForAddrDesc(addrDesc bchain.AddressDescriptor) (v []string, err error) {
|
||||||
|
defer func(s time.Time) { c.observeRPCLatency("GetMempoolTransactionsForAddrDesc", s, err) }(time.Now())
|
||||||
|
return c.b.GetMempoolTransactionsForAddrDesc(addrDesc)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *blockChainWithMetrics) GetMempoolEntry(txid string) (v *bchain.MempoolEntry, err error) {
|
func (c *blockChainWithMetrics) GetMempoolEntry(txid string) (v *bchain.MempoolEntry, err error) {
|
||||||
defer func(s time.Time) { c.observeRPCLatency("GetMempoolEntry", s, err) }(time.Now())
|
defer func(s time.Time) { c.observeRPCLatency("GetMempoolEntry", s, err) }(time.Now())
|
||||||
return c.b.GetMempoolEntry(txid)
|
return c.b.GetMempoolEntry(txid)
|
||||||
|
|||||||
@ -52,22 +52,22 @@ func GetChainParams(chain string) *chaincfg.Params {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetAddrDescFromVout returns internal address representation (descriptor) of given transaction output
|
// GetAddrDescFromVout returns internal address representation (descriptor) of given transaction output
|
||||||
func (p *BitcoinParser) GetAddrDescFromVout(output *bchain.Vout) ([]byte, error) {
|
func (p *BitcoinParser) GetAddrDescFromVout(output *bchain.Vout) (bchain.AddressDescriptor, error) {
|
||||||
return hex.DecodeString(output.ScriptPubKey.Hex)
|
return hex.DecodeString(output.ScriptPubKey.Hex)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAddrDescFromAddress returns internal address representation (descriptor) of given address
|
// GetAddrDescFromAddress returns internal address representation (descriptor) of given address
|
||||||
func (p *BitcoinParser) GetAddrDescFromAddress(address string) ([]byte, error) {
|
func (p *BitcoinParser) GetAddrDescFromAddress(address string) (bchain.AddressDescriptor, error) {
|
||||||
return p.addressToOutputScript(address)
|
return p.addressToOutputScript(address)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAddressesFromAddrDesc returns addresses for given address descriptor with flag if the addresses are searchable
|
// GetAddressesFromAddrDesc returns addresses for given address descriptor with flag if the addresses are searchable
|
||||||
func (p *BitcoinParser) GetAddressesFromAddrDesc(addrDesc []byte) ([]string, bool, error) {
|
func (p *BitcoinParser) GetAddressesFromAddrDesc(addrDesc bchain.AddressDescriptor) ([]string, bool, error) {
|
||||||
return p.OutputScriptToAddressesFunc(addrDesc)
|
return p.OutputScriptToAddressesFunc(addrDesc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetScriptFromAddrDesc returns output script for given address descriptor
|
// GetScriptFromAddrDesc returns output script for given address descriptor
|
||||||
func (p *BitcoinParser) GetScriptFromAddrDesc(addrDesc []byte) ([]byte, error) {
|
func (p *BitcoinParser) GetScriptFromAddrDesc(addrDesc bchain.AddressDescriptor) ([]byte, error) {
|
||||||
return addrDesc, nil
|
return addrDesc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -617,12 +617,17 @@ func (b *BitcoinRPC) ResyncMempool(onNewTxAddr func(txid string, addr string)) (
|
|||||||
return b.Mempool.Resync(onNewTxAddr)
|
return b.Mempool.Resync(onNewTxAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMempoolTransactions returns slice of mempool transactions for given address.
|
// GetMempoolTransactions returns slice of mempool transactions for given address
|
||||||
func (b *BitcoinRPC) GetMempoolTransactions(address string) ([]string, error) {
|
func (b *BitcoinRPC) GetMempoolTransactions(address string) ([]string, error) {
|
||||||
return b.Mempool.GetTransactions(address)
|
return b.Mempool.GetTransactions(address)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EstimateSmartFee returns fee estimation.
|
// GetMempoolTransactionsForAddrDesc returns slice of mempool transactions for given address descriptor
|
||||||
|
func (b *BitcoinRPC) GetMempoolTransactionsForAddrDesc(addrDesc bchain.AddressDescriptor) ([]string, error) {
|
||||||
|
return b.Mempool.GetAddrDescTransactions(addrDesc)
|
||||||
|
}
|
||||||
|
|
||||||
|
// EstimateSmartFee returns fee estimation
|
||||||
func (b *BitcoinRPC) EstimateSmartFee(blocks int, conservative bool) (big.Int, error) {
|
func (b *BitcoinRPC) EstimateSmartFee(blocks int, conservative bool) (big.Int, error) {
|
||||||
// use EstimateFee if EstimateSmartFee is not supported
|
// use EstimateFee if EstimateSmartFee is not supported
|
||||||
if !b.ChainConfig.SupportsEstimateSmartFee && b.ChainConfig.SupportsEstimateFee {
|
if !b.ChainConfig.SupportsEstimateSmartFee && b.ChainConfig.SupportsEstimateFee {
|
||||||
|
|||||||
@ -119,7 +119,7 @@ func (p *EthereumParser) ethTxToTx(tx *rpcTransaction, blocktime int64, confirma
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetAddrDescFromVout returns internal address representation of given transaction output
|
// GetAddrDescFromVout returns internal address representation of given transaction output
|
||||||
func (p *EthereumParser) GetAddrDescFromVout(output *bchain.Vout) ([]byte, error) {
|
func (p *EthereumParser) GetAddrDescFromVout(output *bchain.Vout) (bchain.AddressDescriptor, error) {
|
||||||
if len(output.ScriptPubKey.Addresses) != 1 {
|
if len(output.ScriptPubKey.Addresses) != 1 {
|
||||||
return nil, bchain.ErrAddressMissing
|
return nil, bchain.ErrAddressMissing
|
||||||
}
|
}
|
||||||
@ -131,7 +131,7 @@ func has0xPrefix(s string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetAddrDescFromAddress returns internal address representation of given address
|
// GetAddrDescFromAddress returns internal address representation of given address
|
||||||
func (p *EthereumParser) GetAddrDescFromAddress(address string) ([]byte, error) {
|
func (p *EthereumParser) GetAddrDescFromAddress(address string) (bchain.AddressDescriptor, error) {
|
||||||
// github.com/ethereum/go-ethereum/common.HexToAddress does not handle address errors, using own decoding
|
// github.com/ethereum/go-ethereum/common.HexToAddress does not handle address errors, using own decoding
|
||||||
if has0xPrefix(address) {
|
if has0xPrefix(address) {
|
||||||
address = address[2:]
|
address = address[2:]
|
||||||
@ -146,12 +146,12 @@ func (p *EthereumParser) GetAddrDescFromAddress(address string) ([]byte, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetAddressesFromAddrDesc returns addresses for given address descriptor with flag if the addresses are searchable
|
// GetAddressesFromAddrDesc returns addresses for given address descriptor with flag if the addresses are searchable
|
||||||
func (p *EthereumParser) GetAddressesFromAddrDesc(addrDesc []byte) ([]string, bool, error) {
|
func (p *EthereumParser) GetAddressesFromAddrDesc(addrDesc bchain.AddressDescriptor) ([]string, bool, error) {
|
||||||
return []string{hexutil.Encode(addrDesc)}, true, nil
|
return []string{hexutil.Encode(addrDesc)}, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetScriptFromAddrDesc returns output script for given address descriptor
|
// GetScriptFromAddrDesc returns output script for given address descriptor
|
||||||
func (p *EthereumParser) GetScriptFromAddrDesc(addrDesc []byte) ([]byte, error) {
|
func (p *EthereumParser) GetScriptFromAddrDesc(addrDesc bchain.AddressDescriptor) ([]byte, error) {
|
||||||
return addrDesc, nil
|
return addrDesc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -480,12 +480,12 @@ func (b *EthereumRPC) GetMempool() ([]string, error) {
|
|||||||
return body.Transactions, nil
|
return body.Transactions, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// EstimateFee returns fee estimation.
|
// EstimateFee returns fee estimation
|
||||||
func (b *EthereumRPC) EstimateFee(blocks int) (big.Int, error) {
|
func (b *EthereumRPC) EstimateFee(blocks int) (big.Int, error) {
|
||||||
return b.EstimateSmartFee(blocks, true)
|
return b.EstimateSmartFee(blocks, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EstimateSmartFee returns fee estimation.
|
// EstimateSmartFee returns fee estimation
|
||||||
func (b *EthereumRPC) EstimateSmartFee(blocks int, conservative bool) (big.Int, error) {
|
func (b *EthereumRPC) EstimateSmartFee(blocks int, conservative bool) (big.Int, error) {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), b.timeout)
|
ctx, cancel := context.WithTimeout(context.Background(), b.timeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
@ -503,7 +503,7 @@ func (b *EthereumRPC) EstimateSmartFee(blocks int, conservative bool) (big.Int,
|
|||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendRawTransaction sends raw transaction.
|
// SendRawTransaction sends raw transaction
|
||||||
func (b *EthereumRPC) SendRawTransaction(tx string) (string, error) {
|
func (b *EthereumRPC) SendRawTransaction(tx string) (string, error) {
|
||||||
return "", errors.New("SendRawTransaction: not implemented")
|
return "", errors.New("SendRawTransaction: not implemented")
|
||||||
}
|
}
|
||||||
@ -512,10 +512,16 @@ func (b *EthereumRPC) ResyncMempool(onNewTxAddr func(txid string, addr string))
|
|||||||
return b.Mempool.Resync(onNewTxAddr)
|
return b.Mempool.Resync(onNewTxAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetMempoolTransactions returns slice of mempool transactions for given address
|
||||||
func (b *EthereumRPC) GetMempoolTransactions(address string) ([]string, error) {
|
func (b *EthereumRPC) GetMempoolTransactions(address string) ([]string, error) {
|
||||||
return b.Mempool.GetTransactions(address)
|
return b.Mempool.GetTransactions(address)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetMempoolTransactionsForAddrDesc returns slice of mempool transactions for given address descriptor
|
||||||
|
func (b *EthereumRPC) GetMempoolTransactionsForAddrDesc(addrDesc bchain.AddressDescriptor) ([]string, error) {
|
||||||
|
return b.Mempool.GetAddrDescTransactions(addrDesc)
|
||||||
|
}
|
||||||
|
|
||||||
func (b *EthereumRPC) GetMempoolEntry(txid string) (*bchain.MempoolEntry, error) {
|
func (b *EthereumRPC) GetMempoolEntry(txid string) (*bchain.MempoolEntry, error) {
|
||||||
return nil, errors.New("GetMempoolEntry: not implemented")
|
return nil, errors.New("GetMempoolEntry: not implemented")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package monacoin
|
package monacoin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"blockbook/bchain"
|
||||||
"blockbook/bchain/coins/btc"
|
"blockbook/bchain/coins/btc"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/chaincfg"
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
@ -89,8 +90,8 @@ func GetMonaChainParams(chain string) *monacoinCfg.Params {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAddrIDFromAddress returns internal address representation of given address
|
// GetAddrDescFromAddress returns internal address representation (descriptor) of given address
|
||||||
func (p *MonacoinParser) GetAddrIDFromAddress(address string) ([]byte, error) {
|
func (p *MonacoinParser) GetAddrDescFromAddress(address string) (bchain.AddressDescriptor, error) {
|
||||||
return p.addressToOutputScript(address)
|
return p.addressToOutputScript(address)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -121,6 +121,81 @@ func Test_GetAddrDescFromAddress_Mainnet(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_GetAddressesFromAddrDesc(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
script string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want []string
|
||||||
|
want2 bool
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "P2PKH",
|
||||||
|
args: args{script: "76a91451dadacc7021440cbe4ca148a5db563b329b4c0388ac"},
|
||||||
|
want: []string{"MFMy9FwJsV6HiN5eZDqDETw4pw52q3UGrb"},
|
||||||
|
want2: true,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "P2SH",
|
||||||
|
args: args{script: "a9146449f568c9cd2378138f2636e1567112a184a9e887"},
|
||||||
|
want: []string{"PHjTKtgYLTJ9D2Bzw2f6xBB41KBm2HeGfg"},
|
||||||
|
want2: true,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "P2WPKH",
|
||||||
|
args: args{script: "0014a96d3cef194f469b33801f868ec9bc89a8831c22"},
|
||||||
|
want: []string{"mona1q49knemcefarfkvuqr7rgajdu3x5gx8pzdnurgq"},
|
||||||
|
want2: true,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "P2WSH",
|
||||||
|
args: args{script: "002009d27aa88e70cb7a0da620908c9bc08ac6c633bd1a61036312e514396aeb4893"},
|
||||||
|
want: []string{"mona1qp8f842ywwr9h5rdxyzggex7q3trvvvaarfssxccju52rj6htfzfsqr79j2"},
|
||||||
|
want2: true,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "OP_RETURN ascii",
|
||||||
|
args: args{script: "6a0461686f6a"},
|
||||||
|
want: []string{"OP_RETURN (ahoj)"},
|
||||||
|
want2: false,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "OP_RETURN hex",
|
||||||
|
args: args{script: "6a072020f1686f6a20"},
|
||||||
|
want: []string{"OP_RETURN 07 2020f1686f6a20"},
|
||||||
|
want2: false,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
parser := NewMonacoinParser(GetChainParams("main"), &btc.Configuration{})
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
b, _ := hex.DecodeString(tt.args.script)
|
||||||
|
got, got2, err := parser.GetAddressesFromAddrDesc(b)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("outputScriptToAddresses() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("GetAddressesFromAddrDesc() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(got2, tt.want2) {
|
||||||
|
t.Errorf("GetAddressesFromAddrDesc() = %v, want %v", got2, tt.want2)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
testTx1 bchain.Tx
|
testTx1 bchain.Tx
|
||||||
|
|
||||||
|
|||||||
@ -52,7 +52,7 @@ func GetChainParams(chain string) *chaincfg.Params {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetAddrDescFromVout returns internal address representation of given transaction output
|
// GetAddrDescFromVout returns internal address representation of given transaction output
|
||||||
func (p *ZCashParser) GetAddrDescFromVout(output *bchain.Vout) ([]byte, error) {
|
func (p *ZCashParser) GetAddrDescFromVout(output *bchain.Vout) (bchain.AddressDescriptor, error) {
|
||||||
if len(output.ScriptPubKey.Addresses) != 1 {
|
if len(output.ScriptPubKey.Addresses) != 1 {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@ -61,19 +61,19 @@ func (p *ZCashParser) GetAddrDescFromVout(output *bchain.Vout) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetAddrDescFromAddress returns internal address representation of given address
|
// GetAddrDescFromAddress returns internal address representation of given address
|
||||||
func (p *ZCashParser) GetAddrDescFromAddress(address string) ([]byte, error) {
|
func (p *ZCashParser) GetAddrDescFromAddress(address string) (bchain.AddressDescriptor, error) {
|
||||||
hash, _, err := utils.CheckDecode(address)
|
hash, _, err := utils.CheckDecode(address)
|
||||||
return hash, err
|
return hash, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAddressesFromAddrDesc returns addresses for given address descriptor with flag if the addresses are searchable
|
// GetAddressesFromAddrDesc returns addresses for given address descriptor with flag if the addresses are searchable
|
||||||
func (p *ZCashParser) GetAddressesFromAddrDesc(addrDesc []byte) ([]string, bool, error) {
|
func (p *ZCashParser) GetAddressesFromAddrDesc(addrDesc bchain.AddressDescriptor) ([]string, bool, error) {
|
||||||
// TODO implement
|
// TODO implement
|
||||||
return nil, false, errors.New("GetAddressesFromAddrDesc: not implemented")
|
return nil, false, errors.New("GetAddressesFromAddrDesc: not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetScriptFromAddrDesc returns output script for given address descriptor
|
// GetScriptFromAddrDesc returns output script for given address descriptor
|
||||||
func (p *ZCashParser) GetScriptFromAddrDesc(addrDesc []byte) ([]byte, error) {
|
func (p *ZCashParser) GetScriptFromAddrDesc(addrDesc bchain.AddressDescriptor) ([]byte, error) {
|
||||||
// TODO implement
|
// TODO implement
|
||||||
return nil, errors.New("GetScriptFromAddrDesc: not implemented")
|
return nil, errors.New("GetScriptFromAddrDesc: not implemented")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ type NonUTXOMempool struct {
|
|||||||
chain BlockChain
|
chain BlockChain
|
||||||
mux sync.Mutex
|
mux sync.Mutex
|
||||||
txToInputOutput map[string][]addrIndex
|
txToInputOutput map[string][]addrIndex
|
||||||
addrDescToTx map[string][]outpoint
|
addrDescToTx map[string][]outpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewNonUTXOMempool creates new mempool handler.
|
// NewNonUTXOMempool creates new mempool handler.
|
||||||
@ -27,6 +27,11 @@ func (m *NonUTXOMempool) GetTransactions(address string) ([]string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
return m.GetAddrDescTransactions(addrDesc)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAddrDescTransactions returns slice of mempool transactions for given address descriptor
|
||||||
|
func (m *NonUTXOMempool) GetAddrDescTransactions(addrDesc AddressDescriptor) ([]string, error) {
|
||||||
m.mux.Lock()
|
m.mux.Lock()
|
||||||
defer m.mux.Unlock()
|
defer m.mux.Unlock()
|
||||||
outpoints := m.addrDescToTx[string(addrDesc)]
|
outpoints := m.addrDescToTx[string(addrDesc)]
|
||||||
|
|||||||
@ -74,6 +74,11 @@ func (m *UTXOMempool) GetTransactions(address string) ([]string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
return m.GetAddrDescTransactions(addrDesc)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAddrDescTransactions returns slice of mempool transactions for given address descriptor
|
||||||
|
func (m *UTXOMempool) GetAddrDescTransactions(addrDesc AddressDescriptor) ([]string, error) {
|
||||||
m.mux.Lock()
|
m.mux.Lock()
|
||||||
defer m.mux.Unlock()
|
defer m.mux.Unlock()
|
||||||
outpoints := m.addrDescToTx[string(addrDesc)]
|
outpoints := m.addrDescToTx[string(addrDesc)]
|
||||||
|
|||||||
@ -111,6 +111,9 @@ func (e *RPCError) Error() string {
|
|||||||
return fmt.Sprintf("%d: %s", e.Code, e.Message)
|
return fmt.Sprintf("%d: %s", e.Code, e.Message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddressDescriptor is an opaque type obtained by parser.GetAddrDesc* methods
|
||||||
|
type AddressDescriptor []byte
|
||||||
|
|
||||||
// BlockChain defines common interface to block chain daemon
|
// BlockChain defines common interface to block chain daemon
|
||||||
type BlockChain interface {
|
type BlockChain interface {
|
||||||
// life-cycle methods
|
// life-cycle methods
|
||||||
@ -137,6 +140,7 @@ type BlockChain interface {
|
|||||||
// mempool
|
// mempool
|
||||||
ResyncMempool(onNewTxAddr func(txid string, addr string)) (int, error)
|
ResyncMempool(onNewTxAddr func(txid string, addr string)) (int, error)
|
||||||
GetMempoolTransactions(address string) ([]string, error)
|
GetMempoolTransactions(address string) ([]string, error)
|
||||||
|
GetMempoolTransactionsForAddrDesc(addrDesc AddressDescriptor) ([]string, error)
|
||||||
GetMempoolEntry(txid string) (*MempoolEntry, error)
|
GetMempoolEntry(txid string) (*MempoolEntry, error)
|
||||||
// parser
|
// parser
|
||||||
GetChainParser() BlockChainParser
|
GetChainParser() BlockChainParser
|
||||||
@ -158,10 +162,10 @@ type BlockChainParser interface {
|
|||||||
// it uses string operations to avoid problems with rounding
|
// it uses string operations to avoid problems with rounding
|
||||||
AmountToBigInt(n json.Number) (big.Int, error)
|
AmountToBigInt(n json.Number) (big.Int, error)
|
||||||
// address descriptor conversions
|
// address descriptor conversions
|
||||||
GetAddrDescFromVout(output *Vout) ([]byte, error)
|
GetAddrDescFromVout(output *Vout) (AddressDescriptor, error)
|
||||||
GetAddrDescFromAddress(address string) ([]byte, error)
|
GetAddrDescFromAddress(address string) (AddressDescriptor, error)
|
||||||
GetAddressesFromAddrDesc(addrDesc []byte) ([]string, bool, error)
|
GetAddressesFromAddrDesc(addrDesc AddressDescriptor) ([]string, bool, error)
|
||||||
GetScriptFromAddrDesc(addrDesc []byte) ([]byte, error)
|
GetScriptFromAddrDesc(addrDesc AddressDescriptor) ([]byte, error)
|
||||||
// transactions
|
// transactions
|
||||||
PackedTxidLen() int
|
PackedTxidLen() int
|
||||||
PackTxid(txid string) ([]byte, error)
|
PackTxid(txid string) ([]byte, error)
|
||||||
|
|||||||
@ -155,6 +155,13 @@ func (d *RocksDB) GetMemoryStats() string {
|
|||||||
return fmt.Sprintf("%+v", m)
|
return fmt.Sprintf("%+v", m)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StopIteration is returned by callback function to signal stop of iteration
|
||||||
|
type StopIteration struct{}
|
||||||
|
|
||||||
|
func (e *StopIteration) Error() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
// GetTransactions finds all input/output transactions for address
|
// GetTransactions finds all input/output transactions for address
|
||||||
// Transaction are passed to callback function.
|
// Transaction are passed to callback function.
|
||||||
func (d *RocksDB) GetTransactions(address string, lower uint32, higher uint32, fn func(txid string, vout uint32, isOutput bool) error) (err error) {
|
func (d *RocksDB) GetTransactions(address string, lower uint32, higher uint32, fn func(txid string, vout uint32, isOutput bool) error) (err error) {
|
||||||
@ -165,7 +172,12 @@ func (d *RocksDB) GetTransactions(address string, lower uint32, higher uint32, f
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
return d.GetAddrDescTransactions(addrDesc, lower, higher, fn)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAddrDescTransactions finds all input/output transactions for address descriptor
|
||||||
|
// Transaction are passed to callback function.
|
||||||
|
func (d *RocksDB) GetAddrDescTransactions(addrDesc bchain.AddressDescriptor, lower uint32, higher uint32, fn func(txid string, vout uint32, isOutput bool) error) (err error) {
|
||||||
kstart := packAddressKey(addrDesc, lower)
|
kstart := packAddressKey(addrDesc, lower)
|
||||||
kstop := packAddressKey(addrDesc, higher)
|
kstop := packAddressKey(addrDesc, higher)
|
||||||
|
|
||||||
@ -200,6 +212,9 @@ func (d *RocksDB) GetTransactions(address string, lower uint32, higher uint32, f
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := fn(tx, vout, isOutput); err != nil {
|
if err := fn(tx, vout, isOutput); err != nil {
|
||||||
|
if _, ok := err.(*StopIteration); ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -281,22 +296,22 @@ type outpoint struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type TxInput struct {
|
type TxInput struct {
|
||||||
addrDesc []byte
|
AddrDesc bchain.AddressDescriptor
|
||||||
ValueSat big.Int
|
ValueSat big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ti *TxInput) Addresses(p bchain.BlockChainParser) ([]string, bool, error) {
|
func (ti *TxInput) Addresses(p bchain.BlockChainParser) ([]string, bool, error) {
|
||||||
return p.GetAddressesFromAddrDesc(ti.addrDesc)
|
return p.GetAddressesFromAddrDesc(ti.AddrDesc)
|
||||||
}
|
}
|
||||||
|
|
||||||
type TxOutput struct {
|
type TxOutput struct {
|
||||||
addrDesc []byte
|
AddrDesc bchain.AddressDescriptor
|
||||||
Spent bool
|
Spent bool
|
||||||
ValueSat big.Int
|
ValueSat big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (to *TxOutput) Addresses(p bchain.BlockChainParser) ([]string, bool, error) {
|
func (to *TxOutput) Addresses(p bchain.BlockChainParser) ([]string, bool, error) {
|
||||||
return p.GetAddressesFromAddrDesc(to.addrDesc)
|
return p.GetAddressesFromAddrDesc(to.AddrDesc)
|
||||||
}
|
}
|
||||||
|
|
||||||
type TxAddresses struct {
|
type TxAddresses struct {
|
||||||
@ -322,7 +337,7 @@ type blockTxs struct {
|
|||||||
inputs []outpoint
|
inputs []outpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *RocksDB) resetValueSatToZero(valueSat *big.Int, addrDesc []byte, logText string) {
|
func (d *RocksDB) resetValueSatToZero(valueSat *big.Int, addrDesc bchain.AddressDescriptor, logText string) {
|
||||||
ad, _, err := d.chainParser.GetAddressesFromAddrDesc(addrDesc)
|
ad, _, err := d.chainParser.GetAddressesFromAddrDesc(addrDesc)
|
||||||
had := hex.EncodeToString(addrDesc)
|
had := hex.EncodeToString(addrDesc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -363,7 +378,7 @@ func (d *RocksDB) processAddressesUTXO(block *bchain.Block, addresses map[string
|
|||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
tao.addrDesc = addrDesc
|
tao.AddrDesc = addrDesc
|
||||||
strAddrDesc := string(addrDesc)
|
strAddrDesc := string(addrDesc)
|
||||||
// check that the address was used already in this block
|
// check that the address was used already in this block
|
||||||
o, processed := addresses[strAddrDesc]
|
o, processed := addresses[strAddrDesc]
|
||||||
@ -377,7 +392,7 @@ func (d *RocksDB) processAddressesUTXO(block *bchain.Block, addresses map[string
|
|||||||
})
|
})
|
||||||
ab, e := balances[strAddrDesc]
|
ab, e := balances[strAddrDesc]
|
||||||
if !e {
|
if !e {
|
||||||
ab, err = d.getAddrDescBalance(addrDesc)
|
ab, err = d.GetAddrDescBalance(addrDesc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -431,18 +446,18 @@ func (d *RocksDB) processAddressesUTXO(block *bchain.Block, addresses map[string
|
|||||||
if ot.Spent {
|
if ot.Spent {
|
||||||
glog.Warningf("rocksdb: height %d, tx %v, input tx %v vout %v is double spend", block.Height, tx.Txid, input.Txid, input.Vout)
|
glog.Warningf("rocksdb: height %d, tx %v, input tx %v vout %v is double spend", block.Height, tx.Txid, input.Txid, input.Vout)
|
||||||
}
|
}
|
||||||
tai.addrDesc = ot.addrDesc
|
tai.AddrDesc = ot.AddrDesc
|
||||||
tai.ValueSat = ot.ValueSat
|
tai.ValueSat = ot.ValueSat
|
||||||
// mark the output as spent in tx
|
// mark the output as spent in tx
|
||||||
ot.Spent = true
|
ot.Spent = true
|
||||||
if len(ot.addrDesc) == 0 {
|
if len(ot.AddrDesc) == 0 {
|
||||||
if !logged {
|
if !logged {
|
||||||
glog.Warningf("rocksdb: height %d, tx %v, input tx %v vout %v skipping empty address", block.Height, tx.Txid, input.Txid, input.Vout)
|
glog.Warningf("rocksdb: height %d, tx %v, input tx %v vout %v skipping empty address", block.Height, tx.Txid, input.Txid, input.Vout)
|
||||||
logged = true
|
logged = true
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
strAddrDesc := string(ot.addrDesc)
|
strAddrDesc := string(ot.AddrDesc)
|
||||||
// check that the address was used already in this block
|
// check that the address was used already in this block
|
||||||
o, processed := addresses[strAddrDesc]
|
o, processed := addresses[strAddrDesc]
|
||||||
if processed {
|
if processed {
|
||||||
@ -455,7 +470,7 @@ func (d *RocksDB) processAddressesUTXO(block *bchain.Block, addresses map[string
|
|||||||
})
|
})
|
||||||
ab, e := balances[strAddrDesc]
|
ab, e := balances[strAddrDesc]
|
||||||
if !e {
|
if !e {
|
||||||
ab, err = d.getAddrDescBalance(ot.addrDesc)
|
ab, err = d.GetAddrDescBalance(ot.AddrDesc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -470,7 +485,7 @@ func (d *RocksDB) processAddressesUTXO(block *bchain.Block, addresses map[string
|
|||||||
}
|
}
|
||||||
ab.BalanceSat.Sub(&ab.BalanceSat, &ot.ValueSat)
|
ab.BalanceSat.Sub(&ab.BalanceSat, &ot.ValueSat)
|
||||||
if ab.BalanceSat.Sign() < 0 {
|
if ab.BalanceSat.Sign() < 0 {
|
||||||
d.resetValueSatToZero(&ab.BalanceSat, ot.addrDesc, "balance")
|
d.resetValueSatToZero(&ab.BalanceSat, ot.AddrDesc, "balance")
|
||||||
}
|
}
|
||||||
ab.SentSat.Add(&ab.SentSat, &ot.ValueSat)
|
ab.SentSat.Add(&ab.SentSat, &ot.ValueSat)
|
||||||
}
|
}
|
||||||
@ -489,7 +504,7 @@ func processedInTx(o []outpoint, btxID []byte) bool {
|
|||||||
|
|
||||||
func (d *RocksDB) storeAddresses(wb *gorocksdb.WriteBatch, height uint32, addresses map[string][]outpoint) error {
|
func (d *RocksDB) storeAddresses(wb *gorocksdb.WriteBatch, height uint32, addresses map[string][]outpoint) error {
|
||||||
for addrDesc, outpoints := range addresses {
|
for addrDesc, outpoints := range addresses {
|
||||||
ba := []byte(addrDesc)
|
ba := bchain.AddressDescriptor(addrDesc)
|
||||||
key := packAddressKey(ba, height)
|
key := packAddressKey(ba, height)
|
||||||
val := d.packOutpoints(outpoints)
|
val := d.packOutpoints(outpoints)
|
||||||
wb.PutCF(d.cfh[cfAddresses], key, val)
|
wb.PutCF(d.cfh[cfAddresses], key, val)
|
||||||
@ -513,14 +528,14 @@ func (d *RocksDB) storeBalances(wb *gorocksdb.WriteBatch, abm map[string]*AddrBa
|
|||||||
for addrDesc, ab := range abm {
|
for addrDesc, ab := range abm {
|
||||||
// balance with 0 transactions is removed from db - happens in disconnect
|
// balance with 0 transactions is removed from db - happens in disconnect
|
||||||
if ab == nil || ab.Txs <= 0 {
|
if ab == nil || ab.Txs <= 0 {
|
||||||
wb.DeleteCF(d.cfh[cfAddressBalance], []byte(addrDesc))
|
wb.DeleteCF(d.cfh[cfAddressBalance], bchain.AddressDescriptor(addrDesc))
|
||||||
} else {
|
} else {
|
||||||
l := packVaruint(uint(ab.Txs), buf)
|
l := packVaruint(uint(ab.Txs), buf)
|
||||||
ll := packBigint(&ab.SentSat, buf[l:])
|
ll := packBigint(&ab.SentSat, buf[l:])
|
||||||
l += ll
|
l += ll
|
||||||
ll = packBigint(&ab.BalanceSat, buf[l:])
|
ll = packBigint(&ab.BalanceSat, buf[l:])
|
||||||
l += ll
|
l += ll
|
||||||
wb.PutCF(d.cfh[cfAddressBalance], []byte(addrDesc), buf[:l])
|
wb.PutCF(d.cfh[cfAddressBalance], bchain.AddressDescriptor(addrDesc), buf[:l])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -609,7 +624,7 @@ func (d *RocksDB) getBlockTxs(height uint32) ([]blockTxs, error) {
|
|||||||
return bt, nil
|
return bt, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *RocksDB) getAddrDescBalance(addrDesc []byte) (*AddrBalance, error) {
|
func (d *RocksDB) GetAddrDescBalance(addrDesc bchain.AddressDescriptor) (*AddrBalance, error) {
|
||||||
val, err := d.db.GetCF(d.ro, d.cfh[cfAddressBalance], addrDesc)
|
val, err := d.db.GetCF(d.ro, d.cfh[cfAddressBalance], addrDesc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -636,7 +651,7 @@ func (d *RocksDB) GetAddressBalance(address string) (*AddrBalance, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return d.getAddrDescBalance(addrDesc)
|
return d.GetAddrDescBalance(addrDesc)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *RocksDB) getTxAddresses(btxID []byte) (*TxAddresses, error) {
|
func (d *RocksDB) getTxAddresses(btxID []byte) (*TxAddresses, error) {
|
||||||
@ -680,23 +695,23 @@ func packTxAddresses(ta *TxAddresses, buf []byte, varBuf []byte) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func appendTxInput(txi *TxInput, buf []byte, varBuf []byte) []byte {
|
func appendTxInput(txi *TxInput, buf []byte, varBuf []byte) []byte {
|
||||||
la := len(txi.addrDesc)
|
la := len(txi.AddrDesc)
|
||||||
l := packVaruint(uint(la), varBuf)
|
l := packVaruint(uint(la), varBuf)
|
||||||
buf = append(buf, varBuf[:l]...)
|
buf = append(buf, varBuf[:l]...)
|
||||||
buf = append(buf, txi.addrDesc...)
|
buf = append(buf, txi.AddrDesc...)
|
||||||
l = packBigint(&txi.ValueSat, varBuf)
|
l = packBigint(&txi.ValueSat, varBuf)
|
||||||
buf = append(buf, varBuf[:l]...)
|
buf = append(buf, varBuf[:l]...)
|
||||||
return buf
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
func appendTxOutput(txo *TxOutput, buf []byte, varBuf []byte) []byte {
|
func appendTxOutput(txo *TxOutput, buf []byte, varBuf []byte) []byte {
|
||||||
la := len(txo.addrDesc)
|
la := len(txo.AddrDesc)
|
||||||
if txo.Spent {
|
if txo.Spent {
|
||||||
la = ^la
|
la = ^la
|
||||||
}
|
}
|
||||||
l := packVarint(la, varBuf)
|
l := packVarint(la, varBuf)
|
||||||
buf = append(buf, varBuf[:l]...)
|
buf = append(buf, varBuf[:l]...)
|
||||||
buf = append(buf, txo.addrDesc...)
|
buf = append(buf, txo.AddrDesc...)
|
||||||
l = packBigint(&txo.ValueSat, varBuf)
|
l = packBigint(&txo.ValueSat, varBuf)
|
||||||
buf = append(buf, varBuf[:l]...)
|
buf = append(buf, varBuf[:l]...)
|
||||||
return buf
|
return buf
|
||||||
@ -723,8 +738,8 @@ func unpackTxAddresses(buf []byte) (*TxAddresses, error) {
|
|||||||
|
|
||||||
func unpackTxInput(ti *TxInput, buf []byte) int {
|
func unpackTxInput(ti *TxInput, buf []byte) int {
|
||||||
al, l := unpackVaruint(buf)
|
al, l := unpackVaruint(buf)
|
||||||
ti.addrDesc = make([]byte, al)
|
ti.AddrDesc = make([]byte, al)
|
||||||
copy(ti.addrDesc, buf[l:l+int(al)])
|
copy(ti.AddrDesc, buf[l:l+int(al)])
|
||||||
al += uint(l)
|
al += uint(l)
|
||||||
ti.ValueSat, l = unpackBigint(buf[al:])
|
ti.ValueSat, l = unpackBigint(buf[al:])
|
||||||
return l + int(al)
|
return l + int(al)
|
||||||
@ -736,8 +751,8 @@ func unpackTxOutput(to *TxOutput, buf []byte) int {
|
|||||||
to.Spent = true
|
to.Spent = true
|
||||||
al = ^al
|
al = ^al
|
||||||
}
|
}
|
||||||
to.addrDesc = make([]byte, al)
|
to.AddrDesc = make([]byte, al)
|
||||||
copy(to.addrDesc, buf[l:l+al])
|
copy(to.AddrDesc, buf[l:l+al])
|
||||||
al += l
|
al += l
|
||||||
to.ValueSat, l = unpackBigint(buf[al:])
|
to.ValueSat, l = unpackBigint(buf[al:])
|
||||||
return l + al
|
return l + al
|
||||||
@ -790,7 +805,7 @@ func (d *RocksDB) unpackNOutpoints(buf []byte) ([]outpoint, int, error) {
|
|||||||
return outpoints, p, nil
|
return outpoints, p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *RocksDB) addAddrDescToRecords(op int, wb *gorocksdb.WriteBatch, records map[string][]outpoint, addrDesc []byte, btxid []byte, vout int32, bh uint32) error {
|
func (d *RocksDB) addAddrDescToRecords(op int, wb *gorocksdb.WriteBatch, records map[string][]outpoint, addrDesc bchain.AddressDescriptor, btxid []byte, vout int32, bh uint32) error {
|
||||||
if len(addrDesc) > 0 {
|
if len(addrDesc) > 0 {
|
||||||
if len(addrDesc) > maxAddrDescLen {
|
if len(addrDesc) > maxAddrDescLen {
|
||||||
glog.Infof("rocksdb: block %d, skipping addrDesc of length %d", bh, len(addrDesc))
|
glog.Infof("rocksdb: block %d, skipping addrDesc of length %d", bh, len(addrDesc))
|
||||||
@ -846,7 +861,7 @@ func (d *RocksDB) writeAddressesNonUTXO(wb *gorocksdb.WriteBatch, block *bchain.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for addrDesc, outpoints := range addresses {
|
for addrDesc, outpoints := range addresses {
|
||||||
key := packAddressKey([]byte(addrDesc), block.Height)
|
key := packAddressKey(bchain.AddressDescriptor(addrDesc), block.Height)
|
||||||
switch op {
|
switch op {
|
||||||
case opInsert:
|
case opInsert:
|
||||||
val := d.packOutpoints(outpoints)
|
val := d.packOutpoints(outpoints)
|
||||||
@ -1022,12 +1037,12 @@ func (d *RocksDB) allAddressesScan(lower uint32, higher uint32) ([][]byte, [][]b
|
|||||||
func (d *RocksDB) disconnectTxAddresses(wb *gorocksdb.WriteBatch, height uint32, txid string, inputs []outpoint, txa *TxAddresses,
|
func (d *RocksDB) disconnectTxAddresses(wb *gorocksdb.WriteBatch, height uint32, txid string, inputs []outpoint, txa *TxAddresses,
|
||||||
txAddressesToUpdate map[string]*TxAddresses, balances map[string]*AddrBalance) error {
|
txAddressesToUpdate map[string]*TxAddresses, balances map[string]*AddrBalance) error {
|
||||||
addresses := make(map[string]struct{})
|
addresses := make(map[string]struct{})
|
||||||
getAddressBalance := func(addrDesc []byte) (*AddrBalance, error) {
|
getAddressBalance := func(addrDesc bchain.AddressDescriptor) (*AddrBalance, error) {
|
||||||
var err error
|
var err error
|
||||||
s := string(addrDesc)
|
s := string(addrDesc)
|
||||||
b, fb := balances[s]
|
b, fb := balances[s]
|
||||||
if !fb {
|
if !fb {
|
||||||
b, err = d.getAddrDescBalance(addrDesc)
|
b, err = d.GetAddrDescBalance(addrDesc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -1036,13 +1051,13 @@ func (d *RocksDB) disconnectTxAddresses(wb *gorocksdb.WriteBatch, height uint32,
|
|||||||
return b, nil
|
return b, nil
|
||||||
}
|
}
|
||||||
for i, t := range txa.Inputs {
|
for i, t := range txa.Inputs {
|
||||||
if len(t.addrDesc) > 0 {
|
if len(t.AddrDesc) > 0 {
|
||||||
s := string(t.addrDesc)
|
s := string(t.AddrDesc)
|
||||||
_, exist := addresses[s]
|
_, exist := addresses[s]
|
||||||
if !exist {
|
if !exist {
|
||||||
addresses[s] = struct{}{}
|
addresses[s] = struct{}{}
|
||||||
}
|
}
|
||||||
b, err := getAddressBalance(t.addrDesc)
|
b, err := getAddressBalance(t.AddrDesc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -1053,12 +1068,12 @@ func (d *RocksDB) disconnectTxAddresses(wb *gorocksdb.WriteBatch, height uint32,
|
|||||||
}
|
}
|
||||||
b.SentSat.Sub(&b.SentSat, &t.ValueSat)
|
b.SentSat.Sub(&b.SentSat, &t.ValueSat)
|
||||||
if b.SentSat.Sign() < 0 {
|
if b.SentSat.Sign() < 0 {
|
||||||
d.resetValueSatToZero(&b.SentSat, t.addrDesc, "sent amount")
|
d.resetValueSatToZero(&b.SentSat, t.AddrDesc, "sent amount")
|
||||||
}
|
}
|
||||||
b.BalanceSat.Add(&b.BalanceSat, &t.ValueSat)
|
b.BalanceSat.Add(&b.BalanceSat, &t.ValueSat)
|
||||||
} else {
|
} else {
|
||||||
ad, _, _ := d.chainParser.GetAddressesFromAddrDesc(t.addrDesc)
|
ad, _, _ := d.chainParser.GetAddressesFromAddrDesc(t.AddrDesc)
|
||||||
had := hex.EncodeToString(t.addrDesc)
|
had := hex.EncodeToString(t.AddrDesc)
|
||||||
glog.Warningf("Balance for address %s (%s) not found", ad, had)
|
glog.Warningf("Balance for address %s (%s) not found", ad, had)
|
||||||
}
|
}
|
||||||
s = string(inputs[i].btxID)
|
s = string(inputs[i].btxID)
|
||||||
@ -1074,13 +1089,13 @@ func (d *RocksDB) disconnectTxAddresses(wb *gorocksdb.WriteBatch, height uint32,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, t := range txa.Outputs {
|
for _, t := range txa.Outputs {
|
||||||
if len(t.addrDesc) > 0 {
|
if len(t.AddrDesc) > 0 {
|
||||||
s := string(t.addrDesc)
|
s := string(t.AddrDesc)
|
||||||
_, exist := addresses[s]
|
_, exist := addresses[s]
|
||||||
if !exist {
|
if !exist {
|
||||||
addresses[s] = struct{}{}
|
addresses[s] = struct{}{}
|
||||||
}
|
}
|
||||||
b, err := getAddressBalance(t.addrDesc)
|
b, err := getAddressBalance(t.AddrDesc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -1091,11 +1106,11 @@ func (d *RocksDB) disconnectTxAddresses(wb *gorocksdb.WriteBatch, height uint32,
|
|||||||
}
|
}
|
||||||
b.BalanceSat.Sub(&b.BalanceSat, &t.ValueSat)
|
b.BalanceSat.Sub(&b.BalanceSat, &t.ValueSat)
|
||||||
if b.BalanceSat.Sign() < 0 {
|
if b.BalanceSat.Sign() < 0 {
|
||||||
d.resetValueSatToZero(&b.BalanceSat, t.addrDesc, "balance")
|
d.resetValueSatToZero(&b.BalanceSat, t.AddrDesc, "balance")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ad, _, _ := d.chainParser.GetAddressesFromAddrDesc(t.addrDesc)
|
ad, _, _ := d.chainParser.GetAddressesFromAddrDesc(t.AddrDesc)
|
||||||
had := hex.EncodeToString(t.addrDesc)
|
had := hex.EncodeToString(t.AddrDesc)
|
||||||
glog.Warningf("Balance for address %s (%s) not found", ad, had)
|
glog.Warningf("Balance for address %s (%s) not found", ad, had)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1427,7 +1442,7 @@ func (d *RocksDB) ComputeInternalStateColumnStats(stopCompute chan os.Signal) er
|
|||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
|
|
||||||
func packAddressKey(addrDesc []byte, height uint32) []byte {
|
func packAddressKey(addrDesc bchain.AddressDescriptor, height uint32) []byte {
|
||||||
bheight := packUint(height)
|
bheight := packUint(height)
|
||||||
buf := make([]byte, 0, len(addrDesc)+len(bheight))
|
buf := make([]byte, 0, len(addrDesc)+len(bheight))
|
||||||
buf = append(buf, addrDesc...)
|
buf = append(buf, addrDesc...)
|
||||||
|
|||||||
@ -816,22 +816,22 @@ func TestRocksDB_Index_UTXO(t *testing.T) {
|
|||||||
Height: 225494,
|
Height: 225494,
|
||||||
Inputs: []TxInput{
|
Inputs: []TxInput{
|
||||||
{
|
{
|
||||||
addrDesc: addressToAddrDesc(addr3, d.chainParser),
|
AddrDesc: addressToAddrDesc(addr3, d.chainParser),
|
||||||
ValueSat: *satB1T2A3,
|
ValueSat: *satB1T2A3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
addrDesc: addressToAddrDesc(addr2, d.chainParser),
|
AddrDesc: addressToAddrDesc(addr2, d.chainParser),
|
||||||
ValueSat: *satB1T1A2,
|
ValueSat: *satB1T1A2,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Outputs: []TxOutput{
|
Outputs: []TxOutput{
|
||||||
{
|
{
|
||||||
addrDesc: addressToAddrDesc(addr6, d.chainParser),
|
AddrDesc: addressToAddrDesc(addr6, d.chainParser),
|
||||||
Spent: true,
|
Spent: true,
|
||||||
ValueSat: *satB2T1A6,
|
ValueSat: *satB2T1A6,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
addrDesc: addressToAddrDesc(addr7, d.chainParser),
|
AddrDesc: addressToAddrDesc(addr7, d.chainParser),
|
||||||
Spent: false,
|
Spent: false,
|
||||||
ValueSat: *satB2T1A7,
|
ValueSat: *satB2T1A7,
|
||||||
},
|
},
|
||||||
@ -1001,17 +1001,17 @@ func Test_packTxAddresses_unpackTxAddresses(t *testing.T) {
|
|||||||
Height: 123,
|
Height: 123,
|
||||||
Inputs: []TxInput{
|
Inputs: []TxInput{
|
||||||
{
|
{
|
||||||
addrDesc: addressToAddrDesc("tb1qgw4vyzs3dcy75nmezjlpc40yc9a2vq9hghdyt2", parser),
|
AddrDesc: addressToAddrDesc("tb1qgw4vyzs3dcy75nmezjlpc40yc9a2vq9hghdyt2", parser),
|
||||||
ValueSat: *big.NewInt(0),
|
ValueSat: *big.NewInt(0),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
addrDesc: addressToAddrDesc("tb1q233n429a9e2jh48gnsq7w0qm0yz7kkzx0qczw8", parser),
|
AddrDesc: addressToAddrDesc("tb1q233n429a9e2jh48gnsq7w0qm0yz7kkzx0qczw8", parser),
|
||||||
ValueSat: *big.NewInt(1234123421342341234),
|
ValueSat: *big.NewInt(1234123421342341234),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Outputs: []TxOutput{
|
Outputs: []TxOutput{
|
||||||
{
|
{
|
||||||
addrDesc: addressToAddrDesc("tb1qgw4vyzs3dcy75nmezjlpc40yc9a2vq9hghdyt2", parser),
|
AddrDesc: addressToAddrDesc("tb1qgw4vyzs3dcy75nmezjlpc40yc9a2vq9hghdyt2", parser),
|
||||||
ValueSat: *big.NewInt(1),
|
ValueSat: *big.NewInt(1),
|
||||||
Spent: true,
|
Spent: true,
|
||||||
},
|
},
|
||||||
@ -1025,39 +1025,39 @@ func Test_packTxAddresses_unpackTxAddresses(t *testing.T) {
|
|||||||
Height: 12345,
|
Height: 12345,
|
||||||
Inputs: []TxInput{
|
Inputs: []TxInput{
|
||||||
{
|
{
|
||||||
addrDesc: addressToAddrDesc("2N7iL7AvS4LViugwsdjTB13uN4T7XhV1bCP", parser),
|
AddrDesc: addressToAddrDesc("2N7iL7AvS4LViugwsdjTB13uN4T7XhV1bCP", parser),
|
||||||
ValueSat: *big.NewInt(9011000000),
|
ValueSat: *big.NewInt(9011000000),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
addrDesc: addressToAddrDesc("2Mt9v216YiNBAzobeNEzd4FQweHrGyuRHze", parser),
|
AddrDesc: addressToAddrDesc("2Mt9v216YiNBAzobeNEzd4FQweHrGyuRHze", parser),
|
||||||
ValueSat: *big.NewInt(8011000000),
|
ValueSat: *big.NewInt(8011000000),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
addrDesc: addressToAddrDesc("2NDyqJpHvHnqNtL1F9xAeCWMAW8WLJmEMyD", parser),
|
AddrDesc: addressToAddrDesc("2NDyqJpHvHnqNtL1F9xAeCWMAW8WLJmEMyD", parser),
|
||||||
ValueSat: *big.NewInt(7011000000),
|
ValueSat: *big.NewInt(7011000000),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Outputs: []TxOutput{
|
Outputs: []TxOutput{
|
||||||
{
|
{
|
||||||
addrDesc: addressToAddrDesc("2MuwoFGwABMakU7DCpdGDAKzyj2nTyRagDP", parser),
|
AddrDesc: addressToAddrDesc("2MuwoFGwABMakU7DCpdGDAKzyj2nTyRagDP", parser),
|
||||||
ValueSat: *big.NewInt(5011000000),
|
ValueSat: *big.NewInt(5011000000),
|
||||||
Spent: true,
|
Spent: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
addrDesc: addressToAddrDesc("2Mvcmw7qkGXNWzkfH1EjvxDcNRGL1Kf2tEM", parser),
|
AddrDesc: addressToAddrDesc("2Mvcmw7qkGXNWzkfH1EjvxDcNRGL1Kf2tEM", parser),
|
||||||
ValueSat: *big.NewInt(6011000000),
|
ValueSat: *big.NewInt(6011000000),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
addrDesc: addressToAddrDesc("2N9GVuX3XJGHS5MCdgn97gVezc6EgvzikTB", parser),
|
AddrDesc: addressToAddrDesc("2N9GVuX3XJGHS5MCdgn97gVezc6EgvzikTB", parser),
|
||||||
ValueSat: *big.NewInt(7011000000),
|
ValueSat: *big.NewInt(7011000000),
|
||||||
Spent: true,
|
Spent: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
addrDesc: addressToAddrDesc("mzii3fuRSpExMLJEHdHveW8NmiX8MPgavk", parser),
|
AddrDesc: addressToAddrDesc("mzii3fuRSpExMLJEHdHveW8NmiX8MPgavk", parser),
|
||||||
ValueSat: *big.NewInt(999900000),
|
ValueSat: *big.NewInt(999900000),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
addrDesc: addressToAddrDesc("mqHPFTRk23JZm9W1ANuEFtwTYwxjESSgKs", parser),
|
AddrDesc: addressToAddrDesc("mqHPFTRk23JZm9W1ANuEFtwTYwxjESSgKs", parser),
|
||||||
ValueSat: *big.NewInt(5000000000),
|
ValueSat: *big.NewInt(5000000000),
|
||||||
Spent: true,
|
Spent: true,
|
||||||
},
|
},
|
||||||
@ -1071,17 +1071,17 @@ func Test_packTxAddresses_unpackTxAddresses(t *testing.T) {
|
|||||||
Height: 123456789,
|
Height: 123456789,
|
||||||
Inputs: []TxInput{
|
Inputs: []TxInput{
|
||||||
{
|
{
|
||||||
addrDesc: []byte{},
|
AddrDesc: []byte{},
|
||||||
ValueSat: *big.NewInt(1234),
|
ValueSat: *big.NewInt(1234),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Outputs: []TxOutput{
|
Outputs: []TxOutput{
|
||||||
{
|
{
|
||||||
addrDesc: []byte{},
|
AddrDesc: []byte{},
|
||||||
ValueSat: *big.NewInt(5678),
|
ValueSat: *big.NewInt(5678),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
addrDesc: []byte{},
|
AddrDesc: []byte{},
|
||||||
ValueSat: *big.NewInt(98),
|
ValueSat: *big.NewInt(98),
|
||||||
Spent: true,
|
Spent: true,
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user