Add Avalanche (#850)

This commit is contained in:
kevin 2023-01-16 02:33:07 -07:00 committed by Martin
parent 778c071d12
commit 0d9d09b755
11 changed files with 1061 additions and 263 deletions

View File

@ -0,0 +1,153 @@
package avalanche
import (
"context"
"encoding/json"
"fmt"
"net/url"
"github.com/ava-labs/avalanchego/api/info"
"github.com/ava-labs/coreth/core/types"
"github.com/ava-labs/coreth/ethclient"
"github.com/ava-labs/coreth/interfaces"
"github.com/ava-labs/coreth/rpc"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/golang/glog"
"github.com/juju/errors"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/eth"
)
const (
// MainNet is production network
MainNet eth.Network = 43114
)
// AvalancheRPC is an interface to JSON-RPC avalanche service.
type AvalancheRPC struct {
*eth.EthereumRPC
info info.Client
}
// NewAvalancheRPC returns new AvalancheRPC instance.
func NewAvalancheRPC(config json.RawMessage, pushHandler func(bchain.NotificationType)) (bchain.BlockChain, error) {
c, err := eth.NewEthereumRPC(config, pushHandler)
if err != nil {
return nil, err
}
s := &AvalancheRPC{
EthereumRPC: c.(*eth.EthereumRPC),
}
return s, nil
}
// Initialize avalanche rpc interface
func (b *AvalancheRPC) Initialize() error {
b.OpenRPC = func(url string) (bchain.EVMRPCClient, bchain.EVMClient, error) {
r, err := rpc.Dial(url)
if err != nil {
return nil, nil, err
}
rc := &AvalancheRPCClient{Client: r}
c := &AvalancheClient{Client: ethclient.NewClient(r)}
return rc, c, nil
}
rpcUrl, err := url.Parse(b.ChainConfig.RPCURL)
if err != nil {
return err
}
scheme := "http"
if rpcUrl.Scheme == "wss" || rpcUrl.Scheme == "https" {
scheme = "https"
}
rpcClient, client, err := b.OpenRPC(b.ChainConfig.RPCURL)
if err != nil {
return err
}
// set chain specific
b.Client = client
b.RPC = rpcClient
b.info = info.NewClient(fmt.Sprintf("%s://%s", scheme, rpcUrl.Host))
b.MainNetChainID = MainNet
b.NewBlock = &AvalancheNewBlock{channel: make(chan *types.Header)}
b.NewTx = &AvalancheNewTx{channel: make(chan common.Hash)}
ctx, cancel := context.WithTimeout(context.Background(), b.Timeout)
defer cancel()
id, err := b.Client.NetworkID(ctx)
if err != nil {
return err
}
// parameters for getInfo request
switch eth.Network(id.Uint64()) {
case MainNet:
b.Testnet = false
b.Network = "livenet"
default:
return errors.Errorf("Unknown network id %v", id)
}
glog.Info("rpc: block chain ", b.Network)
return nil
}
// GetChainInfo returns information about the connected backend
func (b *AvalancheRPC) GetChainInfo() (*bchain.ChainInfo, error) {
ci, err := b.EthereumRPC.GetChainInfo()
if err != nil {
fmt.Println(err)
return nil, err
}
ctx, cancel := context.WithTimeout(context.Background(), b.Timeout)
defer cancel()
v, err := b.info.GetNodeVersion(ctx)
if err != nil {
fmt.Println("here", err)
return nil, err
}
if avm, ok := v.VMVersions["avm"]; ok {
ci.Version = avm
}
return ci, nil
}
// EthereumTypeEstimateGas returns estimation of gas consumption for given transaction parameters
func (b *AvalancheRPC) EthereumTypeEstimateGas(params map[string]interface{}) (uint64, error) {
ctx, cancel := context.WithTimeout(context.Background(), b.Timeout)
defer cancel()
msg := interfaces.CallMsg{}
if s, ok := eth.GetStringFromMap("from", params); ok && len(s) > 0 {
msg.From = common.HexToAddress(s)
}
if s, ok := eth.GetStringFromMap("to", params); ok && len(s) > 0 {
a := common.HexToAddress(s)
msg.To = &a
}
if s, ok := eth.GetStringFromMap("data", params); ok && len(s) > 0 {
msg.Data = common.FromHex(s)
}
if s, ok := eth.GetStringFromMap("value", params); ok && len(s) > 0 {
msg.Value, _ = hexutil.DecodeBig(s)
}
if s, ok := eth.GetStringFromMap("gas", params); ok && len(s) > 0 {
msg.Gas, _ = hexutil.DecodeUint64(s)
}
if s, ok := eth.GetStringFromMap("gasPrice", params); ok && len(s) > 0 {
msg.GasPrice, _ = hexutil.DecodeBig(s)
}
return b.Client.EstimateGas(ctx, msg)
}

View File

@ -0,0 +1,143 @@
package avalanche
import (
"context"
"math/big"
"strings"
"github.com/ava-labs/coreth/core/types"
"github.com/ava-labs/coreth/ethclient"
"github.com/ava-labs/coreth/interfaces"
"github.com/ava-labs/coreth/rpc"
"github.com/ethereum/go-ethereum/common"
"github.com/trezor/blockbook/bchain"
)
// AvalancheClient wraps a client to implement the EVMClient interface
type AvalancheClient struct {
ethclient.Client
}
// HeaderByNumber returns a block header that implements the EVMHeader interface
func (c *AvalancheClient) HeaderByNumber(ctx context.Context, number *big.Int) (bchain.EVMHeader, error) {
h, err := c.Client.HeaderByNumber(ctx, number)
if err != nil {
return nil, err
}
return &AvalancheHeader{Header: h}, nil
}
// EstimateGas returns the current estimated gas cost for executing a transaction
func (c *AvalancheClient) EstimateGas(ctx context.Context, msg interface{}) (uint64, error) {
return c.Client.EstimateGas(ctx, msg.(interfaces.CallMsg))
}
// BalanceAt returns the balance for the given account at a specific block, or latest known block if no block number is provided
func (c *AvalancheClient) BalanceAt(ctx context.Context, addrDesc bchain.AddressDescriptor, blockNumber *big.Int) (*big.Int, error) {
return c.Client.BalanceAt(ctx, common.BytesToAddress(addrDesc), blockNumber)
}
// NonceAt returns the nonce for the given account at a specific block, or latest known block if no block number is provided
func (c *AvalancheClient) NonceAt(ctx context.Context, addrDesc bchain.AddressDescriptor, blockNumber *big.Int) (uint64, error) {
return c.Client.NonceAt(ctx, common.BytesToAddress(addrDesc), blockNumber)
}
// AvalancheRPCClient wraps an rpc client to implement the EVMRPCClient interface
type AvalancheRPCClient struct {
*rpc.Client
}
// EthSubscribe subscribes to events and returns a client subscription that implements the EVMClientSubscription interface
func (c *AvalancheRPCClient) EthSubscribe(ctx context.Context, channel interface{}, args ...interface{}) (bchain.EVMClientSubscription, error) {
sub, err := c.Client.EthSubscribe(ctx, channel, args...)
if err != nil {
return nil, err
}
return &AvalancheClientSubscription{ClientSubscription: sub}, nil
}
// CallContext performs a JSON-RPC call with the given arguments
func (c *AvalancheRPCClient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error {
err := c.Client.CallContext(ctx, result, method, args...)
// unfinalized data cannot be queried error returned when trying to query a block height greater than last finalized block
// do not throw rpc error and instead treat as ErrBlockNotFound
// https://docs.avax.network/quickstart/exchanges/integrate-exchange-with-avalanche#determining-finality
if err != nil && !strings.Contains(err.Error(), "cannot query unfinalized data") {
return err
}
return nil
}
// AvalancheHeader wraps a block header to implement the EVMHeader interface
type AvalancheHeader struct {
*types.Header
}
// Hash returns the block hash as a hex string
func (h *AvalancheHeader) Hash() string {
return h.Header.Hash().Hex()
}
// Number returns the block number
func (h *AvalancheHeader) Number() *big.Int {
return h.Header.Number
}
// Difficulty returns the block difficulty
func (h *AvalancheHeader) Difficulty() *big.Int {
return h.Header.Difficulty
}
// AvalancheHash wraps a transaction hash to implement the EVMHash interface
type AvalancheHash struct {
common.Hash
}
// AvalancheClientSubscription wraps a client subcription to implement the EVMClientSubscription interface
type AvalancheClientSubscription struct {
*rpc.ClientSubscription
}
// AvalancheNewBlock wraps a block header channel to implement the EVMNewBlockSubscriber interface
type AvalancheNewBlock struct {
channel chan *types.Header
}
// Channel returns the underlying channel as an empty interface
func (s *AvalancheNewBlock) Channel() interface{} {
return s.channel
}
// Read from the underlying channel and return a block header that implements the EVMHeader interface
func (s *AvalancheNewBlock) Read() (bchain.EVMHeader, bool) {
h, ok := <-s.channel
return &AvalancheHeader{Header: h}, ok
}
// Close the underlying channel
func (s *AvalancheNewBlock) Close() {
close(s.channel)
}
// AvalancheNewTx wraps a transaction hash channel to conform with the EVMNewTxSubscriber interface
type AvalancheNewTx struct {
channel chan common.Hash
}
// Channel returns the underlying channel as an empty interface
func (s *AvalancheNewTx) Channel() interface{} {
return s.channel
}
// Read from the underlying channel and return a transaction hash that implements the EVMHash interface
func (s *AvalancheNewTx) Read() (bchain.EVMHash, bool) {
h, ok := <-s.channel
return &AvalancheHash{Hash: h}, ok
}
// Close the underlying channel
func (s *AvalancheNewTx) Close() {
close(s.channel)
}

View File

@ -11,6 +11,7 @@ import (
"github.com/juju/errors"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/avalanche"
"github.com/trezor/blockbook/bchain/coins/bch"
"github.com/trezor/blockbook/bchain/coins/bellcoin"
"github.com/trezor/blockbook/bchain/coins/bitcore"
@ -131,6 +132,8 @@ func init() {
BlockChainFactories["BitZeny"] = bitzeny.NewBitZenyRPC
BlockChainFactories["Trezarcoin"] = trezarcoin.NewTrezarcoinRPC
BlockChainFactories["ECash"] = ecash.NewECashRPC
BlockChainFactories["Avalanche"] = avalanche.NewAvalancheRPC
BlockChainFactories["Avalanche Archive"] = avalanche.NewAvalancheRPC
}
// GetCoinNameFromConfig gets coin name and coin shortcut from config file

View File

@ -0,0 +1,51 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
=AzIy
-----END PGP PUBLIC KEY BLOCK-----

View File

@ -0,0 +1,69 @@
{
"coin": {
"name": "Avalanche",
"shortcut": "AVAX",
"label": "Avalanche",
"alias": "avalanche"
},
"ports": {
"backend_rpc": 8098,
"backend_p2p": 38398,
"blockbook_internal": 9098,
"blockbook_public": 9198
},
"ipc": {
"rpc_url_template": "ws://127.0.0.1:{{.Ports.BackendRPC}}/ext/bc/C/ws",
"rpc_timeout": 25
},
"backend": {
"package_name": "backend-avalanche",
"package_revision": "satoshilabs-1",
"system_user": "avalanche",
"version": "1.9.7",
"binary_url": "https://github.com/ava-labs/avalanchego/releases/download/v1.9.7/avalanchego-linux-amd64-v1.9.7.tar.gz",
"verification_type": "gpg",
"verification_source": "https://github.com/ava-labs/avalanchego/releases/download/v1.9.7/avalanchego-linux-amd64-v1.9.7.tar.gz.sig",
"extract_command": "tar -C backend --strip 1 -xf",
"exclude_files": [],
"exec_command_template": "{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/avalanchego --data-dir {{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend --log-dir {{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend --http-port {{.Ports.BackendRPC}} --staking-port {{.Ports.BackendP2P}} --public-ip 127.0.0.1 --staking-ephemeral-cert-enabled --chain-config-content ewogICJDIjp7CiAgICAiY29uZmlnIjoiZXdvZ0lDSmxkR2d0WVhCcGN5STZXd29nSUNBZ0ltVjBhQ0lzQ2lBZ0lDQWlaWFJvTFdacGJIUmxjaUlzQ2lBZ0lDQWlibVYwSWl3S0lDQWdJQ0prWldKMVp5MTBjbUZqWlhJaUxBb2dJQ0FnSW5kbFlqTWlMQW9nSUNBZ0ltbHVkR1Z5Ym1Gc0xXVjBhQ0lzQ2lBZ0lDQWlhVzUwWlhKdVlXd3RZbXh2WTJ0amFHRnBiaUlzQ2lBZ0lDQWlhVzUwWlhKdVlXd3RkSEpoYm5OaFkzUnBiMjRpTEFvZ0lDQWdJbWx1ZEdWeWJtRnNMWFI0TFhCdmIyd2lMQW9nSUNBZ0ltbHVkR1Z5Ym1Gc0xXUmxZblZuSWdvZ0lGMEtmUT09IgogIH0KfQ==",
"logrotate_files_template": "{{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log",
"postinst_script_template": "",
"service_type": "simple",
"service_additional_params_template": "",
"protect_memory": true,
"mainnet": true,
"server_config_file": "",
"client_config_file": "",
"platforms": {
"arm64": {
"binary_url": "https://github.com/ava-labs/avalanchego/releases/download/v1.9.7/avalanchego-linux-arm64-v1.9.7.tar.gz",
"verification_source": "https://github.com/ava-labs/avalanchego/releases/download/v1.9.7/avalanchego-linux-arm64-v1.9.7.tar.gz.sig"
}
}
},
"blockbook": {
"package_name": "blockbook-avalanche",
"system_user": "blockbook-avalanche",
"internal_binding_template": ":{{.Ports.BlockbookInternal}}",
"public_binding_template": ":{{.Ports.BlockbookPublic}}",
"explorer_url": "",
"additional_params": "",
"block_chain": {
"parse": true,
"mempool_workers": 8,
"mempool_sub_workers": 2,
"block_addresses_to_keep": 300,
"additional_params": {
"mempoolTxTimeoutHours": 48,
"queryBackendOnMempoolResync": false,
"fiat_rates": "coingecko",
"fiat_rates_vs_currencies": "AED,ARS,AUD,BDT,BHD,BMD,BRL,CAD,CHF,CLP,CNY,CZK,DKK,EUR,GBP,HKD,HUF,IDR,ILS,INR,JPY,KRW,KWD,LKR,MMK,MXN,MYR,NGN,NOK,NZD,PHP,PKR,PLN,RUB,SAR,SEK,SGD,THB,TRY,TWD,UAH,USD,VEF,VND,ZAR,BTC,ETH",
"fiat_rates_params": "{\"url\": \"https://api.coingecko.com/api/v3\", \"coin\": \"avalanche-2\",\"platformIdentifier\": \"avalanche\",\"platformVsCurrency\": \"usd\",\"periodSeconds\": 900}"
}
}
},
"meta": {
"package_maintainer": "IT",
"package_maintainer_email": "it@satoshilabs.com"
}
}

View File

@ -0,0 +1,72 @@
{
"coin": {
"name": "Avalanche Archive",
"shortcut": "AVAX",
"label": "Avalanche",
"alias": "avalanche_archive"
},
"ports": {
"backend_rpc": 8099,
"backend_p2p": 38399,
"blockbook_internal": 9099,
"blockbook_public": 9199
},
"ipc": {
"rpc_url_template": "ws://127.0.0.1:{{.Ports.BackendRPC}}/ext/bc/C/ws",
"rpc_timeout": 25
},
"backend": {
"package_name": "backend-avalanche-archive",
"package_revision": "satoshilabs-1",
"system_user": "avalanche",
"version": "1.9.7",
"binary_url": "https://github.com/ava-labs/avalanchego/releases/download/v1.9.7/avalanchego-linux-amd64-v1.9.7.tar.gz",
"verification_type": "gpg",
"verification_source": "https://github.com/ava-labs/avalanchego/releases/download/v1.9.7/avalanchego-linux-amd64-v1.9.7.tar.gz.sig",
"extract_command": "tar -C backend --strip 1 -xf",
"exclude_files": [],
"exec_command_template": "{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/avalanchego --data-dir {{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend --log-dir {{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend --http-port {{.Ports.BackendRPC}} --staking-port {{.Ports.BackendP2P}} --public-ip 127.0.0.1 --staking-ephemeral-cert-enabled --chain-config-content ewogICJDIjp7CiAgICAiY29uZmlnIjoiZXdvZ0lDSmxkR2d0WVhCcGN5STZXd29nSUNBZ0ltVjBhQ0lzQ2lBZ0lDQWlaWFJvTFdacGJIUmxjaUlzQ2lBZ0lDQWlibVYwSWl3S0lDQWdJQ0prWldKMVp5MTBjbUZqWlhJaUxBb2dJQ0FnSW5kbFlqTWlMQW9nSUNBZ0ltbHVkR1Z5Ym1Gc0xXVjBhQ0lzQ2lBZ0lDQWlhVzUwWlhKdVlXd3RZbXh2WTJ0amFHRnBiaUlzQ2lBZ0lDQWlhVzUwWlhKdVlXd3RkSEpoYm5OaFkzUnBiMjRpTEFvZ0lDQWdJbWx1ZEdWeWJtRnNMWFI0TFhCdmIyd2lMQW9nSUNBZ0ltbHVkR1Z5Ym1Gc0xXUmxZblZuSWdvZ0lGMHNDaUFnSW5CeWRXNXBibWN0Wlc1aFlteGxaQ0k2Wm1Gc2MyVUtmUT09IgogIH0KfQ==",
"logrotate_files_template": "{{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log",
"postinst_script_template": "",
"service_type": "simple",
"service_additional_params_template": "",
"protect_memory": true,
"mainnet": true,
"server_config_file": "",
"client_config_file": "",
"platforms": {
"arm64": {
"binary_url": "https://github.com/ava-labs/avalanchego/releases/download/v1.9.7/avalanchego-linux-arm64-v1.9.7.tar.gz",
"verification_source": "https://github.com/ava-labs/avalanchego/releases/download/v1.9.7/avalanchego-linux-arm64-v1.9.7.tar.gz.sig"
}
}
},
"blockbook": {
"package_name": "blockbook-avalanche-archive",
"system_user": "blockbook-avalanche",
"internal_binding_template": ":{{.Ports.BlockbookInternal}}",
"public_binding_template": ":{{.Ports.BlockbookPublic}}",
"explorer_url": "",
"additional_params": "-workers=16",
"block_chain": {
"parse": true,
"mempool_workers": 8,
"mempool_sub_workers": 2,
"block_addresses_to_keep": 600,
"additional_params": {
"address_aliases": true,
"mempoolTxTimeoutHours": 48,
"processInternalTransactions": true,
"queryBackendOnMempoolResync": false,
"fiat_rates": "coingecko",
"fiat_rates_vs_currencies": "AED,ARS,AUD,BDT,BHD,BMD,BRL,CAD,CHF,CLP,CNY,CZK,DKK,EUR,GBP,HKD,HUF,IDR,ILS,INR,JPY,KRW,KWD,LKR,MMK,MXN,MYR,NGN,NOK,NZD,PHP,PKR,PLN,RUB,SAR,SEK,SGD,THB,TRY,TWD,UAH,USD,VEF,VND,ZAR,BTC,ETH",
"fiat_rates_params": "{\"url\": \"https://api.coingecko.com/api/v3\", \"coin\": \"avalanche-2\",\"platformIdentifier\": \"avalanche\",\"platformVsCurrency\": \"usd\",\"periodSeconds\": 900}",
"fourByteSignatures": "https://www.4byte.directory/api/v1/signatures/"
}
}
},
"meta": {
"package_maintainer": "IT",
"package_maintainer_email": "it@satoshilabs.com"
}
}

View File

@ -46,6 +46,8 @@
| BitZeny | 9095 | 9195 | 8095 | 38395 |
| Trezarcoin | 9096 | 9196 | 8096 | 38396 |
| eCash | 9097 | 9197 | 8097 | 38397 |
| Avalanche | 9098 | 9198 | 8098 | 38398 p2p |
| Avalanche Archive | 9099 | 9199 | 8099 | 38399 p2p |
| Bitcoin Signet | 19020 | 19120 | 18020 | 48320 |
| Bitcoin Regtest | 19021 | 19121 | 18021 | 48321 |
| Ethereum Goerli | 19026 | 19126 | 18026 | 48326 p2p |

73
go.mod
View File

@ -1,9 +1,11 @@
module github.com/trezor/blockbook
go 1.17
go 1.19
require (
github.com/Groestlcoin/go-groestl-hash v0.0.0-20181012171753-790653ac190c // indirect
github.com/ava-labs/avalanchego v1.9.7
github.com/ava-labs/coreth v0.11.6
github.com/bsm/go-vlq v0.0.0-20150828105119-ec6e8d4f5f4e
github.com/dchest/blake256 v1.0.0 // indirect
github.com/deckarep/golang-set v1.8.0
@ -14,8 +16,8 @@ require (
github.com/decred/dcrd/dcrutil/v3 v3.0.0
github.com/decred/dcrd/hdkeychain/v3 v3.0.0
github.com/decred/dcrd/txscript/v3 v3.0.0
github.com/ethereum/go-ethereum v1.10.25
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
github.com/ethereum/go-ethereum v1.10.26
github.com/golang/glog v1.0.0
github.com/golang/protobuf v1.5.2
github.com/gorilla/websocket v1.4.2
github.com/juju/errors v0.0.0-20170703010042-c7d06af17c68
@ -30,22 +32,23 @@ require (
github.com/pebbe/zmq4 v1.2.1
github.com/pirk/ecashaddr-converter v0.0.0-20220121162910-c6cb45163b29
github.com/pirk/ecashutil v0.0.0-20220124103933-d37f548d249e
github.com/prometheus/client_golang v1.8.0
github.com/prometheus/client_golang v1.13.0
github.com/schancel/cashaddr-converter v0.0.0-20181111022653-4769e7add95a
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519
google.golang.org/protobuf v1.26.0
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d
google.golang.org/protobuf v1.28.1
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 // indirect
)
require (
github.com/NYTimes/gziphandler v1.1.1 // indirect
github.com/PiRK/cashaddr-converter v0.0.0-20220121162910-c6cb45163b29 // indirect
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect
github.com/VictoriaMetrics/fastcache v1.10.0 // indirect
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/btcsuite/btcd v0.20.1-beta // indirect
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f // indirect
github.com/cespare/xxhash/v2 v2.1.1 // indirect
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dchest/siphash v1.2.1 // indirect
github.com/decred/base58 v1.0.3 // indirect
@ -56,18 +59,54 @@ require (
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
github.com/decred/dcrd/wire v1.4.0 // indirect
github.com/decred/slog v1.1.0 // indirect
github.com/go-ole/go-ole v1.2.1 // indirect
github.com/go-logr/logr v1.2.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-stack/stack v1.8.0 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/uuid v1.2.0 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/gorilla/rpc v1.2.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 // indirect
github.com/holiman/uint256 v1.2.0 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.14.0 // indirect
github.com/prometheus/procfs v0.2.0 // indirect
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect
github.com/stretchr/testify v1.8.0 // indirect
github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect
github.com/rjeczalik/notify v0.9.2 // indirect
github.com/rs/cors v1.7.0 // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
github.com/stretchr/testify v1.8.1 // indirect
github.com/supranational/blst v0.3.11-0.20220920110316-f72618070295 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect
github.com/tklauser/go-sysconf v0.3.5 // indirect
github.com/tklauser/numcpus v0.2.2 // indirect
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
go.opentelemetry.io/otel v1.11.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.11.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.11.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.11.0 // indirect
go.opentelemetry.io/otel/sdk v1.11.0 // indirect
go.opentelemetry.io/otel/trace v1.11.0 // indirect
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
go.uber.org/zap v1.24.0 // indirect
golang.org/x/exp v0.0.0-20220426173459-3bcf042a4bf5 // indirect
golang.org/x/net v0.1.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.1.0 // indirect
golang.org/x/term v0.1.0 // indirect
golang.org/x/text v0.4.0 // indirect
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
gonum.org/v1/gonum v0.11.0 // indirect
google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c // indirect
google.golang.org/grpc v1.50.1 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

722
go.sum

File diff suppressed because it is too large Load Diff

33
tests/rpc/testdata/avalanche.json vendored Normal file
View File

@ -0,0 +1,33 @@
{
"blockHeight": 23253547,
"blockHash": "0x987b44029c49a7ea619cf853edfb8ab35691f1121f4d497a1896714bfcf5b4ec",
"blockTime": 1670262361,
"blockSize": 865,
"blockTxs": [
"0x59a1c3ce0f901e71c4f1c88dc829e35d29ce900ae3a74366d16aedb4a2e33992"
],
"txDetails": {
"0x59a1c3ce0f901e71c4f1c88dc829e35d29ce900ae3a74366d16aedb4a2e33992": {
"txid": "0x59a1c3ce0f901e71c4f1c88dc829e35d29ce900ae3a74366d16aedb4a2e33992",
"blockTime": 1670262361,
"time": 1670262361,
"vin": [
{
"addresses": [
"0x2Dc3bbe90DD2d70dD9CF2D181ee667E95837b565"
]
}
],
"vout": [
{
"value": 1.010479009433962264,
"scriptPubKey": {
"addresses": [
"0x8D940A4859570754D364b86Ccc05052Ea5068Ea6"
]
}
}
]
}
}
}

View File

@ -1,4 +1,7 @@
{
"avalanche": {
"rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "EstimateFee", "GetBlockHeader"]
},
"bcash": {
"rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync",
"EstimateFee", "GetBestBlockHash", "GetBestBlockHeight", "GetBlockHeader"],