-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/feature/mesh' into develop
- Loading branch information
Showing
33 changed files
with
1,087 additions
and
274 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,278 @@ | ||
# Mesh API Implementation for Radix | ||
|
||
## Mesh API information | ||
|
||
- [Mesh API Homepage](https://docs.cdp.coinbase.com/mesh/docs/welcome) | ||
- [Mesh API Specification](https://github.com/coinbase/mesh-specifications) | ||
- [Mesh API CLI Test Tool](https://github.com/coinbase/mesh-cli) | ||
|
||
## Supported Features | ||
|
||
| Feature | Status | | ||
| ---------------------------- | ----------------------------------------------------------------------| | ||
| Data API | Feature-complete, with some quirks | | ||
| - `/network/list` | Complete | | ||
| - `/network/status` | Complete | | ||
| - `/network/options` | Complete | | ||
| - `/block` | Feature-complete (exposes only balance-changing operations) | | ||
| - `/block/transaction` | Feature-complete (exposes only balance-changing operations) | | ||
| - `/account/balance` | Complete (historical balances available if explicitly enabled) | | ||
| - `/mempool` | Complete (transactions are not held for a meaningful duration) | | ||
| - `/mempool/transaction` | Complete (basic operations supported) | | ||
| Construction API | Complete | | ||
| - `/construction/derive` | Complete | | ||
| - `/construction/preprocess` | Complete | | ||
| - `/construction/metadata` | Complete | | ||
| - `/construction/payloads` | Complete (supports Withdraw and Deposit operations only) | | ||
| - `/construction/combine` | Complete | | ||
| - `/construction/parse` | Complete (basic operations supported) | | ||
| - `/construction/hash` | Complete | | ||
| - `/construction/submit` | Complete | | ||
|
||
## Additional Considerations | ||
|
||
### Accounts | ||
|
||
The current implementation has the following constraints: | ||
- **Supports only account components**: Returns block operations or balances exclusively for accounts. Other components (e.g., smart contracts, lockers) are ignored. | ||
- **Supports only Withdraw, Deposit, and FeePayment operations**: Minting and burning are skipped. | ||
|
||
These constraints simplify the implementation without causing Mesh CLI tests to fail. If non-account components must be supported, the following may be required: | ||
- Adding support for Minting and Burning operations. | ||
- Providing explicit support for non-account components in balance fetching (or using `dump_component_state()`, which is resource-intensive). | ||
- Exempting some addresses. | ||
|
||
### Operations | ||
|
||
Currently, a very specific parser is used to extract operations from given instructions (endpoints: `/mempool/transaction` and `/construction/parse`). | ||
It works only with the instructions constructed by Mesh. | ||
`Withdraw` and `Deposit` are the direct result of the instructions being used, while a `FeePayment` is added at commit time. | ||
|
||
Technically, it would be possible to use transaction previews, receipts, and balance change summaries to extract operations. | ||
But we don't do it for following reasons: | ||
- both endpoint methods should work offline | ||
- both endpoint methods should be static (not affected by current state of the network) | ||
- this approach is deemed too resource-heavy | ||
|
||
## Configuration | ||
|
||
### Server settings | ||
There are 3 configuration settings for a node's Mesh API server, which can: | ||
- enable/disable Mesh API server launch (disabled by default), | ||
- override the default port (3337), | ||
- override the default bind address (127.0.0.1). | ||
|
||
#### Node running bare-metal | ||
```plaintext | ||
api.mesh.enabled=<true/false> | ||
api.mesh.port=<port number> | ||
api.mesh.bind_address=<ip address> | ||
``` | ||
#### Node running in Docker | ||
Set below environmental variables | ||
|
||
```plaintext | ||
RADIXDLT_MESH_API_ENABLED=<true/false> | ||
RADIXDLT_MESH_API_PORT=<port number> | ||
RADIXDLT_MESH_API_BIND_ADDRESS=<ip address> | ||
``` | ||
|
||
### Enable historical balances for reconciliation tests | ||
In order to proceed with reconciliation tests historical balances shall be enabled. | ||
There are 2 useful settings: | ||
- enable/disable historical substate values (disabled by default), | ||
- adjust the state version history length to keep (60000 by default). | ||
|
||
#### Node running bare-metal | ||
```plaintext | ||
db.historical_substate_values.enable=<true/false> | ||
state_hash_tree.state_version_history_length=<history_length_to_keep> | ||
``` | ||
|
||
#### Node running in Docker | ||
``` | ||
RADIXDLT_DB_HISTORICAL_SUBSTATE_VALUES_ENABLE=<true/false> | ||
RADIXDLT_STATE_HASH_TREE_STATE_VERSION_HISTORY_LENGTH=<history_length_to_keep> | ||
``` | ||
|
||
### Base URL | ||
|
||
```plaintext | ||
http://<bind_address>:<port>/mesh | ||
``` | ||
|
||
**Example**: Fetching account balance | ||
```plaintext | ||
http://localhost:3337/mesh/account/balance | ||
``` | ||
|
||
## Testing | ||
|
||
### Mesh CLI | ||
|
||
#### Steps: | ||
1. [Terminal 1] Download the `rosetta-cli` prebuilt binary: | ||
```bash | ||
curl -sSfL https://raw.githubusercontent.com/coinbase/mesh-cli/master/scripts/install.sh | sh -s | ||
|
||
alias mesh-cli='./bin/rosetta-cli --configuration-file <root-of-babylon-node-repo>/core-rust/mesh-api-server/mesh-cli-configs/localnet.json' | ||
``` | ||
**Note:** As of November 2024, there are issues with the prebuilt MacOS binary. Use the workaround below: | ||
```bash | ||
git clone [email protected]:coinbase/mesh-cli | ||
cd mesh-cli | ||
git checkout bbbd759 | ||
alias mesh-cli='go run main.go --configuration-file <root-of-babylon-node-repo>/core-rust/mesh-api-server/mesh-cli-configs/localnet.json' | ||
``` | ||
|
||
2. [Terminal 2] Launch the node: | ||
|
||
- Node running bare-metal | ||
- Change working directory to the root of the `babylon-node` repository | ||
- Enable Mesh API server in `core/default.config` | ||
```plaintext | ||
api.mesh.enabled=true | ||
``` | ||
- Optionally setup Mesh port and bind address | ||
``` | ||
api.mesh.port=3337 | ||
api.mesh.bind_address= | ||
``` | ||
- For reconciliation tests enable historical balances and optionally set state history length | ||
``` | ||
db.historical_substate_values.enable=true | ||
state_hash_tree.state_version_history_length=60000 | ||
``` | ||
|
||
- Start the node | ||
```bash | ||
RADIXDLT_NODE_KEY=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY= ./gradlew :core:run --info | ||
``` | ||
|
||
- Node running in Docker | ||
|
||
- Manual setup for production or testnet | ||
|
||
Follow these steps to setup a node - [Manual Setup with Docker](https://docs.radixdlt.com/v1/docs/node-setup-docker). | ||
|
||
Before launching a node set Mesh environment variables (mentioned in previous section) in `radix-fullnode-compose.yml` in `core` section: | ||
- Enable Mesh API server: | ||
```yaml | ||
RADIXDLT_MESH_API_ENABLED: 'true' | ||
``` | ||
- Optionally setup Mesh port and bind address | ||
```yaml | ||
RADIXDLT_MESH_API_PORT: 3337 | ||
RADIXDLT_MESH_API_BIND_ADDRESS: '0.0.0.0' | ||
``` | ||
- For reconciliation tests enable historical balances and optionally set state history length | ||
```yaml | ||
RADIXDLT_DB_HISTORICAL_SUBSTATE_VALUES_ENABLE: 'true' | ||
RADIXDLT_STATE_HASH_TREE_STATE_VERSION_HISTORY_LENGTH: 60000 | ||
``` | ||
|
||
- Simple setup for testnet | ||
|
||
Follow these steps to setup a node - [Simple testnet setup](https://github.com/radixdlt/babylon-node/tree/develop/testnet-node). | ||
|
||
Before launching a node set Mesh environment variables (mentioned in previous section) in `radix-node.env`: | ||
- Enable Mesh API server: | ||
```plaintext | ||
RADIXDLT_MESH_API_ENABLED=true | ||
``` | ||
- Optionally setup Mesh port and bind address | ||
```plaintext | ||
RADIXDLT_MESH_API_PORT=3337 | ||
RADIXDLT_MESH_API_BIND_ADDRESS=0.0.0.0 | ||
``` | ||
- For reconciliation tests enable historical balances and optionally set state history length | ||
```plaintext | ||
RADIXDLT_DB_HISTORICAL_SUBSTATE_VALUES_ENABLE=true | ||
RADIXDLT_STATE_HASH_TREE_STATE_VERSION_HISTORY_LENGTH=60000 | ||
``` | ||
|
||
3. [Terminal 1] Run Mesh API tests: | ||
```bash | ||
mesh-cli check:data | ||
mesh-cli check:construction | ||
mesh-cli check:spec | ||
``` | ||
|
||
#### Reconciliation Tests | ||
|
||
If whole ledger shall be reconciled for eg. `mainnet` or `stokenet`, then make sure to: | ||
- Set a future `state_version` in the `data.end_conditions.index` field of the `mesh-cli` config file. | ||
- Launch the node with an empty database. | ||
- Start `mesh-cli` as soon as possible to avoid pruning historical balances. | ||
|
||
### Unit Tests | ||
|
||
- **Java:** | ||
```bash | ||
./gradlew :core:test --tests '*MeshApiMempoolEndpointsTest*' | ||
``` | ||
- **Rust:** (To Be Determined) | ||
|
||
## Abstractions | ||
|
||
### NetworkIdentifier | ||
|
||
Fields: | ||
- `blockchain`: "radix" | ||
- `network`: Network variant (e.g., `mainnet`, `stokenet`, `localnet`). | ||
- `sub_network_identifier`: Not set. | ||
|
||
### Block | ||
|
||
Represents a single transaction. | ||
|
||
### BlockIdentifier | ||
|
||
Fields: | ||
- `index`: State version. | ||
- `hash`: Hex-encoded string of 32 bytes composed of: | ||
- `transaction_tree_hash` (bytes[0..12]). | ||
- `receipt_tree_hash` (bytes[0..12]). | ||
- `state_version` (bytes[0..8]). | ||
|
||
### TransactionIdentifier | ||
|
||
- **User transaction:** Bech32-encoded `transaction_intent_hash` (e.g., `txid_tdx_2_1nvm90npmkjcltvpy38nr373pt38ctptgg9y0g3wemhtjxyjmau7s32hd0n`). | ||
- **Non-user transaction:** Bech32-encoded `ledger_transaction_hash` (e.g., `ledgertransaction_tdx_2_1s45u3f6xrh4tf4040aqt9fql3wqlhvwwwfpaz4rsru3pr88f3anstnds7s`). | ||
|
||
### AccountIdentifier | ||
|
||
Fields: | ||
- `address`: Bech32-encoded Global Entity Address. | ||
- `sub_account`: Not set. | ||
- `metadata`: Not set. | ||
|
||
### Currency | ||
|
||
Fields: | ||
- `symbol`: Bech32-encoded Resource Address. | ||
- `decimals`: Resource divisibility. | ||
- `metadata`: Not set. | ||
|
||
### Amount | ||
|
||
Fields: | ||
- `value`: Currency amount. | ||
- `currency`: Resource information. | ||
- `metadata`: Not set. | ||
|
||
### Operation | ||
|
||
Fields: | ||
- `operation_identifier`: Index of the operation within a transaction. | ||
- `related_operations`: Not set. | ||
- `type`: | ||
- `Withdraw`: Withdraw assets from an account (always success, failed operations are filtered out). | ||
- `Deposit`: Deposit assets to an account (always success, failed operations are filtered out). | ||
- `FeePayment`: Withdraw assets to cover transaction fees (always success, even if the transaction fails). | ||
- `status`: Operation status. | ||
- `account`: Account transferring the resources. | ||
- `amount`: Amount of currency transferred. | ||
- `coin_change`: Not set. | ||
- `metadata`: Not set. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
{ | ||
"network": { | ||
"blockchain": "radix", | ||
"network": "mainnet" | ||
}, | ||
"online_url": "http://127.0.0.1:3337/mesh", | ||
"data_directory": "test-data/mainnet", | ||
"http_timeout": 10, | ||
"max_retries": 5, | ||
"retry_elapsed_time": 0, | ||
"max_online_connections": 120, | ||
"max_sync_concurrency": 64, | ||
"tip_delay": 300, | ||
"max_reorg_depth": 100, | ||
"log_configuration": false, | ||
"compression_disabled": false, | ||
"l0_in_memory_enabled": false, | ||
"all_in_memory_enabled": false, | ||
"error_stack_trace_disabled": false, | ||
"coin_supported": false, | ||
"data": { | ||
"active_reconciliation_concurrency": 16, | ||
"inactive_reconciliation_concurrency": 4, | ||
"inactive_reconciliation_frequency": 250, | ||
"log_blocks": false, | ||
"log_transactions": false, | ||
"log_balance_changes": false, | ||
"log_reconciliations": false, | ||
"ignore_reconciliation_error": false, | ||
"exempt_accounts": "", | ||
"bootstrap_balances": "", | ||
"interesting_accounts": "", | ||
"reconciliation_disabled": false, | ||
"reconciliation_drain_disabled": false, | ||
"inactive_discrepancy_search_disabled": false, | ||
"balance_tracking_disabled": false, | ||
"coin_tracking_disabled": false, | ||
"status_port": 9090, | ||
"results_output_file": "", | ||
"pruning_block_disabled": false, | ||
"pruning_balance_disabled": false, | ||
"initial_balance_fetch_disabled": false, | ||
"historical_balance_disabled": false, | ||
"end_conditions": { | ||
"index": 104281038 | ||
} | ||
}, | ||
"construction": { | ||
"offline_url": "http://localhost:3337/mesh", | ||
"constructor_dsl_file": "mainnet.ros", | ||
"stale_depth": 1000, | ||
"broadcast_limit": 1000, | ||
"end_conditions": { | ||
"radix_workflow": 1 | ||
} | ||
}, | ||
"perf": null, | ||
"sign": null | ||
} |
Oops, something went wrong.