Add Avalanche (#850)
This commit is contained in:
parent
778c071d12
commit
0d9d09b755
153
bchain/coins/avalanche/avalancherpc.go
Normal file
153
bchain/coins/avalanche/avalancherpc.go
Normal 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)
|
||||
}
|
||||
143
bchain/coins/avalanche/evm.go
Normal file
143
bchain/coins/avalanche/evm.go
Normal 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)
|
||||
}
|
||||
@ -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
|
||||
|
||||
51
build/docker/deb/gpg-keys/avalanche-releases.asc
Normal file
51
build/docker/deb/gpg-keys/avalanche-releases.asc
Normal file
@ -0,0 +1,51 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mQINBF7T6r4BEACmdzpthz6plCzb36P5Fx+Jwmm2/SlfKoXAEnJhjP+oK7PAvak+
|
||||
2sDFVv+MI5+nxJXQOdVat5/d9YlbwvgTQ4v/Iz0rJdSpjqKwUaJsDuHTedx6e/VA
|
||||
y7hYXwEcsLjiK9Ws7f9Oem1fvPa6tbLGQ5oSM0B8OKXAiR/YGcA+pC7SKURbbdY3
|
||||
hfwRljeJ3/Uq8CTuDw1VsOqEELqlCED8VuSWG4CTOyU+KvV0jIB9TrRB0U/jb+XB
|
||||
m/Jon/ZQFT5miPT+8VUa6L3WkVW9d97kiPhdH0d4yASoQ4AFiLpaEXXVWT9Nhvpg
|
||||
VMYYxscA3EnjaTXBR/kUfgmlbXfkiHv8reawynxGLwupK+qpH0XJbawJ7Hgvhej1
|
||||
SkU3WxhWuKdD92t3JXnWtJTiqQA42DPf5Bl1p3o7TRWMz57GRc8H7l/DdlZ1FbMJ
|
||||
TylAC+MJc5InJP//kZURMuKnsLkX4WyfF13fxb4oNXUt0wojdUvTQYnPDNFxW2Nr
|
||||
ddAtT+VoeRXQtIk6YjR+WkTF6/XYbSq734e0gLKC4aDd3EvbpYT/ZqpGr1VOfhve
|
||||
dIWbkHhqBtTHJQQy5ET7PiduN7S2OQGtuYUVzLp71iLAOK7hWOo5vWYDlwphK+uB
|
||||
MuGSdsnmtpceGOaqANVtpFmLsPAGSzxMQ368lnefCas3/ybvglu0M3YD1QARAQAB
|
||||
tCRBdmEgTGFicywgSW5jLiA8Y29udGFjdEBhdmFsYWJzLm9yZz6JAk4EEwEIADgW
|
||||
IQRTlb2hEpysPnRpnQfZMICwwNX+iwUCXtPqvgIbAwULCQgHAwUVCgkICwUWAgMB
|
||||
AAIeAQIXgAAKCRDZMICwwNX+iz+jEACElYnwV7VHgF70W2yJqPmJGZXswWlid6w4
|
||||
NTVOUV9jZTtIH88Jb81K03cOrzREXMX7H4qfEcsa2GM9s6n1IZJl+emaSCr3Z/sV
|
||||
aNR4vSRWT6/IrvbSpVYdh3XOVjA11464ldr5VAtjh528pHfzR2krzhuMOaQL8r27
|
||||
TuiUDBjkAVBoWHwN9nahj0OU56r00Mr4fZUWFuNBRgpaQoB6FwjQ1xtoedgN97iI
|
||||
QPwqEJdUzXQasl+K62TV7F8HUT2+25cEsu+w6OPSsERRgZLv3OHiEbO+ld9+KWDv
|
||||
QywcTjIBHCF/5qL2gfx3TQ7KwxrUEquOm/QJL4mz9HwfLLaR6Etg1NhMFooTdstQ
|
||||
tAJK6eUmRQk1psFP3yGbdSElkZ/RfbZvYcjm+x/r70Xo9T3Rv8fvIg6fqjnApmqW
|
||||
7BT59iFUOWrATEUAi393hem81njll+fBxd3p+4ilhAEz39Z5NoHX0ddktnSa81Pz
|
||||
4yKOJpcOB/mo7UwOoZ0iKND+ZSZxeo7YWlHZ5cSqRGyW5C/1PsLfqdRDw8SBO6A5
|
||||
rnjeppB+jiaPIqqKLGYRSV24H5PM9F7Uh1/H1lAIwXoxbSvkTelV0fTC+Bb9uPvu
|
||||
AdLxDf/TiLnRL7zsV/buHamrO83fh772kVjwNvverNuNcpcBTHuAHruqT9jcMmv3
|
||||
IU46JdCefLkCDQRe0+q+ARAA8JGJzbWdn2vz1gtEhKLLe3gDcncr3wrqCF+joEQ6
|
||||
1XKE0vrgycLh79YMgBtkH9IXsP07KUXQ+xjSbW0SsHGYtANg16JxdRdDiJfkPl0R
|
||||
ilALkuLvOrwLh2GJN1L7YggcWV/RTQ2NRpUFAdKQVU4x9N+E3QTRkVzcn2p/eiQh
|
||||
cT4c4itWke7J17CvXwVRnSOMuse23wEj/Y5BHhLYn13ojknAK3UHXJGRVm5C0M14
|
||||
D9rTJBCrI03pBnBzQhxkXSbeC++vevU/DBN19ph6Mq6dv6VUP5Ai996Cs1IDfbB8
|
||||
CNW/IjJ+GSkciIurSFNXyFKa6ppSowYdxB1Fqabyx1isKGASfzNooCByVuj7xhFM
|
||||
QjrAL2ZtOC1vjjUeuQ9ZpAmBa842xukJ8/ffvbvFoFXOOpJEJ9VZP2l5GWmanr/a
|
||||
MkVvykssGmH8vLWytWa8J0QeA0FEFyiNc3kfkozIjScI90RdEj+ddp8z9H09/ml8
|
||||
xr1Xj07w3zz20/rRIdmpVTpo44jF0jV0h7n33dg+LWX7iDU+NpalfX0DH/sEuzEa
|
||||
RYZsR09ExxLWBdHZ8HWIFRFRIrEg45oa7umo+YxypwrQFSxDT6v0QTPgle1Ged7h
|
||||
f47filRbrHhXhVxKWLPJok+Bme0NOAXFs1bSw3xCnkL4RlSckrPrUwQPGLqNQ6hd
|
||||
rrUAEQEAAYkCNgQYAQgAIBYhBFOVvaESnKw+dGmdB9kwgLDA1f6LBQJe0+q+AhsM
|
||||
AAoJENkwgLDA1f6LgAcP/3YGbQY753108CRdVA+R8RQRKF8Wl7rBUNnXXCnuJ0j5
|
||||
4JaeqOkX5JQtEEnIMJZdpOFF6iK9LH9afbCUMiV/BLYbo1qPTAMgVVp8vfDkq4GT
|
||||
wk4QIo3fLUEGW01IT93OY/OH4FsC8NcN9+mWnoiwlvyIfR7IauDbmbQ6eDzKr8r4
|
||||
K4am45eSPPOrS+W2+LjpjIMGzr971jL+FLeXoejiX0SeHJ/YGpv/qJnVZW3lVE9u
|
||||
nomutcMCzbceZJuU4f6NoUDjGVEnNr3eUvPXPyrD53mD2G4C2H/pRteS6Oo7gsaH
|
||||
Y2HfTngO8xVrMKQA6qGxilhYNSF0narDb7I+MCMTG0eGyGhixElmd2smmjbAzKY8
|
||||
dkMI7JYbhzbpfUVmiFhVEbr1mcCC8ZgkVCFmvw+Phbh29EUsMi9vQaHAzp/yZQ2+
|
||||
duBUPalYe+4ZPujq9QlvqLxUyDoqUg31TLaHHsvinByo6ZNXQ1NzGuYbVy1CYlK8
|
||||
9LqRPKFrO9bLsgwpE8pGkaOCl/1eATGru2b3jfwenknEBxvnXpexHLdUaJDcnBjH
|
||||
nqpSPI6o3NXVvLp5On2ygXBNEQTbcCrMxs1YSafXwlWyteYXdBHSBOPSfhoscYLF
|
||||
mvjNjlpX8tBPVnwHjpdxP+XitvrN/MVmGaMMfe+WDRRdUiup1Mj4ha8BzUggbGoq
|
||||
=AzIy
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
69
configs/coins/avalanche.json
Normal file
69
configs/coins/avalanche.json
Normal 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"
|
||||
}
|
||||
}
|
||||
72
configs/coins/avalanche_archive.json
Normal file
72
configs/coins/avalanche_archive.json
Normal 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"
|
||||
}
|
||||
}
|
||||
@ -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
73
go.mod
@ -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
|
||||
)
|
||||
|
||||
33
tests/rpc/testdata/avalanche.json
vendored
Normal file
33
tests/rpc/testdata/avalanche.json
vendored
Normal 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"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,7 @@
|
||||
{
|
||||
"avalanche": {
|
||||
"rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "EstimateFee", "GetBlockHeader"]
|
||||
},
|
||||
"bcash": {
|
||||
"rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync",
|
||||
"EstimateFee", "GetBestBlockHash", "GetBestBlockHeight", "GetBlockHeader"],
|
||||
|
||||
Loading…
Reference in New Issue
Block a user