Update api.GetAddress to return more ethereum specific data
This commit is contained in:
parent
45e1e32e18
commit
70559ab9e0
@ -90,7 +90,7 @@ type Erc20Token struct {
|
|||||||
Txs int `json:"txs"`
|
Txs int `json:"txs"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Symbol string `json:"symbol"`
|
Symbol string `json:"symbol"`
|
||||||
Decimal int `json:"decimal"`
|
Decimals int `json:"decimals"`
|
||||||
Balance string `json:"balance,omitempty"`
|
Balance string `json:"balance,omitempty"`
|
||||||
BalanceSat string `json:"balanceSat,omitempty"`
|
BalanceSat string `json:"balanceSat,omitempty"`
|
||||||
ContractIndex string `json:"-"`
|
ContractIndex string `json:"-"`
|
||||||
@ -153,9 +153,11 @@ type Address struct {
|
|||||||
Paging
|
Paging
|
||||||
AddrStr string `json:"addrStr"`
|
AddrStr string `json:"addrStr"`
|
||||||
Balance string `json:"balance"`
|
Balance string `json:"balance"`
|
||||||
|
BalanceSat string `json:"balanceSat"`
|
||||||
TotalReceived string `json:"totalReceived,omitempty"`
|
TotalReceived string `json:"totalReceived,omitempty"`
|
||||||
TotalSent string `json:"totalSent,omitempty"`
|
TotalSent string `json:"totalSent,omitempty"`
|
||||||
UnconfirmedBalance string `json:"unconfirmedBalance"`
|
UnconfirmedBalance string `json:"unconfirmedBalance"`
|
||||||
|
UnconfirmedBalanceSat string `json:"unconfirmedBalanceSat"`
|
||||||
UnconfirmedTxApperances int `json:"unconfirmedTxApperances"`
|
UnconfirmedTxApperances int `json:"unconfirmedTxApperances"`
|
||||||
TxApperances int `json:"txApperances"`
|
TxApperances int `json:"txApperances"`
|
||||||
Transactions []*Tx `json:"txs,omitempty"`
|
Transactions []*Tx `json:"txs,omitempty"`
|
||||||
|
|||||||
308
api/worker.go
308
api/worker.go
@ -433,68 +433,79 @@ func computePaging(count, page, itemsOnPage int) (Paging, int, int, int) {
|
|||||||
}, from, to, page
|
}, from, to, page
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Worker) getEthereumTypeAddressBalances(addrDesc bchain.AddressDescriptor, option GetAddressOption) (*db.AddrBalance, []Erc20Token, *bchain.Erc20Contract, error) {
|
func (w *Worker) getEthereumTypeAddressBalances(addrDesc bchain.AddressDescriptor, option GetAddressOption) (*db.AddrBalance, []Erc20Token, *bchain.Erc20Contract, uint64, error) {
|
||||||
var (
|
var (
|
||||||
ba *db.AddrBalance
|
ba *db.AddrBalance
|
||||||
erc20t []Erc20Token
|
erc20t []Erc20Token
|
||||||
ci *bchain.Erc20Contract
|
ci *bchain.Erc20Contract
|
||||||
|
n uint64
|
||||||
)
|
)
|
||||||
ca, err := w.db.GetAddrDescContracts(addrDesc)
|
ca, err := w.db.GetAddrDescContracts(addrDesc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, NewAPIError(fmt.Sprintf("Address not found, %v", err), true)
|
return nil, nil, nil, 0, NewAPIError(fmt.Sprintf("Address not found, %v", err), true)
|
||||||
}
|
}
|
||||||
if ca != nil {
|
if ca != nil {
|
||||||
ba = &db.AddrBalance{
|
ba = &db.AddrBalance{
|
||||||
Txs: uint32(ca.EthTxs),
|
Txs: uint32(ca.EthTxs),
|
||||||
}
|
}
|
||||||
// do not read balances etc in case of ExistOnly option
|
var b *big.Int
|
||||||
if option != Basic {
|
b, err = w.chain.EthereumTypeGetBalance(addrDesc)
|
||||||
var b *big.Int
|
if err != nil {
|
||||||
b, err = w.chain.EthereumTypeGetBalance(addrDesc)
|
return nil, nil, nil, 0, errors.Annotatef(err, "EthereumTypeGetBalance %v", addrDesc)
|
||||||
|
}
|
||||||
|
if b != nil {
|
||||||
|
ba.BalanceSat = *b
|
||||||
|
}
|
||||||
|
n, err = w.chain.EthereumTypeGetNonce(addrDesc)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, 0, errors.Annotatef(err, "EthereumTypeGetNonce %v", addrDesc)
|
||||||
|
}
|
||||||
|
erc20t = make([]Erc20Token, len(ca.Contracts))
|
||||||
|
for i, c := range ca.Contracts {
|
||||||
|
ci, err := w.chain.EthereumTypeGetErc20ContractInfo(c.Contract)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, errors.Annotatef(err, "EthereumTypeGetBalance %v", addrDesc)
|
return nil, nil, nil, 0, errors.Annotatef(err, "EthereumTypeGetErc20ContractInfo %v", c.Contract)
|
||||||
}
|
}
|
||||||
if b != nil {
|
if ci == nil {
|
||||||
ba.BalanceSat = *b
|
ci = &bchain.Erc20Contract{}
|
||||||
|
addresses, _, _ := w.chainParser.GetAddressesFromAddrDesc(c.Contract)
|
||||||
|
if len(addresses) > 0 {
|
||||||
|
ci.Contract = addresses[0]
|
||||||
|
ci.Name = addresses[0]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
erc20t = make([]Erc20Token, len(ca.Contracts))
|
// do not read contract balances etc in case of Basic option
|
||||||
for i, c := range ca.Contracts {
|
if option != Basic {
|
||||||
ci, err := w.chain.EthereumTypeGetErc20ContractInfo(c.Contract)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, nil, errors.Annotatef(err, "EthereumTypeGetErc20ContractInfo %v", c.Contract)
|
|
||||||
}
|
|
||||||
if ci == nil {
|
|
||||||
ci = &bchain.Erc20Contract{}
|
|
||||||
addresses, _, _ := w.chainParser.GetAddressesFromAddrDesc(c.Contract)
|
|
||||||
if len(addresses) > 0 {
|
|
||||||
ci.Contract = addresses[0]
|
|
||||||
ci.Name = addresses[0]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
b, err = w.chain.EthereumTypeGetErc20ContractBalance(addrDesc, c.Contract)
|
b, err = w.chain.EthereumTypeGetErc20ContractBalance(addrDesc, c.Contract)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// return nil, nil, nil, errors.Annotatef(err, "EthereumTypeGetErc20ContractBalance %v %v", addrDesc, c.Contract)
|
// return nil, nil, nil, errors.Annotatef(err, "EthereumTypeGetErc20ContractBalance %v %v", addrDesc, c.Contract)
|
||||||
glog.Warningf("EthereumTypeGetErc20ContractBalance addr %v, contract %v, %v", addrDesc, c.Contract, err)
|
glog.Warningf("EthereumTypeGetErc20ContractBalance addr %v, contract %v, %v", addrDesc, c.Contract, err)
|
||||||
}
|
}
|
||||||
if b == nil {
|
} else {
|
||||||
b = &big.Int{}
|
b = nil
|
||||||
}
|
|
||||||
erc20t[i] = Erc20Token{
|
|
||||||
Balance: bchain.AmountToDecimalString(b, ci.Decimals),
|
|
||||||
Contract: ci.Contract,
|
|
||||||
Name: ci.Name,
|
|
||||||
Symbol: ci.Symbol,
|
|
||||||
Txs: int(c.Txs),
|
|
||||||
ContractIndex: strconv.Itoa(i + 1),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ci, err = w.chain.EthereumTypeGetErc20ContractInfo(addrDesc)
|
var balance, balanceSat string
|
||||||
if err != nil {
|
if b != nil {
|
||||||
return nil, nil, nil, err
|
balance = bchain.AmountToDecimalString(b, ci.Decimals)
|
||||||
|
balanceSat = b.String()
|
||||||
|
}
|
||||||
|
erc20t[i] = Erc20Token{
|
||||||
|
Balance: balance,
|
||||||
|
BalanceSat: balanceSat,
|
||||||
|
Contract: ci.Contract,
|
||||||
|
Name: ci.Name,
|
||||||
|
Symbol: ci.Symbol,
|
||||||
|
Txs: int(c.Txs),
|
||||||
|
Decimals: ci.Decimals,
|
||||||
|
ContractIndex: strconv.Itoa(i + 1),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ci, err = w.chain.EthereumTypeGetErc20ContractInfo(addrDesc)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, 0, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ba, erc20t, ci, nil
|
return ba, erc20t, ci, n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAddress computes address value and gets transactions for given address
|
// GetAddress computes address value and gets transactions for given address
|
||||||
@ -509,15 +520,23 @@ func (w *Worker) GetAddress(address string, page int, txsOnPage int, option GetA
|
|||||||
return nil, NewAPIError(fmt.Sprintf("Invalid address, %v", err), true)
|
return nil, NewAPIError(fmt.Sprintf("Invalid address, %v", err), true)
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
ba *db.AddrBalance
|
ba *db.AddrBalance
|
||||||
erc20t []Erc20Token
|
erc20t []Erc20Token
|
||||||
erc20c *bchain.Erc20Contract
|
erc20c *bchain.Erc20Contract
|
||||||
|
txm []string
|
||||||
|
txs []*Tx
|
||||||
|
txids []string
|
||||||
|
pg Paging
|
||||||
|
uBalSat big.Int
|
||||||
|
totalReceived, totalSent, nonce string
|
||||||
)
|
)
|
||||||
if w.chainType == bchain.ChainEthereumType {
|
if w.chainType == bchain.ChainEthereumType {
|
||||||
ba, erc20t, erc20c, err = w.getEthereumTypeAddressBalances(addrDesc, option)
|
var n uint64
|
||||||
|
ba, erc20t, erc20c, n, err = w.getEthereumTypeAddressBalances(addrDesc, option)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
nonce = strconv.Itoa(int(n))
|
||||||
} else {
|
} else {
|
||||||
// ba can be nil if the address is only in mempool!
|
// ba can be nil if the address is only in mempool!
|
||||||
ba, err = w.db.GetAddrDescBalance(addrDesc)
|
ba, err = w.db.GetAddrDescBalance(addrDesc)
|
||||||
@ -525,132 +544,125 @@ func (w *Worker) GetAddress(address string, page int, txsOnPage int, option GetA
|
|||||||
return nil, NewAPIError(fmt.Sprintf("Address not found, %v", err), true)
|
return nil, NewAPIError(fmt.Sprintf("Address not found, %v", err), true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if only check that the address exist, return if we have the address
|
// get tx history if requested by option or check mempool if there are some transactions for a new address
|
||||||
if option == Basic && ba != nil {
|
if option == TxidHistory || option == TxHistory || ba == nil {
|
||||||
return &Address{AddrStr: address}, nil
|
// convert the address to the format defined by the parser
|
||||||
}
|
addresses, _, err := w.chainParser.GetAddressesFromAddrDesc(addrDesc)
|
||||||
// convert the address to the format defined by the parser
|
|
||||||
addresses, _, err := w.chainParser.GetAddressesFromAddrDesc(addrDesc)
|
|
||||||
if err != nil {
|
|
||||||
glog.V(2).Infof("GetAddressesFromAddrDesc error %v, %v", err, addrDesc)
|
|
||||||
}
|
|
||||||
if len(addresses) == 1 {
|
|
||||||
address = addresses[0]
|
|
||||||
}
|
|
||||||
txc, err := w.getAddressTxids(addrDesc, false, filter)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Annotatef(err, "getAddressTxids %v false", addrDesc)
|
|
||||||
}
|
|
||||||
txc = UniqueTxidsInReverse(txc)
|
|
||||||
var txm []string
|
|
||||||
// if there are only unconfirmed transactions, ba is nil
|
|
||||||
if ba == nil {
|
|
||||||
ba = &db.AddrBalance{}
|
|
||||||
page = 0
|
|
||||||
}
|
|
||||||
txm, err = w.getAddressTxids(addrDesc, true, filter)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Annotatef(err, "getAddressTxids %v true", addrDesc)
|
|
||||||
}
|
|
||||||
txm = UniqueTxidsInReverse(txm)
|
|
||||||
// check if the address exist
|
|
||||||
if len(txc)+len(txm) == 0 || option == Basic {
|
|
||||||
return &Address{
|
|
||||||
AddrStr: address,
|
|
||||||
Balance: w.chainParser.AmountToDecimalString(&ba.BalanceSat),
|
|
||||||
TotalReceived: w.chainParser.AmountToDecimalString(ba.ReceivedSat()),
|
|
||||||
TotalSent: w.chainParser.AmountToDecimalString(&ba.SentSat),
|
|
||||||
TxApperances: int(ba.Txs),
|
|
||||||
Erc20Contract: erc20c,
|
|
||||||
Erc20Tokens: erc20t,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
bestheight, _, err := w.db.GetBestBlock()
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Annotatef(err, "GetBestBlock")
|
|
||||||
}
|
|
||||||
pg, from, to, page := computePaging(len(txc), page, txsOnPage)
|
|
||||||
var txs []*Tx
|
|
||||||
var txids []string
|
|
||||||
if option == TxidHistory {
|
|
||||||
txids = make([]string, len(txm)+to-from)
|
|
||||||
} else {
|
|
||||||
txs = make([]*Tx, len(txm)+to-from)
|
|
||||||
}
|
|
||||||
txi := 0
|
|
||||||
// load mempool transactions
|
|
||||||
var uBalSat big.Int
|
|
||||||
for _, txid := range txm {
|
|
||||||
tx, err := w.GetTransaction(txid, false, false)
|
|
||||||
// mempool transaction may fail
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Error("GetTransaction in mempool ", tx, ": ", err)
|
glog.V(2).Infof("GetAddressesFromAddrDesc error %v, %v", err, addrDesc)
|
||||||
} else {
|
}
|
||||||
uBalSat.Add(&uBalSat, tx.getAddrVoutValue(addrDesc))
|
if len(addresses) == 1 {
|
||||||
uBalSat.Sub(&uBalSat, tx.getAddrVinValue(addrDesc))
|
address = addresses[0]
|
||||||
if page == 0 {
|
}
|
||||||
if option == TxidHistory {
|
txm, err = w.getAddressTxids(addrDesc, true, filter)
|
||||||
txids[txi] = tx.Txid
|
if err != nil {
|
||||||
|
return nil, errors.Annotatef(err, "getAddressTxids %v true", addrDesc)
|
||||||
|
}
|
||||||
|
txm = UniqueTxidsInReverse(txm)
|
||||||
|
// if there are only unconfirmed transactions, there is no paging
|
||||||
|
if ba == nil {
|
||||||
|
ba = &db.AddrBalance{}
|
||||||
|
page = 0
|
||||||
|
}
|
||||||
|
if option == TxidHistory || option == TxHistory {
|
||||||
|
txc, err := w.getAddressTxids(addrDesc, false, filter)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Annotatef(err, "getAddressTxids %v false", addrDesc)
|
||||||
|
}
|
||||||
|
txc = UniqueTxidsInReverse(txc)
|
||||||
|
bestheight, _, err := w.db.GetBestBlock()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Annotatef(err, "GetBestBlock")
|
||||||
|
}
|
||||||
|
var from, to int
|
||||||
|
pg, from, to, page = computePaging(len(txc), page, txsOnPage)
|
||||||
|
if option == TxidHistory {
|
||||||
|
txids = make([]string, len(txm)+to-from)
|
||||||
|
} else {
|
||||||
|
txs = make([]*Tx, len(txm)+to-from)
|
||||||
|
}
|
||||||
|
txi := 0
|
||||||
|
// load mempool transactions
|
||||||
|
for _, txid := range txm {
|
||||||
|
tx, err := w.GetTransaction(txid, false, false)
|
||||||
|
// mempool transaction may fail
|
||||||
|
if err != nil {
|
||||||
|
glog.Error("GetTransaction in mempool ", tx, ": ", err)
|
||||||
} else {
|
} else {
|
||||||
txs[txi] = tx
|
uBalSat.Add(&uBalSat, tx.getAddrVoutValue(addrDesc))
|
||||||
|
uBalSat.Sub(&uBalSat, tx.getAddrVinValue(addrDesc))
|
||||||
|
if page == 0 {
|
||||||
|
if option == TxidHistory {
|
||||||
|
txids[txi] = tx.Txid
|
||||||
|
} else {
|
||||||
|
txs[txi] = tx
|
||||||
|
}
|
||||||
|
txi++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(txc) != int(ba.Txs) && w.chainType == bchain.ChainBitcoinType && filter == AddressFilterNone {
|
||||||
|
glog.Warning("DB inconsistency for address ", address, ": number of txs from column addresses ", len(txc), ", from addressBalance ", ba.Txs)
|
||||||
|
}
|
||||||
|
for i := from; i < to; i++ {
|
||||||
|
txid := txc[i]
|
||||||
|
if option == TxidHistory {
|
||||||
|
txids[txi] = txid
|
||||||
|
} else {
|
||||||
|
if w.chainType == bchain.ChainEthereumType {
|
||||||
|
txs[txi], err = w.GetTransaction(txid, false, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Annotatef(err, "GetTransaction %v", txid)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ta, err := w.db.GetTxAddresses(txid)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Annotatef(err, "GetTxAddresses %v", txid)
|
||||||
|
}
|
||||||
|
if ta == nil {
|
||||||
|
glog.Warning("DB inconsistency: tx ", txid, ": not found in txAddresses")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
bi, err := w.db.GetBlockInfo(ta.Height)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Annotatef(err, "GetBlockInfo %v", ta.Height)
|
||||||
|
}
|
||||||
|
if bi == nil {
|
||||||
|
glog.Warning("DB inconsistency: block height ", ta.Height, ": not found in db")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
txs[txi] = w.txFromTxAddress(txid, ta, bi, bestheight)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
txi++
|
txi++
|
||||||
}
|
}
|
||||||
}
|
if option == TxidHistory {
|
||||||
}
|
txids = txids[:txi]
|
||||||
if len(txc) != int(ba.Txs) && w.chainType == bchain.ChainBitcoinType && filter == AddressFilterNone {
|
} else if option == TxHistory {
|
||||||
glog.Warning("DB inconsistency for address ", address, ": number of txs from column addresses ", len(txc), ", from addressBalance ", ba.Txs)
|
txs = txs[:txi]
|
||||||
}
|
|
||||||
for i := from; i < to; i++ {
|
|
||||||
txid := txc[i]
|
|
||||||
if option == TxidHistory {
|
|
||||||
txids[txi] = txid
|
|
||||||
} else {
|
|
||||||
if w.chainType == bchain.ChainEthereumType {
|
|
||||||
txs[txi], err = w.GetTransaction(txid, false, true)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Annotatef(err, "GetTransaction %v", txid)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ta, err := w.db.GetTxAddresses(txid)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Annotatef(err, "GetTxAddresses %v", txid)
|
|
||||||
}
|
|
||||||
if ta == nil {
|
|
||||||
glog.Warning("DB inconsistency: tx ", txid, ": not found in txAddresses")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
bi, err := w.db.GetBlockInfo(ta.Height)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Annotatef(err, "GetBlockInfo %v", ta.Height)
|
|
||||||
}
|
|
||||||
if bi == nil {
|
|
||||||
glog.Warning("DB inconsistency: block height ", ta.Height, ": not found in db")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
txs[txi] = w.txFromTxAddress(txid, ta, bi, bestheight)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
txi++
|
|
||||||
}
|
}
|
||||||
if option == TxidHistory {
|
if w.chainType == bchain.ChainBitcoinType {
|
||||||
txids = txids[:txi]
|
totalReceived = w.chainParser.AmountToDecimalString(ba.ReceivedSat())
|
||||||
} else {
|
totalSent = w.chainParser.AmountToDecimalString(&ba.SentSat)
|
||||||
txs = txs[:txi]
|
|
||||||
}
|
}
|
||||||
r := &Address{
|
r := &Address{
|
||||||
Paging: pg,
|
Paging: pg,
|
||||||
AddrStr: address,
|
AddrStr: address,
|
||||||
Balance: w.chainParser.AmountToDecimalString(&ba.BalanceSat),
|
Balance: w.chainParser.AmountToDecimalString(&ba.BalanceSat),
|
||||||
TotalReceived: w.chainParser.AmountToDecimalString(ba.ReceivedSat()),
|
BalanceSat: ba.BalanceSat.String(),
|
||||||
TotalSent: w.chainParser.AmountToDecimalString(&ba.SentSat),
|
TotalReceived: totalReceived,
|
||||||
|
TotalSent: totalSent,
|
||||||
TxApperances: int(ba.Txs),
|
TxApperances: int(ba.Txs),
|
||||||
UnconfirmedBalance: w.chainParser.AmountToDecimalString(&uBalSat),
|
UnconfirmedBalance: w.chainParser.AmountToDecimalString(&uBalSat),
|
||||||
|
UnconfirmedBalanceSat: uBalSat.String(),
|
||||||
UnconfirmedTxApperances: len(txm),
|
UnconfirmedTxApperances: len(txm),
|
||||||
Transactions: txs,
|
Transactions: txs,
|
||||||
Txids: txids,
|
Txids: txids,
|
||||||
Erc20Contract: erc20c,
|
Erc20Contract: erc20c,
|
||||||
Erc20Tokens: erc20t,
|
Erc20Tokens: erc20t,
|
||||||
|
Nonce: nonce,
|
||||||
}
|
}
|
||||||
glog.Info("GetAddress ", address, " finished in ", time.Since(start))
|
glog.Info("GetAddress ", address, " finished in ", time.Since(start))
|
||||||
return r, nil
|
return r, nil
|
||||||
|
|||||||
@ -34,6 +34,11 @@ func (b *BaseChain) EthereumTypeGetBalance(addrDesc AddressDescriptor) (*big.Int
|
|||||||
return nil, errors.New("Not supported")
|
return nil, errors.New("Not supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EthereumTypeGetNonce is not supported
|
||||||
|
func (b *BaseChain) EthereumTypeGetNonce(addrDesc AddressDescriptor) (uint64, error) {
|
||||||
|
return 0, errors.New("Not supported")
|
||||||
|
}
|
||||||
|
|
||||||
// EthereumTypeGetErc20ContractInfo is not supported
|
// EthereumTypeGetErc20ContractInfo is not supported
|
||||||
func (b *BaseChain) EthereumTypeGetErc20ContractInfo(contractDesc AddressDescriptor) (*Erc20Contract, error) {
|
func (b *BaseChain) EthereumTypeGetErc20ContractInfo(contractDesc AddressDescriptor) (*Erc20Contract, error) {
|
||||||
return nil, errors.New("Not supported")
|
return nil, errors.New("Not supported")
|
||||||
|
|||||||
@ -247,6 +247,11 @@ func (c *blockChainWithMetrics) EthereumTypeGetBalance(addrDesc bchain.AddressDe
|
|||||||
return c.b.EthereumTypeGetBalance(addrDesc)
|
return c.b.EthereumTypeGetBalance(addrDesc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *blockChainWithMetrics) EthereumTypeGetNonce(addrDesc bchain.AddressDescriptor) (v uint64, err error) {
|
||||||
|
defer func(s time.Time) { c.observeRPCLatency("EthereumTypeGetNonce", s, err) }(time.Now())
|
||||||
|
return c.b.EthereumTypeGetNonce(addrDesc)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *blockChainWithMetrics) EthereumTypeGetErc20ContractInfo(contractDesc bchain.AddressDescriptor) (v *bchain.Erc20Contract, err error) {
|
func (c *blockChainWithMetrics) EthereumTypeGetErc20ContractInfo(contractDesc bchain.AddressDescriptor) (v *bchain.Erc20Contract, err error) {
|
||||||
defer func(s time.Time) { c.observeRPCLatency("EthereumTypeGetErc20ContractInfo", s, err) }(time.Now())
|
defer func(s time.Time) { c.observeRPCLatency("EthereumTypeGetErc20ContractInfo", s, err) }(time.Now())
|
||||||
return c.b.EthereumTypeGetErc20ContractInfo(contractDesc)
|
return c.b.EthereumTypeGetErc20ContractInfo(contractDesc)
|
||||||
|
|||||||
@ -674,6 +674,13 @@ func (b *EthereumRPC) EthereumTypeGetBalance(addrDesc bchain.AddressDescriptor)
|
|||||||
return b.client.BalanceAt(ctx, ethcommon.BytesToAddress(addrDesc), nil)
|
return b.client.BalanceAt(ctx, ethcommon.BytesToAddress(addrDesc), nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EthereumTypeGetNonce returns current balance of an address
|
||||||
|
func (b *EthereumRPC) EthereumTypeGetNonce(addrDesc bchain.AddressDescriptor) (uint64, error) {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), b.timeout)
|
||||||
|
defer cancel()
|
||||||
|
return b.client.NonceAt(ctx, ethcommon.BytesToAddress(addrDesc), nil)
|
||||||
|
}
|
||||||
|
|
||||||
// ResyncMempool gets mempool transactions and maps output scripts to transactions.
|
// ResyncMempool gets mempool transactions and maps output scripts to transactions.
|
||||||
// ResyncMempool is not reentrant, it should be called from a single thread.
|
// ResyncMempool is not reentrant, it should be called from a single thread.
|
||||||
// Return value is number of transactions in mempool
|
// Return value is number of transactions in mempool
|
||||||
|
|||||||
@ -215,6 +215,7 @@ type BlockChain interface {
|
|||||||
GetChainParser() BlockChainParser
|
GetChainParser() BlockChainParser
|
||||||
// EthereumType specific
|
// EthereumType specific
|
||||||
EthereumTypeGetBalance(addrDesc AddressDescriptor) (*big.Int, error)
|
EthereumTypeGetBalance(addrDesc AddressDescriptor) (*big.Int, error)
|
||||||
|
EthereumTypeGetNonce(addrDesc AddressDescriptor) (uint64, error)
|
||||||
EthereumTypeGetErc20ContractInfo(contractDesc AddressDescriptor) (*Erc20Contract, error)
|
EthereumTypeGetErc20ContractInfo(contractDesc AddressDescriptor) (*Erc20Contract, error)
|
||||||
EthereumTypeGetErc20ContractBalance(addrDesc, contractDesc AddressDescriptor) (*big.Int, error)
|
EthereumTypeGetErc20ContractBalance(addrDesc, contractDesc AddressDescriptor) (*big.Int, error)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -405,7 +405,7 @@ func httpTests(t *testing.T, ts *httptest.Server) {
|
|||||||
status: http.StatusOK,
|
status: http.StatusOK,
|
||||||
contentType: "application/json; charset=utf-8",
|
contentType: "application/json; charset=utf-8",
|
||||||
body: []string{
|
body: []string{
|
||||||
`{"page":1,"totalPages":1,"itemsOnPage":1000,"addrStr":"mv9uLThosiEnGRbVPS7Vhyw6VssbVRsiAw","balance":"0","totalReceived":"12345.67890123","totalSent":"12345.67890123","unconfirmedBalance":"0","unconfirmedTxApperances":0,"txApperances":2,"transactions":["7c3be24063f268aaa1ed81b64776798f56088757641a34fb156c4f51ed2e9d25","effd9ef509383d536b1c8af5bf434c8efbf521a4f2befd4022bbd68694b4ac75"]}`,
|
`{"page":1,"totalPages":1,"itemsOnPage":1000,"addrStr":"mv9uLThosiEnGRbVPS7Vhyw6VssbVRsiAw","balance":"0","balanceSat":"0","totalReceived":"12345.67890123","totalSent":"12345.67890123","unconfirmedBalance":"0","unconfirmedBalanceSat":"0","unconfirmedTxApperances":0,"txApperances":2,"transactions":["7c3be24063f268aaa1ed81b64776798f56088757641a34fb156c4f51ed2e9d25","effd9ef509383d536b1c8af5bf434c8efbf521a4f2befd4022bbd68694b4ac75"]}`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user