Skip to content

Commit

Permalink
P-Chain Support (#123)
Browse files Browse the repository at this point in the history
* backend structure to support p-chain and c-chain atomic tx (#122)

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* lint fixes

* /construction/derive support for p-chain and c-chain bech32 addresses (#124)

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* /account/balance and /account/coins support for p-chain and c-chain atomic tx (#125)

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* /network/options and /network/status support for p-chain (#126)

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* /construction/preprocess and /construction/metadata endpoints for p-chain (#127)

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* Added Postman collection for all endpoints (#129)

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* updating account endpoints to exclude multisig utxos (#132)

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* trigger checks

* /construction/payloads for p-chain (#130)

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* /block and /block/transaction endpoints for p-chain (#131)

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>
Co-authored-by: Raj Ranjan <rranjan01234@gmail.com>

* simplify postman collection usage for construction requests (#133)

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* /construction/preprocess and /construction/metadata endpoints for c-chain atomic transactions (#134)

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* P-chain parse combine hash submit (#136)

* /construction/parse and /construction/combine endpoints for p-chain

* /construction/hash and /construction/submit endpoints for p-chain

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* Account and block endpoint fixes (#137)

* adding block identifier to /account calls for c-chain atomic tx

* Use transaction ids instead of block ids for C-chain atomic txs

* support shared memory balance for p-chain

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* C chain construction rest (#139)

* /construction/payloads for c-chain atomic transactions

* /construction/parse and /construction/combine for c-chain atomic tx

* /construction/hash and /construction/submit endpoints for c-chain atomic tx

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* minor fixes (#140)

* skip outputs without any addresses

* remove artificial create chain output

* add staking parameters to transaction metadata when parsing

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* P-Chain Avalanchego 1.8.x support (#144)

* updated platformvm types and added indexer parsing support for Blueberry blocks

* fixed indexer parser tests

* support parsing of new transaction types

* fixed incorrect threshold value set for the staking reward outputs

* update CI golang to 1.18

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* Version upgrades (#148)

* update avalanchego version to 1.8.5

* change minimum go version to 1.18

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* Merge branch 'master' of https://github.com/ava-labs/avalanche-rosetta into pchain-support

* Add cross chain operations to transaction metadata (#149)

* added exported outputs and imported inputs to metadata of p-chain transactions

* added exported outputs to metadata of c-chain atomic transactions

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* addressed pchain-support merge pr comments (#151)

* utilize txs.CodecVersion
* fix Blueberry block timestamp handling
* handle missing Blueberry transaction types
* rename indexer parser initialize method
* use blocks.Parse to parse block bytes
* code style fixes

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* fix tests

* Fixing AdvanceTimeTx lookup and multisig check regression  (#152)

* added dependency tx handling logic for advance time tx

* fix p-chain imported input parsing bug

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* add signer to permissionless validator tx output metadata (#153)

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* v1.9.0 support and other fixes requested in #123 (#154)

* avalanchego 1.9.0 compatibility changes

* added comments to p-chain indexer parser timestamp logic

* add multiple transaction support to banff proposal block parsing

* added import aliases to p-chain indexer parser code

* added comments to isGenesisBlockRequest check

* added comments to indexer container lookup logic

* better error messages for pre/post height lookup during utxo retrieval

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* Multiple fixes (#156)

* better error handling for p-chain tx-parser constructor

* sort evm input and outputs for c-chain atomic transactions

* renamed metadata variables for staking tx builder

* added overflow check to staking transaction weight calculations

* return error if reward transaction points to an unsupported transaction type

* style fixes

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* update codec and version sources and add operation identifier to c-chain export tx (#157)

* update codec and version sources

* add operation identifier to c-chain export transaction parsing

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* Multiple updates (#159)

* use tx id generation logic from avalanchego in hash endpoint

* added comments to exported types

* make genesisTimestamp in p-chain indexer parser more verbose

* add operation identifier to p-chain import/export transaction parsing

* add support for non-AVAX currencies in account and block endpoints

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* minor cleanups

* nits

* nit

* more cleanup

* prepended base to rpc/indexer endpoints, to avoid confusion

* appease linter

* pchain indexer dropped unused attribute

* nit

* nit

* init pchain parser in constructor

* renamed ParseBlockAtIndex to ParseBlockAtHeight

* some more cleanup

* wip: cleanup timestamp

* fixed UTs

* nit

* comment nit

* cleanup

* parser cleanup

* init chainIDs in backend ctor

* nit

* restructured network identifier handling

* validate network name in main

* fixes

* wip: repacking genesis stuff to genesisHandler

* dropped code duplication

* nit

* wip

* wip

* types cleanup

* more types cleanup

* cleanup

* nit

* chainIDs type cleanup

* cleanup AvaxTx implementation

* fixes following code review

* fixed chainID build

* fix

* DependencyTx cleanup

* changed utxosMap indexing

* nit

* nit

* some more cleanup

* nit

* nit

* nit

* nits

* nits

* Fixed Pchain Indexer parser  + minor cleanups (#160)

* minor cleanups

* nits

* nit

* more cleanup

* prepended base to rpc/indexer endpoints, to avoid confusion

* appease linter

* pchain indexer dropped unused attribute

* nit

* nit

* init pchain parser in constructor

* renamed ParseBlockAtIndex to ParseBlockAtHeight

* some more cleanup

* wip: cleanup timestamp

* fixed UTs

* nit

* comment nit

* fixes following code review

* reverted blkTime extraction in pchain indexer parser

* Backend block cleanup (#162)

* minor cleanups

* nits

* nit

* more cleanup

* prepended base to rpc/indexer endpoints, to avoid confusion

* appease linter

* pchain indexer dropped unused attribute

* nit

* nit

* init pchain parser in constructor

* renamed ParseBlockAtIndex to ParseBlockAtHeight

* some more cleanup

* wip: cleanup timestamp

* fixed UTs

* nit

* comment nit

* cleanup

* parser cleanup

* init chainIDs in backend ctor

* nit

* fixes

* fixes following code review

* fixed chainID build

* reverted blkTime extraction in pchain indexer parser

* Pchain network id checks (#163)

* minor cleanups

* nits

* nit

* more cleanup

* prepended base to rpc/indexer endpoints, to avoid confusion

* appease linter

* pchain indexer dropped unused attribute

* nit

* nit

* init pchain parser in constructor

* renamed ParseBlockAtIndex to ParseBlockAtHeight

* some more cleanup

* wip: cleanup timestamp

* fixed UTs

* nit

* comment nit

* cleanup

* parser cleanup

* init chainIDs in backend ctor

* nit

* restructured network identifier handling

* validate network name in main

* fixes

* fixes following code review

* fixed chainID build

* fix

* reverted blkTime extraction in pchain indexer parser

* cleanup

* Pchain genesis repack (#164)

* minor cleanups

* nits

* nit

* more cleanup

* prepended base to rpc/indexer endpoints, to avoid confusion

* appease linter

* pchain indexer dropped unused attribute

* nit

* nit

* init pchain parser in constructor

* renamed ParseBlockAtIndex to ParseBlockAtHeight

* some more cleanup

* wip: cleanup timestamp

* fixed UTs

* nit

* comment nit

* cleanup

* parser cleanup

* init chainIDs in backend ctor

* nit

* restructured network identifier handling

* validate network name in main

* fixes

* wip: repacking genesis stuff to genesisHandler

* dropped code duplication

* nit

* fixes following code review

* fixed chainID build

* fix

* reverted blkTime extraction in pchain indexer parser

* cleanup

* fill in asset ids for P-chain allocation transaction outputs

* pchain tx parser cleanup (#165)

* minor cleanups

* nits

* nit

* more cleanup

* prepended base to rpc/indexer endpoints, to avoid confusion

* appease linter

* pchain indexer dropped unused attribute

* nit

* nit

* init pchain parser in constructor

* renamed ParseBlockAtIndex to ParseBlockAtHeight

* some more cleanup

* wip: cleanup timestamp

* fixed UTs

* nit

* comment nit

* cleanup

* parser cleanup

* init chainIDs in backend ctor

* nit

* restructured network identifier handling

* validate network name in main

* fixes

* wip: repacking genesis stuff to genesisHandler

* dropped code duplication

* nit

* wip

* wip

* types cleanup

* more types cleanup

* cleanup

* nit

* chainIDs type cleanup

* cleanup AvaxTx implementation

* fixes following code review

* fixed chainID build

* fix

* reverted blkTime extraction in pchain indexer parser

* cleanup

* fill in asset ids for P-chain allocation transaction outputs

* nit

* DependencyTx cleanup (#166)

* minor cleanups

* nits

* nit

* more cleanup

* prepended base to rpc/indexer endpoints, to avoid confusion

* appease linter

* pchain indexer dropped unused attribute

* nit

* nit

* init pchain parser in constructor

* renamed ParseBlockAtIndex to ParseBlockAtHeight

* some more cleanup

* wip: cleanup timestamp

* fixed UTs

* nit

* comment nit

* cleanup

* parser cleanup

* init chainIDs in backend ctor

* nit

* restructured network identifier handling

* validate network name in main

* fixes

* wip: repacking genesis stuff to genesisHandler

* dropped code duplication

* nit

* wip

* wip

* types cleanup

* more types cleanup

* cleanup

* nit

* chainIDs type cleanup

* cleanup AvaxTx implementation

* fixes following code review

* fixed chainID build

* fix

* DependencyTx cleanup

* changed utxosMap indexing

* nit

* nit

* some more cleanup

* nit

* nit

* nit

* reverted blkTime extraction in pchain indexer parser

* cleanup

* fill in asset ids for P-chain allocation transaction outputs

* nit

* merged pchain-support

* nit

* nit fix

* added Initialize to common.AvaxTx

* fixed some more uninitilized txs

* some more cleanup

* nit

* TxDependency Bugfix (#172)

bugfix + UTs

* Accounts nits (#167)

nits and cleanup on Accounts

* pchain tx parser fix (#168)

pchain tx parser - locked inputs fix

* fixed network names

* cleanup

* fix c-chain atomic transaction balance currencies (#173)

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* Network name-backward compatible fix (#174)

lowercase NetworkIdentifier for backward compatibility

* [Codebase cleanup] Network identifier Cleanup (#170)

networkIdentifier constants cleanup

* rename rpc_endpoint/indexer_endpoint to rpc_base_url/indexer_base_url in Docker entrypoint (#180)

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* stopped getting blocks from indexer by ID

* notes

* Fix Pchain Block ID usage (#182)

stopped getting blocks from indexer by ID

* Drop proposer type (#183)

dropped proposer type

* nit

* disable p-chain indexer related calls in offline mode (#189)

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* no indexer call on genesis (#190)

* fixed compilation post merge

* fixed network name verification for offline mode

* Get network name fix (#194)

* reverted faulty change

* refactored common methods in cchain and pchain clients

* fixed GetNetworkName validation

* some more validation fixes

* Lazy inits (#195)

* Lazily initialized networkID

* lazily initialized genesis block

* lazily initialized ChainIDs

* dropped useless func

* nit

* appeased linter

* Dropped most lazy inits in favour of Avalanchego codebase methods (#196)

* drop unused GetNetworkName method from client

* dropped GetNetworkID API calls in favour of avalanchego constants package

* dropped genesis lazy initialization following GetNetworkID calls removal

* appease linter

* fix panic in offline mode

* tech notes to ease up maintenance

* add pending rewards balance support for p-chain (#200)

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* add tx fee metadata to cross chain c-chain transaction parsing (#201)

Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>

* updated avalanchego to v1.9.10

* updated avalanchego version to 1.9.11

---------

Co-authored-by: bilgehansahin <bilgehansahin@gmail.com>
Co-authored-by: Bilgehan Sahin <bilgehan.sahin@coinbase.com>
Co-authored-by: Alberto Benegiamo <alberto.benegiamo@gmail.com>
  • Loading branch information
4 people authored Mar 8, 2023
1 parent d33c11b commit aa522c5
Show file tree
Hide file tree
Showing 127 changed files with 18,506 additions and 409 deletions.
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,10 @@ rosetta-data
*.swp
data
.vscode*
__debug_bin*
__debug_bin*

# *.json is excluded above, make sure we include postman collection
!postman/*.json

# *.json is excluded above, make sure we include indexer testdata
!service/backend/pchain/indexer/testdata/**
7 changes: 7 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ run:
issues:
# Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
max-same-issues: 0
exclude:
- "G114: Use of net/http serve function that has no support for setting timeouts"
exclude-rules:
# ref: https://github.com/dominikh/go-tools/issues/1365
- path: client/pchainclient.go
linters:
- unused

linters:
# please, do not use `enable-all`: it's deprecated and will be removed soon.
Expand Down
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ DOCKER_ORG ?= avaplatform
DOCKER_IMAGE ?= ${DOCKER_ORG}/${PROJECT}
DOCKER_LABEL ?= latest
DOCKER_TAG ?= ${DOCKER_IMAGE}:${DOCKER_LABEL}
AVALANCHE_VERSION ?= v1.9.9
AVALANCHE_VERSION ?= v1.9.11

build:
export CGO_CFLAGS="-O -D__BLST_PORTABLE__" && go build -o ./rosetta-server ./cmd/server
Expand Down Expand Up @@ -118,3 +118,6 @@ check-mainnet-construction:
mocks:
rm -rf mocks;
mockery --dir client --all --case underscore --outpkg client --output mocks/client;
mockery --dir service --name '.*Backend' --case underscore --outpkg chain --output mocks/service;
mockery --dir service/backend --all --case underscore --outpkg chain --output mocks/service/backend;
mockery --dir service/backend/pchain/indexer --all --case underscore --outpkg chain --output mocks/service/backend/pchain/indexer;
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Before you start running the server you need to create a configuration file:

```json
{
"rpc_endpoint": "https://api.avax-test.network",
"rpc_base_url": "https://api.avax-test.network",
"mode": "online",
"listen_addr": "0.0.0.0:8080",
"genesis_block_hash" :"0x31ced5b9beb7f8782b014660da0cb18cc409f121f408186886e1ca3e8eeca96b",
Expand All @@ -45,14 +45,15 @@ Start the server by running the following command:
```bash
./rosetta-server -config=./config.json
```

## Configuration

Full configuration example:

```json
{
"mode": "online",
"rpc_endpoint": "http://localhost:9650",
"rpc_base_url": "http://localhost:9650",
"listen_addr": "0.0.0.0:8080",
"network_name": "Fuji",
"chain_id": 43113,
Expand All @@ -71,7 +72,7 @@ Where:
| Name | Type | Default | Description
|---------------|---------|---------|-------------------------------------------
| mode | string | `online` | Mode of operations. One of: `online`, `offline`
| rpc_endpoint | string | `http://localhost:9650` | Avalanche RPC endpoint
| rpc_base_url | string | `http://localhost:9650` | Avalanche RPC base url
| listen_addr | string | `http://localhost:8080` | Rosetta server listen address (host/port)
| network_name | string | - | Avalanche network name
| chain_id | integer | - | Avalanche C-Chain ID
Expand Down Expand Up @@ -156,7 +157,7 @@ Run the construction check for ERC-20s:
make check-testnet-construction-erc20
```

## Rebuild the ContractInfoToken.go autogen file.
## Rebuild the ContractInfoToken.go autogen file

```bash
abigen --abi contractInfo.abi --pkg main --type ContractInfoToken --out client/contractInfoToken.go
Expand Down
20 changes: 15 additions & 5 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,23 @@ import (
"math/big"
"strings"

"github.com/ava-labs/avalanche-rosetta/constants"
"github.com/ava-labs/avalanchego/api"
"github.com/ava-labs/avalanchego/api/info"
"github.com/ava-labs/avalanchego/utils/rpc"
"github.com/ava-labs/avalanchego/ids"
ethtypes "github.com/ava-labs/coreth/core/types"
"github.com/ava-labs/coreth/interfaces"
"github.com/ava-labs/coreth/plugin/evm"
ethcommon "github.com/ethereum/go-ethereum/common"
)

// Interface compliance
var _ Client = &client{}

type Client interface {
IsBootstrapped(context.Context, string, ...rpc.Option) (bool, error)
// info.Client methods
InfoClient

ChainID(context.Context) (*big.Int, error)
BlockByHash(context.Context, ethcommon.Hash) (*ethtypes.Block, error)
BlockByNumber(context.Context, *big.Int) (*ethtypes.Block, error)
Expand All @@ -32,14 +37,18 @@ type Client interface {
SuggestGasPrice(context.Context) (*big.Int, error)
EstimateGas(context.Context, interfaces.CallMsg) (uint64, error)
TxPoolContent(context.Context) (*TxPoolContent, error)
GetNetworkName(context.Context, ...rpc.Option) (string, error)
Peers(context.Context, ...rpc.Option) ([]info.Peer, error)
GetContractInfo(ethcommon.Address, bool) (string, uint8, error)
CallContract(context.Context, interfaces.CallMsg, *big.Int) ([]byte, error)
IssueTx(ctx context.Context, txBytes []byte) (ids.ID, error)
GetAtomicUTXOs(ctx context.Context, addrs []string, sourceChain string, limit uint32, startAddress, startUTXOID string) ([][]byte, api.Index, error)
EstimateBaseFee(ctx context.Context) (*big.Int, error)
}

type EvmClient evm.Client

type client struct {
info.Client
EvmClient
*EthClient
*ContractClient
}
Expand All @@ -53,8 +62,9 @@ func NewClient(ctx context.Context, endpoint string) (Client, error) {
return nil, err
}

return client{
return &client{
Client: info.NewClient(endpoint),
EvmClient: evm.NewClient(endpoint, constants.CChain.String()),
EthClient: eth,
ContractClient: NewContractClient(eth.Client),
}, nil
Expand Down
12 changes: 7 additions & 5 deletions client/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ const (
contractCacheSize = 1024
)

type ContractInfo struct {
Symbol string
Decimals uint8
}

// ContractClient is a client for the calling contract information
type ContractClient struct {
ethClient ethclient.Client
cache *cache.LRU[common.Address, *ContractInfo]
}

type ContractInfo struct {
Symbol string
Decimals uint8
}

// NewContractClient returns a new ContractInfo client
func NewContractClient(c ethclient.Client) *ContractClient {
return &ContractClient{
Expand All @@ -31,6 +31,8 @@ func NewContractClient(c ethclient.Client) *ContractClient {

// GetContractInfo returns the symbol and decimals for [addr].
func (c *ContractClient) GetContractInfo(addr common.Address, erc20 bool) (string, uint8, error) {
// We don't define another struct because this is never used outside of this
// function.
if currency, cached := c.cache.Get(addr); cached {
return currency.Symbol, currency.Decimals, nil
}
Expand Down
17 changes: 17 additions & 0 deletions client/info_client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package client

import (
"context"

"github.com/ava-labs/avalanchego/api/info"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/utils/rpc"
)

// InfoClient collects all Avalanchego info.Client methods common
// to Rosetta Clients
type InfoClient interface {
GetBlockchainID(context.Context, string, ...rpc.Option) (ids.ID, error)
IsBootstrapped(context.Context, string, ...rpc.Option) (bool, error)
Peers(context.Context, ...rpc.Option) ([]info.Peer, error)
}
96 changes: 96 additions & 0 deletions client/pchainclient.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package client

import (
"context"
"strings"

"github.com/ava-labs/avalanchego/api"
"github.com/ava-labs/avalanchego/api/info"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/indexer"
"github.com/ava-labs/avalanchego/utils/rpc"
"github.com/ava-labs/avalanchego/vms/avm"
"github.com/ava-labs/avalanchego/vms/platformvm"
"github.com/ava-labs/avalanchego/vms/platformvm/signer"

"github.com/ava-labs/avalanche-rosetta/constants"
)

// Interface compliance
var _ PChainClient = &pchainClient{}

// PChainClient contains all client methods used to interact with avalanchego in order to support P-chain operations in Rosetta.
//
// These methods are cloned from the underlying avalanchego client interfaces, following the example of Client interface used to support C-chain operations.
type PChainClient interface {
// info.Client methods
InfoClient
GetNodeID(context.Context, ...rpc.Option) (ids.NodeID, *signer.ProofOfPossession, error)
GetTxFee(context.Context, ...rpc.Option) (*info.GetTxFeeResponse, error)

// indexer.Client methods
// Note: we use indexer only to be able to retrieve blocks by height.
// Blocks by ID are retrieved via platformVM.GetBlock, thus ignoring the proposerVM part
// and using Pchain Block ID rather than encompassing Snowman++ block ID
GetContainerByIndex(ctx context.Context, index uint64, options ...rpc.Option) (indexer.Container, error)
GetLastAccepted(context.Context, ...rpc.Option) (indexer.Container, uint64, error)

// platformvm.Client methods
GetUTXOs(
ctx context.Context,
addrs []ids.ShortID,
limit uint32,
startAddress ids.ShortID,
startUTXOID ids.ID,
options ...rpc.Option,
) ([][]byte, ids.ShortID, ids.ID, error)
GetAtomicUTXOs(
ctx context.Context,
addrs []ids.ShortID,
sourceChain string,
limit uint32,
startAddress ids.ShortID,
startUTXOID ids.ID,
options ...rpc.Option,
) ([][]byte, ids.ShortID, ids.ID, error)
GetRewardUTXOs(context.Context, *api.GetTxArgs, ...rpc.Option) ([][]byte, error)
GetHeight(ctx context.Context, options ...rpc.Option) (uint64, error)
GetBalance(ctx context.Context, addrs []ids.ShortID, options ...rpc.Option) (*platformvm.GetBalanceResponse, error)
GetTx(ctx context.Context, txID ids.ID, options ...rpc.Option) ([]byte, error)
GetBlock(ctx context.Context, blockID ids.ID, options ...rpc.Option) ([]byte, error)
IssueTx(ctx context.Context, tx []byte, options ...rpc.Option) (ids.ID, error)
GetStake(ctx context.Context, addrs []ids.ShortID, options ...rpc.Option) (map[ids.ID]uint64, [][]byte, error)
GetCurrentValidators(ctx context.Context, subnetID ids.ID, nodeIDs []ids.NodeID, options ...rpc.Option) ([]platformvm.ClientPermissionlessValidator, error)

// avm.Client methods
GetAssetDescription(ctx context.Context, assetID string, options ...rpc.Option) (*avm.GetAssetDescriptionReply, error)
}

type (
indexerClient = indexer.Client
platformvmClient = platformvm.Client
infoClient = info.Client
)

type pchainClient struct {
platformvmClient
indexerClient
infoClient
xChainClient avm.Client
}

// NewPChainClient returns a new client for Avalanche APIs related to P-chain
func NewPChainClient(ctx context.Context, rpcBaseURL, indexerBaseURL string) PChainClient {
rpcBaseURL = strings.TrimSuffix(rpcBaseURL, "/")

return pchainClient{
platformvmClient: platformvm.NewClient(rpcBaseURL),
xChainClient: avm.NewClient(rpcBaseURL, constants.XChain.String()),
infoClient: info.NewClient(rpcBaseURL),
indexerClient: indexer.NewClient(indexerBaseURL + "/ext/index/P/block"),
}
}

func (p pchainClient) GetAssetDescription(ctx context.Context, assetID string, options ...rpc.Option) (*avm.GetAssetDescriptionReply, error) {
return p.xChainClient.GetAssetDescription(ctx, assetID, options...)
}
34 changes: 34 additions & 0 deletions cmd/server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Avalanche Rosetta: some technical notes

Some notes to ease up maintenance handover

## Emerging architecture

Avalanche-Rosetta used to be centered around the C-chain. Support for P-Chain and X-chain (the latter to allow import/export tracking) has been added later on. To host these chains a structure is emerging:

- Clients: client package collects all the calls to AvalancheGo node backing Rosetta server. Note that to support P-chain, the indexer must be supported by the AvalancheGo node backing Rosetta. The indexer is required to poll P-chain block by height (C-chain supports that natively, P-chain does not).
- Backends: backends of P-chain and X-chain pull information from client and implements the logic for the various services that Rosetta provides. C-chain has not (yet) a backend since its logic is still implemented at the service level. Creation of C-chain backend is left for a future refactoring.
- Services: the entry points for the API that Rosetta provides. Services route the request to the right backend (P-chain, X-chain or fallback to C-chain logic not yet repackaged into its backend). Moreover it returns the backend response to client.

## P-chain Block querying and Genesis special case

P-chain blocks are queried as follows:

- by hash. In such case GetBlock API of platformVM is hit
- by height. In such case the indexer is used. Note that the indexer returns the whole proposerVM blocks. So block retrieved by proposerVM is further processed to extract the P-chain inner block and only the latter is returned.

**P-chain Genesis Data must not be polled from APIs**. The reasons are that:

- `NetworkStatus` endpoint must return Genesis ID and Timestamp if AvalancheGo P-chain client has not complete bootstrapping yet
- If AvalancheGo P-chain node has not done bootstrapping, GetBlock endpoint cannot serve P-chain Genesis block.

Genesis Block information is parsed directly from AvalancheGo codebase rather than be called from GetBlock endpoint.

## Snowman++ handling

Snowman++ headers (aka proposerVM header) are not returned to client. P-chain blocks are referenced by:

- Their height
- Their BlockID (not the full proposerVM block ID)

ProposerVM headers are used only to retrieved timestamp for pre-Banff blocks. Note that indexer timestamp is never used as it cannot guarantee a deployment-independent information.
Loading

0 comments on commit aa522c5

Please sign in to comment.