Skip to content

Commit

Permalink
feat(connector-iroha): adds connector plugin
Browse files Browse the repository at this point in the history
1. Enables Cactus to manipulate Iroha ledger
2. Supports 19/20 commands and 14/15 queries of the Iroha ledger
3. Possibility of starting Iroha and Postgres with random ports
4. Possibility of passing arbitrary Iroha admin/node keypairs to the test ledger
5. Offers a comprehensive transaction test suite to validate support for Iroha commands and queries
6. Provides an example of asset transfer between two separate Iroha nodes

Signed-off-by: im8a <xuhan@lafayette.edu>
  • Loading branch information
hanxu12 authored and petermetz committed Aug 30, 2021
1 parent d9f6d5d commit 4745df0
Show file tree
Hide file tree
Showing 43 changed files with 4,295 additions and 6 deletions.
1 change: 1 addition & 0 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"myapp",
"mychannel",
"myroot",
"mysecretpassword",
"myvolume",
"Nerc",
"NETWORKSCOPEALLFORTX",
Expand Down
17 changes: 17 additions & 0 deletions docs/source/support/iroha.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Iroha Support
-----------------

```{note}
The deployContract feature not yet implemented since Iroha lacks full smart contract support during the initial development stage of the Iroha connector plugin.
```

<details>
<summary>Hyperledger Cactus v0.9.0</summary>

