Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions api/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ func (w *Worker) getTransaction(txid string, spendingTxs bool, specificJSON bool
}
return nil, NewAPIError(fmt.Sprintf("Transaction '%v' not found (%v)", txid, err), true)
}
return w.getTransactionFromBchainTx(bchainTx, height, spendingTxs, specificJSON, addresses)
return w.GetTransactionFromBchainTx(bchainTx, height, spendingTxs, specificJSON, addresses)
}

func (w *Worker) getParsedEthereumInputData(data string) *bchain.EthereumParsedInputData {
Expand Down Expand Up @@ -284,8 +284,8 @@ func (w *Worker) getConfirmationETA(tx *Tx) (int64, uint32) {
return etaSeconds, etaBlocks
}

// getTransactionFromBchainTx reads transaction data from txid
func (w *Worker) getTransactionFromBchainTx(bchainTx *bchain.Tx, height int, spendingTxs bool, specificJSON bool, addresses map[string]struct{}) (*Tx, error) {
// GetTransactionFromBchainTx reads transaction data from txid
func (w *Worker) GetTransactionFromBchainTx(bchainTx *bchain.Tx, height int, spendingTxs bool, specificJSON bool, addresses map[string]struct{}) (*Tx, error) {
var err error
var ta *db.TxAddresses
var tokens []TokenTransfer
Expand Down
4 changes: 4 additions & 0 deletions bchain/basechain.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,7 @@ func (b *BaseChain) EthereumTypeRpcCall(data, to, from string) (string, error) {
func (b *BaseChain) EthereumTypeGetRawTransaction(txid string) (string, error) {
return "", errors.New("not supported")
}

func (b *BaseChain) EthereumTypeGetTransactionReceipt(txid string) (*RpcReceipt, error) {
return nil, errors.New("not supported")
}
5 changes: 5 additions & 0 deletions bchain/coins/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,11 @@ func (c *blockChainWithMetrics) EthereumTypeGetRawTransaction(txid string) (v st
return c.b.EthereumTypeGetRawTransaction(txid)
}

func (c *blockChainWithMetrics) EthereumTypeGetTransactionReceipt(txid string) (v *bchain.RpcReceipt, err error) {
defer func(s time.Time) { c.observeRPCLatency("EthereumTypeGetTransactionReceipt", s, err) }(time.Now())
return c.b.EthereumTypeGetTransactionReceipt(txid)
}

type mempoolWithMetrics struct {
mempool bchain.Mempool
m *common.Metrics
Expand Down
14 changes: 11 additions & 3 deletions bchain/coins/eth/ethrpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -944,8 +944,7 @@ func (b *EthereumRPC) GetTransaction(txid string) (*bchain.Tx, error) {
return nil, errors.Annotatef(err, "txid %v", txid)
}
tx.BaseFeePerGas = ht.BaseFeePerGas
var receipt bchain.RpcReceipt
err = b.RPC.CallContext(ctx, &receipt, "eth_getTransactionReceipt", hash)
receipt, err := b.EthereumTypeGetTransactionReceipt(txid)
if err != nil {
return nil, errors.Annotatef(err, "txid %v", txid)
}
Expand All @@ -957,7 +956,7 @@ func (b *EthereumRPC) GetTransaction(txid string) (*bchain.Tx, error) {
if err != nil {
return nil, errors.Annotatef(err, "txid %v", txid)
}
btx, err = b.Parser.ethTxToTx(tx, &receipt, nil, time, confirmations, true)
btx, err = b.Parser.ethTxToTx(tx, receipt, nil, time, confirmations, true)
if err != nil {
return nil, errors.Annotatef(err, "txid %v", txid)
}
Expand Down Expand Up @@ -1190,6 +1189,15 @@ func (b *EthereumRPC) callRpcStringResult(rpcMethod string, args ...interface{})
return result, nil
}

// EthereumTypeGetTransactionReceipt returns the transaction receipt by the transaction ID.
func (b *EthereumRPC) EthereumTypeGetTransactionReceipt(txid string) (*bchain.RpcReceipt, error) {
ctx, cancel := context.WithTimeout(context.Background(), b.Timeout)
defer cancel()
var r *bchain.RpcReceipt
err := b.RPC.CallContext(ctx, &r, "eth_getTransactionReceipt", ethcommon.HexToHash(txid))
return r, err
}

// EthereumTypeGetBalance returns current balance of an address
func (b *EthereumRPC) EthereumTypeGetBalance(addrDesc bchain.AddressDescriptor) (*big.Int, error) {
ctx, cancel := context.WithTimeout(context.Background(), b.Timeout)
Expand Down
3 changes: 2 additions & 1 deletion bchain/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ type MempoolTxidFilterEntries struct {
}

// OnNewBlockFunc is used to send notification about a new block
type OnNewBlockFunc func(hash string, height uint32)
type OnNewBlockFunc func(block *Block)

// OnNewTxAddrFunc is used to send notification about a new transaction/address
type OnNewTxAddrFunc func(tx *Tx, desc AddressDescriptor)
Expand Down Expand Up @@ -346,6 +346,7 @@ type BlockChain interface {
EthereumTypeGetStakingPoolsData(addrDesc AddressDescriptor) ([]StakingPoolData, error)
EthereumTypeRpcCall(data, to, from string) (string, error)
EthereumTypeGetRawTransaction(txid string) (string, error)
EthereumTypeGetTransactionReceipt(txid string) (*RpcReceipt, error)
GetTokenURI(contractDesc AddressDescriptor, tokenID *big.Int) (string, error)
}

Expand Down
1 change: 1 addition & 0 deletions blockbook-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,7 @@ export interface WsSendTransactionReq {
export interface WsSubscribeAddressesReq {
/** List of addresses to subscribe for updates (e.g., new transactions). */
addresses: string[];
newBlockTxs?: boolean;
}
export interface WsSubscribeFiatRatesReq {
/** Fiat currency code (e.g. 'USD'). */
Expand Down
8 changes: 4 additions & 4 deletions blockbook.go
Original file line number Diff line number Diff line change
Expand Up @@ -520,26 +520,26 @@ func syncIndexLoop() {
glog.Info("syncIndexLoop starting")
// resync index about every 15 minutes if there are no chanSyncIndex requests, with debounce 1 second
common.TickAndDebounce(time.Duration(*resyncIndexPeriodMs)*time.Millisecond, debounceResyncIndexMs*time.Millisecond, chanSyncIndex, func() {
if err := syncWorker.ResyncIndex(onNewBlockHash, false); err != nil {
if err := syncWorker.ResyncIndex(onNewBlock, false); err != nil {
glog.Error("syncIndexLoop ", errors.ErrorStack(err), ", will retry...")
// retry once in case of random network error, after a slight delay
time.Sleep(time.Millisecond * 2500)
if err := syncWorker.ResyncIndex(onNewBlockHash, false); err != nil {
if err := syncWorker.ResyncIndex(onNewBlock, false); err != nil {
glog.Error("syncIndexLoop ", errors.ErrorStack(err))
}
}
})
glog.Info("syncIndexLoop stopped")
}

func onNewBlockHash(hash string, height uint32) {
func onNewBlock(block *bchain.Block) {
defer func() {
if r := recover(); r != nil {
glog.Error("onNewBlockHash recovered from panic: ", r)
}
}()
for _, c := range callbacksOnNewBlock {
c(hash, height)
c(block)
}
}

Expand Down
4 changes: 2 additions & 2 deletions db/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ func (w *SyncWorker) connectBlocks(onNewBlock bchain.OnNewBlockFunc, initialSync
return err
}
if onNewBlock != nil {
onNewBlock(res.block.Hash, res.block.Height)
onNewBlock(res.block)
}
w.metrics.BlockbookBestHeight.Set(float64(res.block.Height))
if res.block.Height > 0 && res.block.Height%1000 == 0 {
Expand Down Expand Up @@ -325,7 +325,7 @@ func (w *SyncWorker) ParallelConnectBlocks(onNewBlock bchain.OnNewBlockFunc, low
}

if onNewBlock != nil {
onNewBlock(b.Hash, b.Height)
onNewBlock(b)
}
w.metrics.BlockbookBestHeight.Set(float64(b.Height))

Expand Down
15 changes: 14 additions & 1 deletion docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1004,7 +1004,7 @@ The client can subscribe to the following events:

- `subscribeNewBlock` - new block added to blockchain
- `subscribeNewTransaction` - new transaction added to blockchain (all addresses)
- `subscribeAddresses` - new transaction for a given address (list of addresses) added to mempool
- `subscribeAddresses` - new transaction for a given address (list of addresses) added to mempool (and optionally confirmed in a new block)
- `subscribeFiatRates` - new currency rate ticker

There can be always only one subscription of given event per connection, i.e. new list of addresses replaces previous list of addresses.
Expand Down Expand Up @@ -1035,6 +1035,19 @@ Example for subscribing to an address (or multiple addresses)
}
```

Example for subscribing to an address (or multiple addresses) including new block (confirmed) transactions

```javascript
{
"id":"1",
"method":"subscribeAddresses",
"params":{
"addresses":["mnYYiDCb2JZXnqEeXta1nkt5oCVe2RVhJj", "tb1qp0we5epypgj4acd2c4au58045ruud2pd6heuee"],
"newBlockTxs": true,
}
}
```

## Legacy API V1

The legacy API is a compatible subset of API provided by **Bitcore Insight**. It is supported only for Bitcoin-type coins. The details of the REST/socket.io requests can be found in the Insight's documentation.
Expand Down
6 changes: 3 additions & 3 deletions server/public.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,9 @@ func (s *PublicServer) Shutdown(ctx context.Context) error {
}

// OnNewBlock notifies users subscribed to bitcoind/hashblock about new block
func (s *PublicServer) OnNewBlock(hash string, height uint32) {
s.socketio.OnNewBlockHash(hash)
s.websocket.OnNewBlock(hash, height)
func (s *PublicServer) OnNewBlock(block *bchain.Block) {
s.socketio.OnNewBlockHash(block.Hash)
s.websocket.OnNewBlock(block)
}

// OnNewFiatRatesTicker notifies users subscribed to bitcoind/fiatrates about new ticker
Expand Down
Loading