Skip to content

Commit

Permalink
feat(cactus-example-electricity-trade): use openapi ethereum connector
Browse files Browse the repository at this point in the history
- Refactor electricity trade sample to use openapi ethereum connector instead
    of ethereum-socketio.
- Sample still uses offline signing from cmd-socketio-server
- Handle case in ethereum connector where receipt doesn't contain status.
- Add sawtooth test-ledger script to wait until docker is fully started before
    proceeding forward.
- Remove periodicExecuter from sample app (didn't work and not used

Signed-off-by: Michal Bajer <michal.bajer@fujitsu.com>
  • Loading branch information
outSH authored and petermetz committed Oct 4, 2023
1 parent c9316eb commit 9e66850
Show file tree
Hide file tree
Showing 26 changed files with 322 additions and 586 deletions.
63 changes: 0 additions & 63 deletions examples/cactus-example-electricity-trade/BalanceManagement.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ import {
ConfigUtil,
LPInfoHolder,
} from "@hyperledger/cactus-cmd-socketio-server";
import { makeRawTransaction } from "./TransactionEthereum";
import { sendEthereumTransaction } from "./TransactionEthereum";

//const config: any = JSON.parse(fs.readFileSync("/etc/cactus/default.json", 'utf8'));
const config: any = ConfigUtil.getConfig() as any;
import { getLogger } from "log4js";
import {
Expand All @@ -42,16 +41,6 @@ interface SawtoothEventData {
blockData: [];
}

interface EthData {
hash: string;
}

interface EthEvent {
blockData: { transactions: { [key: string]: EthData } };
hash: string;
status: number;
}

interface SawtoothBlockDataData {
header_signature: string;
hash: string;
Expand Down Expand Up @@ -130,67 +119,27 @@ export class BusinessLogicElectricityTrade extends BusinessLogicBase {
return;
}

const txParam: {
fromAddress: string;
fromAddressPkey: string;
toAddress: string;
amount: number;
gas: number;
} = {
fromAddress: accountInfo["fromAddress"],
fromAddressPkey: accountInfo["fromAddressPkey"],
toAddress: accountInfo["toAddress"],
amount: Number(transactionSubset["Value"]),
gas: config.electricityTradeInfo.ethereum.gas,
};
logger.debug(`####txParam = ${json2str(txParam)}`);

// Get Verifier Instance
logger.debug(
`##remittanceTransaction(): businessLogicID: ${this.businessLogicID}`,
);
const useValidator = JSON.parse(
routesTransactionManagement.getValidatorToUse(this.businessLogicID),
);
// const verifierEthereum = routesTransactionManagement.getVerifier(useValidator['validatorID'][1]);
const verifierEthereum = routesVerifierFactory.getVerifier(
useValidator["validatorID"][1],
);
verifierEthereum.startMonitor(
"BusinessLogicElectricityTrade",
{},
routesTransactionManagement,
);
logger.debug("getVerifierEthereum");

interface RawTransationResultData {
args: unknown;
}
// Generate parameters for// sendRawTransaction
logger.debug(`####exec makeRawTransaction!!`);
makeRawTransaction(txParam)
sendEthereumTransaction(
{
to: accountInfo["toAddress"],
value: Number(transactionSubset["Value"]),
gas: config.electricityTradeInfo.ethereum.gas,
},
accountInfo["fromAddress"],
accountInfo["fromAddressPkey"],
)
.then((result) => {
logger.info("remittanceTransaction txId : " + result.txId);
// Set Parameter
logger.debug("remittanceTransaction data : " + json2str(result.data));
const contract = {}; // NOTE: Since contract does not need to be specified, specify an empty object.
const method = { type: "web3Eth", command: "sendSignedTransaction" };
const args: RawTransationResultData = {
args: [result.data["serializedTx"]],
};

// Run Verifier (Ethereum)
verifierEthereum
.sendAsyncRequest(contract, method, args)
.then(() => {
logger.debug(`##remittanceTransaction sendAsyncRequest finish`);
})
.catch((err) => {
logger.error(err);
});
logger.info(
"remittanceTransaction txId : " +
result.transactionReceipt.transactionHash,
);
logger.debug(`##remittanceTransaction sendAsyncRequest finish`);
})
.catch((err) => {
logger.error(err);
logger.error("sendEthereumTransaction remittance ERROR:", err);
});
}

Expand All @@ -203,10 +152,6 @@ export class BusinessLogicElectricityTrade extends BusinessLogicBase {
switch (ledgerEvent.verifierId) {
case config.electricityTradeInfo.sawtooth.validatorID:
this.onEventSawtooth(ledgerEvent.data, targetIndex);
break;
case config.electricityTradeInfo.ethereum.validatorID:
this.onEventEthereum(ledgerEvent.data, targetIndex);

break;
default:
logger.error(
Expand Down Expand Up @@ -263,52 +208,6 @@ export class BusinessLogicElectricityTrade extends BusinessLogicBase {
}
}

onEventEthereum(event: EthEvent, targetIndex: number): void {
logger.debug(`##in onEventEthereum()`);
const tx = this.getTransactionFromEthereumEvent(event, targetIndex);
if (tx == null) {
logger.error(`##onEventEthereum(): invalid event: ${json2str(event)}`);
return;
}

try {
const txId = tx["hash"];
const status = event["status"];

logger.debug(`##txId = ${txId}`);
logger.debug(`##status =${status}`);

if (status !== 200) {
logger.error(
`##onEventEthereum(): error event, status: ${status}, txId: ${txId}`,
);
return;
}
} catch (err) {
logger.error(
`##onEventEthereum(): err: ${err}, event: ${json2str(event)}`,
);
}
}

getTransactionFromEthereumEvent(
event: EthEvent,
targetIndex: number,
): EthData | undefined {
try {
const retTransaction = event["blockData"]["transactions"][targetIndex];
logger.debug(
`##getTransactionFromEthereumEvent(), retTransaction: ${retTransaction}`,
);
return retTransaction;
// return (retTransaction as unknown) as EthEvent;
} catch (err) {
logger.error(
`##getTransactionFromEthereumEvent(): invalid even, err:${err}, event:${event}`,
);
}
}

getOperationStatus(): Record<string, unknown> {
logger.debug(`##in getOperationStatus()`);
return {};
Expand All @@ -324,8 +223,6 @@ export class BusinessLogicElectricityTrade extends BusinessLogicBase {
switch (ledgerEvent.verifierId) {
case config.electricityTradeInfo.sawtooth.validatorID:
return this.getTxIDFromEventSawtooth(ledgerEvent.data, targetIndex);
case config.electricityTradeInfo.ethereum.validatorID:
return this.getTxIDFromEventEtherem(ledgerEvent.data, targetIndex);
default:
logger.error(
`##getTxIDFromEvent(): invalid verifierId: ${ledgerEvent.verifierId}`,
Expand Down Expand Up @@ -367,38 +264,6 @@ export class BusinessLogicElectricityTrade extends BusinessLogicBase {
}
}

getTxIDFromEventEtherem(event: EthEvent, targetIndex: number): string | null {
logger.debug(`##in getTxIDFromEventEtherem()`);
const tx = this.getTransactionFromEthereumEvent(event, targetIndex);
if (tx == null) {
logger.warn(`#getTxIDFromEventEtherem(): skip(not found tx)`);
return null;
}

try {
const txId = tx["hash"];

if (typeof txId !== "string") {
logger.warn(
`#getTxIDFromEventEtherem(): skip(invalid block, not found txId.), event: ${json2str(
event,
)}`,
);

return null;
}

logger.debug(`###getTxIDFromEventEtherem(): txId: ${txId}`);

return txId;
} catch (err) {
logger.error(
`##getTxIDFromEventEtherem(): err: ${err}, event: ${json2str(event)}`,
);
return null;
}
}

getEventDataNum(ledgerEvent: LedgerEvent): number {
logger.debug(
`##in BLP:getEventDataNum(), ledgerEvent.verifierId: ${ledgerEvent.verifierId}`,
Expand All @@ -413,9 +278,6 @@ export class BusinessLogicElectricityTrade extends BusinessLogicBase {
case config.electricityTradeInfo.sawtooth.validatorID:
retEventNum = event["blockData"].length;
break;
case config.electricityTradeInfo.ethereum.validatorID:
retEventNum = event["blockData"]["transactions"].length;
break;
default:
logger.error(
`##getEventDataNum(): invalid verifierId: ${ledgerEvent.verifierId}`,
Expand Down
19 changes: 6 additions & 13 deletions examples/cactus-example-electricity-trade/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ In this example, we use the Sawtooth intkey transaction processor as an applicat

- Available ports:
- `5034`: the port of `cactus-cmd-socketio-server`
- `5050`: the port of `cactus-plugin-ledger-connector-go-ethereum-socketio`
- `5140`: the port of `cactus-plugin-ledger-connector-sawtooth-socketio`
- You can modify port exported to the host in `./docker-compose.yml`
- Available directory (This directory must be empty):
Expand Down Expand Up @@ -60,11 +59,6 @@ In this example, we use the Sawtooth intkey transaction processor as an applicat
```
cmd-socketio-base-dummy | OK - Exit
cmd-socketio-base-dummy exited with code 0
cactus-example-electricity-trade-ethereum-validator |
cactus-example-electricity-trade-ethereum-validator | > @hyperledger/cactus-plugin-ledger-connector-go-ethereum-socketio@1.0.0-rc.3 start /root/cactus
cactus-example-electricity-trade-ethereum-validator | > cd ./dist && node common/core/bin/www.js
cactus-example-electricity-trade-ethereum-validator |
cactus-example-electricity-trade-ethereum-validator | listening on *:5050
cactus-example-electricity-trade-sawtooth-validator |
cactus-example-electricity-trade-sawtooth-validator | > @hyperledger/cactus-plugin-ledger-connector-sawtooth-socketio@1.0.0-rc.3 start /root/cactus
cactus-example-electricity-trade-sawtooth-validator | > cd ./dist && node common/core/bin/www.js
Expand All @@ -83,8 +77,7 @@ For development purposes, it might be useful to run the sample application outsi

1. Configure cactus and start the ledgers as described above.
1. Run `./script-dockerless-config-patch.sh` from `cactus-example-electricity-trade/` directory. This will patch the configs and copy it to global location.
1. Start validators (each in separate cmd window).
1. `cd packages/cactus-plugin-ledger-connector-go-ethereum-socketio/ && npm run start`
1. Start sawtooth validators (in separate cmd window, ethereum connector started as part of BLP).
1. `cd packages/cactus-plugin-ledger-connector-sawtooth-socketio/ && npm run start`
1. Start electricity-trade: `npm run start-dockerless`

Expand All @@ -103,10 +96,10 @@ For development purposes, it might be useful to run the sample application outsi

```
# Source Eth balance:
{"status":200,"amount":100000}
100000
# Destination Eth balance:
{"status":200,"amount":0}
0
# Electricity usage
```
Expand Down Expand Up @@ -155,18 +148,18 @@ For development purposes, it might be useful to run the sample application outsi
}
```

1. (Optional) Check the balance on Ethereum accounts using the following script
1. (Optional) Check the balance on Ethereum accounts using the following script (after `##remittanceTransaction sendAsyncRequest finish` is printed)

- `./script-get-app.sh`

The result looks like the following:

```
# Source Eth balance:
{"status":200,"amount":99976}
99976
# Destination Eth balance:
{"status":200,"amount":24}
24
# Electricity usage
MI000001: 74
Expand Down
Loading

0 comments on commit 9e66850

Please sign in to comment.