| Iroha version | runTransaction |
| --- | :---: |
| Iroha 1.2.0 and Postgres 9.5 |[test](https://github.com/hyperledger/cactus/blob/v0.9.0/packages/cactus-plugin-ledger-connector-iroha/src/test/typescript/integration/run-transaction-endpoint-v1.test.ts) |

</details>

<br>
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"test:plugin-htlc-besu-erc20": "tap --jobs=1 --timeout=600 \"packages/*htlc-eth-besu-erc20/src/test/typescript/{unit,integration}/\"",
"test:plugin": "tap --jobs=1 --timeout=600 \"packages/*test-plugin-htlc-eth-besu/src/test/typescript/{unit,integration}/\"",
"test:plugin-ledger-connector-quorum": "tap --ts --jobs=1 --timeout=60 \"packages/cactus-*-quorum/src/test/typescript/{unit,integration}/\"",
"test:plugin-ledger-connector-iroha": "tap --ts --jobs=1 --timeout=600 \"packages/cactus-*-iroha/src/test/typescript/{unit,integration}/\"",
"test:plugin-htlc-besu": "tap --jobs=1 --timeout=600 \"packages/*htlc-eth-besu/src/test/typescript/{integration}/\"",
"test:plugin-ledger-connector-corda": "tap --ts --jobs=1 --timeout=600 \"packages/cactus-*-corda/src/test/typescript/{unit,integration}/\"",
"webpack": "npm-run-all webpack:dev webpack:prod",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export class Http405NotAllowedError extends Error {}
1 change: 1 addition & 0 deletions packages/cactus-common/src/main/typescript/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ export { ISignerKeyPair } from "./signer-key-pair";
export { Secp256k1Keys } from "./secp256k1-keys";
export { KeyFormat, KeyConverter } from "./key-converter";
export { IAsyncProvider } from "./i-async-provider";
export { Http405NotAllowedError } from "./http/http-status-code-errors";
5 changes: 5 additions & 0 deletions packages/cactus-plugin-ledger-connector-iroha/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM ghcr.io/hyperledger/cactus-cmd-api-server:2021-08-15--refactor-1222

ARG NPM_PKG_VERSION=latest

RUN npm i @hyperledger/cactus-plugin-ledger-connector-iroha@${NPM_PKG_VERSION} --production
235 changes: 235 additions & 0 deletions packages/cactus-plugin-ledger-connector-iroha/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
# `@hyperledger/cactus-plugin-ledger-connector-iroha`

This plugin provides `Cactus` a way to interact with Iroha networks. Using this we can perform:
* Run various Iroha leger commands and queries.
* Build and sign transactions using any arbitrary credential.
## Summary

- [Getting Started](#getting-started)
- [Architecture](#architecture)
- [Usage](#usage)
- [Runing the tests](#running-the-tests)
- [Built With](#built-with)
- [Contributing](#contributing)
- [License](#license)
- [Acknowledgments](#acknowledgments)

## Getting Started

Clone the git repository on your local machine. Follow these instructions that will get you a copy of the project up and running on your local machine for development and testing purposes.

### Prerequisites

In the root of the project, execute the command to install the dependencies:
```sh
yarn run configure
```

### Compiling

In the project root folder, run this command to compile the plugin and create the dist directory:
```sh
# For one off builds:
yarn run build:dev:backend
```

```sh
# For continuous watching of the source code with
# automatic recompilation (more convenient)
yarn run watch
```

### Architecture
The sequence diagrams for various endpoints are mentioned below

#### run-transaction-endpoint
![run-transaction-endpoint sequence diagram](docs/architecture/images/run-transaction-endpoint.png)

The above diagram shows the sequence diagram of run-transaction-endpoint. User A (One of the many Users) interacts with the API Client which in turn, calls the API server. The API server then executes `transact()` method which is explained in detailed in the subsequent diagrams.

![run-transaction-endpoint transact() method](docs/architecture/images/run-transaction-endpoint-transact.png)

The above diagram shows the sequence diagram of `transact()` method of the `PluginLedgerConnectorIroha` class. The caller to this function, which in reference to the above sequence diagram is API server, sends `RunTransactionRequestV1` object as an argument to the `transact()` method. Based on the exact command name of the request, corresponsing response `RunTransactionResponse` is sent back to the caller.

### Usage

To use this import public-api and create new **PluginFactoryLedgerConnector**. Then use it to create a connector.
```typescript
const factory = new PluginFactoryLedgerConnector({
pluginImportType: PluginImportType.Local,
});

const connector: PluginLedgerConnectorIroha = await factory.create({
rpcToriiPortHost,
instanceId: uuidv4(),
pluginRegistry: new PluginRegistry(),
});
```
You can make calls through the connector to the plugin API:

```typescript
async transact(req: RunTransactionRequestV1):Promise<RunTransactionResponse>;
```

Call example to run an Iroha execute account command:
```typescript
const req = {
commandName: IrohaCommand.CreateAccount,
baseConfig: {
irohaHost: "localhost",
irohaPort: 50051,
creatorAccountId: "admin@test",
privKey: ["f101537e319568c765b2cc89698325604991dca57b9716b58016b253506cab70"],
quorum: 1,
timeoutLimit: 5000,
},
const res = await apiClient.runTransactionV1(req);
```
Call example to run an Iroha get account query:
```typescript
const req = {
commandName: IrohaQuery.GetAccount,
baseConfig: {
irohaHost: "localhost",
irohaPort: 50051,
creatorAccountId: "admin@test",
privKey: ["f101537e319568c765b2cc89698325604991dca57b9716b58016b253506cab70"],
quorum: 1,
timeoutLimit: 5000,
},
params: ["admin@test"],
};
const res = await apiClient.runTransactionV1(req);
```
> Extensive documentation and examples in the [readthedocs](https://readthedocs.org/projects/hyperledger-cactus/) (WIP)

### Building/running the container image locally

In the Cactus project root say:

```sh
DOCKER_BUILDKIT=1 docker build -f ./packages/cactus-plugin-ledger-connector-iroha/Dockerfile . -t cplcb
```

Build with a specific version of the npm package:
```sh
DOCKER_BUILDKIT=1 docker build --build-arg NPM_PKG_VERSION=latest -f ./packages/cactus-plugin-ledger-connector-iroha/Dockerfile . -t cplcb
```

#### Running the container

Launch container with plugin configuration as an **environment variable**:
```sh
docker run \
--rm \
--publish 3000:3000 \
--publish 4000:4000 \
--publish 5000:5000 \
--env PLUGINS='[{"packageName": "@hyperledger/cactus-plugin-ledger-connector-iroha", "type": "org.hyperledger.cactus.plugin_import_type.LOCAL", "options": {"rpcApiHttpHost": "http://localhost:8545", "instanceId": "some-unique-iroha-connector-instance-id"}}]' \
cplcb
```

Launch container with plugin configuration as a **CLI argument**:
```sh
docker run \
--rm \
--publish 3000:3000 \
--publish 4000:4000 \
--publish 5000:5000 \
cplcb \
./node_modules/.bin/cactusapi \
--plugins='[{"packageName": "@hyperledger/cactus-plugin-ledger-connector-iroha", "type": "org.hyperledger.cactus.plugin_import_type.LOCAL", "options": {"rpcApiHttpHost": "http://localhost:8545", "instanceId": "some-unique-iroha-connector-instance-id"}}]'
```

Launch container with **configuration file** mounted from host machine:
```sh

echo '[{"packageName": "@hyperledger/cactus-plugin-ledger-connector-iroha", "type": "org.hyperledger.cactus.plugin_import_type.LOCAL", "options": {"rpcApiHttpHost": "http://localhost:8545", "instanceId": "some-unique-iroha-connector-instance-id"}}]' > cactus.json

docker run \
--rm \
--publish 3000:3000 \
--publish 4000:4000 \
--publish 5000:5000 \
--mount type=bind,source="$(pwd)"/cactus.json,target=/cactus.json \
cplcb \
./node_modules/.bin/cactusapi \
--config-file=/cactus.json
```

#### Testing API calls with the container

Don't have an Iroha network on hand to test with? Test or develop against our Iroha All-In-One dockerfile!

**Terminal Window 1 (Ledger)**
```sh
docker run -p 0.0.0.0:8545:8545/tcp -p 0.0.0.0:8546:8546/tcp -p 0.0.0.0:8888:8888/tcp -p 0.0.0.0:9001:9001/tcp -p 0.0.0.0:9545:9545/tcp hyperledger/cactus-iroha-all-in-one:latest
```

**Terminal Window 2 (Cactus API Server)**
```sh
docker run \
--network host \
--rm \
--publish 3000:3000 \
--publish 4000:4000 \
--publish 5000:5000 \
--env PLUGINS='[{"packageName": "@hyperledger/cactus-plugin-ledger-connector-iroha", "type": "org.hyperledger.cactus.plugin_import_type.LOCAL", "options": {"rpcApiHttpHost": "http://localhost:8545", "instanceId": "some-unique-iroha-connector-instance-id"}}]' \
cplcb
```

**Terminal Window 3 (curl - replace transaction request as needed)**
```sh
curl --location --request POST 'http://127.0.0.1:4000/api/v1/plugins/@hyperledger/cactus-plugin-ledger-connector-iroha/run-transaction' \
--header 'Content-Type: application/json' \
--data-raw '{
commandName: 'createAsset',
baseConfig: {
irohaHost: 'localhost',
irohaPort: 50051,
creatorAccountId: 'admin@test',
privKey: [
'f101537e319568c765b2cc89698325604991dca57b9716b58016b253506cab70'
],
quorum: 1,
timeoutLimit: 5000
},
params: [ 'coolcoin', 'test', 3]
}'
```

The above should produce a response that looks similar to this:

```json
{
"success": true,
"data": {
"transactionReceipt": {
"txHash": "c3ffd772f26950243aa357ab4f21b9703d5172490b66ddc285355230d6df60b8",
"status": "COMMITTED"
}
}
}
```

## Running the tests

To check that all has been installed correctly and that the plugin has no errors run the tests:

* Run this command at the project's root:
```sh
yarn run test:plugin-ledger-connector-iroha
```

## Contributing

We welcome contributions to Hyperledger Cactus in many forms, and there’s always plenty to do!

Please review [CONTIRBUTING.md](../../CONTRIBUTING.md) to get started.

## License

This distribution is published under the Apache License Version 2.0 found in the [LICENSE](../../LICENSE) file.

## Acknowledgments
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
@startuml
title Hyperledger Cactus\nSequence Diagram\nRun Transaction Endpoint\ntransact() method

skinparam sequenceArrowThickness 2
skinparam roundcorner 20
skinparam maxmessagesize 120
skinparam sequenceParticipant underline

actor "Caller" as caller
participant "PluginLedgerConnectorIroha" as t << (C,#ADD1B2) class >>

autoactivate on

activate caller
caller -> t: transact(RunTransactionRequest)

alt #LightBlue commandName is an Iroha command
t -> t: generate Iroha commandOptions
return RunTransactionResponse
t --> caller: return RunTransactionResponse
else #LightGreen commandName is an Iroha query
t -> t: generate Iroha queryOptions
return RunTransactionResponse
t --> caller: return RunTransactionResponse
else #LightCoral default
t --> caller: throw RuntimeError("command or query does not exist)
end
@enduml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
@startuml Sequence Diagram - Transaction

title Hyperledger Cactus\nSequence Diagram\nRun Transaction Endpoint

skinparam sequenceArrowThickness 2
skinparam roundcorner 20
skinparam maxmessagesize 120
skinparam sequenceParticipant underline

box "Users" #LightBlue
actor "User A" as a
end box

box "Hyperledger Cactus" #LightGray
entity "API Client" as apic
entity "API Server" as apis
end box

box "Ledger Connector" #LightGreen
database "Iroha" as irohacon
end box

a --> apic : Tx Iroha Ledger
apic --> apis: Request
apis --> irohacon: transact()
irohacon --> apis: Response
apis --> apic: Formatted Response
apic --> a: RunTransactionResponse
@enduml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"$schema": "node_modules/@openapitools/openapi-generator-cli/config.schema.json",
"spaces": 2,
"generator-cli": {
"version": "5.1.1"
}
}
Loading

0 comments on commit 4745df0

Please sign in to comment.