Merge branch 'indexv3' into explorer
This commit is contained in:
commit
6bfc7240a9
59
api/types.go
59
api/types.go
@ -1,5 +1,7 @@
|
||||
package api
|
||||
|
||||
import "math/big"
|
||||
|
||||
type ScriptSig struct {
|
||||
Hex string `json:"hex"`
|
||||
Asm string `json:"asm,omitempty"`
|
||||
@ -12,8 +14,8 @@ type Vin struct {
|
||||
N int `json:"n"`
|
||||
ScriptSig ScriptSig `json:"scriptSig"`
|
||||
Addr string `json:"addr"`
|
||||
ValueSat int64 `json:"valueSat"`
|
||||
Value float64 `json:"value"`
|
||||
Value string `json:"value"`
|
||||
ValueSat big.Int `json:"-"`
|
||||
}
|
||||
|
||||
type ScriptPubKey struct {
|
||||
@ -23,7 +25,8 @@ type ScriptPubKey struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
}
|
||||
type Vout struct {
|
||||
Value float64 `json:"value"`
|
||||
Value string `json:"value"`
|
||||
ValueSat big.Int `json:"-"`
|
||||
N int `json:"n"`
|
||||
ScriptPubKey ScriptPubKey `json:"scriptPubKey"`
|
||||
SpentTxID string `json:"spentTxId,omitempty"`
|
||||
@ -32,34 +35,30 @@ type Vout struct {
|
||||
}
|
||||
|
||||
type Tx struct {
|
||||
Txid string `json:"txid"`
|
||||
Version int32 `json:"version,omitempty"`
|
||||
Locktime uint32 `json:"locktime,omitempty"`
|
||||
Vin []Vin `json:"vin"`
|
||||
Vout []Vout `json:"vout"`
|
||||
Blockhash string `json:"blockhash,omitempty"`
|
||||
Blockheight int `json:"blockheight"`
|
||||
Confirmations uint32 `json:"confirmations"`
|
||||
Time int64 `json:"time,omitempty"`
|
||||
Blocktime int64 `json:"blocktime"`
|
||||
ValueOut float64 `json:"valueOut"`
|
||||
Size int `json:"size,omitempty"`
|
||||
ValueIn float64 `json:"valueIn"`
|
||||
Fees float64 `json:"fees"`
|
||||
WithSpends bool `json:"withSpends,omitempty"`
|
||||
Txid string `json:"txid"`
|
||||
Version int32 `json:"version,omitempty"`
|
||||
Locktime uint32 `json:"locktime,omitempty"`
|
||||
Vin []Vin `json:"vin"`
|
||||
Vout []Vout `json:"vout"`
|
||||
Blockhash string `json:"blockhash,omitempty"`
|
||||
Blockheight int `json:"blockheight"`
|
||||
Confirmations uint32 `json:"confirmations"`
|
||||
Time int64 `json:"time,omitempty"`
|
||||
Blocktime int64 `json:"blocktime"`
|
||||
ValueOut string `json:"valueOut"`
|
||||
Size int `json:"size,omitempty"`
|
||||
ValueIn string `json:"valueIn"`
|
||||
Fees string `json:"fees"`
|
||||
WithSpends bool `json:"withSpends,omitempty"`
|
||||
}
|
||||
|
||||
type Address struct {
|
||||
AddrStr string `json:"addrStr"`
|
||||
Balance float64 `json:"balance"`
|
||||
BalanceSat int64 `json:"balanceSat"`
|
||||
TotalReceived float64 `json:"totalReceived"`
|
||||
TotalReceivedSat int64 `json:"totalReceivedSat"`
|
||||
TotalSent float64 `json:"totalSent"`
|
||||
TotalSentSat int64 `json:"totalSentSat"`
|
||||
UnconfirmedBalance float64 `json:"unconfirmedBalance"`
|
||||
UnconfirmedBalanceSat int64 `json:"unconfirmedBalanceSat"`
|
||||
UnconfirmedTxApperances int `json:"unconfirmedTxApperances"`
|
||||
TxApperances int `json:"txApperances"`
|
||||
Transactions []*Tx `json:"transactions"`
|
||||
AddrStr string `json:"addrStr"`
|
||||
Balance string `json:"balance"`
|
||||
TotalReceived string `json:"totalReceived"`
|
||||
TotalSent string `json:"totalSent"`
|
||||
UnconfirmedBalance string `json:"unconfirmedBalance"`
|
||||
UnconfirmedTxApperances int `json:"unconfirmedTxApperances"`
|
||||
TxApperances int `json:"txApperances"`
|
||||
Transactions []*Tx `json:"transactions"`
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import (
|
||||
"blockbook/bchain"
|
||||
"blockbook/common"
|
||||
"blockbook/db"
|
||||
"math/big"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
@ -44,7 +45,7 @@ func (w *Worker) GetTransaction(txid string, bestheight uint32, spendingTx bool)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
var valIn, valOut, fees float64
|
||||
var valInSat, valOutSat, feesSat big.Int
|
||||
vins := make([]Vin, len(bchainTx.Vin))
|
||||
for i := range bchainTx.Vin {
|
||||
bchainVin := &bchainTx.Vin[i]
|
||||
@ -61,9 +62,9 @@ func (w *Worker) GetTransaction(txid string, bestheight uint32, spendingTx bool)
|
||||
}
|
||||
if len(otx.Vout) > int(vin.Vout) {
|
||||
vout := &otx.Vout[vin.Vout]
|
||||
vin.Value = vout.Value
|
||||
valIn += vout.Value
|
||||
vin.ValueSat = int64(vout.Value*1E8 + 0.5)
|
||||
vin.ValueSat = vout.ValueSat
|
||||
vin.Value = w.chainParser.AmountToDecimalString(&vout.ValueSat)
|
||||
valInSat.Add(&valInSat, &vout.ValueSat)
|
||||
if vout.Address != nil {
|
||||
a := vout.Address.String()
|
||||
vin.Addr = a
|
||||
@ -76,8 +77,9 @@ func (w *Worker) GetTransaction(txid string, bestheight uint32, spendingTx bool)
|
||||
bchainVout := &bchainTx.Vout[i]
|
||||
vout := &vouts[i]
|
||||
vout.N = i
|
||||
vout.Value = bchainVout.Value
|
||||
valOut += bchainVout.Value
|
||||
vout.ValueSat = bchainVout.ValueSat
|
||||
vout.Value = w.chainParser.AmountToDecimalString(&bchainVout.ValueSat)
|
||||
valOutSat.Add(&valOutSat, &bchainVout.ValueSat)
|
||||
vout.ScriptPubKey.Hex = bchainVout.ScriptPubKey.Hex
|
||||
vout.ScriptPubKey.Addresses = bchainVout.ScriptPubKey.Addresses
|
||||
if spendingTx {
|
||||
@ -85,9 +87,9 @@ func (w *Worker) GetTransaction(txid string, bestheight uint32, spendingTx bool)
|
||||
}
|
||||
}
|
||||
// for coinbase transactions valIn is 0
|
||||
fees = valIn - valOut
|
||||
if fees < 0 {
|
||||
fees = 0
|
||||
feesSat.Sub(&valInSat, &valOutSat)
|
||||
if feesSat.Sign() == -1 {
|
||||
feesSat.SetUint64(0)
|
||||
}
|
||||
// for now do not return size, we would have to compute vsize of segwit transactions
|
||||
// size:=len(bchainTx.Hex) / 2
|
||||
@ -96,13 +98,13 @@ func (w *Worker) GetTransaction(txid string, bestheight uint32, spendingTx bool)
|
||||
Blockheight: int(height),
|
||||
Blocktime: bchainTx.Blocktime,
|
||||
Confirmations: bchainTx.Confirmations,
|
||||
Fees: fees,
|
||||
Fees: w.chainParser.AmountToDecimalString(&feesSat),
|
||||
Locktime: bchainTx.LockTime,
|
||||
WithSpends: spendingTx,
|
||||
Time: bchainTx.Time,
|
||||
Txid: bchainTx.Txid,
|
||||
ValueIn: valIn,
|
||||
ValueOut: valOut,
|
||||
ValueIn: w.chainParser.AmountToDecimalString(&valInSat),
|
||||
ValueOut: w.chainParser.AmountToDecimalString(&valOutSat),
|
||||
Version: bchainTx.Version,
|
||||
Vin: vins,
|
||||
Vout: vouts,
|
||||
@ -131,26 +133,26 @@ func (s *Worker) getAddressTxids(address string, mempool bool) ([]string, error)
|
||||
return txids, nil
|
||||
}
|
||||
|
||||
func (t *Tx) getAddrVoutValue(addrID string) float64 {
|
||||
var val float64
|
||||
func (t *Tx) getAddrVoutValue(addrID string) *big.Int {
|
||||
var val big.Int
|
||||
for _, vout := range t.Vout {
|
||||
for _, a := range vout.ScriptPubKey.Addresses {
|
||||
if a == addrID {
|
||||
val += vout.Value
|
||||
val.Add(&val, &vout.ValueSat)
|
||||
}
|
||||
}
|
||||
}
|
||||
return val
|
||||
return &val
|
||||
}
|
||||
|
||||
func (t *Tx) getAddrVinValue(addrID string) float64 {
|
||||
var val float64
|
||||
func (t *Tx) getAddrVinValue(addrID string) *big.Int {
|
||||
var val big.Int
|
||||
for _, vin := range t.Vin {
|
||||
if vin.Addr == addrID {
|
||||
val += vin.Value
|
||||
val.Add(&val, &vin.ValueSat)
|
||||
}
|
||||
}
|
||||
return val
|
||||
return &val
|
||||
}
|
||||
|
||||
// UniqueTxidsInReverse reverts the order of transactions (so that newest are first) and removes duplicate transactions
|
||||
@ -181,6 +183,7 @@ func (w *Worker) GetAddress(addrID string, page int) (*Address, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
txm = UniqueTxidsInReverse(txm)
|
||||
bestheight, _, err := w.db.GetBestBlock()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -191,14 +194,14 @@ func (w *Worker) GetAddress(addrID string, page int) (*Address, error) {
|
||||
}
|
||||
txs := make([]*Tx, len(txm)+lc)
|
||||
txi := 0
|
||||
var uBal, bal, totRecv, totSent float64
|
||||
var uBalSat, balSat, totRecvSat, totSentSat big.Int
|
||||
for _, tx := range txm {
|
||||
tx, err := w.GetTransaction(tx, bestheight, false)
|
||||
// mempool transaction may fail
|
||||
if err != nil {
|
||||
glog.Error("GetTransaction ", tx, ": ", err)
|
||||
} else {
|
||||
uBal = tx.getAddrVoutValue(addrID) - tx.getAddrVinValue(addrID)
|
||||
uBalSat.Sub(tx.getAddrVoutValue(addrID), tx.getAddrVinValue(addrID))
|
||||
txs[txi] = tx
|
||||
txi++
|
||||
}
|
||||
@ -216,26 +219,23 @@ func (w *Worker) GetAddress(addrID string, page int) (*Address, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
totRecv += tx.getAddrVoutValue(addrID)
|
||||
totSent += tx.getAddrVinValue(addrID)
|
||||
totRecvSat.Add(&totRecvSat, tx.getAddrVoutValue(addrID))
|
||||
totSentSat.Add(&totSentSat, tx.getAddrVinValue(addrID))
|
||||
if i >= from && i < to {
|
||||
txs[txi] = tx
|
||||
txi++
|
||||
}
|
||||
}
|
||||
}
|
||||
bal = totRecv - totSent
|
||||
balSat.Sub(&totRecvSat, &totSentSat)
|
||||
r := &Address{
|
||||
AddrStr: addrID,
|
||||
Balance: bal,
|
||||
BalanceSat: int64(bal*1E8 + 0.5),
|
||||
TotalReceived: totRecv,
|
||||
TotalReceivedSat: int64(totRecv*1E8 + 0.5),
|
||||
TotalSent: totSent,
|
||||
TotalSentSat: int64(totSent*1E8 + 0.5),
|
||||
Balance: w.chainParser.AmountToDecimalString(&balSat),
|
||||
TotalReceived: w.chainParser.AmountToDecimalString(&totRecvSat),
|
||||
TotalSent: w.chainParser.AmountToDecimalString(&totSentSat),
|
||||
Transactions: txs[:txi],
|
||||
TxApperances: len(txc),
|
||||
UnconfirmedBalance: uBal,
|
||||
UnconfirmedBalance: w.chainParser.AmountToDecimalString(&uBalSat),
|
||||
UnconfirmedTxApperances: len(txm),
|
||||
}
|
||||
glog.Info(addrID, " finished")
|
||||
|
||||
@ -3,6 +3,8 @@ package bchain
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"math/big"
|
||||
"strings"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/juju/errors"
|
||||
@ -14,6 +16,7 @@ type AddressFactoryFunc func(string) (Address, error)
|
||||
type BaseParser struct {
|
||||
AddressFactory AddressFactoryFunc
|
||||
BlockAddressesToKeep int
|
||||
AmountDecimalPoint int
|
||||
}
|
||||
|
||||
// AddressToOutputScript converts address to ScriptPubKey - currently not implemented
|
||||
@ -36,7 +39,52 @@ func (p *BaseParser) ParseTx(b []byte) (*Tx, error) {
|
||||
return nil, errors.New("ParseTx: not implemented")
|
||||
}
|
||||
|
||||
// ParseTxFromJson parses JSON message containing transaction and returs Tx struct
|
||||
const zeros = "0000000000000000000000000000000000000000"
|
||||
|
||||
// AmountToBigInt converts amount in json.Number (string) to big.Int
|
||||
// it uses string operations to avoid problems with rounding
|
||||
func (p *BaseParser) AmountToBigInt(n json.Number) (big.Int, error) {
|
||||
var r big.Int
|
||||
s := string(n)
|
||||
i := strings.IndexByte(s, '.')
|
||||
if i == -1 {
|
||||
s = s + zeros[:p.AmountDecimalPoint]
|
||||
} else {
|
||||
z := p.AmountDecimalPoint - len(s) + i + 1
|
||||
if z > 0 {
|
||||
s = s[:i] + s[i+1:] + zeros[:z]
|
||||
} else {
|
||||
s = s[:i] + s[i+1:len(s)+z]
|
||||
}
|
||||
}
|
||||
if _, ok := r.SetString(s, 10); !ok {
|
||||
return r, errors.New("AmountToBigInt: failed to convert")
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// AmountToDecimalString converts amount in big.Int to string with decimal point in the correct place
|
||||
func (p *BaseParser) AmountToDecimalString(a *big.Int) string {
|
||||
n := a.String()
|
||||
var s string
|
||||
if n[0] == '-' {
|
||||
n = n[1:]
|
||||
s = "-"
|
||||
}
|
||||
if len(n) <= p.AmountDecimalPoint {
|
||||
n = zeros[:p.AmountDecimalPoint-len(n)+1] + n
|
||||
}
|
||||
i := len(n) - p.AmountDecimalPoint
|
||||
ad := strings.TrimRight(n[i:], "0")
|
||||
if len(ad) > 0 {
|
||||
n = n[:i] + "." + ad
|
||||
} else {
|
||||
n = n[:i]
|
||||
}
|
||||
return s + n
|
||||
}
|
||||
|
||||
// ParseTxFromJson parses JSON message containing transaction and returns Tx struct
|
||||
func (p *BaseParser) ParseTxFromJson(msg json.RawMessage) (*Tx, error) {
|
||||
var tx Tx
|
||||
err := json.Unmarshal(msg, &tx)
|
||||
@ -44,13 +92,20 @@ func (p *BaseParser) ParseTxFromJson(msg json.RawMessage) (*Tx, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i, vout := range tx.Vout {
|
||||
for i := range tx.Vout {
|
||||
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(vout.JsonValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vout.JsonValue = ""
|
||||
if len(vout.ScriptPubKey.Addresses) == 1 {
|
||||
a, err := p.AddressFactory(vout.ScriptPubKey.Addresses[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tx.Vout[i].Address = a
|
||||
vout.Address = a
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,7 +182,7 @@ func (p *BaseParser) PackTx(tx *Tx, height uint32, blockTime int64) ([]byte, err
|
||||
Addresses: vo.ScriptPubKey.Addresses,
|
||||
N: vo.N,
|
||||
ScriptPubKeyHex: hex,
|
||||
Value: vo.Value,
|
||||
ValueSat: vo.ValueSat.Bytes(),
|
||||
}
|
||||
}
|
||||
pt := &ProtoTransaction{
|
||||
@ -176,13 +231,15 @@ func (p *BaseParser) UnpackTx(buf []byte) (*Tx, uint32, error) {
|
||||
}
|
||||
vout := make([]Vout, len(pt.Vout))
|
||||
for i, pto := range pt.Vout {
|
||||
var vs big.Int
|
||||
vs.SetBytes(pto.ValueSat)
|
||||
vout[i] = Vout{
|
||||
N: pto.N,
|
||||
ScriptPubKey: ScriptPubKey{
|
||||
Addresses: pto.Addresses,
|
||||
Hex: hex.EncodeToString(pto.ScriptPubKeyHex),
|
||||
},
|
||||
Value: pto.Value,
|
||||
ValueSat: vs,
|
||||
}
|
||||
if len(pto.Addresses) == 1 {
|
||||
a, err := p.AddressFactory(pto.Addresses[0])
|
||||
|
||||
56
bchain/baseparser_test.go
Normal file
56
bchain/baseparser_test.go
Normal file
@ -0,0 +1,56 @@
|
||||
package bchain
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math/big"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func NewBaseParser(adp int) *BaseParser {
|
||||
return &BaseParser{
|
||||
AmountDecimalPoint: adp,
|
||||
}
|
||||
}
|
||||
|
||||
var amounts = []struct {
|
||||
a *big.Int
|
||||
s string
|
||||
adp int
|
||||
alternative string
|
||||
}{
|
||||
{big.NewInt(123456789), "1.23456789", 8, "!"},
|
||||
{big.NewInt(2), "0.00000002", 8, "!"},
|
||||
{big.NewInt(300000000), "3", 8, "!"},
|
||||
{big.NewInt(498700000), "4.987", 8, "!"},
|
||||
{big.NewInt(567890), "0.00000000000056789", 18, "!"},
|
||||
{big.NewInt(-100000000), "-1", 8, "!"},
|
||||
{big.NewInt(-8), "-0.00000008", 8, "!"},
|
||||
{big.NewInt(-89012345678), "-890.12345678", 8, "!"},
|
||||
{big.NewInt(-12345), "-0.00012345", 8, "!"},
|
||||
{big.NewInt(12345678), "0.123456789012", 8, "0.12345678"}, // test of truncation of too many decimal places
|
||||
}
|
||||
|
||||
func TestBaseParser_AmountToDecimalString(t *testing.T) {
|
||||
for _, tt := range amounts {
|
||||
t.Run(tt.s, func(t *testing.T) {
|
||||
if got := NewBaseParser(tt.adp).AmountToDecimalString(tt.a); got != tt.s && got != tt.alternative {
|
||||
t.Errorf("BaseParser.AmountToDecimalString() = %v, want %v", got, tt.s)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBaseParser_AmountToBigInt(t *testing.T) {
|
||||
for _, tt := range amounts {
|
||||
t.Run(tt.s, func(t *testing.T) {
|
||||
got, err := NewBaseParser(tt.adp).AmountToBigInt(json.Number(tt.s))
|
||||
if err != nil {
|
||||
t.Errorf("BaseParser.AmountToBigInt() error = %v", err)
|
||||
return
|
||||
}
|
||||
if got.Cmp(tt.a) != 0 {
|
||||
t.Errorf("BaseParser.AmountToBigInt() = %v, want %v", got, tt.a)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -49,6 +49,7 @@ func NewBCashParser(params *chaincfg.Params, c *btc.Configuration) (*BCashParser
|
||||
BaseParser: &bchain.BaseParser{
|
||||
AddressFactory: func(addr string) (bchain.Address, error) { return newBCashAddress(addr, format) },
|
||||
BlockAddressesToKeep: c.BlockAddressesToKeep,
|
||||
AmountDecimalPoint: 8,
|
||||
},
|
||||
Params: params,
|
||||
OutputScriptToAddressesFunc: outputScriptToAddresses,
|
||||
|
||||
@ -7,6 +7,7 @@ import (
|
||||
"blockbook/bchain/coins/btc"
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
@ -159,8 +160,8 @@ func init() {
|
||||
},
|
||||
Vout: []bchain.Vout{
|
||||
{
|
||||
Value: 0.00038812,
|
||||
N: 0,
|
||||
ValueSat: *big.NewInt(38812),
|
||||
N: 0,
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Hex: "a9146144d57c8aff48492c9dfb914e120b20bad72d6f87",
|
||||
Addresses: []string{
|
||||
@ -190,8 +191,8 @@ func init() {
|
||||
},
|
||||
Vout: []bchain.Vout{
|
||||
{
|
||||
Value: .1,
|
||||
N: 0,
|
||||
ValueSat: *big.NewInt(10000000),
|
||||
N: 0,
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Hex: "a914cd668d781ece600efa4b2404dc91fd26b8b8aed887",
|
||||
Addresses: []string{
|
||||
@ -201,8 +202,8 @@ func init() {
|
||||
Address: addr2,
|
||||
},
|
||||
{
|
||||
Value: 9.20081157,
|
||||
N: 1,
|
||||
ValueSat: *big.NewInt(920081157),
|
||||
N: 1,
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Hex: "a914246655bdbd54c7e477d0ea2375e86e0db2b8f80a87",
|
||||
Addresses: []string{
|
||||
|
||||
@ -5,6 +5,7 @@ import (
|
||||
"blockbook/bchain/coins/btc"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"math/big"
|
||||
|
||||
"github.com/cpacia/bchutil"
|
||||
"github.com/golang/glog"
|
||||
@ -132,7 +133,7 @@ func (b *BCashRPC) GetBlockFull(hash string) (*bchain.Block, error) {
|
||||
}
|
||||
|
||||
// EstimateSmartFee returns fee estimation.
|
||||
func (b *BCashRPC) EstimateSmartFee(blocks int, conservative bool) (float64, error) {
|
||||
func (b *BCashRPC) EstimateSmartFee(blocks int, conservative bool) (big.Int, error) {
|
||||
glog.V(1).Info("rpc: estimatesmartfee ", blocks)
|
||||
|
||||
res := btc.ResEstimateSmartFee{}
|
||||
@ -141,13 +142,18 @@ func (b *BCashRPC) EstimateSmartFee(blocks int, conservative bool) (float64, err
|
||||
// conservative param is omitted
|
||||
err := b.Call(&req, &res)
|
||||
|
||||
var r big.Int
|
||||
if err != nil {
|
||||
return 0, err
|
||||
return r, err
|
||||
}
|
||||
if res.Error != nil {
|
||||
return 0, res.Error
|
||||
return r, res.Error
|
||||
}
|
||||
return res.Result.Feerate, nil
|
||||
r, err = b.Parser.AmountToBigInt(res.Result.Feerate)
|
||||
if err != nil {
|
||||
return r, err
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func isErrBlockNotFound(err *bchain.RPCError) bool {
|
||||
|
||||
@ -18,6 +18,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
@ -175,12 +176,12 @@ func (c *blockChainWithMetrics) GetTransactionForMempool(txid string) (v *bchain
|
||||
return c.b.GetTransactionForMempool(txid)
|
||||
}
|
||||
|
||||
func (c *blockChainWithMetrics) EstimateSmartFee(blocks int, conservative bool) (v float64, err error) {
|
||||
func (c *blockChainWithMetrics) EstimateSmartFee(blocks int, conservative bool) (v big.Int, err error) {
|
||||
defer func(s time.Time) { c.observeRPCLatency("EstimateSmartFee", s, err) }(time.Now())
|
||||
return c.b.EstimateSmartFee(blocks, conservative)
|
||||
}
|
||||
|
||||
func (c *blockChainWithMetrics) EstimateFee(blocks int) (v float64, err error) {
|
||||
func (c *blockChainWithMetrics) EstimateFee(blocks int) (v big.Int, err error) {
|
||||
defer func(s time.Time) { c.observeRPCLatency("EstimateFee", s, err) }(time.Now())
|
||||
return c.b.EstimateFee(blocks)
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"math/big"
|
||||
|
||||
vlq "github.com/bsm/go-vlq"
|
||||
"github.com/btcsuite/btcd/blockchain"
|
||||
@ -30,6 +31,7 @@ func NewBitcoinParser(params *chaincfg.Params, c *Configuration) *BitcoinParser
|
||||
&bchain.BaseParser{
|
||||
AddressFactory: bchain.NewBaseAddress,
|
||||
BlockAddressesToKeep: c.BlockAddressesToKeep,
|
||||
AmountDecimalPoint: 8,
|
||||
},
|
||||
params,
|
||||
outputScriptToAddresses,
|
||||
@ -123,8 +125,10 @@ func (p *BitcoinParser) TxFromMsgTx(t *wire.MsgTx, parseAddresses bool) bchain.T
|
||||
// missing: Asm,
|
||||
// missing: Type,
|
||||
}
|
||||
var vs big.Int
|
||||
vs.SetInt64(out.Value)
|
||||
vout[i] = bchain.Vout{
|
||||
Value: float64(out.Value) / 1E8,
|
||||
ValueSat: vs,
|
||||
N: uint32(i),
|
||||
ScriptPubKey: s,
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ package btc
|
||||
import (
|
||||
"blockbook/bchain"
|
||||
"encoding/hex"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
@ -152,8 +153,8 @@ func init() {
|
||||
},
|
||||
Vout: []bchain.Vout{
|
||||
{
|
||||
Value: 0.00038812,
|
||||
N: 0,
|
||||
ValueSat: *big.NewInt(38812),
|
||||
N: 0,
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Hex: "a9146144d57c8aff48492c9dfb914e120b20bad72d6f87",
|
||||
Addresses: []string{
|
||||
@ -183,8 +184,8 @@ func init() {
|
||||
},
|
||||
Vout: []bchain.Vout{
|
||||
{
|
||||
Value: .1,
|
||||
N: 0,
|
||||
ValueSat: *big.NewInt(10000000),
|
||||
N: 0,
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Hex: "a914cd668d781ece600efa4b2404dc91fd26b8b8aed887",
|
||||
Addresses: []string{
|
||||
@ -194,8 +195,8 @@ func init() {
|
||||
Address: addr2,
|
||||
},
|
||||
{
|
||||
Value: 9.20081157,
|
||||
N: 1,
|
||||
ValueSat: *big.NewInt(920081157),
|
||||
N: 1,
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Hex: "a914246655bdbd54c7e477d0ea2375e86e0db2b8f80a87",
|
||||
Addresses: []string{
|
||||
|
||||
@ -8,6 +8,7 @@ import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
@ -36,19 +37,21 @@ type BitcoinRPC struct {
|
||||
}
|
||||
|
||||
type Configuration struct {
|
||||
CoinName string `json:"coin_name"`
|
||||
CoinShortcut string `json:"coin_shortcut"`
|
||||
RPCURL string `json:"rpc_url"`
|
||||
RPCUser string `json:"rpc_user"`
|
||||
RPCPass string `json:"rpc_pass"`
|
||||
RPCTimeout int `json:"rpc_timeout"`
|
||||
Parse bool `json:"parse"`
|
||||
MessageQueueBinding string `json:"message_queue_binding"`
|
||||
Subversion string `json:"subversion"`
|
||||
BlockAddressesToKeep int `json:"block_addresses_to_keep"`
|
||||
MempoolWorkers int `json:"mempool_workers"`
|
||||
MempoolSubWorkers int `json:"mempool_sub_workers"`
|
||||
AddressFormat string `json:"address_format"`
|
||||
CoinName string `json:"coin_name"`
|
||||
CoinShortcut string `json:"coin_shortcut"`
|
||||
RPCURL string `json:"rpc_url"`
|
||||
RPCUser string `json:"rpc_user"`
|
||||
RPCPass string `json:"rpc_pass"`
|
||||
RPCTimeout int `json:"rpc_timeout"`
|
||||
Parse bool `json:"parse"`
|
||||
MessageQueueBinding string `json:"message_queue_binding"`
|
||||
Subversion string `json:"subversion"`
|
||||
BlockAddressesToKeep int `json:"block_addresses_to_keep"`
|
||||
MempoolWorkers int `json:"mempool_workers"`
|
||||
MempoolSubWorkers int `json:"mempool_sub_workers"`
|
||||
AddressFormat string `json:"address_format"`
|
||||
SupportsEstimateFee bool `json:"supports_estimate_fee"`
|
||||
SupportsEstimateSmartFee bool `json:"supports_estimate_smart_fee"`
|
||||
}
|
||||
|
||||
// NewBitcoinRPC returns new BitcoinRPC instance.
|
||||
@ -70,6 +73,9 @@ func NewBitcoinRPC(config json.RawMessage, pushHandler func(bchain.NotificationT
|
||||
if c.MempoolSubWorkers < 1 {
|
||||
c.MempoolSubWorkers = 1
|
||||
}
|
||||
// btc supports both calls, other coins overriding BitcoinRPC can change this
|
||||
c.SupportsEstimateFee = true
|
||||
c.SupportsEstimateSmartFee = true
|
||||
|
||||
transport := &http.Transport{
|
||||
Dial: (&net.Dialer{KeepAlive: 600 * time.Second}).Dial,
|
||||
@ -302,8 +308,8 @@ type CmdEstimateSmartFee struct {
|
||||
type ResEstimateSmartFee struct {
|
||||
Error *bchain.RPCError `json:"error"`
|
||||
Result struct {
|
||||
Feerate float64 `json:"feerate"`
|
||||
Blocks int `json:"blocks"`
|
||||
Feerate json.Number `json:"feerate"`
|
||||
Blocks int `json:"blocks"`
|
||||
} `json:"result"`
|
||||
}
|
||||
|
||||
@ -318,7 +324,7 @@ type CmdEstimateFee struct {
|
||||
|
||||
type ResEstimateFee struct {
|
||||
Error *bchain.RPCError `json:"error"`
|
||||
Result float64 `json:"result"`
|
||||
Result json.Number `json:"result"`
|
||||
}
|
||||
|
||||
// sendrawtransaction
|
||||
@ -617,7 +623,12 @@ func (b *BitcoinRPC) GetMempoolTransactions(address string) ([]string, error) {
|
||||
}
|
||||
|
||||
// EstimateSmartFee returns fee estimation.
|
||||
func (b *BitcoinRPC) EstimateSmartFee(blocks int, conservative bool) (float64, error) {
|
||||
func (b *BitcoinRPC) EstimateSmartFee(blocks int, conservative bool) (big.Int, error) {
|
||||
// use EstimateFee if EstimateSmartFee is not supported
|
||||
if !b.ChainConfig.SupportsEstimateSmartFee && b.ChainConfig.SupportsEstimateFee {
|
||||
return b.EstimateFee(blocks)
|
||||
}
|
||||
|
||||
glog.V(1).Info("rpc: estimatesmartfee ", blocks)
|
||||
|
||||
res := ResEstimateSmartFee{}
|
||||
@ -630,17 +641,27 @@ func (b *BitcoinRPC) EstimateSmartFee(blocks int, conservative bool) (float64, e
|
||||
}
|
||||
err := b.Call(&req, &res)
|
||||
|
||||
var r big.Int
|
||||
if err != nil {
|
||||
return 0, err
|
||||
return r, err
|
||||
}
|
||||
if res.Error != nil {
|
||||
return 0, res.Error
|
||||
return r, res.Error
|
||||
}
|
||||
return res.Result.Feerate, nil
|
||||
r, err = b.Parser.AmountToBigInt(res.Result.Feerate)
|
||||
if err != nil {
|
||||
return r, err
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// EstimateFee returns fee estimation.
|
||||
func (b *BitcoinRPC) EstimateFee(blocks int) (float64, error) {
|
||||
func (b *BitcoinRPC) EstimateFee(blocks int) (big.Int, error) {
|
||||
// use EstimateSmartFee if EstimateFee is not supported
|
||||
if !b.ChainConfig.SupportsEstimateFee && b.ChainConfig.SupportsEstimateSmartFee {
|
||||
return b.EstimateSmartFee(blocks, true)
|
||||
}
|
||||
|
||||
glog.V(1).Info("rpc: estimatefee ", blocks)
|
||||
|
||||
res := ResEstimateFee{}
|
||||
@ -648,13 +669,18 @@ func (b *BitcoinRPC) EstimateFee(blocks int) (float64, error) {
|
||||
req.Params.Blocks = blocks
|
||||
err := b.Call(&req, &res)
|
||||
|
||||
var r big.Int
|
||||
if err != nil {
|
||||
return 0, err
|
||||
return r, err
|
||||
}
|
||||
if res.Error != nil {
|
||||
return 0, res.Error
|
||||
return r, res.Error
|
||||
}
|
||||
return res.Result, nil
|
||||
r, err = b.Parser.AmountToBigInt(res.Result)
|
||||
if err != nil {
|
||||
return r, err
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// SendRawTransaction sends raw transaction.
|
||||
@ -685,13 +711,20 @@ func (b *BitcoinRPC) GetMempoolEntry(txid string) (*bchain.MempoolEntry, error)
|
||||
Params: []string{txid},
|
||||
}
|
||||
err := b.Call(&req, &res)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if res.Error != nil {
|
||||
return nil, res.Error
|
||||
}
|
||||
res.Result.FeeSat, err = b.Parser.AmountToBigInt(res.Result.Fee)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res.Result.ModifiedFeeSat, err = b.Parser.AmountToBigInt(res.Result.ModifiedFee)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res.Result, nil
|
||||
}
|
||||
|
||||
|
||||
@ -24,6 +24,7 @@ func NewDashRPC(config json.RawMessage, pushHandler func(bchain.NotificationType
|
||||
b.(*btc.BitcoinRPC),
|
||||
}
|
||||
s.RPCMarshaler = btc.JSONMarshalerV1{}
|
||||
s.ChainConfig.SupportsEstimateSmartFee = false
|
||||
|
||||
return s, nil
|
||||
}
|
||||
@ -53,8 +54,3 @@ func (b *DashRPC) Initialize() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// EstimateSmartFee returns fee estimation.
|
||||
func (b *DashRPC) EstimateSmartFee(blocks int, conservative bool) (float64, error) {
|
||||
return b.EstimateFee(blocks)
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
@ -111,8 +112,8 @@ func init() {
|
||||
},
|
||||
Vout: []bchain.Vout{
|
||||
{
|
||||
Value: 27478.75452951,
|
||||
N: 0,
|
||||
ValueSat: *big.NewInt(2747875452951),
|
||||
N: 0,
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Hex: "76a914eef21768a546590993e313c7f3dfadf6a6efa1e888ac",
|
||||
Addresses: []string{
|
||||
@ -122,8 +123,8 @@ func init() {
|
||||
Address: addr1,
|
||||
},
|
||||
{
|
||||
Value: 74.20567469,
|
||||
N: 1,
|
||||
ValueSat: *big.NewInt(7420567469),
|
||||
N: 1,
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Hex: "76a914e0fee2ea29dd9c6c759d8341bd0da4c4f738cced88ac",
|
||||
Addresses: []string{
|
||||
@ -153,8 +154,8 @@ func init() {
|
||||
},
|
||||
Vout: []bchain.Vout{
|
||||
{
|
||||
Value: 59890867.89818935,
|
||||
N: 0,
|
||||
ValueSat: *big.NewInt(5989086789818935),
|
||||
N: 0,
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Hex: "76a9149355c01ed20057eac9fe0bbf8b07d87e62fe712d88ac",
|
||||
Addresses: []string{
|
||||
@ -164,8 +165,8 @@ func init() {
|
||||
Address: addr3,
|
||||
},
|
||||
{
|
||||
Value: 9999998.90000000,
|
||||
N: 1,
|
||||
ValueSat: *big.NewInt(999999890000000),
|
||||
N: 1,
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Hex: "76a9145b4f2511c94e4fcaa8f8835b2458f8cb6542ca7688ac",
|
||||
Addresses: []string{
|
||||
|
||||
@ -24,6 +24,7 @@ func NewDogecoinRPC(config json.RawMessage, pushHandler func(bchain.Notification
|
||||
b.(*btc.BitcoinRPC),
|
||||
}
|
||||
s.RPCMarshaler = btc.JSONMarshalerV1{}
|
||||
s.ChainConfig.SupportsEstimateSmartFee = false
|
||||
|
||||
return s, nil
|
||||
}
|
||||
@ -69,8 +70,3 @@ func (b *DogecoinRPC) GetBlock(hash string, height uint32) (*bchain.Block, error
|
||||
}
|
||||
return b.GetBlockWithoutHeader(hash, height)
|
||||
}
|
||||
|
||||
// EstimateSmartFee returns fee estimation.
|
||||
func (b *DogecoinRPC) EstimateSmartFee(blocks int, conservative bool) (float64, error) {
|
||||
return b.EstimateFee(blocks)
|
||||
}
|
||||
|
||||
@ -22,7 +22,11 @@ type EthereumParser struct {
|
||||
|
||||
// NewEthereumParser returns new EthereumParser instance
|
||||
func NewEthereumParser() *EthereumParser {
|
||||
return &EthereumParser{&bchain.BaseParser{AddressFactory: bchain.NewBaseAddress}}
|
||||
return &EthereumParser{&bchain.BaseParser{
|
||||
AddressFactory: bchain.NewBaseAddress,
|
||||
BlockAddressesToKeep: 0,
|
||||
AmountDecimalPoint: 18,
|
||||
}}
|
||||
}
|
||||
|
||||
type rpcTransaction struct {
|
||||
@ -86,6 +90,10 @@ func (p *EthereumParser) ethTxToTx(tx *rpcTransaction, blocktime int64, confirma
|
||||
}
|
||||
tx.BlockHash = bh
|
||||
h := hex.EncodeToString(b)
|
||||
vs, err := hexutil.DecodeBig(tx.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &bchain.Tx{
|
||||
Blocktime: blocktime,
|
||||
Confirmations: confirmations,
|
||||
@ -105,8 +113,8 @@ func (p *EthereumParser) ethTxToTx(tx *rpcTransaction, blocktime int64, confirma
|
||||
},
|
||||
Vout: []bchain.Vout{
|
||||
{
|
||||
N: 0, // there is always up to one To address
|
||||
// Value - cannot be set, it does not fit precisely to float64
|
||||
N: 0, // there is always up to one To address
|
||||
ValueSat: *vs,
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
// Hex
|
||||
Addresses: ta,
|
||||
@ -286,9 +294,3 @@ func (p *EthereumParser) UnpackBlockHash(buf []byte) (string, error) {
|
||||
func (p *EthereumParser) IsUTXOChain() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// KeepBlockAddresses returns number of blocks which are to be kept in blockaddresses column
|
||||
// do not use the blockaddresses for eth
|
||||
func (p *EthereumParser) KeepBlockAddresses() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ package eth
|
||||
import (
|
||||
"blockbook/bchain"
|
||||
"encoding/hex"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
@ -63,6 +64,68 @@ func TestEthParser_GetAddrIDFromAddress(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
testTx1, testTx2 bchain.Tx
|
||||
testTxPacked1 = "08aebf0a1205012a05f20018a0f73622081234567890abcdef2a24f025caaf00000000000000000000000000000000000000000000000000000000000002253220e6b168d6bb3d8ed78e03dbf828b6bfd1fb613f6e129cba624964984553724c5d38f095af014092f4c1d5054a14682b7903a11098cf770c7aef4aa02a85b3f3601a5214dacc9c61754a0c4616fc5323dc946e89eb272302580162011b6a201bd40a31122c03918df6d166d740a6a3a22f08a25934ceb1688c62977661c80c7220607fbc15c1f7995a4258f5a9bccc63b040362d1991d5efe1361c56222e4ca89f"
|
||||
testTxPacked2 = "08ece40212050430e234001888a4012201213220cd647151552b5132b2aef7c9be00dc6f73afc5901dde157aab131335baaa853b38889eaf0140fa83c3d5054a14555ee11fbddc0e49a9bab358a8941ad95ffdb48f52143e3a3d69dc66ba10737f531ed088954a9ec89d97580a6201296a20f7161c170d43573ad9c8d701cdaf714ff2a548a562b0dc639230d17889fcd40572203c4977fc90385a27efa0032e17b49fd575b2826cb56e3d1ecf21524f2a94f915"
|
||||
)
|
||||
|
||||
func init() {
|
||||
var (
|
||||
addr1, addr2 bchain.Address
|
||||
err error
|
||||
)
|
||||
addr1, err = bchain.NewBaseAddress("0x682b7903a11098cf770c7aef4aa02a85b3f3601a")
|
||||
if err == nil {
|
||||
addr2, err = bchain.NewBaseAddress("0x555ee11fbddc0e49a9bab358a8941ad95ffdb48f")
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
testTx1 = bchain.Tx{
|
||||
Blocktime: 1521515026,
|
||||
Hex: "7b226e6f6e6365223a2230783239666165222c226761735072696365223a223078313261303566323030222c22676173223a2230786462626130222c22746f223a22307836383262373930336131313039386366373730633761656634616130326138356233663336303161222c2276616c7565223a22307831323334353637383930616263646566222c22696e707574223a223078663032356361616630303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030323235222c2268617368223a22307865366231363864366262336438656437386530336462663832386236626664316662363133663665313239636261363234393634393834353533373234633564222c22626c6f636b4e756d626572223a223078326263616630222c2266726f6d223a22307864616363396336313735346130633436313666633533323364633934366538396562323732333032222c227472616e73616374696f6e496e646578223a22307831222c2276223a2230783162222c2272223a22307831626434306133313132326330333931386466366431363664373430613661336132326630386132353933346365623136383863363239373736363163383063222c2273223a22307836303766626331356331663739393561343235386635613962636363363362303430333632643139393164356566653133363163353632323265346361383966227d",
|
||||
Time: 1521515026,
|
||||
Txid: "0xe6b168d6bb3d8ed78e03dbf828b6bfd1fb613f6e129cba624964984553724c5d",
|
||||
Vin: []bchain.Vin{
|
||||
{
|
||||
Addresses: []string{"0xdacc9c61754a0c4616fc5323dc946e89eb272302"},
|
||||
},
|
||||
},
|
||||
Vout: []bchain.Vout{
|
||||
{
|
||||
ValueSat: *big.NewInt(1311768467294899695),
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Addresses: []string{"0x682b7903a11098cf770c7aef4aa02a85b3f3601a"},
|
||||
},
|
||||
Address: addr1,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
testTx2 = bchain.Tx{
|
||||
Blocktime: 1521533434,
|
||||
Hex: "7b226e6f6e6365223a22307862323663222c226761735072696365223a223078343330653233343030222c22676173223a22307835323038222c22746f223a22307835353565653131666264646330653439613962616233353861383934316164393566666462343866222c2276616c7565223a2230783231222c22696e707574223a223078222c2268617368223a22307863643634373135313535326235313332623261656637633962653030646336663733616663353930316464653135376161623133313333356261616138353362222c22626c6f636b4e756d626572223a223078326263663038222c2266726f6d223a22307833653361336436396463363662613130373337663533316564303838393534613965633839643937222c227472616e73616374696f6e496e646578223a22307861222c2276223a2230783239222c2272223a22307866373136316331373064343335373361643963386437303163646166373134666632613534386135363262306463363339323330643137383839666364343035222c2273223a22307833633439373766633930333835613237656661303033326531376234396664353735623238323663623536653364316563663231353234663261393466393135227d",
|
||||
Time: 1521533434,
|
||||
Txid: "0xcd647151552b5132b2aef7c9be00dc6f73afc5901dde157aab131335baaa853b",
|
||||
Vin: []bchain.Vin{
|
||||
{
|
||||
Addresses: []string{"0x3e3a3d69dc66ba10737f531ed088954a9ec89d97"},
|
||||
},
|
||||
},
|
||||
Vout: []bchain.Vout{
|
||||
{
|
||||
ValueSat: *big.NewInt(33),
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Addresses: []string{"0x555ee11fbddc0e49a9bab358a8941ad95ffdb48f"},
|
||||
},
|
||||
Address: addr2,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestEthereumParser_PackTx(t *testing.T) {
|
||||
type args struct {
|
||||
tx *bchain.Tx
|
||||
@ -77,61 +140,27 @@ func TestEthereumParser_PackTx(t *testing.T) {
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "with 0x prefix",
|
||||
name: "1",
|
||||
args: args{
|
||||
tx: &bchain.Tx{
|
||||
Blocktime: 1521515026,
|
||||
Hex: "7b226e6f6e6365223a2230783239666165222c226761735072696365223a223078313261303566323030222c22676173223a2230786462626130222c22746f223a22307836383262373930336131313039386366373730633761656634616130326138356233663336303161222c2276616c7565223a22307830222c22696e707574223a223078663032356361616630303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030323235222c2268617368223a22307865366231363864366262336438656437386530336462663832386236626664316662363133663665313239636261363234393634393834353533373234633564222c22626c6f636b4e756d626572223a223078326263616630222c2266726f6d223a22307864616363396336313735346130633436313666633533323364633934366538396562323732333032222c227472616e73616374696f6e496e646578223a22307831222c2276223a2230783162222c2272223a22307831626434306133313132326330333931386466366431363664373430613661336132326630386132353933346365623136383863363239373736363163383063222c2273223a22307836303766626331356331663739393561343235386635613962636363363362303430333632643139393164356566653133363163353632323265346361383966227d",
|
||||
Time: 1521515026,
|
||||
Txid: "0xe6b168d6bb3d8ed78e03dbf828b6bfd1fb613f6e129cba624964984553724c5d",
|
||||
Vin: []bchain.Vin{
|
||||
{
|
||||
Addresses: []string{"0xdacc9c61754a0c4616fc5323dc946e89eb272302"},
|
||||
},
|
||||
},
|
||||
Vout: []bchain.Vout{
|
||||
{
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Addresses: []string{"0x682b7903a11098cf770c7aef4aa02a85b3f3601a"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
tx: &testTx1,
|
||||
height: 2870000,
|
||||
blockTime: 1521515026,
|
||||
},
|
||||
want: "08aebf0a1205012a05f20018a0f7362a24f025caaf00000000000000000000000000000000000000000000000000000000000002253220e6b168d6bb3d8ed78e03dbf828b6bfd1fb613f6e129cba624964984553724c5d38f095af014092f4c1d5054a14682b7903a11098cf770c7aef4aa02a85b3f3601a5214dacc9c61754a0c4616fc5323dc946e89eb272302580162011b6a201bd40a31122c03918df6d166d740a6a3a22f08a25934ceb1688c62977661c80c7220607fbc15c1f7995a4258f5a9bccc63b040362d1991d5efe1361c56222e4ca89f",
|
||||
want: testTxPacked1,
|
||||
},
|
||||
{
|
||||
name: "without 0x prefix",
|
||||
name: "2",
|
||||
args: args{
|
||||
tx: &bchain.Tx{
|
||||
Blocktime: 1521533434,
|
||||
Hex: "7b226e6f6e6365223a22307862323663222c226761735072696365223a223078343330653233343030222c22676173223a22307835323038222c22746f223a22307835353565653131666264646330653439613962616233353861383934316164393566666462343866222c2276616c7565223a22307831626330313539643533306536303030222c22696e707574223a223078222c2268617368223a22307863643634373135313535326235313332623261656637633962653030646336663733616663353930316464653135376161623133313333356261616138353362222c22626c6f636b4e756d626572223a223078326263663038222c2266726f6d223a22307833653361336436396463363662613130373337663533316564303838393534613965633839643937222c227472616e73616374696f6e496e646578223a22307861222c2276223a2230783239222c2272223a22307866373136316331373064343335373361643963386437303163646166373134666632613534386135363262306463363339323330643137383839666364343035222c2273223a22307833633439373766633930333835613237656661303033326531376234396664353735623238323663623536653364316563663231353234663261393466393135227d",
|
||||
Time: 1521533434,
|
||||
Txid: "cd647151552b5132b2aef7c9be00dc6f73afc5901dde157aab131335baaa853b",
|
||||
Vin: []bchain.Vin{
|
||||
{
|
||||
Addresses: []string{"3e3a3d69dc66ba10737f531ed088954a9ec89d97"},
|
||||
},
|
||||
},
|
||||
Vout: []bchain.Vout{
|
||||
{
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Addresses: []string{"555ee11fbddc0e49a9bab358a8941ad95ffdb48f"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
tx: &testTx2,
|
||||
height: 2871048,
|
||||
blockTime: 1521533434,
|
||||
},
|
||||
want: "08ece40212050430e234001888a40122081bc0159d530e60003220cd647151552b5132b2aef7c9be00dc6f73afc5901dde157aab131335baaa853b38889eaf0140fa83c3d5054a14555ee11fbddc0e49a9bab358a8941ad95ffdb48f52143e3a3d69dc66ba10737f531ed088954a9ec89d97580a6201296a20f7161c170d43573ad9c8d701cdaf714ff2a548a562b0dc639230d17889fcd40572203c4977fc90385a27efa0032e17b49fd575b2826cb56e3d1ecf21524f2a94f915",
|
||||
want: testTxPacked2,
|
||||
},
|
||||
}
|
||||
p := NewEthereumParser()
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
p := NewEthereumParser()
|
||||
got, err := p.PackTx(tt.args.tx, tt.args.height, tt.args.blockTime)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("EthereumParser.PackTx() error = %v, wantErr %v", err, tt.wantErr)
|
||||
@ -146,18 +175,6 @@ func TestEthereumParser_PackTx(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEthereumParser_UnpackTx(t *testing.T) {
|
||||
var (
|
||||
addr1, addr2 bchain.Address
|
||||
err error
|
||||
)
|
||||
addr1, err = bchain.NewBaseAddress("0x682b7903a11098cf770c7aef4aa02a85b3f3601a")
|
||||
if err == nil {
|
||||
addr2, err = bchain.NewBaseAddress("0x555ee11fbddc0e49a9bab358a8941ad95ffdb48f")
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
type args struct {
|
||||
hex string
|
||||
}
|
||||
@ -170,57 +187,21 @@ func TestEthereumParser_UnpackTx(t *testing.T) {
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "1",
|
||||
args: args{hex: "08aebf0a1205012a05f20018a0f7362a24f025caaf00000000000000000000000000000000000000000000000000000000000002253220e6b168d6bb3d8ed78e03dbf828b6bfd1fb613f6e129cba624964984553724c5d38f095af014092f4c1d5054a14682b7903a11098cf770c7aef4aa02a85b3f3601a5214dacc9c61754a0c4616fc5323dc946e89eb272302580162011b6a201bd40a31122c03918df6d166d740a6a3a22f08a25934ceb1688c62977661c80c7220607fbc15c1f7995a4258f5a9bccc63b040362d1991d5efe1361c56222e4ca89f"},
|
||||
want: &bchain.Tx{
|
||||
Blocktime: 1521515026,
|
||||
Hex: "7b226e6f6e6365223a2230783239666165222c226761735072696365223a223078313261303566323030222c22676173223a2230786462626130222c22746f223a22307836383262373930336131313039386366373730633761656634616130326138356233663336303161222c2276616c7565223a22307830222c22696e707574223a223078663032356361616630303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030323235222c2268617368223a22307865366231363864366262336438656437386530336462663832386236626664316662363133663665313239636261363234393634393834353533373234633564222c22626c6f636b4e756d626572223a223078326263616630222c2266726f6d223a22307864616363396336313735346130633436313666633533323364633934366538396562323732333032222c227472616e73616374696f6e496e646578223a22307831222c2276223a2230783162222c2272223a22307831626434306133313132326330333931386466366431363664373430613661336132326630386132353933346365623136383863363239373736363163383063222c2273223a22307836303766626331356331663739393561343235386635613962636363363362303430333632643139393164356566653133363163353632323265346361383966227d",
|
||||
Time: 1521515026,
|
||||
Txid: "0xe6b168d6bb3d8ed78e03dbf828b6bfd1fb613f6e129cba624964984553724c5d",
|
||||
Vin: []bchain.Vin{
|
||||
{
|
||||
Addresses: []string{"0xdacc9c61754a0c4616fc5323dc946e89eb272302"},
|
||||
},
|
||||
},
|
||||
Vout: []bchain.Vout{
|
||||
{
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Addresses: []string{"0x682b7903a11098cf770c7aef4aa02a85b3f3601a"},
|
||||
},
|
||||
Address: addr1,
|
||||
},
|
||||
},
|
||||
},
|
||||
name: "1",
|
||||
args: args{hex: testTxPacked1},
|
||||
want: &testTx1,
|
||||
want1: 2870000,
|
||||
},
|
||||
{
|
||||
name: "1",
|
||||
args: args{hex: "08ece40212050430e234001888a40122081bc0159d530e60003220cd647151552b5132b2aef7c9be00dc6f73afc5901dde157aab131335baaa853b38889eaf0140fa83c3d5054a14555ee11fbddc0e49a9bab358a8941ad95ffdb48f52143e3a3d69dc66ba10737f531ed088954a9ec89d97580a6201296a20f7161c170d43573ad9c8d701cdaf714ff2a548a562b0dc639230d17889fcd40572203c4977fc90385a27efa0032e17b49fd575b2826cb56e3d1ecf21524f2a94f915"},
|
||||
want: &bchain.Tx{
|
||||
Blocktime: 1521533434,
|
||||
Hex: "7b226e6f6e6365223a22307862323663222c226761735072696365223a223078343330653233343030222c22676173223a22307835323038222c22746f223a22307835353565653131666264646330653439613962616233353861383934316164393566666462343866222c2276616c7565223a22307831626330313539643533306536303030222c22696e707574223a223078222c2268617368223a22307863643634373135313535326235313332623261656637633962653030646336663733616663353930316464653135376161623133313333356261616138353362222c22626c6f636b4e756d626572223a223078326263663038222c2266726f6d223a22307833653361336436396463363662613130373337663533316564303838393534613965633839643937222c227472616e73616374696f6e496e646578223a22307861222c2276223a2230783239222c2272223a22307866373136316331373064343335373361643963386437303163646166373134666632613534386135363262306463363339323330643137383839666364343035222c2273223a22307833633439373766633930333835613237656661303033326531376234396664353735623238323663623536653364316563663231353234663261393466393135227d",
|
||||
Time: 1521533434,
|
||||
Txid: "0xcd647151552b5132b2aef7c9be00dc6f73afc5901dde157aab131335baaa853b",
|
||||
Vin: []bchain.Vin{
|
||||
{
|
||||
Addresses: []string{"0x3e3a3d69dc66ba10737f531ed088954a9ec89d97"},
|
||||
},
|
||||
},
|
||||
Vout: []bchain.Vout{
|
||||
{
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Addresses: []string{"0x555ee11fbddc0e49a9bab358a8941ad95ffdb48f"},
|
||||
},
|
||||
Address: addr2,
|
||||
},
|
||||
},
|
||||
},
|
||||
name: "2",
|
||||
args: args{hex: testTxPacked2},
|
||||
want: &testTx2,
|
||||
want1: 2871048,
|
||||
},
|
||||
}
|
||||
p := NewEthereumParser()
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
p := NewEthereumParser()
|
||||
b, err := hex.DecodeString(tt.args.hex)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
||||
@ -479,12 +479,12 @@ func (b *EthereumRPC) GetMempool() ([]string, error) {
|
||||
}
|
||||
|
||||
// EstimateFee returns fee estimation.
|
||||
func (b *EthereumRPC) EstimateFee(blocks int) (float64, error) {
|
||||
func (b *EthereumRPC) EstimateFee(blocks int) (big.Int, error) {
|
||||
return b.EstimateSmartFee(blocks, true)
|
||||
}
|
||||
|
||||
// EstimateSmartFee returns fee estimation.
|
||||
func (b *EthereumRPC) EstimateSmartFee(blocks int, conservative bool) (float64, error) {
|
||||
func (b *EthereumRPC) EstimateSmartFee(blocks int, conservative bool) (big.Int, error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), b.timeout)
|
||||
defer cancel()
|
||||
// TODO - what parameters of msg to use to get better estimate, maybe more data from the wallet are needed
|
||||
@ -493,10 +493,12 @@ func (b *EthereumRPC) EstimateSmartFee(blocks int, conservative bool) (float64,
|
||||
To: &a,
|
||||
}
|
||||
g, err := b.client.EstimateGas(ctx, msg)
|
||||
var r big.Int
|
||||
if err != nil {
|
||||
return 0, err
|
||||
return r, err
|
||||
}
|
||||
return float64(g), nil
|
||||
r.SetUint64(g)
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// SendRawTransaction sends raw transaction.
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"blockbook/bchain"
|
||||
"blockbook/bchain/coins/btc"
|
||||
"encoding/hex"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
@ -173,8 +174,8 @@ func init() {
|
||||
},
|
||||
Vout: []bchain.Vout{
|
||||
{
|
||||
Value: 12.52000000,
|
||||
N: 0,
|
||||
ValueSat: *big.NewInt(1252000000),
|
||||
N: 0,
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Hex: "76a9141ae882e788091732da6910595314447c9e38bd8d88ac",
|
||||
Addresses: []string{
|
||||
@ -184,8 +185,8 @@ func init() {
|
||||
Address: addr1,
|
||||
},
|
||||
{
|
||||
Value: 0.01000487,
|
||||
N: 1,
|
||||
ValueSat: *big.NewInt(1000487),
|
||||
N: 1,
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Hex: "76a9146b474cbf0f6004329b630bdd4798f2c23d1751b688ac",
|
||||
Addresses: []string{
|
||||
|
||||
@ -24,6 +24,7 @@ func NewLitecoinRPC(config json.RawMessage, pushHandler func(bchain.Notification
|
||||
b.(*btc.BitcoinRPC),
|
||||
}
|
||||
s.RPCMarshaler = btc.JSONMarshalerV2{}
|
||||
s.ChainConfig.SupportsEstimateFee = false
|
||||
|
||||
return s, nil
|
||||
}
|
||||
@ -54,8 +55,3 @@ func (b *LitecoinRPC) Initialize() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// EstimateFee returns fee estimation.
|
||||
func (b *LitecoinRPC) EstimateFee(blocks int) (float64, error) {
|
||||
return b.EstimateSmartFee(blocks, true)
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@ func NewNamecoinRPC(config json.RawMessage, pushHandler func(bchain.Notification
|
||||
b.(*btc.BitcoinRPC),
|
||||
}
|
||||
s.RPCMarshaler = btc.JSONMarshalerV1{}
|
||||
s.ChainConfig.SupportsEstimateSmartFee = false
|
||||
|
||||
return s, nil
|
||||
}
|
||||
@ -69,8 +70,3 @@ func (b *NamecoinRPC) GetBlock(hash string, height uint32) (*bchain.Block, error
|
||||
}
|
||||
return b.GetBlockWithoutHeader(hash, height)
|
||||
}
|
||||
|
||||
// EstimateSmartFee returns fee estimation.
|
||||
func (b *NamecoinRPC) EstimateSmartFee(blocks int, conservative bool) (float64, error) {
|
||||
return b.EstimateFee(blocks)
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"blockbook/bchain"
|
||||
"blockbook/bchain/coins/btc"
|
||||
"encoding/hex"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
@ -105,8 +106,8 @@ func init() {
|
||||
},
|
||||
Vout: []bchain.Vout{
|
||||
{
|
||||
Value: 0.10781192,
|
||||
N: 0,
|
||||
ValueSat: *big.NewInt(10781192),
|
||||
N: 0,
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Hex: "76a91499b16da88a7e29b913b6131df2644d6d06cb331b88ac",
|
||||
Addresses: []string{
|
||||
@ -116,8 +117,8 @@ func init() {
|
||||
Address: addr1,
|
||||
},
|
||||
{
|
||||
Value: 0.5000000,
|
||||
N: 1,
|
||||
ValueSat: *big.NewInt(50000000),
|
||||
N: 1,
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Hex: "a91446eb90e002f137f05385896c882fe000cc2e967f87",
|
||||
Addresses: []string{
|
||||
|
||||
@ -24,6 +24,7 @@ func NewVertcoinRPC(config json.RawMessage, pushHandler func(bchain.Notification
|
||||
b.(*btc.BitcoinRPC),
|
||||
}
|
||||
s.RPCMarshaler = btc.JSONMarshalerV2{}
|
||||
s.ChainConfig.SupportsEstimateFee = false
|
||||
|
||||
return s, nil
|
||||
}
|
||||
@ -54,8 +55,3 @@ func (b *VertcoinRPC) Initialize() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// EstimateFee returns fee estimation.
|
||||
func (b *VertcoinRPC) EstimateFee(blocks int) (float64, error) {
|
||||
return b.EstimateSmartFee(blocks, true)
|
||||
}
|
||||
|
||||
@ -20,12 +20,13 @@ type ZCashParser struct {
|
||||
*bchain.BaseParser
|
||||
}
|
||||
|
||||
// NewZCAshParser returns new ZCAshParser instance
|
||||
// NewZCashParser returns new ZCashParser instance
|
||||
func NewZCashParser(c *btc.Configuration) *ZCashParser {
|
||||
return &ZCashParser{
|
||||
&bchain.BaseParser{
|
||||
AddressFactory: bchain.NewBaseAddress,
|
||||
BlockAddressesToKeep: c.BlockAddressesToKeep,
|
||||
AmountDecimalPoint: 8,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"blockbook/bchain"
|
||||
"blockbook/bchain/coins/btc"
|
||||
"encoding/hex"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
@ -13,8 +14,8 @@ import (
|
||||
var (
|
||||
testTx1, testTx2 bchain.Tx
|
||||
|
||||
testTxPacked1 = "0a20e64aac0c211ad210c90934f06b1cc932327329e41a9f70c6eb76f79ef798b7b812ab1002000000019c012650c99d0ef761e863dbb966babf2cb7a7a2b5d90b1461c09521c473d23d000000006b483045022100f220f48c5267ef92a1e7a4d3b44fe9d97cce76eeba2785d45a0e2620b70e8d7302205640bc39e197ce19d95a98a3239af0f208ca289c067f80c97d8e411e61da5dee0121021721e83315fb5282f1d9d2a11892322df589bccd9cef45517b5fb3cfd3055c83ffffffff018eec1a3c040000001976a9149bb8229741305d8316ba3ca6a8d20740ce33c24188ac000000000162b4fc6b0000000000000000000000006ffa88c89b74f0f82e24744296845a0d0113b132ff5dfc2af34e6418eb15206af53078c4dd475cf143cd9a427983f5993622464b53e3a37d2519a946492c3977e30f0866550b9097222993a439a39260ac5e7d36aef38c7fdd1df3035a2d5817a9c20526e38f52f822d4db9d2f0156c4119d786d6e3a060ca871df7fae9a5c3a9c921b38ddc6414b13d16aa807389c68016e54bd6a9eb3b23a6bc7bf152e6dba15e9ec36f95dab15ad8f4a92a9d0309bbd930ef24bb7247bf534065c1e2f5b42e2c80eb59f48b4da6ec522319e065f8c4e463f95cc7fcad8d7ee91608e3c0ffcaa44129ba2d2da45d9a413919eca41af29faaf806a3eeb823e5a6c51afb1ec709505d812c0306bd76061a0a62d207355ad44d1ffce2b9e1dfd0818f79bd0f8e4031116b71fee2488484f17818b80532865773166cd389929e8409bb94e3948bd2e0215ef96d4e29d094590fda0de50715c11ff47c03380bb1d31b14e5b4ad8a372ca0b03364ef85f086b8a8eb5c56c3b1aee33e2cfbf1b2be1a3fb41b14b2c432b5d04d54c058fa87a96ae1d65d61b79360d09acc1e25a883fd7ae9a2a734a03362903021401c243173e1050b5cdb459b9ffc07c95e920f026618952d3a800b2e47e03b902084aed7ee8466a65d34abdbbd292781564dcd9b7440029d48c2640ebc196d4b40217f2872c1d0c1c9c2abf1147d6a5a9501895bc92960bfa182ceeb76a658224f1022bc53c4c1cd6888d72a152dc1aec5ba8a1d750fb7e498bee844d3481e4b4cd210227f94f775744185c9f24571b7df0c1c694cb2d3e4e9b955ed0b1caad2b02b5702139c4fbba03f0e422b2f3e4fc822b4f58baf32e7cd217cdbdec8540cb13d6496f271959b72a05e130eeffbe5b9a7fcd2793347cd9c0ea695265669844c363190f690c52a600cf413c3f00bdc5e9d1539e0cc63f4ec2945e0d86e6304a6deb5651e73eac21add5a641dfc95ab56200ed40d81f76755aee4659334c17ed3841ca5a5ab22f923956be1d264be2b485a0de55404510ece5c73d6626798be688f9dc18b69846acfe897a357cc4afe31f57fea32896717f124290e68f36f849fa6ecf76e02087f8c19dbc566135d7fa2daca2d843b9cc5bc3897d35f1de7d174f6407658f4a3706c12cea53d880b4d8c4d45b3f0d210214f815be49a664021a4a44b4a63e06a41d76b46f9aa6bad248e8d1a974ae7bbae5ea8ac269447db91637a19346729083cad5aebd5ff43ea13d04783068e9136da321b1152c666d2995d0ca06b26541deac62f4ef91f0e4af445b18a5c2a17c96eada0b27f85bb26dfb8f16515114c6b9f88037e2b85b3b84b65822eb99c992d99d12dcf9c71e5b46a586016faf5758483a716566db95b42187c101df68ca0554824e1c23cf0302bea03ad0a146af57e91794a268b8c82d78211718c8b5fea286f5de72fc7dfffecddcc02413525c472cb26022641d4bec2b8b7e71a7beb9ee18b82632799498eeee9a351cb9431a8d1906d5164acdf351bd538c3e9d1da8a211fe1cd18c44e72d8cdf16ce3fc9551552c05d52846ea7ef619232102588395cc2bcce509a4e7f150262a76c15475496c923dfce6bfc05871467ee7c213b39ea365c010083e0b1ba8926d3a9e586d8b11c9bab2a47d888bc7cb1a226c0086a1530e295d0047547006f4c8f1c24cdd8e16bb3845749895dec95f03fcda97d3224f6875b1b7b1c819d2fd35dd30968a3c82bc480d10082caf9d9dda8f9ec649c136c7fa07978099d97eaf4abfdc9854c266979d3cfc868f60689b6e3098b6c52a21796fe7c259d9a0dadf1b6efa59297d4c8c902febe7acf826eed30d40d2ac5119be91b51f4839d94599872c9a93c3e2691294914034001d3a278cb4a84d4ae048c0201a97e4cf1341ee663a162f5b586355018b9e5e30624ccdbeacf7d0382afacaf45f08e84d30c50bcd4e55c3138377261deb4e8c2931cd3c51cee94a048ae4839517b6e6537a5c0148d3830a33fea719ef9b4fa437e4d5fecdb646397c19ee56a0973c362a81803895cdc67246352dc566689cb203f9ebda900a5537bbb75aa25ddf3d4ab87b88737a58d760e1d271f08265daae1fe056e71971a8b826e5b215a05b71f99315b167dd2ec78874189657acafac2b5eeb9a901913f55f7ab69e1f9b203504448d414e71098b932a2309db57257eb3fef9de2f2a5a69aa46747d7b827df838345d38b95772bdab8c178c45777b92e8773864964b8e12ae29dbc1b21bf6527589f6bec71ff1cbb9928477409811c2e8150c79c3f21027ee954863b716875d3e9adfc6fdb18cd57a49bb395ca5c42da56f3beb78aad3a7a487de34a870bca61f3cdec422061328c83c910ab32ea7403c354915b7ebee29e1fea5a75158197e4a68e103f017fd7de5a70148ee7ce59356b1a74f83492e14faaa6cd4870bcc004e6eb0114d3429b74ea98fe2851b4553467a7660074e69b040aa31220d0e405d9166dbaf15e3ae2d8ec3b049ed99d17e0743bb6a1a7c3890bbdb7117f7374ad7a59aa1ab47d10445b28f4bc033794a71f88a8bf024189e9d27f9dc5859a4296437585b215656f807aca9dad35747494a43b8a1cf38be2b18a13de32a262ab29f9ba271c4fbce1a470a8243ebf9e7fd37b09262314afbb9a7e180218a0f1c9d505200028b0eb113299010a0012203dd273c42195c061140bd9b5a2a7b72cbfba66b9db63e861f70e9dc95026019c1800226b483045022100f220f48c5267ef92a1e7a4d3b44fe9d97cce76eeba2785d45a0e2620b70e8d7302205640bc39e197ce19d95a98a3239af0f208ca289c067f80c97d8e411e61da5dee0121021721e83315fb5282f1d9d2a11892322df589bccd9cef45517b5fb3cfd3055c8328ffffffff0f3a4b091e6c90cd3ebc664010001a1976a9149bb8229741305d8316ba3ca6a8d20740ce33c24188ac222374315934794c31344143486141626a656d6b647057376e594e48576e76317951624441"
|
||||
testTxPacked2 = "0a20bb47a9dd926de63e9d4f8dac58c3f63f4a079569ed3b80e932274a80f60e58b512e20101000000019cafb5c287980e6e5afb47339f6c1c81136d8255f5bd5226b36b01288494c46f000000006b483045022100c92b2f3c54918fa26288530c63a58197ea4974e5b6d92db792dd9717e6d9183c02204e577254213675466a6adad3ae6e9384cf8269fb2dd9943b86fac0c0ad8e3f98012102c99dab469e63b232488b3e7acb9cfcab7e5755f61aad318d9e06b38e5ea22880feffffff0223a7a784010000001976a914826f87806ddd4643730be99b41c98acc379e83db88ac80969800000000001976a914e395634b7684289285926d4c64db395b783720ec88ac6e75040018e4b1c9d50520eeea1128f9ea113299010a0012206fc4948428016bb32652bdf555826d13811c6c9f3347fb5a6e0e9887c2b5af9c1800226b483045022100c92b2f3c54918fa26288530c63a58197ea4974e5b6d92db792dd9717e6d9183c02204e577254213675466a6adad3ae6e9384cf8269fb2dd9943b86fac0c0ad8e3f98012102c99dab469e63b232488b3e7acb9cfcab7e5755f61aad318d9e06b38e5ea2288028feffffff0f3a4b09257b2170264d504010001a1976a914826f87806ddd4643730be99b41c98acc379e83db88ac22237431566d4854547770457477766f6a786f644e32435351714c596931687a59336341713a4b099a9999999999b93f10011a1976a914e395634b7684289285926d4c64db395b783720ec88ac222374316563784d587070685554525158474c586e56684a367563714433445a6970646467"
|
||||
testTxPacked1 = "0a20e64aac0c211ad210c90934f06b1cc932327329e41a9f70c6eb76f79ef798b7b812ab1002000000019c012650c99d0ef761e863dbb966babf2cb7a7a2b5d90b1461c09521c473d23d000000006b483045022100f220f48c5267ef92a1e7a4d3b44fe9d97cce76eeba2785d45a0e2620b70e8d7302205640bc39e197ce19d95a98a3239af0f208ca289c067f80c97d8e411e61da5dee0121021721e83315fb5282f1d9d2a11892322df589bccd9cef45517b5fb3cfd3055c83ffffffff018eec1a3c040000001976a9149bb8229741305d8316ba3ca6a8d20740ce33c24188ac000000000162b4fc6b0000000000000000000000006ffa88c89b74f0f82e24744296845a0d0113b132ff5dfc2af34e6418eb15206af53078c4dd475cf143cd9a427983f5993622464b53e3a37d2519a946492c3977e30f0866550b9097222993a439a39260ac5e7d36aef38c7fdd1df3035a2d5817a9c20526e38f52f822d4db9d2f0156c4119d786d6e3a060ca871df7fae9a5c3a9c921b38ddc6414b13d16aa807389c68016e54bd6a9eb3b23a6bc7bf152e6dba15e9ec36f95dab15ad8f4a92a9d0309bbd930ef24bb7247bf534065c1e2f5b42e2c80eb59f48b4da6ec522319e065f8c4e463f95cc7fcad8d7ee91608e3c0ffcaa44129ba2d2da45d9a413919eca41af29faaf806a3eeb823e5a6c51afb1ec709505d812c0306bd76061a0a62d207355ad44d1ffce2b9e1dfd0818f79bd0f8e4031116b71fee2488484f17818b80532865773166cd389929e8409bb94e3948bd2e0215ef96d4e29d094590fda0de50715c11ff47c03380bb1d31b14e5b4ad8a372ca0b03364ef85f086b8a8eb5c56c3b1aee33e2cfbf1b2be1a3fb41b14b2c432b5d04d54c058fa87a96ae1d65d61b79360d09acc1e25a883fd7ae9a2a734a03362903021401c243173e1050b5cdb459b9ffc07c95e920f026618952d3a800b2e47e03b902084aed7ee8466a65d34abdbbd292781564dcd9b7440029d48c2640ebc196d4b40217f2872c1d0c1c9c2abf1147d6a5a9501895bc92960bfa182ceeb76a658224f1022bc53c4c1cd6888d72a152dc1aec5ba8a1d750fb7e498bee844d3481e4b4cd210227f94f775744185c9f24571b7df0c1c694cb2d3e4e9b955ed0b1caad2b02b5702139c4fbba03f0e422b2f3e4fc822b4f58baf32e7cd217cdbdec8540cb13d6496f271959b72a05e130eeffbe5b9a7fcd2793347cd9c0ea695265669844c363190f690c52a600cf413c3f00bdc5e9d1539e0cc63f4ec2945e0d86e6304a6deb5651e73eac21add5a641dfc95ab56200ed40d81f76755aee4659334c17ed3841ca5a5ab22f923956be1d264be2b485a0de55404510ece5c73d6626798be688f9dc18b69846acfe897a357cc4afe31f57fea32896717f124290e68f36f849fa6ecf76e02087f8c19dbc566135d7fa2daca2d843b9cc5bc3897d35f1de7d174f6407658f4a3706c12cea53d880b4d8c4d45b3f0d210214f815be49a664021a4a44b4a63e06a41d76b46f9aa6bad248e8d1a974ae7bbae5ea8ac269447db91637a19346729083cad5aebd5ff43ea13d04783068e9136da321b1152c666d2995d0ca06b26541deac62f4ef91f0e4af445b18a5c2a17c96eada0b27f85bb26dfb8f16515114c6b9f88037e2b85b3b84b65822eb99c992d99d12dcf9c71e5b46a586016faf5758483a716566db95b42187c101df68ca0554824e1c23cf0302bea03ad0a146af57e91794a268b8c82d78211718c8b5fea286f5de72fc7dfffecddcc02413525c472cb26022641d4bec2b8b7e71a7beb9ee18b82632799498eeee9a351cb9431a8d1906d5164acdf351bd538c3e9d1da8a211fe1cd18c44e72d8cdf16ce3fc9551552c05d52846ea7ef619232102588395cc2bcce509a4e7f150262a76c15475496c923dfce6bfc05871467ee7c213b39ea365c010083e0b1ba8926d3a9e586d8b11c9bab2a47d888bc7cb1a226c0086a1530e295d0047547006f4c8f1c24cdd8e16bb3845749895dec95f03fcda97d3224f6875b1b7b1c819d2fd35dd30968a3c82bc480d10082caf9d9dda8f9ec649c136c7fa07978099d97eaf4abfdc9854c266979d3cfc868f60689b6e3098b6c52a21796fe7c259d9a0dadf1b6efa59297d4c8c902febe7acf826eed30d40d2ac5119be91b51f4839d94599872c9a93c3e2691294914034001d3a278cb4a84d4ae048c0201a97e4cf1341ee663a162f5b586355018b9e5e30624ccdbeacf7d0382afacaf45f08e84d30c50bcd4e55c3138377261deb4e8c2931cd3c51cee94a048ae4839517b6e6537a5c0148d3830a33fea719ef9b4fa437e4d5fecdb646397c19ee56a0973c362a81803895cdc67246352dc566689cb203f9ebda900a5537bbb75aa25ddf3d4ab87b88737a58d760e1d271f08265daae1fe056e71971a8b826e5b215a05b71f99315b167dd2ec78874189657acafac2b5eeb9a901913f55f7ab69e1f9b203504448d414e71098b932a2309db57257eb3fef9de2f2a5a69aa46747d7b827df838345d38b95772bdab8c178c45777b92e8773864964b8e12ae29dbc1b21bf6527589f6bec71ff1cbb9928477409811c2e8150c79c3f21027ee954863b716875d3e9adfc6fdb18cd57a49bb395ca5c42da56f3beb78aad3a7a487de34a870bca61f3cdec422061328c83c910ab32ea7403c354915b7ebee29e1fea5a75158197e4a68e103f017fd7de5a70148ee7ce59356b1a74f83492e14faaa6cd4870bcc004e6eb0114d3429b74ea98fe2851b4553467a7660074e69b040aa31220d0e405d9166dbaf15e3ae2d8ec3b049ed99d17e0743bb6a1a7c3890bbdb7117f7374ad7a59aa1ab47d10445b28f4bc033794a71f88a8bf024189e9d27f9dc5859a4296437585b215656f807aca9dad35747494a43b8a1cf38be2b18a13de32a262ab29f9ba271c4fbce1a470a8243ebf9e7fd37b09262314afbb9a7e180218a0f1c9d505200028b0eb113299010a0012203dd273c42195c061140bd9b5a2a7b72cbfba66b9db63e861f70e9dc95026019c1800226b483045022100f220f48c5267ef92a1e7a4d3b44fe9d97cce76eeba2785d45a0e2620b70e8d7302205640bc39e197ce19d95a98a3239af0f208ca289c067f80c97d8e411e61da5dee0121021721e83315fb5282f1d9d2a11892322df589bccd9cef45517b5fb3cfd3055c8328ffffffff0f3a490a05043c1aec8e10001a1976a9149bb8229741305d8316ba3ca6a8d20740ce33c24188ac222374315934794c31344143486141626a656d6b647057376e594e48576e76317951624441"
|
||||
testTxPacked2 = "0a20bb47a9dd926de63e9d4f8dac58c3f63f4a079569ed3b80e932274a80f60e58b512e20101000000019cafb5c287980e6e5afb47339f6c1c81136d8255f5bd5226b36b01288494c46f000000006b483045022100c92b2f3c54918fa26288530c63a58197ea4974e5b6d92db792dd9717e6d9183c02204e577254213675466a6adad3ae6e9384cf8269fb2dd9943b86fac0c0ad8e3f98012102c99dab469e63b232488b3e7acb9cfcab7e5755f61aad318d9e06b38e5ea22880feffffff0223a7a784010000001976a914826f87806ddd4643730be99b41c98acc379e83db88ac80969800000000001976a914e395634b7684289285926d4c64db395b783720ec88ac6e75040018e4b1c9d50520eeea1128f9ea113299010a0012206fc4948428016bb32652bdf555826d13811c6c9f3347fb5a6e0e9887c2b5af9c1800226b483045022100c92b2f3c54918fa26288530c63a58197ea4974e5b6d92db792dd9717e6d9183c02204e577254213675466a6adad3ae6e9384cf8269fb2dd9943b86fac0c0ad8e3f98012102c99dab469e63b232488b3e7acb9cfcab7e5755f61aad318d9e06b38e5ea2288028feffffff0f3a490a050184a7a72310001a1976a914826f87806ddd4643730be99b41c98acc379e83db88ac22237431566d4854547770457477766f6a786f644e32435351714c596931687a59336341713a470a0398968010011a1976a914e395634b7684289285926d4c64db395b783720ec88ac222374316563784d587070685554525158474c586e56684a367563714433445a6970646467"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -51,8 +52,8 @@ func init() {
|
||||
},
|
||||
Vout: []bchain.Vout{
|
||||
{
|
||||
Value: 181.88266638,
|
||||
N: 0,
|
||||
ValueSat: *big.NewInt(18188266638),
|
||||
N: 0,
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Hex: "76a9149bb8229741305d8316ba3ca6a8d20740ce33c24188ac",
|
||||
Addresses: []string{
|
||||
@ -82,8 +83,8 @@ func init() {
|
||||
},
|
||||
Vout: []bchain.Vout{
|
||||
{
|
||||
Value: 65.20547107,
|
||||
N: 0,
|
||||
ValueSat: *big.NewInt(6520547107),
|
||||
N: 0,
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Hex: "76a914826f87806ddd4643730be99b41c98acc379e83db88ac",
|
||||
Addresses: []string{
|
||||
@ -93,8 +94,8 @@ func init() {
|
||||
Address: addr2,
|
||||
},
|
||||
{
|
||||
Value: .1,
|
||||
N: 1,
|
||||
ValueSat: *big.NewInt(10000000),
|
||||
N: 1,
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Hex: "76a914e395634b7684289285926d4c64db395b783720ec88ac",
|
||||
Addresses: []string{
|
||||
|
||||
@ -22,6 +22,7 @@ func NewZCashRPC(config json.RawMessage, pushHandler func(bchain.NotificationTyp
|
||||
BitcoinRPC: b.(*btc.BitcoinRPC),
|
||||
}
|
||||
z.RPCMarshaler = btc.JSONMarshalerV1{}
|
||||
z.ChainConfig.SupportsEstimateSmartFee = false
|
||||
return z, nil
|
||||
}
|
||||
|
||||
@ -114,14 +115,6 @@ func (z *ZCashRPC) GetTransactionForMempool(txid string) (*bchain.Tx, error) {
|
||||
return z.GetTransaction(txid)
|
||||
}
|
||||
|
||||
// EstimateSmartFee returns fee estimation.
|
||||
func (z *ZCashRPC) EstimateSmartFee(blocks int, conservative bool) (float64, error) {
|
||||
glog.V(1).Info("rpc: estimatesmartfee")
|
||||
|
||||
// return z.estimateFee(blocks)
|
||||
return z.EstimateFee(blocks)
|
||||
}
|
||||
|
||||
// GetMempoolEntry returns mempool data for given transaction
|
||||
func (z *ZCashRPC) GetMempoolEntry(txid string) (*bchain.MempoolEntry, error) {
|
||||
return nil, errors.New("GetMempoolEntry: not implemented")
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
// +build integration
|
||||
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"blockbook/bchain"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@ -83,7 +82,7 @@ func LoadRPCConfig(coin string) (json.RawMessage, error) {
|
||||
return json.RawMessage(fmt.Sprintf(t, coin, c.URL, c.User, c.Pass)), nil
|
||||
}
|
||||
|
||||
func LoadTestData(coin string) (*TestData, error) {
|
||||
func LoadTestData(coin string, parser bchain.BlockChainParser) (*TestData, error) {
|
||||
b, err := readDataFile(".", "bchain/tests/rpc/testdata", coin+".json")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -93,5 +92,16 @@ func LoadTestData(coin string) (*TestData, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// convert amounts in test json to bit.Int and clear the temporary JsonValue
|
||||
for _, tx := range v.TxDetails {
|
||||
for i := range tx.Vout {
|
||||
vout := &tx.Vout[i]
|
||||
vout.ValueSat, err = parser.AmountToBigInt(vout.JsonValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vout.JsonValue = ""
|
||||
}
|
||||
}
|
||||
return &v, nil
|
||||
}
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
// +build integration
|
||||
|
||||
package rpc
|
||||
|
||||
import (
|
||||
@ -9,6 +7,7 @@ import (
|
||||
"net"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/deckarep/golang-set"
|
||||
)
|
||||
@ -56,7 +55,7 @@ func NewTest(coin string, factory TestChainFactoryFunc) (*Test, error) {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
td, err = LoadTestData(coin)
|
||||
td, err = LoadTestData(coin, cli.GetChainParser())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -162,7 +161,7 @@ func (rt *Test) TestGetTransaction(t *testing.T) {
|
||||
got.Confirmations = 0
|
||||
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("GetTransaction() got %v, want %v", got, want)
|
||||
t.Errorf("GetTransaction() got %+v, want %+v", got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -181,7 +180,7 @@ func (rt *Test) TestGetTransactionForMempool(t *testing.T) {
|
||||
// transactions parsed from JSON may contain additional data
|
||||
got.Confirmations, got.Blocktime, got.Time = 0, 0, 0
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("GetTransactionForMempool() got %v, want %v", got, want)
|
||||
t.Errorf("GetTransactionForMempool() got %+v, want %+v", got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -329,8 +328,8 @@ func (rt *Test) TestGetMempoolEntry(t *testing.T) {
|
||||
if e.Size <= 0 {
|
||||
t.Errorf("GetMempoolEntry() got zero or negative size %d", e.Size)
|
||||
}
|
||||
if e.Fee <= 0 {
|
||||
t.Errorf("GetMempoolEntry() got zero or negative fee %f", e.Fee)
|
||||
if e.FeeSat.Sign() != 1 {
|
||||
t.Errorf("GetMempoolEntry() got zero or negative fee %v", e.FeeSat.String())
|
||||
}
|
||||
|
||||
// done
|
||||
@ -347,8 +346,11 @@ func (rt *Test) TestEstimateSmartFee(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if fee != -1 && fee < 0 {
|
||||
t.Errorf("EstimateSmartFee() returned unexpected fee rate: %f", fee)
|
||||
if fee.Sign() == -1 {
|
||||
sf := rt.Client.GetChainParser().AmountToDecimalString(&fee)
|
||||
if sf != "-1" {
|
||||
t.Errorf("EstimateSmartFee() returned unexpected fee rate: %v", sf)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -361,8 +363,11 @@ func (rt *Test) TestEstimateFee(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if fee != -1 && fee < 0 {
|
||||
t.Errorf("EstimateFee() returned unexpected fee rate: %f", fee)
|
||||
if fee.Sign() == -1 {
|
||||
sf := rt.Client.GetChainParser().AmountToDecimalString(&fee)
|
||||
if sf != "-1" {
|
||||
t.Errorf("EstimateFee() returned unexpected fee rate: %v", sf)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -385,6 +390,7 @@ func (rt *Test) TestGetBestBlockHash(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if hash != hh {
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
2
bchain/tests/rpc/testdata/Bcash.json
vendored
2
bchain/tests/rpc/testdata/Bcash.json
vendored
@ -70,6 +70,7 @@
|
||||
"blocktime":1531135480,
|
||||
"time":1531135480,
|
||||
"locktime": 0,
|
||||
"version": 1,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "fe496933e0a3582ef020bd35c38fe8244a80fa7c63e7607f6f9ccb0806f419e4",
|
||||
@ -175,6 +176,7 @@
|
||||
"blocktime":1531135480,
|
||||
"time":1531135480,
|
||||
"locktime": 0,
|
||||
"version": 1,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "52f37874fd5a2497c5d84619ab415ca17ebb1d49d559f0d468869f70537354b9",
|
||||
|
||||
2
bchain/tests/rpc/testdata/Bcash_Testnet.json
vendored
2
bchain/tests/rpc/testdata/Bcash_Testnet.json
vendored
@ -12,6 +12,7 @@
|
||||
"blocktime":1529571678,
|
||||
"time":1529571678,
|
||||
"locktime": 0,
|
||||
"version": 1,
|
||||
"vin": [
|
||||
{
|
||||
"coinbase": "03fbf212055374617368",
|
||||
@ -34,6 +35,7 @@
|
||||
"blocktime":1529571678,
|
||||
"time":1529571678,
|
||||
"locktime": 0,
|
||||
"version": 1,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "58ff2450a71b3c228d17d04ec8edcaae452bc97d5ccc4591e2741fd8b031d221",
|
||||
|
||||
2
bchain/tests/rpc/testdata/Bitcoin.json
vendored
2
bchain/tests/rpc/testdata/Bitcoin.json
vendored
@ -120,6 +120,7 @@
|
||||
"blocktime": 1529915213,
|
||||
"time": 1529915213,
|
||||
"locktime": 0,
|
||||
"version": 1,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "83eff5bcc738d52e04528984cd5cf601b69e7df65b2b10ed2475c0072cdde14c",
|
||||
@ -153,6 +154,7 @@
|
||||
"blocktime": 1529915213,
|
||||
"time": 1529915213,
|
||||
"locktime": 529149,
|
||||
"version": 2,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "413988d546516707f3b20ca9876e026a9472bd814662e42f37f4e57a15713da7",
|
||||
|
||||
@ -43,6 +43,7 @@
|
||||
"blocktime": 1528788394,
|
||||
"time": 1528788394,
|
||||
"locktime": 0,
|
||||
"version": 1,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "4097f5265397047bffe219a1bca65ea5726402c3d9aeecd577fa1c274fc1b8a4",
|
||||
@ -84,6 +85,7 @@
|
||||
"blocktime": 1528788394,
|
||||
"time": 1528788394,
|
||||
"locktime": 0,
|
||||
"version": 1,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "80437ba4e81bde8b584258f5adad0d08dea60f1e38026344442ad59a4ef797c9",
|
||||
|
||||
1
bchain/tests/rpc/testdata/Dash.json
vendored
1
bchain/tests/rpc/testdata/Dash.json
vendored
@ -27,6 +27,7 @@
|
||||
"blocktime": 1530189699,
|
||||
"time": 1530189699,
|
||||
"locktime": 0,
|
||||
"version": 1,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "a78824a88c089ea1344fe2a33c454024e6501e76cca2590515b390d85082bd23",
|
||||
|
||||
2
bchain/tests/rpc/testdata/Dash_Testnet.json
vendored
2
bchain/tests/rpc/testdata/Dash_Testnet.json
vendored
@ -31,6 +31,7 @@
|
||||
"blocktime": 1528713762,
|
||||
"time": 1528713762,
|
||||
"locktime": 139520,
|
||||
"version": 2,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "a41616c7585c98aeda98d6ff6766b15455e327c9472582b80289dab7597ad309",
|
||||
@ -64,6 +65,7 @@
|
||||
"blocktime": 1528713762,
|
||||
"time": 1528713762,
|
||||
"locktime": 139520,
|
||||
"version": 2,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "187ae015e41dff766f5a18ae705f59db950a6729a06fa5fd04630c362a9aee27",
|
||||
|
||||
29
bchain/tests/rpc/testdata/Ethereum_Testnet.json
vendored
29
bchain/tests/rpc/testdata/Ethereum_Testnet.json
vendored
@ -16,38 +16,21 @@
|
||||
"0x7f0d140329941f120b5b3fc751e30adeb87b2aebbfce5adcd0216604a34b6cc0"
|
||||
],
|
||||
"txDetails": {
|
||||
"0xe6b168d6bb3d8ed78e03dbf828b6bfd1fb613f6e129cba624964984553724c5d": {
|
||||
"hex": "7b226e6f6e6365223a2230783239666165222c226761735072696365223a223078313261303566323030222c22676173223a2230786462626130222c22746f223a22307836383262373930336131313039386366373730633761656634616130326138356233663336303161222c2276616c7565223a22307830222c22696e707574223a223078663032356361616630303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030323235222c2268617368223a22307865366231363864366262336438656437386530336462663832386236626664316662363133663665313239636261363234393634393834353533373234633564222c22626c6f636b4e756d626572223a223078326263616630222c2266726f6d223a22307864616363396336313735346130633436313666633533323364633934366538396562323732333032222c227472616e73616374696f6e496e646578223a22307831222c2276223a2230783162222c2272223a22307831626434306133313132326330333931386466366431363664373430613661336132326630386132353933346365623136383863363239373736363163383063222c2273223a22307836303766626331356331663739393561343235386635613962636363363362303430333632643139393164356566653133363163353632323265346361383966227d",
|
||||
"txid": "0xe6b168d6bb3d8ed78e03dbf828b6bfd1fb613f6e129cba624964984553724c5d",
|
||||
"0x7f0d140329941f120b5b3fc751e30adeb87b2aebbfce5adcd0216604a34b6cc0": {
|
||||
"hex": "7b226e6f6e6365223a223078333632306136222c226761735072696365223a223078313261303566323030222c22676173223a22307835323038222c22746f223a22307831623137626331326166623635643563346238316139666632613037366234326131396661616136222c2276616c7565223a223078646530623662336137363430303030222c22696e707574223a223078222c2268617368223a22307837663064313430333239393431663132306235623366633735316533306164656238376232616562626663653561646364303231363630346133346236636330222c22626c6f636b4e756d626572223a223078326263616630222c2266726f6d223a22307838316237653038663635626466353634383630366338393939386139636338313634333937363437222c227472616e73616374696f6e496e646578223a22307862222c2276223a2230783162222c2272223a22307862666662323864633865373939383833366639356664616139396433626435666635346365663562313839636462383537333537666161326431616231393136222c2273223a22307833616462316365313264396664306538616662373064386639346534636538356137666639346465333966623636333139363638363435663464643138646432227d",
|
||||
"txid": "0x7f0d140329941f120b5b3fc751e30adeb87b2aebbfce5adcd0216604a34b6cc0",
|
||||
"blocktime": 1521515026,
|
||||
"time": 1521515026,
|
||||
"vin": [
|
||||
{
|
||||
"addresses": ["0xdacc9c61754a0c4616fc5323dc946e89eb272302"]
|
||||
"addresses": ["0x81b7e08f65bdf5648606c89998a9cc8164397647"]
|
||||
}
|
||||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 1,
|
||||
"scriptPubKey": {
|
||||
"addresses": ["0x682b7903a11098cf770c7aef4aa02a85b3f3601a"]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"0x17ee235fc0359155b25419e0e4c65d9c500df6e71e8288d6ef020d04cc2f2cb3": {
|
||||
"hex": "7b226e6f6e6365223a223078346566222c226761735072696365223a223078626134336237343030222c22676173223a2230783936653838222c22746f223a22307864303534323939633438326164356362333961336661383734373235663965326132306433343963222c2276616c7565223a22307830222c22696e707574223a2230783165626366613630303030303030303030303030303030303030303030303030633034383732383566313736663532306635636434363732306236383662366534366165636430373030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303031303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030313430303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030633461303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303530303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030353831303030303030303030303030303030303030303030303030633365313631343261306432366336616530623163656238643961373236653734653164613664663666656562653137653437306464626434656261663364623938333136386235316337623136363732613131623966306662383864623438323962653237346230303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303034363336663665363230303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303437323666373336313030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c2268617368223a22307831376565323335666330333539313535623235343139653065346336356439633530306466366537316538323838643665663032306430346363326632636233222c22626c6f636b4e756d626572223a223078326263616630222c2266726f6d223a22307838623461353365353739303739343466633261653539623837373066393331623639326232373062222c227472616e73616374696f6e496e646578223a22307830222c2276223a2230783163222c2272223a22307866633739633836353638323039313030323134616339353662373930653066383935656130343135313438643233613239353632356564393761633936333534222c2273223a223078373232303833616331643764663662626162393939383537616163323561336665646265386130633561326266376364653835393738363266373862313937227d",
|
||||
"txid": "0x17ee235fc0359155b25419e0e4c65d9c500df6e71e8288d6ef020d04cc2f2cb3",
|
||||
"blocktime": 1521515026,
|
||||
"time": 1521515026,
|
||||
"vin": [
|
||||
{
|
||||
"addresses": ["0x8b4a53e57907944fc2ae59b8770f931b692b270b"]
|
||||
}
|
||||
],
|
||||
"vout": [
|
||||
{
|
||||
"scriptPubKey": {
|
||||
"addresses": ["0xd054299c482ad5cb39a3fa874725f9e2a20d349c"]
|
||||
"addresses": ["0x1b17bc12afb65d5c4b81a9ff2a076b42a19faaa6"]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
1
bchain/tests/rpc/testdata/Namecoin.json
vendored
1
bchain/tests/rpc/testdata/Namecoin.json
vendored
@ -39,6 +39,7 @@
|
||||
"blocktime": 1530003649,
|
||||
"time": 1530003649,
|
||||
"locktime": 404678,
|
||||
"version": 1,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "223a4ff7a613173ffbc67f9efffe1b0c3fd5ba2471935a44cc81814038272901",
|
||||
|
||||
2
bchain/tests/rpc/testdata/Vertcoin.json
vendored
2
bchain/tests/rpc/testdata/Vertcoin.json
vendored
@ -14,6 +14,7 @@
|
||||
"blocktime": 1529932850,
|
||||
"time": 1529932850,
|
||||
"locktime": 952232,
|
||||
"version": 2,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "8ec70404bdd16559c589736863ee9d9f69431ba4e6b2ab3b1641b3f9f3821624",
|
||||
@ -47,6 +48,7 @@
|
||||
"blocktime": 1529932850,
|
||||
"time": 1529932850,
|
||||
"locktime": 952233,
|
||||
"version": 1,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "5765db7dd62cddada154b2c95505e298818a308cc1ce1e28d6e8565301cb8d74",
|
||||
|
||||
2
bchain/tests/rpc/testdata/Zcash.json
vendored
2
bchain/tests/rpc/testdata/Zcash.json
vendored
@ -22,6 +22,7 @@
|
||||
"blocktime": 1530264033,
|
||||
"time": 1530264033,
|
||||
"locktime": 349399,
|
||||
"version": 3,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "9c9faac29b0fa1b0e683727f2973bfcb87e4baadd07e9c997b431a31713cb30c",
|
||||
@ -57,6 +58,7 @@
|
||||
"blocktime": 1530264033,
|
||||
"time": 1530264033,
|
||||
"locktime": 0,
|
||||
"version": 3,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "4440c8e9d5b57da7ca0fb3f62ec13f392267aeb797c123bb01e850adf8573dd0",
|
||||
|
||||
2
bchain/tests/rpc/testdata/Zcash_Testnet.json
vendored
2
bchain/tests/rpc/testdata/Zcash_Testnet.json
vendored
@ -13,6 +13,7 @@
|
||||
"blocktime": 1528781777,
|
||||
"time": 1528781777,
|
||||
"locktime": 251028,
|
||||
"version": 3,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "19a1d013b898239e9a2943faa07f8716b9be168bc8e001daf3625f535fde1a60",
|
||||
@ -48,6 +49,7 @@
|
||||
"blocktime": 1528781777,
|
||||
"time": 1528781777,
|
||||
"locktime": 251090,
|
||||
"version": 3,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "9acab5f13cf94074e75f5686b59fccd938f54b5f20ddddfcb6077c679a13c0ea",
|
||||
|
||||
@ -148,7 +148,7 @@ func (m *ProtoTransaction_VinType) GetAddresses() []string {
|
||||
}
|
||||
|
||||
type ProtoTransaction_VoutType struct {
|
||||
Value float64 `protobuf:"fixed64,1,opt,name=Value" json:"Value,omitempty"`
|
||||
ValueSat []byte `protobuf:"bytes,1,opt,name=ValueSat,proto3" json:"ValueSat,omitempty"`
|
||||
N uint32 `protobuf:"varint,2,opt,name=N" json:"N,omitempty"`
|
||||
ScriptPubKeyHex []byte `protobuf:"bytes,3,opt,name=ScriptPubKeyHex,proto3" json:"ScriptPubKeyHex,omitempty"`
|
||||
Addresses []string `protobuf:"bytes,4,rep,name=Addresses" json:"Addresses,omitempty"`
|
||||
@ -159,11 +159,11 @@ func (m *ProtoTransaction_VoutType) String() string { return proto.Co
|
||||
func (*ProtoTransaction_VoutType) ProtoMessage() {}
|
||||
func (*ProtoTransaction_VoutType) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 1} }
|
||||
|
||||
func (m *ProtoTransaction_VoutType) GetValue() float64 {
|
||||
func (m *ProtoTransaction_VoutType) GetValueSat() []byte {
|
||||
if m != nil {
|
||||
return m.Value
|
||||
return m.ValueSat
|
||||
}
|
||||
return 0
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ProtoTransaction_VoutType) GetN() uint32 {
|
||||
@ -196,26 +196,26 @@ func init() {
|
||||
func init() { proto.RegisterFile("tx.proto", fileDescriptor0) }
|
||||
|
||||
var fileDescriptor0 = []byte{
|
||||
// 330 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0xc1, 0x4e, 0xc2, 0x40,
|
||||
0x10, 0x86, 0xb3, 0xb4, 0x14, 0x18, 0x21, 0x92, 0x89, 0x31, 0x0d, 0xf1, 0x50, 0x39, 0xf5, 0xd4,
|
||||
0x03, 0xc6, 0x07, 0x50, 0x2f, 0x24, 0x1a, 0x42, 0x16, 0xd2, 0x7b, 0x5b, 0x36, 0xb0, 0x11, 0x77,
|
||||
0xb1, 0xdd, 0x1a, 0x78, 0x16, 0x1f, 0xc1, 0x97, 0x34, 0x3b, 0x2d, 0x45, 0x48, 0xbc, 0xed, 0xff,
|
||||
0xef, 0x4c, 0xff, 0x6f, 0xff, 0x14, 0xba, 0x66, 0x1f, 0xed, 0x72, 0x6d, 0x34, 0x7a, 0x69, 0xb6,
|
||||
0x49, 0xa4, 0x1a, 0x7f, 0xbb, 0x30, 0x9c, 0x5b, 0x67, 0x99, 0x27, 0xaa, 0x48, 0x32, 0x23, 0xb5,
|
||||
0x42, 0x04, 0x77, 0xb9, 0x97, 0x2b, 0x9f, 0x05, 0x2c, 0xec, 0x73, 0x3a, 0xe3, 0x10, 0x9c, 0xa9,
|
||||
0xd8, 0xfb, 0x2d, 0xb2, 0xec, 0x11, 0xef, 0xa0, 0xf7, 0xbc, 0xd5, 0xd9, 0xbb, 0x91, 0x1f, 0xc2,
|
||||
0x77, 0x02, 0x16, 0xba, 0xfc, 0x64, 0xe0, 0x08, 0xba, 0x6f, 0xc7, 0x4b, 0x37, 0x60, 0xe1, 0x80,
|
||||
0x37, 0x1a, 0x6f, 0xc1, 0x9b, 0x0a, 0xb9, 0xde, 0x18, 0xbf, 0x4d, 0x37, 0xb5, 0xc2, 0x09, 0x38,
|
||||
0xb1, 0x54, 0xbe, 0x17, 0x38, 0xe1, 0xd5, 0x24, 0x88, 0x2a, 0xc4, 0xe8, 0x12, 0x2f, 0x8a, 0xa5,
|
||||
0x5a, 0x1e, 0x76, 0x82, 0xdb, 0x61, 0x7c, 0x04, 0x37, 0xd6, 0xa5, 0xf1, 0x3b, 0xb4, 0x74, 0xff,
|
||||
0xff, 0x92, 0x2e, 0x0d, 0x6d, 0xd1, 0xf8, 0xe8, 0x87, 0x41, 0xa7, 0xfe, 0x8e, 0x45, 0x7d, 0xd1,
|
||||
0x52, 0xa5, 0x49, 0x21, 0xe8, 0xc9, 0x3d, 0xde, 0xe8, 0xa6, 0x8a, 0xd6, 0x9f, 0x2a, 0xb0, 0x8e,
|
||||
0x74, 0x08, 0x9e, 0xce, 0x38, 0x86, 0xfe, 0x22, 0xcb, 0xe5, 0xce, 0x2c, 0xe4, 0xda, 0xf6, 0xe4,
|
||||
0xd2, 0xfc, 0x99, 0x67, 0x73, 0x16, 0xe2, 0xb3, 0x14, 0x2a, 0x13, 0xf5, 0xc3, 0x1b, 0x6d, 0xcb,
|
||||
0x7c, 0x5a, 0xad, 0x72, 0x51, 0x14, 0xa2, 0xa0, 0x02, 0x7a, 0xfc, 0x64, 0x8c, 0xbe, 0xa0, 0x7b,
|
||||
0xe4, 0xc7, 0x1b, 0x68, 0xc7, 0xc9, 0xb6, 0xac, 0x50, 0x19, 0xaf, 0x04, 0xf6, 0x81, 0xcd, 0x08,
|
||||
0x72, 0xc0, 0xd9, 0x0c, 0x43, 0xb8, 0xae, 0x92, 0xe7, 0x65, 0xfa, 0x2a, 0x0e, 0x16, 0xc8, 0x21,
|
||||
0xa0, 0x4b, 0xfb, 0x3c, 0xd7, 0xbd, 0xc8, 0x4d, 0x3d, 0xfa, 0x59, 0x1e, 0x7e, 0x03, 0x00, 0x00,
|
||||
0xff, 0xff, 0x64, 0x1d, 0x38, 0xac, 0x38, 0x02, 0x00, 0x00,
|
||||
// 331 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x52, 0xc1, 0x6e, 0xea, 0x30,
|
||||
0x10, 0x94, 0x89, 0x5f, 0x80, 0x7d, 0xa0, 0x87, 0xf6, 0xf0, 0x14, 0xa1, 0x1e, 0x52, 0x4e, 0x39,
|
||||
0xe5, 0x40, 0xd5, 0x0f, 0x68, 0x7b, 0x41, 0x6a, 0x85, 0x90, 0x83, 0x72, 0x4f, 0x82, 0x05, 0x56,
|
||||
0xa9, 0x4d, 0x13, 0x47, 0x02, 0xa9, 0x3f, 0xd3, 0x73, 0x7f, 0xb2, 0xf2, 0x12, 0x42, 0x41, 0xea,
|
||||
0x6d, 0x67, 0xbc, 0xe3, 0x19, 0x4f, 0x02, 0x3d, 0xbb, 0x8f, 0x77, 0xa5, 0xb1, 0x06, 0xfd, 0xbc,
|
||||
0xd8, 0x64, 0x4a, 0x4f, 0x3e, 0x39, 0x8c, 0x16, 0x8e, 0x59, 0x96, 0x99, 0xae, 0xb2, 0xc2, 0x2a,
|
||||
0xa3, 0x11, 0x81, 0x2f, 0xf7, 0x6a, 0x15, 0xb0, 0x90, 0x45, 0x03, 0x41, 0x33, 0x8e, 0xc0, 0x9b,
|
||||
0xc9, 0x7d, 0xd0, 0x21, 0xca, 0x8d, 0x78, 0x03, 0xfd, 0xc7, 0xad, 0x29, 0x5e, 0xad, 0x7a, 0x93,
|
||||
0x81, 0x17, 0xb2, 0x88, 0x8b, 0x33, 0x81, 0x63, 0xe8, 0xbd, 0x9c, 0x0e, 0x79, 0xc8, 0xa2, 0xa1,
|
||||
0x68, 0x31, 0xfe, 0x07, 0x7f, 0x26, 0xd5, 0x7a, 0x63, 0x83, 0x3f, 0x74, 0xd2, 0x20, 0x9c, 0x82,
|
||||
0x97, 0x2a, 0x1d, 0xf8, 0xa1, 0x17, 0xfd, 0x9d, 0x86, 0xf1, 0x31, 0x62, 0x7c, 0x1d, 0x2f, 0x4e,
|
||||
0x95, 0x5e, 0x1e, 0x76, 0x52, 0xb8, 0x65, 0xbc, 0x07, 0x9e, 0x9a, 0xda, 0x06, 0x5d, 0x12, 0xdd,
|
||||
0xfe, 0x2e, 0x32, 0xb5, 0x25, 0x15, 0xad, 0x8f, 0xbf, 0x18, 0x74, 0x9b, 0x7b, 0x5c, 0xd4, 0x27,
|
||||
0xa3, 0x74, 0x9e, 0x55, 0x92, 0x9e, 0xdc, 0x17, 0x2d, 0x6e, 0xab, 0xe8, 0xfc, 0xa8, 0x02, 0x1b,
|
||||
0x4b, 0x8f, 0xc2, 0xd3, 0x8c, 0x13, 0x18, 0x24, 0x45, 0xa9, 0x76, 0x36, 0x51, 0x6b, 0xd7, 0x13,
|
||||
0xa7, 0xfd, 0x0b, 0xce, 0xf9, 0x24, 0xf2, 0xbd, 0x96, 0xba, 0x90, 0xcd, 0xc3, 0x5b, 0xec, 0xca,
|
||||
0x7c, 0x58, 0xad, 0x4a, 0x59, 0x55, 0xb2, 0xa2, 0x02, 0xfa, 0xe2, 0x4c, 0x8c, 0x3f, 0xa0, 0x77,
|
||||
0xca, 0xef, 0x6e, 0x49, 0xb3, 0x6d, 0x2d, 0x93, 0xcc, 0x36, 0x1f, 0xa8, 0xc5, 0x38, 0x00, 0x36,
|
||||
0xa7, 0xa8, 0x43, 0xc1, 0xe6, 0x18, 0xc1, 0xbf, 0xa3, 0xff, 0xa2, 0xce, 0x9f, 0xe5, 0xc1, 0xc5,
|
||||
0xf2, 0x48, 0x70, 0x4d, 0x5f, 0xba, 0xf3, 0x2b, 0xf7, 0xdc, 0xa7, 0x5f, 0xe6, 0xee, 0x3b, 0x00,
|
||||
0x00, 0xff, 0xff, 0x95, 0x9e, 0x00, 0x7a, 0x3e, 0x02, 0x00, 0x00,
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ syntax = "proto3";
|
||||
repeated string Addresses = 6;
|
||||
}
|
||||
message VoutType {
|
||||
double Value = 1;
|
||||
bytes ValueSat = 1;
|
||||
uint32 N = 2;
|
||||
bytes ScriptPubKeyHex = 3;
|
||||
repeated string Addresses = 4;
|
||||
|
||||
@ -5,6 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
// errors with specific meaning returned by blockchain rpc
|
||||
@ -49,7 +50,8 @@ type Address interface {
|
||||
}
|
||||
|
||||
type Vout struct {
|
||||
Value float64 `json:"value"`
|
||||
ValueSat big.Int
|
||||
JsonValue json.Number `json:"value"`
|
||||
N uint32 `json:"n"`
|
||||
ScriptPubKey ScriptPubKey `json:"scriptPubKey"`
|
||||
Address Address
|
||||
@ -89,18 +91,20 @@ type BlockHeader struct {
|
||||
}
|
||||
|
||||
type MempoolEntry struct {
|
||||
Size uint32 `json:"size"`
|
||||
Fee float64 `json:"fee"`
|
||||
ModifiedFee float64 `json:"modifiedfee"`
|
||||
Time float64 `json:"time"`
|
||||
Height uint32 `json:"height"`
|
||||
DescendantCount uint32 `json:"descendantcount"`
|
||||
DescendantSize uint32 `json:"descendantsize"`
|
||||
DescendantFees uint32 `json:"descendantfees"`
|
||||
AncestorCount uint32 `json:"ancestorcount"`
|
||||
AncestorSize uint32 `json:"ancestorsize"`
|
||||
AncestorFees uint32 `json:"ancestorfees"`
|
||||
Depends []string `json:"depends"`
|
||||
Size uint32 `json:"size"`
|
||||
FeeSat big.Int
|
||||
Fee json.Number `json:"fee"`
|
||||
ModifiedFeeSat big.Int
|
||||
ModifiedFee json.Number `json:"modifiedfee"`
|
||||
Time uint64 `json:"time"`
|
||||
Height uint32 `json:"height"`
|
||||
DescendantCount uint32 `json:"descendantcount"`
|
||||
DescendantSize uint32 `json:"descendantsize"`
|
||||
DescendantFees uint32 `json:"descendantfees"`
|
||||
AncestorCount uint32 `json:"ancestorcount"`
|
||||
AncestorSize uint32 `json:"ancestorsize"`
|
||||
AncestorFees uint32 `json:"ancestorfees"`
|
||||
Depends []string `json:"depends"`
|
||||
}
|
||||
|
||||
type RPCError struct {
|
||||
@ -132,8 +136,8 @@ type BlockChain interface {
|
||||
GetMempool() ([]string, error)
|
||||
GetTransaction(txid string) (*Tx, error)
|
||||
GetTransactionForMempool(txid string) (*Tx, error)
|
||||
EstimateSmartFee(blocks int, conservative bool) (float64, error)
|
||||
EstimateFee(blocks int) (float64, error)
|
||||
EstimateSmartFee(blocks int, conservative bool) (big.Int, error)
|
||||
EstimateFee(blocks int) (big.Int, error)
|
||||
SendRawTransaction(tx string) (string, error)
|
||||
// mempool
|
||||
ResyncMempool(onNewTxAddr func(txid string, addr string)) (int, error)
|
||||
@ -145,7 +149,7 @@ type BlockChain interface {
|
||||
|
||||
// BlockChainParser defines common interface to parsing and conversions of block chain data
|
||||
type BlockChainParser interface {
|
||||
// self description
|
||||
// chain configuration description
|
||||
// UTXO chains need "inputs" column in db, that map transactions to transactions that spend them
|
||||
// non UTXO chains have mapping of address to input and output transactions directly in "outputs" column in db
|
||||
IsUTXOChain() bool
|
||||
@ -153,6 +157,11 @@ type BlockChainParser interface {
|
||||
// and used in case of fork
|
||||
// if 0 the blockaddresses column is not used at all (usually non UTXO chains)
|
||||
KeepBlockAddresses() int
|
||||
// AmountToDecimalString converts amount in big.Int to string with decimal point in the correct place
|
||||
AmountToDecimalString(a *big.Int) string
|
||||
// AmountToBigInt converts amount in json.Number (string) to big.Int
|
||||
// it uses string operations to avoid problems with rounding
|
||||
AmountToBigInt(n json.Number) (big.Int, error)
|
||||
// address id conversions
|
||||
GetAddrIDFromVout(output *Vout) ([]byte, error)
|
||||
GetAddrIDFromAddress(address string) ([]byte, error)
|
||||
|
||||
@ -175,7 +175,11 @@ func main() {
|
||||
}
|
||||
index.SetInternalState(internalState)
|
||||
if internalState.DbState != common.DbStateClosed {
|
||||
glog.Warning("internalState: database in not closed state ", internalState.DbState, ", possibly previous ungraceful shutdown")
|
||||
if internalState.DbState == common.DbStateInconsistent {
|
||||
glog.Error("internalState: database is in inconsistent state and cannot be used")
|
||||
return
|
||||
}
|
||||
glog.Warning("internalState: database was left in open state, possibly previous ungraceful shutdown")
|
||||
}
|
||||
|
||||
if *computeColumnStats {
|
||||
|
||||
@ -11,6 +11,8 @@ const (
|
||||
DbStateClosed = uint32(iota)
|
||||
// DbStateOpen means db is open or application died without closing the db
|
||||
DbStateOpen
|
||||
// DbStateInconsistent means db is in inconsistent state and cannot be used
|
||||
DbStateInconsistent
|
||||
)
|
||||
|
||||
// InternalStateColumn contains the data of a db column
|
||||
|
||||
1366
db/rocksdb.go
1366
db/rocksdb.go
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
29
db/sync.go
29
db/sync.go
@ -213,17 +213,26 @@ func (w *SyncWorker) ConnectBlocksParallel(lower, higher uint32) error {
|
||||
writeBlockDone := make(chan struct{})
|
||||
writeBlockWorker := func() {
|
||||
defer close(writeBlockDone)
|
||||
bc, err := w.db.InitBulkConnect()
|
||||
if err != nil {
|
||||
glog.Error("sync: InitBulkConnect error ", err)
|
||||
}
|
||||
lastBlock := lower - 1
|
||||
keep := uint32(w.chain.GetChainParser().KeepBlockAddresses())
|
||||
for b := range bch {
|
||||
if lastBlock+1 != b.Height {
|
||||
glog.Error("writeBlockWorker skipped block, last connected block", lastBlock, ", new block ", b.Height)
|
||||
}
|
||||
err := w.db.ConnectBlock(b)
|
||||
err := bc.ConnectBlock(b, b.Height+keep > higher)
|
||||
if err != nil {
|
||||
glog.Error("writeBlockWorker ", b.Height, " ", b.Hash, " error ", err)
|
||||
}
|
||||
lastBlock = b.Height
|
||||
}
|
||||
err = bc.Close()
|
||||
if err != nil {
|
||||
glog.Error("sync: bulkconnect.Close error ", err)
|
||||
}
|
||||
glog.Info("WriteBlock exiting...")
|
||||
}
|
||||
getBlockWorker := func(i int) {
|
||||
@ -276,6 +285,7 @@ func (w *SyncWorker) ConnectBlocksParallel(lower, higher uint32) error {
|
||||
}
|
||||
go writeBlockWorker()
|
||||
var hash string
|
||||
start := time.Now()
|
||||
ConnectLoop:
|
||||
for h := lower; h <= higher; {
|
||||
select {
|
||||
@ -292,7 +302,8 @@ ConnectLoop:
|
||||
}
|
||||
hch <- hashHeight{hash, h}
|
||||
if h > 0 && h%1000 == 0 {
|
||||
glog.Info("connecting block ", h, " ", hash)
|
||||
glog.Info("connecting block ", h, " ", hash, ", elapsed ", time.Since(start))
|
||||
start = time.Now()
|
||||
}
|
||||
h++
|
||||
}
|
||||
@ -346,25 +357,23 @@ func (w *SyncWorker) getBlockChain(out chan blockResult, done chan struct{}) {
|
||||
}
|
||||
|
||||
// DisconnectBlocks removes all data belonging to blocks in range lower-higher,
|
||||
// using block data from blockchain, if they are available,
|
||||
// otherwise doing full scan
|
||||
func (w *SyncWorker) DisconnectBlocks(lower uint32, higher uint32, hashes []string) error {
|
||||
glog.Infof("sync: disconnecting blocks %d-%d", lower, higher)
|
||||
// if the chain uses Block to Addresses mapping, always use DisconnectBlockRange
|
||||
if w.chain.GetChainParser().KeepBlockAddresses() > 0 {
|
||||
return w.db.DisconnectBlockRange(lower, higher)
|
||||
// if the chain is UTXO, always use DisconnectBlockRange
|
||||
if w.chain.GetChainParser().IsUTXOChain() {
|
||||
return w.db.DisconnectBlockRangeUTXO(lower, higher)
|
||||
}
|
||||
blocks := make([]*bchain.Block, len(hashes))
|
||||
var err error
|
||||
// get all blocks first to see if we can avoid full scan
|
||||
// try to get all blocks first to see if we can avoid full scan
|
||||
for i, hash := range hashes {
|
||||
blocks[i], err = w.chain.GetBlock(hash, 0)
|
||||
if err != nil {
|
||||
// cannot get a block, we must do full range scan
|
||||
return w.db.DisconnectBlockRange(lower, higher)
|
||||
return w.db.DisconnectBlockRangeNonUTXO(lower, higher)
|
||||
}
|
||||
}
|
||||
// then disconnect one after another
|
||||
// got all blocks to be disconnected, disconnect them one after another
|
||||
for i, block := range blocks {
|
||||
glog.Info("Disconnecting block ", (int(higher) - i), " ", block.Hash)
|
||||
if err = w.db.DisconnectBlock(block); err != nil {
|
||||
|
||||
@ -113,8 +113,10 @@ func formatUnixTime(ut int64) string {
|
||||
return time.Unix(ut, 0).Format(time.RFC1123)
|
||||
}
|
||||
|
||||
func formatAmount(a float64) string {
|
||||
return strings.TrimRight(strings.TrimRight(fmt.Sprintf("%0.8f", a), "0"), ".")
|
||||
// for now return the string as it is
|
||||
// in future could be used to do coin specific formatting
|
||||
func formatAmount(a string) string {
|
||||
return a
|
||||
}
|
||||
|
||||
// Run starts the server
|
||||
|
||||
@ -7,6 +7,7 @@ import (
|
||||
"blockbook/db"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -236,11 +237,11 @@ type txInputs struct {
|
||||
// ScriptAsm *string `json:"scriptAsm"`
|
||||
Sequence int64 `json:"sequence"`
|
||||
Address *string `json:"address"`
|
||||
Satoshis int64 `json:"satoshis"`
|
||||
Satoshis string `json:"satoshis"`
|
||||
}
|
||||
|
||||
type txOutputs struct {
|
||||
Satoshis int64 `json:"satoshis"`
|
||||
Satoshis string `json:"satoshis"`
|
||||
Script *string `json:"script"`
|
||||
// ScriptAsm *string `json:"scriptAsm"`
|
||||
SpentTxID *string `json:"spentTxId,omitempty"`
|
||||
@ -267,7 +268,7 @@ type resTx struct {
|
||||
|
||||
type addressHistoryItem struct {
|
||||
Addresses map[string]addressHistoryIndexes `json:"addresses"`
|
||||
Satoshis int64 `json:"satoshis"`
|
||||
Satoshis string `json:"satoshis"`
|
||||
Confirmations int `json:"confirmations"`
|
||||
Tx resTx `json:"tx"`
|
||||
}
|
||||
@ -329,7 +330,7 @@ func (s *SocketIoServer) getAddressHistory(addr []string, opts *addrOpts) (res r
|
||||
for _, vout := range tx.Vout {
|
||||
aoh := vout.ScriptPubKey.Hex
|
||||
ao := txOutputs{
|
||||
Satoshis: int64(vout.Value*1E8 + 0.5),
|
||||
Satoshis: vout.ValueSat.String(),
|
||||
Script: &aoh,
|
||||
}
|
||||
if vout.Address != nil {
|
||||
@ -452,6 +453,7 @@ func unmarshalEstimateSmartFee(params []byte) (blocks int, conservative bool, er
|
||||
}
|
||||
|
||||
type resultEstimateSmartFee struct {
|
||||
// for compatibility reasons use float64
|
||||
Result float64 `json:"result"`
|
||||
}
|
||||
|
||||
@ -460,7 +462,7 @@ func (s *SocketIoServer) estimateSmartFee(blocks int, conservative bool) (res re
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
res.Result = fee
|
||||
res.Result, err = strconv.ParseFloat(s.chainParser.AmountToDecimalString(&fee), 64)
|
||||
return
|
||||
}
|
||||
|
||||
@ -479,6 +481,7 @@ func unmarshalEstimateFee(params []byte) (blocks int, err error) {
|
||||
}
|
||||
|
||||
type resultEstimateFee struct {
|
||||
// for compatibility reasons use float64
|
||||
Result float64 `json:"result"`
|
||||
}
|
||||
|
||||
@ -487,7 +490,7 @@ func (s *SocketIoServer) estimateFee(blocks int) (res resultEstimateFee, err err
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
res.Result = fee
|
||||
res.Result, err = strconv.ParseFloat(s.chainParser.AmountToDecimalString(&fee), 64)
|
||||
return
|
||||
}
|
||||
|
||||
@ -588,7 +591,7 @@ func (s *SocketIoServer) getDetailedTransaction(txid string) (res resultGetDetai
|
||||
a := vout.Address.String()
|
||||
ai.Address = &a
|
||||
}
|
||||
ai.Satoshis = int64(vout.Value*1E8 + 0.5)
|
||||
ai.Satoshis = vout.ValueSat.String()
|
||||
}
|
||||
}
|
||||
hi = append(hi, ai)
|
||||
@ -596,7 +599,7 @@ func (s *SocketIoServer) getDetailedTransaction(txid string) (res resultGetDetai
|
||||
for _, vout := range tx.Vout {
|
||||
aos := vout.ScriptPubKey.Hex
|
||||
ao := txOutputs{
|
||||
Satoshis: int64(vout.Value*1E8 + 0.5),
|
||||
Satoshis: vout.ValueSat.String(),
|
||||
Script: &aos,
|
||||
}
|
||||
if vout.Address != nil {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user