Skip to content

Commit

Permalink
Feature: Mesh API Implementation (#1021)
Browse files Browse the repository at this point in the history
## Summary

This PR implements the [Mesh
API](https://docs.cdp.coinbase.com/mesh/docs/welcome) for Radix.

## Details

## Data API

Endpoint | Status
-- | --
- /network/list | Done
- /network/status | Done
- /network/options | Done
- /block | Done
- /block/transaction | Done, `Withdraw` and `Deposit` operations only
- /account/balance | Done, no historical balance lookup
- /mempool | Done
- /mempool/transaction | Done, no operation estimation

## Construction API

All endpoints have been implemented and only single signer/sender is
supported.

Endpoint | Status
-- | --
- /construction/derive | Done
- /construction/preprocess | Done
- /construction/metadata | Done
- /construction/payloads | Done, `Withdraw` and `Deposit` operations
only
- /construction/combine | Done
- /construction/parse | Done
- /construction/hash | Done
- /construction/submit | Done

## Testing

We've added the `mesh-cli` test suites to CI.
  • Loading branch information
iamyulong authored Nov 21, 2024
2 parents 0c4aa93 + c8c5f33 commit b8f3151
Show file tree
Hide file tree
Showing 275 changed files with 26,450 additions and 323 deletions.
33 changes: 33 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,39 @@ jobs:
# Might be set to warn for debugging purposes. Warning, log file will be huge.
RADIXDLT_LOG_LEVEL: error
run: ./gradlew clean runTargetedIntegrationTests --info --refresh-dependencies --parallel
mesh-api-test-suite:
name: Run Mesh API tests
runs-on: selfhosted-ubuntu-22.04-16-cores
steps:
- uses: RDXWorks-actions/checkout@main
with:
# Shallow clones should be disabled for a better relevancy of analysis
fetch-depth: 0
- name: Setup environment
uses: ./.github/actions/setup-env
- name: Cache Gradle packages
uses: RDXWorks-actions/cache@main
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
restore-keys: ${{ runner.os }}-gradle
- name: Build Node
run: ./gradlew build
- name: Run Node in the background
env:
# This is to skip keygen step
RADIXDLT_NODE_KEY: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY=
run: ./gradlew :core:run --info &
- name: Wait for 2 minutes
run: sleep 2m
- name: Install mesh-cli
run: curl -sSfL https://raw.githubusercontent.com/coinbase/mesh-cli/master/scripts/install.sh | sh -s
- name: Run Data API tests
run: ./bin/rosetta-cli check:data --configuration-file core-rust/mesh-api-server/mesh-cli-configs/default.json
- name: Run Construction API tests
run: ./bin/rosetta-cli check:construction --configuration-file core-rust/mesh-api-server/mesh-cli-configs/default.json
- name: Run Coinbase-spec tests
run: ./bin/rosetta-cli check:spec --configuration-file core-rust/mesh-api-server/mesh-cli-configs/default.json
cross-xwin:
name: Cross compile to Windows
runs-on: ubuntu-latest
Expand Down
9 changes: 7 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -178,12 +178,14 @@ RUN USER=root "$HOME/.cargo/bin/cargo" init --lib --name dummy --vcs none . \
&& mkdir -p ./node-common/src \
&& mkdir -p ./state-manager/src \
&& mkdir -p ./p2p/src \
&& mkdir -p ./mesh-api-server/src \
&& touch ./core-api-server/src/lib.rs \
&& touch ./engine-state-api-server/src/lib.rs \
&& touch ./jni-export/src/lib.rs \
&& touch ./node-common/src/lib.rs \
&& touch ./state-manager/src/lib.rs \
&& touch ./p2p/src/lib.rs
&& touch ./p2p/src/lib.rs \
&& touch ./mesh-api-server/src/lib.rs
COPY core-rust/Cargo.toml ./
COPY core-rust/Cargo.lock ./
COPY core-rust/core-api-server/Cargo.toml ./core-api-server
Expand All @@ -192,6 +194,7 @@ COPY core-rust/jni-export/Cargo.toml ./jni-export
COPY core-rust/node-common/Cargo.toml ./node-common
COPY core-rust/state-manager/Cargo.toml ./state-manager
COPY core-rust/p2p/Cargo.toml ./p2p
COPY core-rust/mesh-api-server/Cargo.toml ./mesh-api-server

COPY docker/build_scripts/cargo_build_by_platform.sh /opt/radixdlt/cargo_build_by_platform.sh

Expand All @@ -210,7 +213,7 @@ RUN --mount=type=cache,id=radixdlt-babylon-node-rust-cache,target=/root/.cache/s
FROM library-build-stage-cache-packages AS library-build-stage

# Tidy up from the previous layer
RUN rm -rf core-api-server engine-state-api-server jni-export node-common state-manager
RUN rm -rf core-api-server engine-state-api-server jni-export node-common state-manager mesh-api-server

# Copy across all the code (docker ignore excepted)
COPY core-rust ./
Expand Down Expand Up @@ -309,6 +312,8 @@ ENV RADIXDLT_HOME=/home/radixdlt \
RADIXDLT_PROMETHEUS_API_BIND_ADDRESS=0.0.0.0 \
RADIXDLT_ENGINE_STATE_API_PORT=3336 \
RADIXDLT_ENGINE_STATE_API_BIND_ADDRESS=0.0.0.0 \
RADIXDLT_MESH_API_PORT=3337 \
RADIXDLT_MESH_API_BIND_ADDRESS=0.0.0.0 \
RADIXDLT_NETWORK_ID=240 \
RADIXDLT_NODE_KEY_CREATE_IF_MISSING=false

Expand Down
107 changes: 107 additions & 0 deletions core-rust-bridge/src/main/java/com/radixdlt/api/MeshApiServer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/* Copyright 2021 Radix Publishing Ltd incorporated in Jersey (Channel Islands).
*
* Licensed under the Radix License, Version 1.0 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the License at:
*
* radixfoundation.org/licenses/LICENSE-v1
*
* The Licensor hereby grants permission for the Canonical version of the Work to be
* published, distributed and used under or by reference to the Licensor’s trademark
* Radix ® and use of any unregistered trade names, logos or get-up.
*
* The Licensor provides the Work (and each Contributor provides its Contributions) on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
* including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT,
* MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
*
* Whilst the Work is capable of being deployed, used and adopted (instantiated) to create
* a distributed ledger it is your responsibility to test and validate the code, together
* with all logic and performance of that code under all foreseeable scenarios.
*
* The Licensor does not make or purport to make and hereby excludes liability for all
* and any representation, warranty or undertaking in any form whatsoever, whether express
* or implied, to any entity or person, including any representation, warranty or
* undertaking, as to the functionality security use, value or other characteristics of
* any distributed ledger nor in respect the functioning or value of any tokens which may
* be created stored or transferred using the Work. The Licensor does not warrant that the
* Work or any use of the Work complies with any law or regulation in any territory where
* it may be implemented or used or that it will be appropriate for any specific purpose.
*
* Neither the licensor nor any current or former employees, officers, directors, partners,
* trustees, representatives, agents, advisors, contractors, or volunteers of the Licensor
* shall be liable for any direct or indirect, special, incidental, consequential or other
* losses of any kind, in tort, contract or otherwise (including but not limited to loss
* of revenue, income or profits, or loss of use or data, or loss of reputation, or loss
* of any economic or other opportunity of whatsoever nature or howsoever arising), arising
* out of or in connection with (without limitation of any use, misuse, of any ledger system
* or use made or its functionality or any performance or operation of any code or protocol
* caused by bugs or programming or logic errors or otherwise);
*
* A. any offer, purchase, holding, use, sale, exchange or transmission of any
* cryptographic keys, tokens or assets created, exchanged, stored or arising from any
* interaction with the Work;
*
* B. any failure in a transmission or loss of any token or assets keys or other digital
* artefacts due to errors in transmission;
*
* C. bugs, hacks, logic errors or faults in the Work or any communication;
*
* D. system software or apparatus including but not limited to losses caused by errors
* in holding or transmitting tokens by any third-party;
*
* E. breaches or failure of security including hacker attacks, loss or disclosure of
* password, loss of private key, unauthorised use or misuse of such passwords or keys;
*
* F. any losses including loss of anticipated savings or other benefits resulting from
* use of the Work or any changes to the Work (however implemented).
*
* You are solely responsible for; testing, validating and evaluation of all operation
* logic, functionality, security and appropriateness of using the Work for any commercial
* or non-commercial purpose and for any reproduction or redistribution by You of the
* Work. You assume all risks associated with Your use of the Work and the exercise of
* permissions under this License.
*/

package com.radixdlt.api;

import com.google.common.reflect.TypeToken;
import com.radixdlt.environment.MeshApiServerConfig;
import com.radixdlt.environment.NodeRustEnvironment;
import com.radixdlt.sbor.NodeSborCodecs;

public final class MeshApiServer {

static {
System.loadLibrary("corerust");
}

/** A pointer to the owned Rust structure. */
@SuppressWarnings("unused")
private final long rustMeshApiServerPointer = 0;

public static MeshApiServer create(
NodeRustEnvironment nodeRustEnvironment, MeshApiServerConfig config) {
return new MeshApiServer(nodeRustEnvironment, config);
}

MeshApiServer(NodeRustEnvironment nodeRustEnvironment, MeshApiServerConfig config) {
final var encodedConfig =
NodeSborCodecs.encode(config, NodeSborCodecs.resolveCodec(new TypeToken<>() {}));
init(nodeRustEnvironment, this, encodedConfig);
}

public void start() {
start(this);
}

public void stop() {
stop(this);
}

private static native void init(
NodeRustEnvironment nodeRustEnvironment, MeshApiServer meshApiServer, byte[] config);

private static native void start(MeshApiServer meshApiServer);

private static native void stop(MeshApiServer meshApiServer);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/* Copyright 2021 Radix Publishing Ltd incorporated in Jersey (Channel Islands).
*
* Licensed under the Radix License, Version 1.0 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the License at:
*
* radixfoundation.org/licenses/LICENSE-v1
*
* The Licensor hereby grants permission for the Canonical version of the Work to be
* published, distributed and used under or by reference to the Licensor’s trademark
* Radix ® and use of any unregistered trade names, logos or get-up.
*
* The Licensor provides the Work (and each Contributor provides its Contributions) on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
* including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT,
* MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
*
* Whilst the Work is capable of being deployed, used and adopted (instantiated) to create
* a distributed ledger it is your responsibility to test and validate the code, together
* with all logic and performance of that code under all foreseeable scenarios.
*
* The Licensor does not make or purport to make and hereby excludes liability for all
* and any representation, warranty or undertaking in any form whatsoever, whether express
* or implied, to any entity or person, including any representation, warranty or
* undertaking, as to the functionality security use, value or other characteristics of
* any distributed ledger nor in respect the functioning or value of any tokens which may
* be created stored or transferred using the Work. The Licensor does not warrant that the
* Work or any use of the Work complies with any law or regulation in any territory where
* it may be implemented or used or that it will be appropriate for any specific purpose.
*
* Neither the licensor nor any current or former employees, officers, directors, partners,
* trustees, representatives, agents, advisors, contractors, or volunteers of the Licensor
* shall be liable for any direct or indirect, special, incidental, consequential or other
* losses of any kind, in tort, contract or otherwise (including but not limited to loss
* of revenue, income or profits, or loss of use or data, or loss of reputation, or loss
* of any economic or other opportunity of whatsoever nature or howsoever arising), arising
* out of or in connection with (without limitation of any use, misuse, of any ledger system
* or use made or its functionality or any performance or operation of any code or protocol
* caused by bugs or programming or logic errors or otherwise);
*
* A. any offer, purchase, holding, use, sale, exchange or transmission of any
* cryptographic keys, tokens or assets created, exchanged, stored or arising from any
* interaction with the Work;
*
* B. any failure in a transmission or loss of any token or assets keys or other digital
* artefacts due to errors in transmission;
*
* C. bugs, hacks, logic errors or faults in the Work or any communication;
*
* D. system software or apparatus including but not limited to losses caused by errors
* in holding or transmitting tokens by any third-party;
*
* E. breaches or failure of security including hacker attacks, loss or disclosure of
* password, loss of private key, unauthorised use or misuse of such passwords or keys;
*
* F. any losses including loss of anticipated savings or other benefits resulting from
* use of the Work or any changes to the Work (however implemented).
*
* You are solely responsible for; testing, validating and evaluation of all operation
* logic, functionality, security and appropriateness of using the Work for any commercial
* or non-commercial purpose and for any reproduction or redistribution by You of the
* Work. You assume all risks associated with Your use of the Work and the exercise of
* permissions under this License.
*/

package com.radixdlt.api;

import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import com.google.inject.multibindings.ProvidesIntoSet;
import com.radixdlt.environment.MeshApiServerConfig;
import com.radixdlt.environment.NodeAutoCloseable;
import com.radixdlt.environment.NodeRustEnvironment;
import com.radixdlt.utils.UInt32;

public final class MeshApiServerModule extends AbstractModule {

private final MeshApiServerConfig config;

public MeshApiServerModule(String apiBindAddress, int apiPort, String nodeDisplayVersion) {
this.config =
new MeshApiServerConfig(
apiBindAddress, UInt32.fromNonNegativeInt(apiPort), nodeDisplayVersion);
}

@Provides
@Singleton
private MeshApiServer meshApiServer(NodeRustEnvironment nodeRustEnvironment) {
return MeshApiServer.create(nodeRustEnvironment, config);
}

@ProvidesIntoSet
NodeAutoCloseable closeable(MeshApiServer meshApiServer) {
return meshApiServer::stop;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/* Copyright 2021 Radix Publishing Ltd incorporated in Jersey (Channel Islands).
*
* Licensed under the Radix License, Version 1.0 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the License at:
*
* radixfoundation.org/licenses/LICENSE-v1
*
* The Licensor hereby grants permission for the Canonical version of the Work to be
* published, distributed and used under or by reference to the Licensor’s trademark
* Radix ® and use of any unregistered trade names, logos or get-up.
*
* The Licensor provides the Work (and each Contributor provides its Contributions) on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
* including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT,
* MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
*
* Whilst the Work is capable of being deployed, used and adopted (instantiated) to create
* a distributed ledger it is your responsibility to test and validate the code, together
* with all logic and performance of that code under all foreseeable scenarios.
*
* The Licensor does not make or purport to make and hereby excludes liability for all
* and any representation, warranty or undertaking in any form whatsoever, whether express
* or implied, to any entity or person, including any representation, warranty or
* undertaking, as to the functionality security use, value or other characteristics of
* any distributed ledger nor in respect the functioning or value of any tokens which may
* be created stored or transferred using the Work. The Licensor does not warrant that the
* Work or any use of the Work complies with any law or regulation in any territory where
* it may be implemented or used or that it will be appropriate for any specific purpose.
*
* Neither the licensor nor any current or former employees, officers, directors, partners,
* trustees, representatives, agents, advisors, contractors, or volunteers of the Licensor
* shall be liable for any direct or indirect, special, incidental, consequential or other
* losses of any kind, in tort, contract or otherwise (including but not limited to loss
* of revenue, income or profits, or loss of use or data, or loss of reputation, or loss
* of any economic or other opportunity of whatsoever nature or howsoever arising), arising
* out of or in connection with (without limitation of any use, misuse, of any ledger system
* or use made or its functionality or any performance or operation of any code or protocol
* caused by bugs or programming or logic errors or otherwise);
*
* A. any offer, purchase, holding, use, sale, exchange or transmission of any
* cryptographic keys, tokens or assets created, exchanged, stored or arising from any
* interaction with the Work;
*
* B. any failure in a transmission or loss of any token or assets keys or other digital
* artefacts due to errors in transmission;
*
* C. bugs, hacks, logic errors or faults in the Work or any communication;
*
* D. system software or apparatus including but not limited to losses caused by errors
* in holding or transmitting tokens by any third-party;
*
* E. breaches or failure of security including hacker attacks, loss or disclosure of
* password, loss of private key, unauthorised use or misuse of such passwords or keys;
*
* F. any losses including loss of anticipated savings or other benefits resulting from
* use of the Work or any changes to the Work (however implemented).
*
* You are solely responsible for; testing, validating and evaluation of all operation
* logic, functionality, security and appropriateness of using the Work for any commercial
* or non-commercial purpose and for any reproduction or redistribution by You of the
* Work. You assume all risks associated with Your use of the Work and the exercise of
* permissions under this License.
*/

package com.radixdlt.environment;

import com.radixdlt.sbor.codec.CodecMap;
import com.radixdlt.sbor.codec.StructCodec;
import com.radixdlt.utils.UInt32;

public record MeshApiServerConfig(String bindInterface, UInt32 port, String nodeDisplayVersion) {
public static void registerCodec(CodecMap codecMap) {
codecMap.register(
MeshApiServerConfig.class,
codecs -> StructCodec.fromRecordComponents(MeshApiServerConfig.class, codecs));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ public static void registerCodecsWithCodecMap(CodecMap codecMap) {
CoreApiServerConfig.registerCodec(codecMap);
CoreApiServerFlags.registerCodec(codecMap);
EngineStateApiServerConfig.registerCodec(codecMap);
MeshApiServerConfig.registerCodec(codecMap);
ValidatorInfo.registerCodec(codecMap);
GenesisData.registerCodec(codecMap);
GenesisConsensusManagerConfig.registerCodec(codecMap);
Expand Down
Loading

0 comments on commit b8f3151

Please sign in to comment.