diff --git a/.github/workflows/api.yml b/.github/workflows/api.yml index 5e58d7cbd5..72a90264c1 100644 --- a/.github/workflows/api.yml +++ b/.github/workflows/api.yml @@ -13,8 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: stoplightio/spectral-action@v0.6.0 + - uses: stoplightio/spectral-action@v0.8.2 with: file_glob: doc/api/*.yaml repo_token: ${{ secrets.GITHUB_TOKEN }} - spectral_ruleset: '' diff --git a/CHANGELOG.md b/CHANGELOG.md index 16ac3c9b93..e37ccbef04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,7 @@ - Add new Ethreum RPC mining endpoints: eth_mining, eth_coinbase, eth_hashrate, eth_getWork, eth_submitWork, eth_submitHashrate - Add chain-evm as optional dependency for jcli - Update gas price and block gas limit for EVM params +- Add new 'evm' REST API endpoints 'address_mapping/jormungandr_address', 'address_mapping/evm_address` for getting info about address mapping. They are optional for the 'evm' feature. ## Release 0.13.0 diff --git a/Cargo.lock b/Cargo.lock index 09ef553e59..146a30baca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -568,7 +568,7 @@ dependencies = [ [[package]] name = "cardano-legacy-address" version = "0.1.1" -source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#b6590318da760d223022bf4e3b1c42e1ee697242" +source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#8de67ffd1798220a92cc9d72e83529141248d0a2" dependencies = [ "cbor_event", "cryptoxide 0.4.2", @@ -639,7 +639,7 @@ dependencies = [ [[package]] name = "chain-addr" version = "0.1.0" -source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#b6590318da760d223022bf4e3b1c42e1ee697242" +source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#8de67ffd1798220a92cc9d72e83529141248d0a2" dependencies = [ "bech32 0.8.1", "chain-core", @@ -653,7 +653,7 @@ dependencies = [ [[package]] name = "chain-core" version = "0.1.0" -source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#b6590318da760d223022bf4e3b1c42e1ee697242" +source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#8de67ffd1798220a92cc9d72e83529141248d0a2" dependencies = [ "chain-ser", ] @@ -661,7 +661,7 @@ dependencies = [ [[package]] name = "chain-crypto" version = "0.1.0" -source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#b6590318da760d223022bf4e3b1c42e1ee697242" +source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#8de67ffd1798220a92cc9d72e83529141248d0a2" dependencies = [ "bech32 0.8.1", "cryptoxide 0.4.2", @@ -683,7 +683,7 @@ dependencies = [ [[package]] name = "chain-evm" version = "0.1.0" -source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#b6590318da760d223022bf4e3b1c42e1ee697242" +source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#8de67ffd1798220a92cc9d72e83529141248d0a2" dependencies = [ "aurora-bn", "base64", @@ -712,7 +712,7 @@ dependencies = [ [[package]] name = "chain-impl-mockchain" version = "0.1.0" -source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#b6590318da760d223022bf4e3b1c42e1ee697242" +source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#8de67ffd1798220a92cc9d72e83529141248d0a2" dependencies = [ "cardano-legacy-address", "chain-addr", @@ -744,7 +744,7 @@ dependencies = [ [[package]] name = "chain-network" version = "0.1.0" -source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#b6590318da760d223022bf4e3b1c42e1ee697242" +source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#8de67ffd1798220a92cc9d72e83529141248d0a2" dependencies = [ "async-trait", "chain-crypto", @@ -761,7 +761,7 @@ dependencies = [ [[package]] name = "chain-ser" version = "0.1.0" -source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#b6590318da760d223022bf4e3b1c42e1ee697242" +source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#8de67ffd1798220a92cc9d72e83529141248d0a2" dependencies = [ "thiserror", ] @@ -769,7 +769,7 @@ dependencies = [ [[package]] name = "chain-storage" version = "0.1.0" -source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#b6590318da760d223022bf4e3b1c42e1ee697242" +source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#8de67ffd1798220a92cc9d72e83529141248d0a2" dependencies = [ "criterion", "data-pile", @@ -782,7 +782,7 @@ dependencies = [ [[package]] name = "chain-time" version = "0.1.0" -source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#b6590318da760d223022bf4e3b1c42e1ee697242" +source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#8de67ffd1798220a92cc9d72e83529141248d0a2" dependencies = [ "chain-core", "chain-ser", @@ -794,7 +794,7 @@ dependencies = [ [[package]] name = "chain-vote" version = "0.1.0" -source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#b6590318da760d223022bf4e3b1c42e1ee697242" +source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#8de67ffd1798220a92cc9d72e83529141248d0a2" dependencies = [ "cfg-if 0.1.10", "chain-core", @@ -2261,7 +2261,7 @@ dependencies = [ [[package]] name = "imhamt" version = "0.1.0" -source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#b6590318da760d223022bf4e3b1c42e1ee697242" +source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#8de67ffd1798220a92cc9d72e83529141248d0a2" dependencies = [ "proptest", "rustc_version", @@ -4705,7 +4705,7 @@ dependencies = [ [[package]] name = "sparse-array" version = "0.1.0" -source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#b6590318da760d223022bf4e3b1c42e1ee697242" +source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#8de67ffd1798220a92cc9d72e83529141248d0a2" [[package]] name = "spin" @@ -5466,7 +5466,7 @@ dependencies = [ [[package]] name = "typed-bytes" version = "0.1.0" -source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#b6590318da760d223022bf4e3b1c42e1ee697242" +source = "git+https://github.com/input-output-hk/chain-libs.git?branch=master#8de67ffd1798220a92cc9d72e83529141248d0a2" [[package]] name = "typenum" diff --git a/doc/api/v0.yaml b/doc/api/v0.yaml index 09f3c9132f..db25766380 100644 --- a/doc/api/v0.yaml +++ b/doc/api/v0.yaml @@ -20,6 +20,7 @@ tags: - name: stake - name: utils - name: vote + - name: address_mapping paths: '/api/v0/account/{account_id}': @@ -2415,3 +2416,53 @@ components: description: upper bound of the available options, maximum being 16 (not included) minimum: 1 maximum: 15 + +# it is only enabled with the "evm" feature included during the build +path: + /api/evm/address_mapping/jormungandr_address/{evm_hex_id}: + get: + description: Gets corresponded, mapped jormungadr address for the provided evm address + operationId: AddressMappingJorId + tags: + - address_mapping + parameters: + - in: path + name: evm_hex_id + required: true + description: Hex-encoded evm address. + schema: + type: string + pattern: '[0-9a-f]+' + responses: + '200': + description: Success + content: + application/json: + schema: + type: string + description: hex encoded jormungandr address + +# it is only enabled with the "evm" feature included during the build +path: + /api/evm/address_mapping/evm_address/{jor_hex_id}: + get: + description: Gets corresponded, mapped evm address for the provided jormungandr address + operationId: AddressMappingEvmId + tags: + - address_mapping + parameters: + - in: path + name: jor_hex_id + required: true + description: Hex-encoded jormungandr address. + schema: + type: string + pattern: '[0-9a-f]+' + responses: + '200': + description: Success + content: + application/json: + schema: + type: string + description: hex encoded evm address diff --git a/jormungandr/src/rest/mod.rs b/jormungandr/src/rest/mod.rs index e1f2c54d82..b6cba2a828 100644 --- a/jormungandr/src/rest/mod.rs +++ b/jormungandr/src/rest/mod.rs @@ -25,9 +25,10 @@ pub async fn start_rest_server(config: Config, context: ContextLock) { .write() .await .set_rest_server_stopper(ServerStopper::new(stopper_tx)); + let api = v0::filter(context.clone()).or(v1::filter(context.clone())); let api = warp::path!("api" / ..) - .and(v0::filter(context.clone()).or(v1::filter(context.clone()))) + .and(api) .with(warp::filters::trace::trace(|info| { use http_zipkin::get_trace_context; use tracing::field::Empty; diff --git a/jormungandr/src/rest/v0/handlers.rs b/jormungandr/src/rest/v0/handlers.rs index b70135fca5..ab41816287 100644 --- a/jormungandr/src/rest/v0/handlers.rs +++ b/jormungandr/src/rest/v0/handlers.rs @@ -258,3 +258,26 @@ pub async fn get_active_vote_plans(context: ContextLock) -> Result Result { + let context = context.read().await; + logic::get_jor_address(&context, &evm_id_hex) + .await + .map_err(warp::reject::custom) +} + +#[cfg(feature = "evm")] +pub async fn get_evm_address( + evm_id_hex: String, + context: ContextLock, +) -> Result { + let context = context.read().await; + logic::get_evm_address(&context, &evm_id_hex) + .await + .map_err(warp::reject::custom) + .map(|r| warp::reply::json(&r)) +} diff --git a/jormungandr/src/rest/v0/logic.rs b/jormungandr/src/rest/v0/logic.rs index b47c797f9f..131c675f9c 100644 --- a/jormungandr/src/rest/v0/logic.rs +++ b/jormungandr/src/rest/v0/logic.rs @@ -79,6 +79,9 @@ pub enum Error { Hex(#[from] hex::FromHexError), #[error("Could not process fragment")] Fragment(FragmentsProcessingSummary), + #[cfg(feature = "evm")] + #[error("Can not parse address: {0}")] + AddressParseError(String), } fn parse_account_id(id_hex: &str) -> Result { @@ -591,3 +594,32 @@ pub async fn get_active_vote_plans(context: &Context) -> Result Result { + Ok(context + .blockchain_tip()? + .get_ref() + .await + .ledger() + .jormungandr_mapped_address( + &chain_evm::Address::from_str(evm_id_hex) + .map_err(|e| Error::AddressParseError(e.to_string()))?, + ) + .to_string()) +} + +#[cfg(feature = "evm")] +pub async fn get_evm_address(context: &Context, jor_id_hex: &str) -> Result, Error> { + Ok(context + .blockchain_tip()? + .get_ref() + .await + .ledger() + .evm_mapped_address( + &PublicKey::::from_str(jor_id_hex) + .map_err(|e| Error::AddressParseError(e.to_string()))? + .into(), + ) + .map(|val| val.to_string())) +} diff --git a/jormungandr/src/rest/v0/mod.rs b/jormungandr/src/rest/v0/mod.rs index f54bbd4aa5..e9c6e582a6 100644 --- a/jormungandr/src/rest/v0/mod.rs +++ b/jormungandr/src/rest/v0/mod.rs @@ -222,12 +222,31 @@ pub fn filter( let vote_plans = warp::path!("plans") .and(warp::get()) - .and(with_context) + .and(with_context.clone()) .and_then(handlers::get_active_vote_plans) .boxed(); root.and(committees.or(vote_plans)).boxed() }; + #[cfg(feature = "evm")] + let address_mapping = { + let root = warp::path!("address_mapping" / ..); + + let get_jor_address = warp::path!("jormungandr_address" / String) + .and(warp::get()) + .and(with_context.clone()) + .and_then(handlers::get_jor_address) + .boxed(); + + let get_evm_address = warp::path!("evm_address" / String) + .and(warp::get()) + .and(with_context) + .and_then(handlers::get_evm_address) + .boxed(); + + root.and(get_jor_address.or(get_evm_address)).boxed() + }; + let routes = shutdown .or(account) .or(block) @@ -244,10 +263,12 @@ pub fn filter( .or(rewards) .or(utxo) .or(diagnostic) - .or(votes) - .boxed(); + .or(votes); + + #[cfg(feature = "evm")] + let routes = routes.or(address_mapping); - root.and(routes).recover(handle_rejection).boxed() + root.and(routes.boxed()).recover(handle_rejection).boxed() } /// Convert rejections to actual HTTP errors diff --git a/jormungandr/src/rest/v1/mod.rs b/jormungandr/src/rest/v1/mod.rs index aba98db174..3a988155d0 100644 --- a/jormungandr/src/rest/v1/mod.rs +++ b/jormungandr/src/rest/v1/mod.rs @@ -54,11 +54,9 @@ pub fn filter( .and(with_context) .and_then(handlers::get_accounts_votes_count); - let routes = fragments; + let routes = fragments.or(votes_with_plan).or(votes).or(votes_count); - root.and(routes.or(votes_with_plan).or(votes).or(votes_count)) - .recover(handle_rejection) - .boxed() + root.and(routes).recover(handle_rejection).boxed() } /// Convert rejections to actual HTTP errors diff --git a/jormungandr/src/topology/topology.rs b/jormungandr/src/topology/topology.rs index 7b22bf068b..1dc6e34480 100644 --- a/jormungandr/src/topology/topology.rs +++ b/jormungandr/src/topology/topology.rs @@ -103,7 +103,7 @@ impl LayerBuilder for CustomLayerBuilder { impl P2pTopology { pub fn new(config: &Configuration, stats_counter: Metrics) -> Self { - let addr = config.public_address.or(Some(*LOCAL_ADDR)).unwrap(); + let addr = config.public_address.unwrap_or(*LOCAL_ADDR); let key = secret_key_into_keynesis(config.node_key.clone()); let quarantine = ReportRecords::from_config(config.policy.clone());