From 3e4945b37f13c36ecaafb0c44e2f59ae25cd5279 Mon Sep 17 00:00:00 2001 From: Takuma TAKEUCHI Date: Tue, 2 Feb 2021 08:22:02 +0900 Subject: [PATCH] feat(examples): add an example app using Sawtooth and Go-Ethereum Signed-off-by: Takuma TAKEUCHI --- .../BusinessLogicElectricityTrade.ts | 316 +++++++++++ examples/electricity-trade/RequestInfo.ts | 34 ++ .../electricity-trade/TransactionEthereum.ts | 109 ++++ .../electricity-trade/config/BLP_config.ts | 21 + .../electricity-trade/config/default.json | 39 ++ .../electricity-trade/config/usersetting.json | 26 + examples/electricity-trade/copyBLPConfig.ts | 13 + .../electricity-trade/copyStaticAssets.ts | 15 + examples/electricity-trade/package.json | 39 ++ .../electricity-trade/replaceBLPConfigPath.ts | 22 + examples/electricity-trade/tsconfig.json | 80 +++ examples/electricity-trade/tslint.json | 28 + packages/business-logic-plugin/app.ts | 12 +- packages/config/default.json | 4 + packages/config/verifier-config.json | 9 + .../validator/src/core/config/default.ts | 2 +- .../src/core/validatorKey/keysUr7d10R.priv | 8 + .../validatorKey/sUr7d10R/keysUr7d10R.crt | 10 + packages/routing-interface/BlockMonitor.ts | 55 ++ .../TransactionManagement.ts | 16 +- .../routing-interface/routes/blockmonitor.ts | 51 ++ .../routes/electricity-trade.ts | 66 +++ tools/docker/sawtooth-testnet/README.md | 15 + tools/docker/sawtooth-testnet/copy-debs.yaml | 134 +++++ tools/docker/sawtooth-testnet/external.yaml | 50 ++ tools/docker/sawtooth-testnet/run-lint.yaml | 57 ++ .../sawtooth-testnet/sawtooth-build.yaml | 117 ++++ .../sawtooth-testnet/sawtooth-debug.yaml | 121 +++++ .../sawtooth-default-pbft.yaml | 454 ++++++++++++++++ .../sawtooth-default-poet.yaml | 500 ++++++++++++++++++ .../sawtooth-testnet/sawtooth-default.yaml | 90 ++++ .../sawtooth-testnet/sawtooth-local.yaml | 89 ++++ .../sawtooth-testnet/script-start-docker.sh | 2 + .../smallbank-local-mounted.yaml | 88 +++ 34 files changed, 2679 insertions(+), 13 deletions(-) create mode 100644 examples/electricity-trade/BusinessLogicElectricityTrade.ts create mode 100644 examples/electricity-trade/RequestInfo.ts create mode 100644 examples/electricity-trade/TransactionEthereum.ts create mode 100644 examples/electricity-trade/config/BLP_config.ts create mode 100644 examples/electricity-trade/config/default.json create mode 100644 examples/electricity-trade/config/usersetting.json create mode 100644 examples/electricity-trade/copyBLPConfig.ts create mode 100644 examples/electricity-trade/copyStaticAssets.ts create mode 100644 examples/electricity-trade/package.json create mode 100644 examples/electricity-trade/replaceBLPConfigPath.ts create mode 100644 examples/electricity-trade/tsconfig.json create mode 100644 examples/electricity-trade/tslint.json create mode 100644 packages/ledger-plugin/sawtooth/validator/src/core/validatorKey/keysUr7d10R.priv create mode 100644 packages/ledger-plugin/validatorKey/sUr7d10R/keysUr7d10R.crt create mode 100644 packages/routing-interface/BlockMonitor.ts create mode 100644 packages/routing-interface/routes/blockmonitor.ts create mode 100644 packages/routing-interface/routes/electricity-trade.ts create mode 100644 tools/docker/sawtooth-testnet/README.md create mode 100644 tools/docker/sawtooth-testnet/copy-debs.yaml create mode 100644 tools/docker/sawtooth-testnet/external.yaml create mode 100644 tools/docker/sawtooth-testnet/run-lint.yaml create mode 100644 tools/docker/sawtooth-testnet/sawtooth-build.yaml create mode 100644 tools/docker/sawtooth-testnet/sawtooth-debug.yaml create mode 100644 tools/docker/sawtooth-testnet/sawtooth-default-pbft.yaml create mode 100644 tools/docker/sawtooth-testnet/sawtooth-default-poet.yaml create mode 100644 tools/docker/sawtooth-testnet/sawtooth-default.yaml create mode 100644 tools/docker/sawtooth-testnet/sawtooth-local.yaml create mode 100755 tools/docker/sawtooth-testnet/script-start-docker.sh create mode 100644 tools/docker/sawtooth-testnet/smallbank-local-mounted.yaml diff --git a/examples/electricity-trade/BusinessLogicElectricityTrade.ts b/examples/electricity-trade/BusinessLogicElectricityTrade.ts new file mode 100644 index 0000000000..f5caaf6b8e --- /dev/null +++ b/examples/electricity-trade/BusinessLogicElectricityTrade.ts @@ -0,0 +1,316 @@ +/* + * Copyright 2020 Hyperledger Cactus Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * BusinessLogicElectricityTrade.ts + */ + +import { Request } from 'express'; +import { RequestInfo } from './RequestInfo'; +import { TradeInfo } from '../../packages/routing-interface/TradeInfo'; +import { transactionManagement } from '../../packages/routing-interface/routes/index'; +import { BusinessLogicBase } from '../../packages/business-logic-plugin/BusinessLogicBase'; +import { makeRawTransaction } from './TransactionEthereum' +import { LedgerEvent } from '../../packages/ledger-plugin/LedgerPlugin'; +import { json2str } from '../../packages/ledger-plugin/DriverCommon' + +const fs = require('fs'); +const path = require('path'); +const config: any = JSON.parse(fs.readFileSync(path.resolve(__dirname, "./config/default.json"), 'utf8')); +import { getLogger } from "log4js"; +const moduleName = 'BusinessLogicElectricityTrade'; +const logger = getLogger(`${moduleName}`); +logger.level = config.logLevel; + +export class BusinessLogicElectricityTrade extends BusinessLogicBase { + businessLogicID: string; + + constructor(businessLogicID: string) { + super(); + this.businessLogicID = businessLogicID; + } + + startTransaction(req: Request, businessLogicID: string, tradeID: string) { + + logger.debug("called startTransaction()"); + + // set RequestInfo + const requestInfo: RequestInfo = new RequestInfo(); + requestInfo.businessLogicID = businessLogicID; + + // set TradeID + requestInfo.setTradeID(tradeID); + + // Create trade information + const tradeInfo: TradeInfo = new TradeInfo(requestInfo.businessLogicID, requestInfo.tradeID); + + this.startMonitor(tradeInfo); + } + + startMonitor(tradeInfo: TradeInfo) { + // Get Verifier Instance + logger.debug(`##startMonitor(): businessLogicID: ${tradeInfo.businessLogicID}`); + const useValidator = JSON.parse(transactionManagement.getValidatorToUse(tradeInfo.businessLogicID)); + logger.debug(`filterKey: ${config.electricityTradeInfo.sawtooth.filterKey}`); + const options = { + "filterKey": config.electricityTradeInfo.sawtooth.filterKey + } + const verifierSawtooth = transactionManagement.getVerifier(useValidator['validatorID'][0], options); + logger.debug("getVerifierSawtooth"); + + } + + remittanceTransaction(transactionSubset: object) { + + logger.debug(`called remittanceTransaction(), accountInfo = ${json2str(transactionSubset)}`); + + const accountInfo = this.getAccountInfo(transactionSubset); + if (Object.keys(accountInfo).length === 0) { + logger.debug(`remittanceTransaction(): skip (No target data)`); + 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(transactionManagement.getValidatorToUse(this.businessLogicID)); + const verifierEthereum = transactionManagement.getVerifier(useValidator['validatorID'][1]); + logger.debug("getVerifierEthereum"); + + // Generate parameters for// sendRawTransaction + logger.debug(`####exec makeRawTransaction!!`); + makeRawTransaction(txParam) + .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: "sendRawTransaction"}; + const args = {"args": [result.data["serializedTx"]]}; + + // Run Verifier (Ethereum) + verifierEthereum.requestLedgerOperationNeo(contract, method, args); + }) + .catch(err => { + logger.error(err); + }); + } + + onEvent(ledgerEvent: LedgerEvent, targetIndex: number): void { + logger.debug(`##in BLP:onEvent()`); + logger.debug(`##onEvent(): ${json2str(ledgerEvent['data']['blockData'][targetIndex])}`); + + 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(`##onEvent(), invalid verifierId: ${ledgerEvent.verifierId}`); + return; + } + } + + onEventSawtooth(event: object, targetIndex: number): void { + logger.debug(`##in onEventSawtooth()`); + const tx = this.getTransactionFromSawtoothEvent(event, targetIndex); + if (tx == null) { + logger.error(`##onEventSawtooth(): invalid event: ${json2str(event)}`); + return; + } + + try { + const txId = tx['header_signature']; + logger.debug(`##txId = ${txId}`); + + if (tx['payload_decoded'][0].Verb !== "set") { + const transactionSubset = { + "Name": tx['payload_decoded'][0].Name, + "Value": tx['payload_decoded'][0].Value, + "Verb": tx['payload_decoded'][0].Verb + }; + this.remittanceTransaction(transactionSubset); + } + } + catch (err) { + logger.error(`##onEventSawtooth(): err: ${err}, event: ${json2str(event)}`); + } + } + + getTransactionFromSawtoothEvent(event: object, targetIndex: number): object | null { + try { + const retTransaction = event['blockData'][targetIndex]; + logger.debug(`##getTransactionFromSawtoothEvent(), retTransaction: ${retTransaction}`); + return retTransaction; + } + catch (err) { + logger.error(`##getTransactionFromSawtoothEvent(): invalid even, err:${err}, event:${event}`); + } + } + + onEventEthereum(event: object, 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: object, targetIndex: number): object | null { + try { + const retTransaction = event['blockData']['transactions'][targetIndex]; + logger.debug(`##getTransactionFromEthereumEvent(), retTransaction: ${retTransaction}`); + return retTransaction; + } + catch (err) { + logger.error(`##getTransactionFromEthereumEvent(): invalid even, err:${err}, event:${event}`); + } + } + + getOperationStatus(tradeID: string): object { + logger.debug(`##in getOperationStatus()`); + return {}; + } + + getTxIDFromEvent(ledgerEvent: LedgerEvent, targetIndex: number): string | null { + logger.debug(`##in getTxIDFromEvent`); +// logger.debug(`##event: ${json2str(ledgerEvent)}`); + + 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}`); + } + return null; + } + + getTxIDFromEventSawtooth(event: object, targetIndex: number): string | null { + logger.debug(`##in getTxIDFromEventSawtooth()`); + const tx = this.getTransactionFromSawtoothEvent(event, targetIndex); + if (tx == null) { + logger.warn(`#getTxIDFromEventSawtooth(): skip(not found tx)`); + return null; + } + + try { + const txId = tx['header_signature']; + + if (typeof txId !== 'string') { + logger.warn(`#getTxIDFromEventSawtooth(): skip(invalid block, not found txId.), event: ${json2str(event)}`); + return null; + } + + logger.debug(`###getTxIDFromEventSawtooth(): txId: ${txId}`); + return txId; + + } + catch (err) { + logger.error(`##getTxIDFromEventSawtooth(): err: ${err}, event: ${json2str(event)}`); + return null; + } + } + + getTxIDFromEventEtherem(event: object, 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}`); + const event = ledgerEvent.data; + let retEventNum = 0; + + try { + switch (ledgerEvent.verifierId) { + 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}`); + break; + } + logger.debug(`##getEventDataNum(): retEventNum: ${retEventNum}, verifierId: ${ledgerEvent.verifierId}`); + return retEventNum; + } + catch (err) { + logger.error(`##getEventDataNum(): invalid even, err: ${err}, event: ${event}`); + return 0; + } + } + + getAccountInfo(transactionSubset: object): object { + const transactionInfo = {}; + for (const customer of config.electricityTradeInfo.ethereum.account.customer) { + logger.debug(`customer = ${json2str(customer)}`); + if (transactionSubset['Name'] === customer.number) { + if (transactionSubset['Verb'] === "inc") { + logger.debug('getAccountInfo(): A to B'); + transactionInfo['fromAddress'] = customer.accountA; + transactionInfo['fromAddressPkey'] = config.electricityTradeInfo.ethereum.account.pKey[customer.accountA]; + transactionInfo['toAddress'] = customer.accountB; + } + else if (transactionSubset['Verb'] === "dec"){ + logger.debug('getAccountInfo(): B to A'); + transactionInfo['fromAddress'] = customer.accountB; + transactionInfo['fromAddressPkey'] = config.electricityTradeInfo.ethereum.account.pKey[customer.accountB]; + transactionInfo['toAddress'] = customer.accountA; + } + } + } + return transactionInfo; + } +} diff --git a/examples/electricity-trade/RequestInfo.ts b/examples/electricity-trade/RequestInfo.ts new file mode 100644 index 0000000000..663e763dd3 --- /dev/null +++ b/examples/electricity-trade/RequestInfo.ts @@ -0,0 +1,34 @@ +/* + * Copyright 2020 Hyperledger Cactus Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * RequestInfo.ts + */ + +// transaction information +class TradeInfo { + ethereumAccountA: string; + ethereumAccountB: string; +} + +// authorization information +class AuthInfo { + company: string; +} + +// request information +export class RequestInfo { + businessLogicID: string; + tradeID: string; + tradeInfo: TradeInfo; + authInfo: AuthInfo; + constructor() { + this.tradeInfo = new TradeInfo(); + this.authInfo = new AuthInfo(); + } + + setTradeID(tradeID: string) { + this.tradeID = tradeID; + } +} + diff --git a/examples/electricity-trade/TransactionEthereum.ts b/examples/electricity-trade/TransactionEthereum.ts new file mode 100644 index 0000000000..1446ac7ce7 --- /dev/null +++ b/examples/electricity-trade/TransactionEthereum.ts @@ -0,0 +1,109 @@ +/* + * Copyright 2020 Hyperledger Cactus Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * TransactionEthereum.ts + */ + +const ethJsCommon = require('ethereumjs-common').default; +const ethJsTx = require('ethereumjs-tx').Transaction; +const libWeb3 = require('web3'); + +const fs = require('fs'); +const path = require('path'); +const config: any = JSON.parse(fs.readFileSync(path.resolve(__dirname, "./config/default.json"), 'utf8')); +import { getLogger } from "log4js"; +const moduleName = 'TransactionEthereum'; +const logger = getLogger(`${moduleName}`); +logger.level = config.logLevel; + +const mapFromAddressNonce: Map = new Map(); + +export function makeRawTransaction(txParam: { fromAddress: string, fromAddressPkey: string, toAddress: string, amount: number, gas: number }): Promise<{ data: {}, txId: string }> { + return new Promise(async (resolve, reject) => { + try { + logger.debug("txParam : " + JSON.stringify(txParam)); + // Initial setting + logger.debug('gethUrl: ' + config.electricityTradeInfo.ethereum.gethURL); + const provider = new libWeb3.providers.HttpProvider(config.electricityTradeInfo.ethereum.gethURL); + const web3 = new libWeb3(provider); + + // ethereumjs-tx2.1.2_support + const customCommon = ethJsCommon.forCustomChain( + config.electricityTradeInfo.ethereum.network, + { + name: config.electricityTradeInfo.ethereum.chainName, + networkId: config.electricityTradeInfo.ethereum.networkID, + chainId: config.electricityTradeInfo.ethereum.chainID, + }, + config.electricityTradeInfo.ethereum.hardfork + ); + + // web3_v1.2.9_support + web3.eth.getTransactionCount(txParam.fromAddress) + .then(_nonce => { + let txnCount: number = _nonce; + // NOTE: No need to count up. + + // NOTE: gasPrice is not used + // const gasPrice: string = web3.eth.getGasPrice(); + + const latestNonce = getLatestNonce(txParam.fromAddress); + logger.debug(`#####(A) _nonce: ${_nonce}, latestNonce: ${latestNonce}`); + logger.debug(`####makeRawTransaction(): fromAddress: ${txParam.fromAddress}, txnCount: ${web3.utils.toHex(txnCount)}, latestNonce: ${web3.utils.toHex(latestNonce)}`); + if (txnCount <= latestNonce) { + txnCount = latestNonce + 1; + logger.debug(`####makeRawTransaction(): Adjust txnCount, fromAddress: ${txParam.fromAddress}, txnCount: ${web3.utils.toHex(txnCount)}, latestNonce: ${web3.utils.toHex(latestNonce)}`); + } + logger.debug(`#####(B) _nonce: ${_nonce}, latestNonce: ${latestNonce}, txnCount: ${txnCount}`); + setLatestNonce(txParam.fromAddress, txnCount); + + const privKey: Buffer = Buffer.from(txParam.fromAddressPkey, 'hex'); + logger.debug('##privKey=' + txParam.fromAddressPkey); + const rawTx: { nonce: number, to: string, value: number, gas: number } = { + "nonce": web3.utils.toHex(txnCount), + "to": txParam.toAddress, + "value": txParam.amount, + "gas": txParam.gas, + } + logger.debug('txnCount=' + web3.utils.toHex(txnCount)); + logger.debug('##rawTx=' + JSON.stringify(rawTx)); + const tx = new ethJsTx(rawTx, { common: customCommon }); + tx.sign(privKey); + + // Get Transaction ID + const hash: Buffer = tx.hash(true); + const txId: string = '0x' + hash.toString('hex') + logger.debug('##txId=' + txId); + + const serializedTx: Buffer = tx.serialize(); + const serializedTxHex: string = '0x' + serializedTx.toString('hex'); + logger.debug('##serializedTxHex=' + serializedTxHex); + + const result: { data: {}, txId: string } = { + data: { serializedTx: serializedTxHex }, + txId: txId + } + + return resolve(result); + }) + } catch (err) { + logger.error(err); + return reject(err); + }; + }); +} + + +function getLatestNonce(fromAddress: string): number { + if (mapFromAddressNonce.has(fromAddress)) { + return mapFromAddressNonce.get(fromAddress); + } + //return 0; + return -1; +} + +function setLatestNonce(fromAddress: string, nonce: number): void { + mapFromAddressNonce.set(fromAddress, nonce); +} + diff --git a/examples/electricity-trade/config/BLP_config.ts b/examples/electricity-trade/config/BLP_config.ts new file mode 100644 index 0000000000..e2f494bc5c --- /dev/null +++ b/examples/electricity-trade/config/BLP_config.ts @@ -0,0 +1,21 @@ +/* + * Copyright 2020 Hyperledger Cactus Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * BLP_config.ts + */ + +import { BusinessLogicPlugin } from '../../../packages/business-logic-plugin/BusinessLogicPlugin'; +import { BusinessLogicElectricityTrade } from '../BusinessLogicElectricityTrade'; +// import { BusinessLogicCartrade } from '../examples/cartrade/BusinessLogicXxxxTrade'; + +export function getTargetBLPInstance(businessLogicID: string): BusinessLogicPlugin | null { + switch (businessLogicID) { + case "h40Q9eMD": + return new BusinessLogicElectricityTrade(businessLogicID); + // case "xxxxxxxx": + // return new BusinessLogicXxxxTrace(); + default: + return null; + } +} diff --git a/examples/electricity-trade/config/default.json b/examples/electricity-trade/config/default.json new file mode 100644 index 0000000000..069356c514 --- /dev/null +++ b/examples/electricity-trade/config/default.json @@ -0,0 +1,39 @@ +{ + "electricityTradeInfo": { + "sawtooth": { + "validatorID": "sUr7d10R", + "filterKey": "intkey" + }, + "ethereum": { + "validatorID": "84jUisrs", + "gethURL": "http://localhost:8545", + "chainName": "geth1", + "networkID": 10, + "chainID": 10, + "network": "mainnet", + "hardfork": "petersburg", + "gas": 21000, + "account": { + "customer": [ + { + "number": "CN000001", + "accountA": "0x06fc56347d91c6ad2dae0c3ba38eb12ab0d72e97", + "accountB": "0x9d624f7995e8bd70251f8265f2f9f2b49f169c55" + }, + { + "number": "CN000002", + "accountA": "0x9d624f7995e8bd70251f8265f2f9f2b49f169c55", + "accountB": "0x06fc56347d91c6ad2dae0c3ba38eb12ab0d72e97" + } + ], + "pKey": { + "0xec709e1774f0ce4aba47b52a499f9abaaa159f71": "40d7e5931a6e0807d3ebd70518f635dbf575975d3bb564ff34c99be416067c89", + "0x36e146d5afab61ab125ee671708eeb380aea05b6": "13a45756bc314465c4ae2ff0eb9ab58cf72453c04604d8fa14393eb25ce96d06", + "0x06fc56347d91c6ad2dae0c3ba38eb12ab0d72e97": "cb5d48d371916a4ea1627189d8af4f642a5d72746a06b559780c3f5932658207", + "0x9d624f7995e8bd70251f8265f2f9f2b49f169c55": "3d966c433eb650f40287debacd92afb9c390024e359f9f719b2ca6c0ab07339a" + } + } + } + }, + "logLevel": "debug" +} \ No newline at end of file diff --git a/examples/electricity-trade/config/usersetting.json b/examples/electricity-trade/config/usersetting.json new file mode 100644 index 0000000000..b794425970 --- /dev/null +++ b/examples/electricity-trade/config/usersetting.json @@ -0,0 +1,26 @@ +{ + "blpRegistry": [ + { + "businessLogicID": "guks32pf", + "validatorID": ["84jUisrs", "r9IS4dDf"] + }, + { + "businessLogicID": "h40Q9eMD", + "validatorID": ["sUr7d10R", "84jUisrs"] + } + ], + "logLevel": "debug", + "applicationHostInfo": { + "hostName": "http://xxx.xxxxx.xxx:xxxx", + "hostPort": 5034 + }, + "socketOptions": { + "rejectUnauthorized": false, + "reconnection": false, + "timeout": 20000 + }, + "verifier": { + "maxCounterRequestID":100, + "syncFunctionTimeoutMillisecond":5000 + } +} diff --git a/examples/electricity-trade/copyBLPConfig.ts b/examples/electricity-trade/copyBLPConfig.ts new file mode 100644 index 0000000000..38932f628d --- /dev/null +++ b/examples/electricity-trade/copyBLPConfig.ts @@ -0,0 +1,13 @@ +/* + * Copyright 2020 Hyperledger Cactus Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * copyBLPConfig.ts + */ + +import * as shell from 'shelljs'; + +// NOTE: Copy the static assets to the dist folder. +// Example: +// shell.cp('-R', 'src/routing-interface/views', 'dist/routing-interface/views/'); +shell.cp('../../dist/examples/electricity-trade/config/BLP_config.js', '../../dist/packages/config/'); diff --git a/examples/electricity-trade/copyStaticAssets.ts b/examples/electricity-trade/copyStaticAssets.ts new file mode 100644 index 0000000000..801e45e60a --- /dev/null +++ b/examples/electricity-trade/copyStaticAssets.ts @@ -0,0 +1,15 @@ +/* + * Copyright 2020 Hyperledger Cactus Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * copyStaticAssets.ts + */ + +import * as shell from 'shelljs'; + +// NOTE: Copy the static assets to the dist folder. +// Example: +// shell.cp('-R', 'src/routing-interface/views', 'dist/routing-interface/views/'); +//shell.cp('-R', 'config/default.json', 'dist/examples/electricity-trade/config/'); +shell.cp('-R', 'config/default.json', '../../dist/examples/electricity-trade/config/'); +shell.cp('-R', 'config/usersetting.json', '../../dist/packages/config/'); diff --git a/examples/electricity-trade/package.json b/examples/electricity-trade/package.json new file mode 100644 index 0000000000..5a31bd239e --- /dev/null +++ b/examples/electricity-trade/package.json @@ -0,0 +1,39 @@ +{ + "name": "electricity-trade", + "private": true, + "scripts": { + "start": "node ../../dist/packages/routing-interface/www.js", + "debug": "nodemon --inspect ../../dist/packages/routing-interface/www.js", + "build": "npm run build-ts && npm run copy-static-assets && npm run copy-blp-config && npm run replace-blp-config-path", + "build-ts": "tsc -p ./tsconfig.json", + "tslint": "tslint -c tslint.json -p tsconfig.json './*.ts'", + "copy-static-assets": "ts-node copyStaticAssets.ts", + "copy-blp-config": "ts-node copyBLPConfig.ts", + "replace-blp-config-path": "ts-node replaceBLPConfigPath.ts", + "init-electricity-trade": "ln -s ../examples/electricity-trade/node_modules ../../dist/node_modules" + }, + "dependencies": { + "@types/node": "^14.0.24", + "body-parser": "^1.19.0", + "cookie-parser": "~1.4.4", + "debug": "~2.6.9", + "ethereumjs-common": "^1.5.1", + "ethereumjs-tx": "^2.1.2", + "express": "~4.16.1", + "fabric-ca-client": "~1.4.0", + "fabric-network": "~1.4.0", + "http-errors": "~1.6.3", + "jade": "~1.11.0", + "jsonwebtoken": "^8.5.1", + "log4js": "^3.0.6", + "morgan": "~1.9.1", + "shelljs": "^0.8.4", + "socket.io": "^2.0.4", + "ts-node": "8.9.1", + "web3": "^1.2.9" + }, + "devDependencies": { + "tslint": "6.0.0", + "typescript": "3.9.3" + } +} diff --git a/examples/electricity-trade/replaceBLPConfigPath.ts b/examples/electricity-trade/replaceBLPConfigPath.ts new file mode 100644 index 0000000000..0345e5778a --- /dev/null +++ b/examples/electricity-trade/replaceBLPConfigPath.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2020 Hyperledger Cactus Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * ReplacePath.js + */ +const fs = require('fs') + +const targetFile = '../../dist/packages/config/BLP_config.js'; +const srcStr = '"../BusinessLogicElectricityTrade"'; +const distStr = '"../../examples/electricity-trade/BusinessLogicElectricityTrade"'; + +fs.readFile(targetFile, 'utf8', (readErr, data) => { + if (readErr) { + return console.log(readErr); + } + const result = data.replace(srcStr, distStr); + + fs.writeFile(targetFile, result, 'utf8', (writeErr) => { + if (writeErr) return console.log(writeErr); + }); +}); diff --git a/examples/electricity-trade/tsconfig.json b/examples/electricity-trade/tsconfig.json new file mode 100644 index 0000000000..98a8691880 --- /dev/null +++ b/examples/electricity-trade/tsconfig.json @@ -0,0 +1,80 @@ +{ + "compilerOptions": { + /* Basic Options */ + "incremental": true, /* Enable incremental compilation */ + "target": "ES2017", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ + "module": "CommonJS", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ + "lib": [ + "es2015", + "es2016", + "es2017", + "dom" + ], /* Specify library files to be included in the compilation. */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "declarationDir": "dist/types", + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "./dist/lib/", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "composite": true, /* Enable project compilation */ + // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + /* Strict Type-Checking Options */ +// "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + /* Module Resolution Options */ + "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + "resolveJsonModule": true, /* When true allows the importing of json files in Typescript code */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + "typeRoots": [ + "./node_modules/@types", + "./typings" + ], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + /* Source Map Options */ + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + /* Advanced Options */ + "forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */ + "outDir": "../../dist" + }, + "include": [ + "./*.ts", + "./config/*.ts" + ], + "exclude": [ + "copyStaticAssets.ts", + "copyBLPConfig.ts", + "replaceBLPConfigPath.ts" + ] +} diff --git a/examples/electricity-trade/tslint.json b/examples/electricity-trade/tslint.json new file mode 100644 index 0000000000..9a00b4aa19 --- /dev/null +++ b/examples/electricity-trade/tslint.json @@ -0,0 +1,28 @@ +{ + "defaultSeverity": "error", + "extends": [ + "tslint:recommended" + ], + "jsRules": {}, + "rules": { + "variable-name": { + "options": [ + "allow-leading-underscore", + "ban-keywords", + "check-format" + ] + }, + "no-string-literal": false, + "no-var-requires": false, + "object-literal-shorthand": false, + "max-classes-per-file": false, + "no-console": false + }, + "rulesDirectory": [], + "linterOptions": { + "exclude": [ + "packages/cactus-sdk/src/main/typescript/generated/**/*.ts", + "packages/cactus-sdk/src/main/typescript/public-api.ts" + ] + } +} diff --git a/packages/business-logic-plugin/app.ts b/packages/business-logic-plugin/app.ts index f5bc9d43ac..dbd1a6fe0e 100644 --- a/packages/business-logic-plugin/app.ts +++ b/packages/business-logic-plugin/app.ts @@ -20,6 +20,8 @@ import tradesRouter from '../routing-interface/routes/trades'; import balanceRouter from '../routing-interface/routes/balance'; import carsRouter from '../routing-interface/routes/cars'; import assetRouter from '../routing-interface/routes/asset'; +import blockmonitorRouter from '../routing-interface/routes/blockmonitor'; +import electricityTradeRouter from '../routing-interface/routes/electricity-trade'; const app: express.Express = express(); @@ -32,11 +34,13 @@ app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); app.use('/', indexRouter); -app.use('/api/v1/bl/login/', loginRouter); -app.use('/api/v1/bl/trades/', tradesRouter); +app.use('/api/v1/bl/login/', loginRouter); +app.use('/api/v1/bl/trades/', tradesRouter); app.use('/api/v1/bl/balance/', balanceRouter); -app.use('/api/v1/bl/cars/', carsRouter); -app.use('/api/v1/bl/asset/', assetRouter); +app.use('/api/v1/bl/cars/', carsRouter); +app.use('/api/v1/bl/asset/', assetRouter); +app.use('/api/v1/bl/blockmonitor/', blockmonitorRouter); +app.use('/api/v1/bl/electricity-trade/', electricityTradeRouter); // catch 404 and forward to error handler app.use((req: Request, res: Response, next: NextFunction) => { diff --git a/packages/config/default.json b/packages/config/default.json index baa0651d17..2ac143e55b 100644 --- a/packages/config/default.json +++ b/packages/config/default.json @@ -3,6 +3,10 @@ { "businessLogicID": "guks32pf", "validatorID": ["84jUisrs", "r9IS4dDf"] + }, + { + "businessLogicID": "h40Q9eMD", + "validatorID": ["sUr7d10R", "84jUisrs"] } ], "logLevel": "debug", diff --git a/packages/config/verifier-config.json b/packages/config/verifier-config.json index f88e7cbbc0..90299d35d8 100644 --- a/packages/config/verifier-config.json +++ b/packages/config/verifier-config.json @@ -80,6 +80,15 @@ ] } ] + }, + { + "validatorID": "sUr7d10R", + "validatorURL": "https://localhost:5140", + "validatorKeyPath": "./validatorKey/sUr7d10R/keysUr7d10R.crt", + "ledgerInfo": { + "ledgerAbstract": "Sawtooth Ledger" + }, + "apiInfo": [] } ] } diff --git a/packages/ledger-plugin/sawtooth/validator/src/core/config/default.ts b/packages/ledger-plugin/sawtooth/validator/src/core/config/default.ts index fd04eda3eb..955320c273 100644 --- a/packages/ledger-plugin/sawtooth/validator/src/core/config/default.ts +++ b/packages/ledger-plugin/sawtooth/validator/src/core/config/default.ts @@ -24,7 +24,7 @@ export const config = { }, "pollingInterval": 5000 }, - "validatorKeyPath": "../core/validatorKey/keySawtooth.priv", + "validatorKeyPath": "../core/validatorKey/keysUr7d10R.priv", // Log level (trace/debug/info/warn/error/fatal) "logLevel" : "debug" } diff --git a/packages/ledger-plugin/sawtooth/validator/src/core/validatorKey/keysUr7d10R.priv b/packages/ledger-plugin/sawtooth/validator/src/core/validatorKey/keysUr7d10R.priv new file mode 100644 index 0000000000..6faf76a31e --- /dev/null +++ b/packages/ledger-plugin/sawtooth/validator/src/core/validatorKey/keysUr7d10R.priv @@ -0,0 +1,8 @@ +-----BEGIN EC PARAMETERS----- +BggqhkjOPQMBBw== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEICIlCfK3zMTFzUgdaj01LAHjJmHlbg6Xql9+i70iPz5EoAoGCCqGSM49 +AwEHoUQDQgAEM+lIPbDTOuokqtoYPVvkmrawO5pxOFJSqLt+/PyjKta24oONnXnM +hpI61qTpdHEWH1X0aiR2DkY1tb+lNlxO6g== +-----END EC PRIVATE KEY----- diff --git a/packages/ledger-plugin/validatorKey/sUr7d10R/keysUr7d10R.crt b/packages/ledger-plugin/validatorKey/sUr7d10R/keysUr7d10R.crt new file mode 100644 index 0000000000..34773b65c3 --- /dev/null +++ b/packages/ledger-plugin/validatorKey/sUr7d10R/keysUr7d10R.crt @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBdTCCARoCCQC/F+Mh551QzDAKBggqhkjOPQQDAjBCMQswCQYDVQQGEwJKUDEQ +MA4GA1UECAwHZXNqbXMxMjEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkg +THRkMB4XDTE4MDYyNzA3MjIzNVoXDTI4MDYyNDA3MjIzNVowQjELMAkGA1UEBhMC +SlAxEDAOBgNVBAgMB2Vzam1zMTIxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMg +UHR5IEx0ZDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDPpSD2w0zrqJKraGD1b +5Jq2sDuacThSUqi7fvz8oyrWtuKDjZ15zIaSOtak6XRxFh9V9Gokdg5GNbW/pTZc +TuowCgYIKoZIzj0EAwIDSQAwRgIhAKH6ERsyd5bpEMIkY4clPqguwDWoTLk2VKq6 +ONEhUqotAiEA4yJxGmZpFdRScG2gDUIF2VDeX+XfHdJI2J41hyW9/zI= +-----END CERTIFICATE----- diff --git a/packages/routing-interface/BlockMonitor.ts b/packages/routing-interface/BlockMonitor.ts new file mode 100644 index 0000000000..9b4d1a2d1a --- /dev/null +++ b/packages/routing-interface/BlockMonitor.ts @@ -0,0 +1,55 @@ +/* + * Copyright 2021 Hyperledger Cactus Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * BlockMonitor.ts + */ + +import { LedgerOperation } from '../business-logic-plugin/LedgerOperation'; +import { LPInfoHolder } from './util/LPInfoHolder'; +import { VerifierBase } from '../ledger-plugin/VerifierBase'; +import { ConfigUtil } from './util/ConfigUtil'; +import { LedgerEvent } from '../ledger-plugin/LedgerPlugin'; + +const fs = require('fs'); +const path = require('path'); +const config: any = ConfigUtil.getConfig(); +import { getLogger } from "log4js"; +const moduleName = 'BlockMonitor'; +const logger = getLogger(`${moduleName}`); +logger.level = config.logLevel; + +export class BlockMonitor { + private connectInfo: LPInfoHolder = null; // connection information + private verifierSawtooth: VerifierBase = null; + + constructor() { + this.connectInfo = new LPInfoHolder(); + } + + sawtoothBlockMonitoring(): Promise { + return new Promise((resolve, reject) => { + if (this.verifierSawtooth === null) { + logger.debug("create verifierSawtooth"); + const ledgerPluginInfo: string = this.connectInfo.getLegerPluginInfo("sawtooth"); + this.verifierSawtooth = new VerifierBase(ledgerPluginInfo); + this.verifierSawtooth.setEventListener(this); + const option = { + "filterKey":"intkey" + } + this.verifierSawtooth.startMonitor(option); + } + + const response = { + "status": 200 + } + resolve(response); + }); + } + + + onEvent(ledgerEvent: LedgerEvent): void { + logger.debug(`####in onEvent: event: ${JSON.stringify(ledgerEvent)}`); + } + +} diff --git a/packages/routing-interface/TransactionManagement.ts b/packages/routing-interface/TransactionManagement.ts index 3c5ab0032b..f5aa2d9e8c 100644 --- a/packages/routing-interface/TransactionManagement.ts +++ b/packages/routing-interface/TransactionManagement.ts @@ -50,7 +50,7 @@ export class TransactionManagement { logger.info(`tradeID: ${tradeID}`); // object judgment - if (businessLogicID === "guks32pf") { + if ((businessLogicID === "guks32pf") || (businessLogicID === "h40Q9eMD")) { const blp = getTargetBLPInstance(businessLogicID); if (blp === null) { @@ -111,7 +111,7 @@ export class TransactionManagement { // Get Verifier - getVerifier(validatorId: string): VerifierBase { + getVerifier(validatorId: string, monitorOptions = {}): VerifierBase { // Return Verifier // If you have already made it, please reply. If you haven't made it yet, make it and reply. @@ -124,7 +124,7 @@ export class TransactionManagement { this.verifierArray[validatorId] = new VerifierBase(ledgerPluginInfo); logger.debug("##startMonitor"); this.verifierArray[validatorId].setEventListener(this); - this.verifierArray[validatorId].startMonitor(); + this.verifierArray[validatorId].startMonitor(monitorOptions); return this.verifierArray[validatorId]; } @@ -139,7 +139,7 @@ export class TransactionManagement { // interface VerifierEventListener onEvent(ledgerEvent: LedgerEvent): void { - logger.debug(`####in onEvent: event: ${json2str(ledgerEvent)}`); +// logger.debug(`####in onEvent: event: ${json2str(ledgerEvent)}`); const eventNum = this.getEventNum(ledgerEvent); if (eventNum === 0) { logger.warn(`onEvent(): invalid event, event num is zero., ledgerEvent.verifierId: ${ledgerEvent.verifierId}`); @@ -157,7 +157,7 @@ export class TransactionManagement { private getEventNum(ledgerEvent: LedgerEvent): number { - logger.debug(`##getEventNum: event: ${ledgerEvent}`); +// logger.debug(`##getEventNum: event: ${ledgerEvent}`); for (const businessLogicID of this.blpRegistry.getBusinessLogicIDList()) { logger.debug(`####getEventNum(): businessLogicID: ${businessLogicID}`); const blp = getTargetBLPInstance(businessLogicID); @@ -192,7 +192,7 @@ export class TransactionManagement { private getTxIDFromEvent(ledgerEvent: LedgerEvent, targetIndex: number): string | null { - logger.debug(`##getTxIDFromEvent: event: ${ledgerEvent}`); +// logger.debug(`##getTxIDFromEvent: event: ${ledgerEvent}`); for (const businessLogicID of this.blpRegistry.getBusinessLogicIDList()) { logger.debug(`####getTxIDFromEvent(): businessLogicID: ${businessLogicID}`); const blp = getTargetBLPInstance(businessLogicID); @@ -224,10 +224,10 @@ export class TransactionManagement { continue; } - if (blp.hasTxIDInTransactions(txID)) { +// if (blp.hasTxIDInTransactions(txID)) { logger.debug(`####getBLPInstanceFromTxID(): found!, businessLogicID: ${businessLogicID}`); return blp; - } +// } } // not found. diff --git a/packages/routing-interface/routes/blockmonitor.ts b/packages/routing-interface/routes/blockmonitor.ts new file mode 100644 index 0000000000..c80c1259bb --- /dev/null +++ b/packages/routing-interface/routes/blockmonitor.ts @@ -0,0 +1,51 @@ +/* + * Copyright 2021 Hyperledger Cactus Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * blockmonitor.ts + */ + +import { Router, NextFunction, Request, Response } from 'express'; +import { RIFUtil } from '../util/RIFUtil'; +import { ConfigUtil } from '../util/ConfigUtil'; +import { RIFError, BadRequestError, InternalServerError } from '../RIFError'; +import { BlockMonitor } from '../BlockMonitor'; + +const fs = require('fs'); +const path = require('path'); +const config: any = ConfigUtil.getConfig(); +import { getLogger } from "log4js"; +const moduleName = 'blockmonitor'; +const logger = getLogger(`${moduleName}`); +logger.level = config.logLevel; + +const router: Router = Router(); +const blockMonitor: BlockMonitor = new BlockMonitor(); + +/* sawtoothBlockMonitoring */ +router.get('/start', (req: Request, res: Response, next: NextFunction) => { + try { + + blockMonitor.sawtoothBlockMonitoring().then(result => { + logger.debug("result(sawtoothBlockMonitoring) = " + JSON.stringify(result)); + res.status(200).json(result); + }).catch((err) => { + logger.error(err); + }); + + } catch (err) { + logger.error(`##err name: ${err.constructor.name}`); + + if (err instanceof RIFError) { + logger.debug(`##catch RIFError, ${err.statusCode}, ${err.message}`); + res.status(err.statusCode); + res.send(err.message); + return; + } + + logger.error(`##err in balance: ${err}`); + next(err); + } +}); + +export default router; diff --git a/packages/routing-interface/routes/electricity-trade.ts b/packages/routing-interface/routes/electricity-trade.ts new file mode 100644 index 0000000000..8006790e1b --- /dev/null +++ b/packages/routing-interface/routes/electricity-trade.ts @@ -0,0 +1,66 @@ +/* + * Copyright 2020 Hyperledger Cactus Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * electricity-trade.ts + */ + +import { Router, NextFunction, Request, Response } from 'express'; +import { TransactionManagement } from '../TransactionManagement'; +import { RIFError } from '../RIFError'; +import { ConfigUtil } from '../util/ConfigUtil'; + +const fs = require('fs'); +const path = require('path'); +const config: any = ConfigUtil.getConfig(); +import { getLogger } from "log4js"; +const moduleName = 'trades'; +const logger = getLogger(`${moduleName}`); +logger.level = config.logLevel; + +const router: Router = Router(); +export const transactionManagement: TransactionManagement = new TransactionManagement(); + +// Request Execution of Trade +router.post('/', (req: Request, res: Response, next: NextFunction) => { + try { + const tradeID: string = transactionManagement.startBusinessLogic(req); + + const result = {tradeID: tradeID}; + res.status(200).json(result); + + } catch (err) { + if (err instanceof RIFError) { + res.status(err.statusCode); + res.send(err.message); + return; + } + + next(err); + } +}); + +// Show Current Status of Trade +router.get('/:account', (req: Request, res: Response, next: NextFunction) => { + + res.status(200).json({"message": "Not implemented"}); + +/* + try { + const result = transactionManagement.getOperationStatus(req.params.id); + res.status(200).json(result); + + } catch (err) { + if (err instanceof RIFError) { + res.status(err.statusCode); + res.send(err.message); + return; + } + + next(err); + } +*/ + +}); + +export default router; diff --git a/tools/docker/sawtooth-testnet/README.md b/tools/docker/sawtooth-testnet/README.md new file mode 100644 index 0000000000..e4f2714582 --- /dev/null +++ b/tools/docker/sawtooth-testnet/README.md @@ -0,0 +1,15 @@ + + +# Sawtooth testnet + +## How to build +- ``./script-start-ledger.sh`` + +## Note +- This directory referenced the minimum files (*.yaml on this repository) for Sawtooth ledger construction from the following repository: + - [Hyperledger/sawtooth-core v1-3 (/docker/compose)](https://github.com/hyperledger/sawtooth-core/tree/1-3/docker/compose) \ No newline at end of file diff --git a/tools/docker/sawtooth-testnet/copy-debs.yaml b/tools/docker/sawtooth-testnet/copy-debs.yaml new file mode 100644 index 0000000000..76a6bb5ad2 --- /dev/null +++ b/tools/docker/sawtooth-testnet/copy-debs.yaml @@ -0,0 +1,134 @@ +# Copyright 2018 Cargill Incorporated +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +version: '3.6' + +services: + + settings-tp: + image: sawtooth-settings-tp:${ISOLATION_ID} + volumes: + - ../../build/debs:/build/debs + command: | + bash -c " + cp /tmp/*.deb /build/debs + " + + validator: + image: sawtooth-validator:${ISOLATION_ID} + volumes: + - ../../build/debs:/build/debs + command: | + bash -c " + cp /tmp/*.deb /build/debs + " + + rest-api: + image: sawtooth-rest-api:${ISOLATION_ID} + volumes: + - ../../build/debs:/build/debs + command: | + bash -c " + cp /tmp/*.deb /build/debs + " + + shell: + image: sawtooth-shell:${ISOLATION_ID} + volumes: + - ../../build/debs:/build/debs + command: | + bash -c " + cp /tmp/*.deb /build/debs + " + + admin-tools: + image: sawtooth-admin-tools:${ISOLATION_ID} + volumes: + - ../../build/debs:/build/debs + command: | + bash -c " + cp /tmp/*.deb /build/debs + " + + sawtooth-cli: + image: sawtooth-cli:${ISOLATION_ID} + volumes: + - ../../build/debs:/build/debs + command: | + bash -c " + cp /tmp/*.deb /build/debs + " + + block-info-tp: + image: sawtooth-block-info-tp:${ISOLATION_ID} + volumes: + - ../../build/debs:/build/debs + command: | + bash -c " + cp /tmp/*.deb /build/debs + " + + identity-tp: + image: sawtooth-identity-tp:${ISOLATION_ID} + volumes: + - ../../build/debs:/build/debs + command: | + bash -c " + cp /tmp/*.deb /build/debs + " + + integration: + image: sawtooth-integration:${ISOLATION_ID} + volumes: + - ../../build/debs:/build/debs + command: | + bash -c " + cp /tmp/*.deb /build/debs + " + + smallbank-tp-rust: + image: sawtooth-smallbank-tp-rust:${ISOLATION_ID} + volumes: + - ../../build/debs:/build/debs + command: | + bash -c " + cp /tmp/*.deb /build/debs + " + + smallbank-workload: + image: sawtooth-smallbank-workload:${ISOLATION_ID} + volumes: + - ../../build/debs:/build/debs + command: | + bash -c " + cp /tmp/*.deb /build/debs + " + + intkey-workload: + image: sawtooth-intkey-workload:${ISOLATION_ID} + volumes: + - ../../build/debs:/build/debs + command: | + bash -c " + cp /tmp/*.deb /build/debs + " + + sawtooth-meta: + image: sawtooth-meta:${ISOLATION_ID} + volumes: + - ../../build/debs:/build/debs + command: | + bash -c " + cp /tmp/*.deb /build/debs + " diff --git a/tools/docker/sawtooth-testnet/external.yaml b/tools/docker/sawtooth-testnet/external.yaml new file mode 100644 index 0000000000..6fd740170a --- /dev/null +++ b/tools/docker/sawtooth-testnet/external.yaml @@ -0,0 +1,50 @@ +# Copyright 2018 Cargill Incorporated +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +version: '3.6' + +services: + + apache-basic-auth-proxy: + build: + context: ../ + dockerfile: ./apache-basic-auth-proxy + args: + - http_proxy + - https_proxy + - no_proxy + image: apache-basic-auth-proxy:${ISOLATION_ID} + container_name: apache-basic-auth-proxy-default + + sawtooth-stats-grafana: + build: + context: ../ + dockerfile: ./grafana/sawtooth-stats-grafana + args: + - http_proxy + - https_proxy + - no_proxy + image: sawtooth-stats-grafana:${ISOLATION_ID} + container_name: sawtooth-stats-grafana-default + + sawtooth-stats-influxdb: + build: + context: ../ + dockerfile: ./influxdb/sawtooth-stats-influxdb + args: + - http_proxy + - https_proxy + - no_proxy + image: sawtooth-stats-influxdb:${ISOLATION_ID} + container_name: sawtooth-stats-influxdb-default diff --git a/tools/docker/sawtooth-testnet/run-lint.yaml b/tools/docker/sawtooth-testnet/run-lint.yaml new file mode 100644 index 0000000000..f57d105b46 --- /dev/null +++ b/tools/docker/sawtooth-testnet/run-lint.yaml @@ -0,0 +1,57 @@ + +# Copyright 2018 Cargill Incorporated +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +version: '3.6' + +services: + + lint-python: + build: + context: ../ + dockerfile: ./lint + args: + - http_proxy + - https_proxy + - no_proxy + image: lint:${ISOLATION_ID} + volumes: + - ../../:/project/sawtooth-core + command: run_lint + + lint-rust: + build: + context: ../ + dockerfile: ./lint + args: + - http_proxy + - https_proxy + - no_proxy + image: lint:${ISOLATION_ID} + volumes: + - ../../:/project/sawtooth-core + command: run_lint_rust + + lint-validator: + build: + context: ../ + dockerfile: ./lint + args: + - http_proxy + - https_proxy + - no_proxy + image: lint:${ISOLATION_ID} + volumes: + - ../../:/project/sawtooth-core + command: run_lint_validator diff --git a/tools/docker/sawtooth-testnet/sawtooth-build.yaml b/tools/docker/sawtooth-testnet/sawtooth-build.yaml new file mode 100644 index 0000000000..7340843b45 --- /dev/null +++ b/tools/docker/sawtooth-testnet/sawtooth-build.yaml @@ -0,0 +1,117 @@ +# Copyright 2018 Cargill Incorporated +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +version: '3.6' + +services: + + validator: + build: + context: ../../ + dockerfile: ./validator/Dockerfile + args: + - http_proxy + - https_proxy + - no_proxy + image: sawtooth-validator-local:${ISOLATION_ID} + volumes: + - ../../:/project/sawtooth-core + + adm: + build: + context: ../../ + dockerfile: ./adm/Dockerfile + args: + - http_proxy + - https_proxy + - no_proxy + image: sawtooth-adm-local:${ISOLATION_ID} + volumes: + - ../../:/project/sawtooth-core + + settings-tp: + build: + context: ../../ + dockerfile: ./families/settings/Dockerfile + args: + - http_proxy + - https_proxy + - no_proxy + image: sawtooth-settings-tp-local:${ISOLATION_ID} + volumes: + - ../../:/project/sawtooth-core + + smallbank-rust-tp: + build: + context: ../../ + dockerfile: ./families/smallbank/smallbank_rust/Dockerfile + args: + - http_proxy + - https_proxy + - no_proxy + image: smallbank-rust-tp-local:${ISOLATION_ID} + volumes: + - ../../:/project/sawtooth-core + + smallbank-workload: + build: + context: ../../ + dockerfile: ./perf/smallbank_workload/Dockerfile + args: + - http_proxy + - https_proxy + - no_proxy + image: smallbank-workload-local:${ISOLATION_ID} + volumes: + - ../../:/project/sawtooth-core + + cli: + build: + context: ../../ + dockerfile: ./cli/Dockerfile + args: + - http_proxy + - https_proxy + - no_proxy + image: sawtooth-cli-local:${ISOLATION_ID} + volumes: + - ../../:/project/sawtooth-core + + rest-api: + build: + context: ../../ + dockerfile: ./rest_api/Dockerfile + args: + - http_proxy + - https_proxy + - no_proxy + image: sawtooth-rest-api-local:${ISOLATION_ID} + volumes: + - ../../:/project/sawtooth-core + + block-info-tp: + build: + context: ../../ + dockerfile: ./families/block_info/Dockerfile + image: block-info-tp-local:${ISOLATION_ID} + volumes: + - ../../:/project/sawtooth-core + + identity-rust-tp: + build: + context: ../../ + dockerfile: ./families/identity/Dockerfile + image: identity-rust-tp-local:${ISOLATION_ID} + volumes: + - ../../:/project/sawtooth-core diff --git a/tools/docker/sawtooth-testnet/sawtooth-debug.yaml b/tools/docker/sawtooth-testnet/sawtooth-debug.yaml new file mode 100644 index 0000000000..0fa9eca2cc --- /dev/null +++ b/tools/docker/sawtooth-testnet/sawtooth-debug.yaml @@ -0,0 +1,121 @@ +# Copyright 2017 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ------------------------------------------------------------------------------ + +version: "2.1" + +services: + sawtooth-shell: + build: + context: ../.. + dockerfile: docker/sawtooth-debug-python + args: + - http_proxy + - https_proxy + - no_proxy + volumes: + - ../../:/project/sawtooth-core + image: debug-sawtooth-python + container_name: debug-sawtooth-shell + cap_add: + - SYS_PTRACE + entrypoint: | + bash -c " + sed -i 's|#!/usr/bin/env python3|#!/usr/bin/env python3-dbg|' \ + bin/sawtooth-validator && + sed -i 's|#!/usr/bin/env python3|#!/usr/bin/env python3-dbg|' \ + bin/sawtooth-rest-api && + sed -i 's|#!/usr/bin/env python3|#!/usr/bin/env python3-dbg|' \ + bin/sawtooth && + tail -f /dev/null + " + + validator: + build: + context: ../.. + dockerfile: docker/sawtooth-debug-python + args: + - http_proxy + - https_proxy + - no_proxy + volumes: + - ../../:/project/sawtooth-core + image: debug-sawtooth-python + container_name: debug-validator + cap_add: + - SYS_PTRACE + expose: + - 4004 + - 8800 + ports: + - "4050:4004" + command: | + bash -c " + sleep 3 && + if [ ! -f /etc/sawtooth/keys/validator.priv ]; then + sawadm keygen && + sawtooth keygen my_key && + sawset genesis -k /root/.sawtooth/keys/my_key.priv && + sawadm genesis config-genesis.batch + fi; + sawtooth-validator -vv \ + --endpoint tcp://validator:8800 \ + --bind component:tcp://eth0:4004 \ + --bind network:tcp://eth0:8800 + " + + settings-tp: + build: + context: ../.. + dockerfile: docker/sawtooth-debug-python + args: + - http_proxy + - https_proxy + - no_proxy + volumes: + - ../../:/project/sawtooth-core + image: debug-sawtooth-python + container_name: debug-settings-tp + cap_add: + - SYS_PTRACE + depends_on: + - validator + command: settings-tp -vv -C tcp://validator:4004 + + intkey-tp-python: + image: hyperledger/sawtooth-intkey-tp-python:nightly + container_name: intkey-tp-python + depends_on: + - validator + command: intkey-tp-python -vv -C tcp://validator:4004 + + rest-api: + build: + context: ../.. + dockerfile: docker/sawtooth-debug-python + args: + - http_proxy + - https_proxy + - no_proxy + volumes: + - ../../:/project/sawtooth-core + image: debug-sawtooth-python + container_name: debug-rest-api + cap_add: + - SYS_PTRACE + depends_on: + - validator + ports: + - "8008:8008" + command: sawtooth-rest-api -v --connect tcp://validator:4004 --bind rest-api:8008 diff --git a/tools/docker/sawtooth-testnet/sawtooth-default-pbft.yaml b/tools/docker/sawtooth-testnet/sawtooth-default-pbft.yaml new file mode 100644 index 0000000000..53e470ea5a --- /dev/null +++ b/tools/docker/sawtooth-testnet/sawtooth-default-pbft.yaml @@ -0,0 +1,454 @@ +# Copyright 2019 Cargill Incorporated +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +version: '3.6' + +volumes: + pbft-shared: + +services: + +# -------------=== intkey tp ===------------- + + intkey-tp-0: + image: hyperledger/sawtooth-intkey-tp-python:nightly + container_name: sawtooth-intkey-tp-python-default-0 + expose: + - 4004 + command: intkey-tp-python -C tcp://validator-0:4004 + stop_signal: SIGKILL + + intkey-tp-1: + image: hyperledger/sawtooth-intkey-tp-python:nightly + container_name: sawtooth-intkey-tp-python-default-1 + expose: + - 4004 + command: intkey-tp-python -C tcp://validator-1:4004 + stop_signal: SIGKILL + + intkey-tp-2: + image: hyperledger/sawtooth-intkey-tp-python:nightly + container_name: sawtooth-intkey-tp-python-default-2 + expose: + - 4004 + command: intkey-tp-python -C tcp://validator-2:4004 + stop_signal: SIGKILL + + intkey-tp-3: + image: hyperledger/sawtooth-intkey-tp-python:nightly + container_name: sawtooth-intkey-tp-python-default-3 + expose: + - 4004 + command: intkey-tp-python -C tcp://validator-3:4004 + stop_signal: SIGKILL + + intkey-tp-4: + image: hyperledger/sawtooth-intkey-tp-python:nightly + container_name: sawtooth-intkey-tp-python-default-4 + expose: + - 4004 + command: intkey-tp-python -C tcp://validator-4:4004 + stop_signal: SIGKILL + +# -------------=== rest api ===------------- + + rest-api-0: + image: hyperledger/sawtooth-rest-api:nightly + container_name: sawtooth-rest-api-default-0 + expose: + - 8008 + command: | + bash -c " + sawtooth-rest-api \ + --connect tcp://validator-0:4004 \ + --bind rest-api-0:8008 + " + stop_signal: SIGKILL + + rest-api-1: + image: hyperledger/sawtooth-rest-api:nightly + container_name: sawtooth-rest-api-default-1 + expose: + - 8008 + command: | + bash -c " + sawtooth-rest-api \ + --connect tcp://validator-1:4004 \ + --bind rest-api-1:8008 + " + stop_signal: SIGKILL + + rest-api-2: + image: hyperledger/sawtooth-rest-api:nightly + container_name: sawtooth-rest-api-default-2 + expose: + - 8008 + command: | + bash -c " + sawtooth-rest-api \ + --connect tcp://validator-2:4004 \ + --bind rest-api-2:8008 + " + stop_signal: SIGKILL + + rest-api-3: + image: hyperledger/sawtooth-rest-api:nightly + container_name: sawtooth-rest-api-default-3 + expose: + - 8008 + command: | + bash -c " + sawtooth-rest-api \ + --connect tcp://validator-3:4004 \ + --bind rest-api-3:8008 + " + stop_signal: SIGKILL + + rest-api-4: + image: hyperledger/sawtooth-rest-api:nightly + container_name: sawtooth-rest-api-default-4 + expose: + - 8008 + command: | + bash -c " + sawtooth-rest-api \ + --connect tcp://validator-4:4004 \ + --bind rest-api-4:8008 + " + stop_signal: SIGKILL + +# -------------=== settings tp ===------------- + + settings-tp-0: + image: hyperledger/sawtooth-settings-tp:nightly + container_name: sawtooth-settings-tp-default-0 + expose: + - 4004 + command: settings-tp -C tcp://validator-0:4004 + stop_signal: SIGKILL + + settings-tp-1: + image: hyperledger/sawtooth-settings-tp:nightly + container_name: sawtooth-settings-tp-default-1 + expose: + - 4004 + command: settings-tp -C tcp://validator-1:4004 + stop_signal: SIGKILL + + settings-tp-2: + image: hyperledger/sawtooth-settings-tp:nightly + container_name: sawtooth-settings-tp-default-2 + expose: + - 4004 + command: settings-tp -C tcp://validator-2:4004 + stop_signal: SIGKILL + + settings-tp-3: + image: hyperledger/sawtooth-settings-tp:nightly + container_name: sawtooth-settings-tp-default-3 + expose: + - 4004 + command: settings-tp -C tcp://validator-3:4004 + stop_signal: SIGKILL + + settings-tp-4: + image: hyperledger/sawtooth-settings-tp:nightly + container_name: sawtooth-settings-tp-default-4 + expose: + - 4004 + command: settings-tp -C tcp://validator-4:4004 + stop_signal: SIGKILL + +# -------------=== shell ===------------- + + shell: + image: hyperledger/sawtooth-shell:nightly + container_name: sawtooth-shell-default + volumes: + - pbft-shared:/pbft-shared + command: | + bash -c " + sawtooth keygen + tail -f /dev/null + " + stop_signal: SIGKILL + +# -------------=== validators ===------------- + + validator-0: + image: hyperledger/sawtooth-validator:nightly + container_name: sawtooth-validator-default-0 + expose: + - 4004 + - 5050 + - 8800 + volumes: + - pbft-shared:/pbft-shared + command: | + bash -c " + if [ -e /pbft-shared/validators/validator-0.priv ]; then + cp /pbft-shared/validators/validator-0.pub /etc/sawtooth/keys/validator.pub + cp /pbft-shared/validators/validator-0.priv /etc/sawtooth/keys/validator.priv + fi && + if [ ! -e /etc/sawtooth/keys/validator.priv ]; then + sawadm keygen + mkdir -p /pbft-shared/validators || true + cp /etc/sawtooth/keys/validator.pub /pbft-shared/validators/validator-0.pub + cp /etc/sawtooth/keys/validator.priv /pbft-shared/validators/validator-0.priv + fi && + if [ ! -e config-genesis.batch ]; then + sawset genesis -k /etc/sawtooth/keys/validator.priv -o config-genesis.batch + fi && + while [[ ! -f /pbft-shared/validators/validator-1.pub || \ + ! -f /pbft-shared/validators/validator-2.pub || \ + ! -f /pbft-shared/validators/validator-3.pub || \ + ! -f /pbft-shared/validators/validator-4.pub ]]; + do sleep 1; done + echo sawtooth.consensus.pbft.members=\\['\"'$$(cat /pbft-shared/validators/validator-0.pub)'\"','\"'$$(cat /pbft-shared/validators/validator-1.pub)'\"','\"'$$(cat /pbft-shared/validators/validator-2.pub)'\"','\"'$$(cat /pbft-shared/validators/validator-3.pub)'\"','\"'$$(cat /pbft-shared/validators/validator-4.pub)'\"'\\] && + if [ ! -e config.batch ]; then + sawset proposal create \ + -k /etc/sawtooth/keys/validator.priv \ + sawtooth.consensus.algorithm.name=pbft \ + sawtooth.consensus.algorithm.version=1.0 \ + sawtooth.consensus.pbft.members=\\['\"'$$(cat /pbft-shared/validators/validator-0.pub)'\"','\"'$$(cat /pbft-shared/validators/validator-1.pub)'\"','\"'$$(cat /pbft-shared/validators/validator-2.pub)'\"','\"'$$(cat /pbft-shared/validators/validator-3.pub)'\"','\"'$$(cat /pbft-shared/validators/validator-4.pub)'\"'\\] \ + sawtooth.publisher.max_batches_per_block=1200 \ + -o config.batch + fi && + if [ ! -e /var/lib/sawtooth/genesis.batch ]; then + sawadm genesis config-genesis.batch config.batch + fi && + if [ ! -e /root/.sawtooth/keys/my_key.priv ]; then + sawtooth keygen my_key + fi && + sawtooth-validator -vv \ + --endpoint tcp://validator-0:8800 \ + --bind component:tcp://eth0:4004 \ + --bind consensus:tcp://eth0:5050 \ + --bind network:tcp://eth0:8800 \ + --scheduler parallel \ + --peering static \ + --maximum-peer-connectivity 10000 + " + + validator-1: + image: hyperledger/sawtooth-validator:nightly + container_name: sawtooth-validator-default-1 + expose: + - 4004 + - 5050 + - 8800 + volumes: + - pbft-shared:/pbft-shared + command: | + bash -c " + if [ -e /pbft-shared/validators/validator-1.priv ]; then + cp /pbft-shared/validators/validator-1.pub /etc/sawtooth/keys/validator.pub + cp /pbft-shared/validators/validator-1.priv /etc/sawtooth/keys/validator.priv + fi && + if [ ! -e /etc/sawtooth/keys/validator.priv ]; then + sawadm keygen + mkdir -p /pbft-shared/validators || true + cp /etc/sawtooth/keys/validator.pub /pbft-shared/validators/validator-1.pub + cp /etc/sawtooth/keys/validator.priv /pbft-shared/validators/validator-1.priv + fi && + sawtooth keygen my_key && + sawtooth-validator -vv \ + --endpoint tcp://validator-1:8800 \ + --bind component:tcp://eth0:4004 \ + --bind consensus:tcp://eth0:5050 \ + --bind network:tcp://eth0:8800 \ + --scheduler parallel \ + --peering static \ + --maximum-peer-connectivity 10000 \ + --peers tcp://validator-0:8800 + " + + validator-2: + image: hyperledger/sawtooth-validator:nightly + container_name: sawtooth-validator-default-2 + expose: + - 4004 + - 5050 + - 8800 + volumes: + - pbft-shared:/pbft-shared + command: | + bash -c " + if [ -e /pbft-shared/validators/validator-2.priv ]; then + cp /pbft-shared/validators/validator-2.pub /etc/sawtooth/keys/validator.pub + cp /pbft-shared/validators/validator-2.priv /etc/sawtooth/keys/validator.priv + fi && + if [ ! -e /etc/sawtooth/keys/validator.priv ]; then + sawadm keygen + mkdir -p /pbft-shared/validators || true + cp /etc/sawtooth/keys/validator.pub /pbft-shared/validators/validator-2.pub + cp /etc/sawtooth/keys/validator.priv /pbft-shared/validators/validator-2.priv + fi && + sawtooth keygen my_key && + sawtooth-validator -vv \ + --endpoint tcp://validator-2:8800 \ + --bind component:tcp://eth0:4004 \ + --bind consensus:tcp://eth0:5050 \ + --bind network:tcp://eth0:8800 \ + --scheduler parallel \ + --peering static \ + --maximum-peer-connectivity 10000 \ + --peers tcp://validator-0:8800 \ + --peers tcp://validator-1:8800 + " + + validator-3: + image: hyperledger/sawtooth-validator:nightly + container_name: sawtooth-validator-default-3 + expose: + - 4004 + - 5050 + - 8800 + volumes: + - pbft-shared:/pbft-shared + command: | + bash -c " + if [ -e /pbft-shared/validators/validator-3.priv ]; then + cp /pbft-shared/validators/validator-3.pub /etc/sawtooth/keys/validator.pub + cp /pbft-shared/validators/validator-3.priv /etc/sawtooth/keys/validator.priv + fi && + if [ ! -e /etc/sawtooth/keys/validator.priv ]; then + sawadm keygen + mkdir -p /pbft-shared/validators || true + cp /etc/sawtooth/keys/validator.pub /pbft-shared/validators/validator-3.pub + cp /etc/sawtooth/keys/validator.priv /pbft-shared/validators/validator-3.priv + fi && + sawtooth keygen my_key && + sawtooth-validator -vv \ + --endpoint tcp://validator-3:8800 \ + --bind component:tcp://eth0:4004 \ + --bind consensus:tcp://eth0:5050 \ + --bind network:tcp://eth0:8800 \ + --scheduler parallel \ + --peering static \ + --maximum-peer-connectivity 10000 \ + --peers tcp://validator-0:8800 \ + --peers tcp://validator-1:8800 \ + --peers tcp://validator-2:8800 + " + + validator-4: + image: hyperledger/sawtooth-validator:nightly + container_name: sawtooth-validator-default-4 + expose: + - 4004 + - 5050 + - 8800 + volumes: + - pbft-shared:/pbft-shared + command: | + bash -c " + if [ -e /pbft-shared/validators/validator-4.priv ]; then + cp /pbft-shared/validators/validator-4.pub /etc/sawtooth/keys/validator.pub + cp /pbft-shared/validators/validator-4.priv /etc/sawtooth/keys/validator.priv + fi && + if [ ! -e /etc/sawtooth/keys/validator.priv ]; then + sawadm keygen + mkdir -p /pbft-shared/validators || true + cp /etc/sawtooth/keys/validator.pub /pbft-shared/validators/validator-4.pub + cp /etc/sawtooth/keys/validator.priv /pbft-shared/validators/validator-4.priv + fi && + sawtooth keygen my_key && + sawtooth-validator -vv \ + --endpoint tcp://validator-4:8800 \ + --bind component:tcp://eth0:4004 \ + --bind consensus:tcp://eth0:5050 \ + --bind network:tcp://eth0:8800 \ + --scheduler parallel \ + --peering static \ + --maximum-peer-connectivity 10000 \ + --peers tcp://validator-0:8800 \ + --peers tcp://validator-1:8800 \ + --peers tcp://validator-2:8800 \ + --peers tcp://validator-3:8800 + " + +# -------------=== pbft engines ===------------- + + pbft-0: + image: hyperledger/sawtooth-pbft-engine:nightly + container_name: sawtooth-pbft-engine-default-0 + command: pbft-engine -vv --connect tcp://validator-0:5050 + stop_signal: SIGKILL + + pbft-1: + image: hyperledger/sawtooth-pbft-engine:nightly + container_name: sawtooth-pbft-engine-default-1 + command: pbft-engine -vv --connect tcp://validator-1:5050 + stop_signal: SIGKILL + + pbft-2: + image: hyperledger/sawtooth-pbft-engine:nightly + container_name: sawtooth-pbft-engine-default-2 + command: pbft-engine -vv --connect tcp://validator-2:5050 + stop_signal: SIGKILL + + pbft-3: + image: hyperledger/sawtooth-pbft-engine:nightly + container_name: sawtooth-pbft-engine-default-3 + command: pbft-engine -vv --connect tcp://validator-3:5050 + stop_signal: SIGKILL + + pbft-4: + image: hyperledger/sawtooth-pbft-engine:nightly + container_name: sawtooth-pbft-engine-default-4 + command: pbft-engine -vv --connect tcp://validator-4:5050 + stop_signal: SIGKILL + +# -------------=== xo tps ===------------- + + xo-tp-0: + image: hyperledger/sawtooth-xo-tp-python:nightly + container_name: sawtooth-xo-tp-python-default-0 + expose: + - 4004 + command: xo-tp-python -vv -C tcp://validator-0:4004 + stop_signal: SIGKILL + + xo-tp-1: + image: hyperledger/sawtooth-xo-tp-python:nightly + container_name: sawtooth-xo-tp-python-default-1 + expose: + - 4004 + command: xo-tp-python -vv -C tcp://validator-1:4004 + stop_signal: SIGKILL + + xo-tp-2: + image: hyperledger/sawtooth-xo-tp-python:nightly + container_name: sawtooth-xo-tp-python-default-2 + expose: + - 4004 + command: xo-tp-python -vv -C tcp://validator-2:4004 + stop_signal: SIGKILL + + xo-tp-3: + image: hyperledger/sawtooth-xo-tp-python:nightly + container_name: sawtooth-xo-tp-python-default-3 + expose: + - 4004 + command: xo-tp-python -vv -C tcp://validator-3:4004 + stop_signal: SIGKILL + + xo-tp-4: + image: hyperledger/sawtooth-xo-tp-python:nightly + container_name: sawtooth-xo-tp-python-default-4 + expose: + - 4004 + command: xo-tp-python -vv -C tcp://validator-4:4004 + stop_signal: SIGKILL diff --git a/tools/docker/sawtooth-testnet/sawtooth-default-poet.yaml b/tools/docker/sawtooth-testnet/sawtooth-default-poet.yaml new file mode 100644 index 0000000000..66ecbf3cd2 --- /dev/null +++ b/tools/docker/sawtooth-testnet/sawtooth-default-poet.yaml @@ -0,0 +1,500 @@ +# Copyright 2018 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ------------------------------------------------------------------------------ + +version: "2.1" + +volumes: + poet-shared: + +services: + shell: + image: hyperledger/sawtooth-shell:nightly + container_name: sawtooth-shell-default + entrypoint: "bash -c \"\ + sawtooth keygen && \ + tail -f /dev/null \ + \"" + + validator-0: + image: hyperledger/sawtooth-validator:nightly + container_name: sawtooth-validator-default-0 + expose: + - 4004 + - 5050 + - 8800 + volumes: + - poet-shared:/poet-shared + command: "bash -c \"\ + sawadm keygen --force && \ + mkdir -p /poet-shared/validator-0 || true && \ + cp -a /etc/sawtooth/keys /poet-shared/validator-0/ && \ + while [ ! -f /poet-shared/poet-enclave-measurement ]; do sleep 1; done && \ + while [ ! -f /poet-shared/poet-enclave-basename ]; do sleep 1; done && \ + while [ ! -f /poet-shared/poet.batch ]; do sleep 1; done && \ + cp /poet-shared/poet.batch / && \ + sawset genesis \ + -k /etc/sawtooth/keys/validator.priv \ + -o config-genesis.batch && \ + sawset proposal create \ + -k /etc/sawtooth/keys/validator.priv \ + sawtooth.consensus.algorithm.name=PoET \ + sawtooth.consensus.algorithm.version=0.1 \ + sawtooth.poet.report_public_key_pem=\ + \\\"$$(cat /poet-shared/simulator_rk_pub.pem)\\\" \ + sawtooth.poet.valid_enclave_measurements=$$(cat /poet-shared/poet-enclave-measurement) \ + sawtooth.poet.valid_enclave_basenames=$$(cat /poet-shared/poet-enclave-basename) \ + -o config.batch && \ + sawset proposal create \ + -k /etc/sawtooth/keys/validator.priv \ + sawtooth.poet.target_wait_time=5 \ + sawtooth.poet.initial_wait_time=25 \ + sawtooth.publisher.max_batches_per_block=100 \ + -o poet-settings.batch && \ + sawadm genesis \ + config-genesis.batch config.batch poet.batch poet-settings.batch && \ + sawtooth-validator -v \ + --bind network:tcp://eth0:8800 \ + --bind component:tcp://eth0:4004 \ + --bind consensus:tcp://eth0:5050 \ + --peering static \ + --endpoint tcp://validator-0:8800 \ + --scheduler parallel \ + --network-auth trust + \"" + environment: + PYTHONPATH: "/project/sawtooth-core/consensus/poet/common:\ + /project/sawtooth-core/consensus/poet/simulator:\ + /project/sawtooth-core/consensus/poet/core" + stop_signal: SIGKILL + + validator-1: + image: hyperledger/sawtooth-validator:nightly + container_name: sawtooth-validator-default-1 + expose: + - 4004 + - 5050 + - 8800 + volumes: + - poet-shared:/poet-shared + command: | + bash -c " + sawadm keygen --force && \ + mkdir -p /poet-shared/validator-1 || true && \ + cp -a /etc/sawtooth/keys /poet-shared/validator-1/ && \ + sawtooth-validator -v \ + --bind network:tcp://eth0:8800 \ + --bind component:tcp://eth0:4004 \ + --bind consensus:tcp://eth0:5050 \ + --peering static \ + --endpoint tcp://validator-1:8800 \ + --peers tcp://validator-0:8800 \ + --scheduler parallel \ + --network-auth trust + " + environment: + PYTHONPATH: "/project/sawtooth-core/consensus/poet/common:\ + /project/sawtooth-core/consensus/poet/simulator:\ + /project/sawtooth-core/consensus/poet/core" + stop_signal: SIGKILL + + validator-2: + image: hyperledger/sawtooth-validator:nightly + container_name: sawtooth-validator-default-2 + expose: + - 4004 + - 5050 + - 8800 + volumes: + - poet-shared:/poet-shared + command: | + bash -c " + sawadm keygen --force && \ + mkdir -p /poet-shared/validator-2 && \ + cp -a /etc/sawtooth/keys /poet-shared/validator-2/ && \ + sawtooth-validator -v \ + --bind network:tcp://eth0:8800 \ + --bind component:tcp://eth0:4004 \ + --bind consensus:tcp://eth0:5050 \ + --peering static \ + --endpoint tcp://validator-2:8800 \ + --peers tcp://validator-0:8800,tcp://validator-1:8800 \ + --scheduler parallel \ + --network-auth trust + " + environment: + PYTHONPATH: "/project/sawtooth-core/consensus/poet/common:\ + /project/sawtooth-core/consensus/poet/simulator:\ + /project/sawtooth-core/consensus/poet/core" + stop_signal: SIGKILL + + validator-3: + image: hyperledger/sawtooth-validator:nightly + container_name: sawtooth-validator-default-3 + expose: + - 4004 + - 5050 + - 8800 + volumes: + - poet-shared:/poet-shared + command: | + bash -c " + sawadm keygen --force && \ + mkdir -p /poet-shared/validator-3 && \ + cp -a /etc/sawtooth/keys /poet-shared/validator-3/ && \ + sawtooth-validator -v \ + --bind network:tcp://eth0:8800 \ + --bind component:tcp://eth0:4004 \ + --bind consensus:tcp://eth0:5050 \ + --peering static \ + --endpoint tcp://validator-3:8800 \ + --peers tcp://validator-0:8800,tcp://validator-1:8800,tcp://validator-2:8800 \ + --scheduler parallel \ + --network-auth trust + " + environment: + PYTHONPATH: "/project/sawtooth-core/consensus/poet/common:\ + /project/sawtooth-core/consensus/poet/simulator:\ + /project/sawtooth-core/consensus/poet/core" + stop_signal: SIGKILL + + validator-4: + image: hyperledger/sawtooth-validator:nightly + container_name: sawtooth-validator-default-4 + expose: + - 4004 + - 5050 + - 8800 + volumes: + - poet-shared:/poet-shared + command: | + bash -c " + sawadm keygen --force && \ + mkdir -p /poet-shared/validator-4 && \ + cp -a /etc/sawtooth/keys /poet-shared/validator-4/ && \ + sawtooth-validator -v \ + --bind network:tcp://eth0:8800 \ + --bind component:tcp://eth0:4004 \ + --bind consensus:tcp://eth0:5050 \ + --peering static \ + --endpoint tcp://validator-4:8800 \ + --peers tcp://validator-0:8800,tcp://validator-1:8800,tcp://validator-2:8800,tcp://validator-3:8800 \ + --scheduler parallel \ + --network-auth trust + " + environment: + PYTHONPATH: "/project/sawtooth-core/consensus/poet/common:\ + /project/sawtooth-core/consensus/poet/simulator:\ + /project/sawtooth-core/consensus/poet/core" + stop_signal: SIGKILL + + rest-api-0: + image: hyperledger/sawtooth-rest-api:nightly + container_name: sawtooth-rest-api-default-0 + expose: + - 8008 + command: | + bash -c " + sawtooth-rest-api \ + --connect tcp://validator-0:4004 \ + --bind rest-api-0:8008 + " + stop_signal: SIGKILL + + rest-api-1: + image: hyperledger/sawtooth-rest-api:nightly + container_name: sawtooth-rest-api-default-1 + expose: + - 8008 + command: | + bash -c " + sawtooth-rest-api \ + --connect tcp://validator-1:4004 \ + --bind rest-api-1:8008 + " + stop_signal: SIGKILL + + rest-api-2: + image: hyperledger/sawtooth-rest-api:nightly + container_name: sawtooth-rest-api-default-2 + expose: + - 8008 + command: | + bash -c " + sawtooth-rest-api \ + --connect tcp://validator-2:4004 \ + --bind rest-api-2:8008 + " + stop_signal: SIGKILL + + rest-api-3: + image: hyperledger/sawtooth-rest-api:nightly + container_name: sawtooth-rest-api-default-3 + expose: + - 8008 + command: | + bash -c " + sawtooth-rest-api \ + --connect tcp://validator-3:4004 \ + --bind rest-api-3:8008 + " + stop_signal: SIGKILL + + rest-api-4: + image: hyperledger/sawtooth-rest-api:nightly + container_name: sawtooth-rest-api-default-4 + expose: + - 8008 + command: | + bash -c " + sawtooth-rest-api \ + --connect tcp://validator-4:4004 \ + --bind rest-api-4:8008 + " + stop_signal: SIGKILL + + intkey-tp-0: + image: hyperledger/sawtooth-intkey-tp-python:nightly + container_name: sawtooth-intkey-tp-python-default-0 + expose: + - 4004 + command: intkey-tp-python -C tcp://validator-0:4004 + stop_signal: SIGKILL + + intkey-tp-1: + image: hyperledger/sawtooth-intkey-tp-python:nightly + container_name: sawtooth-intkey-tp-python-default-1 + expose: + - 4004 + command: intkey-tp-python -C tcp://validator-1:4004 + stop_signal: SIGKILL + + intkey-tp-2: + image: hyperledger/sawtooth-intkey-tp-python:nightly + container_name: sawtooth-intkey-tp-python-default-2 + expose: + - 4004 + command: intkey-tp-python -C tcp://validator-2:4004 + stop_signal: SIGKILL + + intkey-tp-3: + image: hyperledger/sawtooth-intkey-tp-python:nightly + container_name: sawtooth-intkey-tp-python-default-3 + expose: + - 4004 + command: intkey-tp-python -C tcp://validator-3:4004 + stop_signal: SIGKILL + + intkey-tp-4: + image: hyperledger/sawtooth-intkey-tp-python:nightly + container_name: sawtooth-intkey-tp-python-default-4 + expose: + - 4004 + command: intkey-tp-python -C tcp://validator-4:4004 + stop_signal: SIGKILL + + xo-tp-0: + image: hyperledger/sawtooth-xo-tp-python:nightly + container_name: sawtooth-xo-tp-python-default-0 + expose: + - 4004 + command: xo-tp-python -vv -C tcp://validator-0:4004 + stop_signal: SIGKILL + + xo-tp-1: + image: hyperledger/sawtooth-xo-tp-python:nightly + container_name: sawtooth-xo-tp-python-default-1 + expose: + - 4004 + command: xo-tp-python -vv -C tcp://validator-1:4004 + stop_signal: SIGKILL + + xo-tp-2: + image: hyperledger/sawtooth-xo-tp-python:nightly + container_name: sawtooth-xo-tp-python-default-2 + expose: + - 4004 + command: xo-tp-python -vv -C tcp://validator-2:4004 + stop_signal: SIGKILL + + xo-tp-3: + image: hyperledger/sawtooth-xo-tp-python:nightly + container_name: sawtooth-xo-tp-python-default-3 + expose: + - 4004 + command: xo-tp-python -vv -C tcp://validator-3:4004 + stop_signal: SIGKILL + + xo-tp-4: + image: hyperledger/sawtooth-xo-tp-python:nightly + container_name: sawtooth-xo-tp-python-default-4 + expose: + - 4004 + command: xo-tp-python -vv -C tcp://validator-4:4004 + stop_signal: SIGKILL + + settings-tp-0: + image: hyperledger/sawtooth-settings-tp:nightly + container_name: sawtooth-settings-tp-default-0 + expose: + - 4004 + command: settings-tp -v -C tcp://validator-0:4004 + stop_signal: SIGKILL + + settings-tp-1: + image: hyperledger/sawtooth-settings-tp:nightly + container_name: sawtooth-settings-tp-default-1 + expose: + - 4004 + command: settings-tp -v -C tcp://validator-1:4004 + stop_signal: SIGKILL + + settings-tp-2: + image: hyperledger/sawtooth-settings-tp:nightly + container_name: sawtooth-settings-tp-default-2 + expose: + - 4004 + command: settings-tp -v -C tcp://validator-2:4004 + stop_signal: SIGKILL + + settings-tp-3: + image: hyperledger/sawtooth-settings-tp:nightly + container_name: sawtooth-settings-tp-default-3 + expose: + - 4004 + command: settings-tp -v -C tcp://validator-3:4004 + stop_signal: SIGKILL + + settings-tp-4: + image: hyperledger/sawtooth-settings-tp:nightly + container_name: sawtooth-settings-tp-default-4 + expose: + - 4004 + command: settings-tp -v -C tcp://validator-4:4004 + stop_signal: SIGKILL + + poet-engine-0: + image: hyperledger/sawtooth-poet-engine:nightly + container_name: sawtooth-poet-engine-0 + volumes: + - poet-shared:/poet-shared + command: "bash -c \"\ + if [ ! -f /poet-shared/poet-enclave-measurement ]; then \ + poet enclave measurement >> /poet-shared/poet-enclave-measurement; \ + fi && \ + if [ ! -f /poet-shared/poet-enclave-basename ]; then \ + poet enclave basename >> /poet-shared/poet-enclave-basename; \ + fi && \ + if [ ! -f /poet-shared/simulator_rk_pub.pem ]; then \ + cp /etc/sawtooth/simulator_rk_pub.pem /poet-shared; \ + fi && \ + while [ ! -f /poet-shared/validator-0/keys/validator.priv ]; do sleep 1; done && \ + cp -a /poet-shared/validator-0/keys /etc/sawtooth && \ + poet registration create -k /etc/sawtooth/keys/validator.priv -o /poet-shared/poet.batch && \ + poet-engine -C tcp://validator-0:5050 --component tcp://validator-0:4004 \ + \"" + + poet-engine-1: + image: hyperledger/sawtooth-poet-engine:nightly + container_name: sawtooth-poet-engine-1 + volumes: + - poet-shared:/poet-shared + command: "bash -c \"\ + while [ ! -f /poet-shared/validator-1/keys/validator.priv ]; do sleep 1; done && \ + cp -a /poet-shared/validator-1/keys /etc/sawtooth && \ + poet-engine -C tcp://validator-1:5050 --component tcp://validator-1:4004 \ + \"" + + poet-engine-2: + image: hyperledger/sawtooth-poet-engine:nightly + container_name: sawtooth-poet-engine-2 + volumes: + - poet-shared:/poet-shared + command: "bash -c \"\ + while [ ! -f /poet-shared/validator-2/keys/validator.priv ]; do sleep 1; done && \ + cp -a /poet-shared/validator-2/keys /etc/sawtooth && \ + poet-engine -C tcp://validator-2:5050 --component tcp://validator-2:4004 \ + \"" + + poet-engine-3: + image: hyperledger/sawtooth-poet-engine:nightly + container_name: sawtooth-poet-engine-3 + volumes: + - poet-shared:/poet-shared + command: "bash -c \"\ + while [ ! -f /poet-shared/validator-3/keys/validator.priv ]; do sleep 1; done && \ + cp -a /poet-shared/validator-3/keys /etc/sawtooth && \ + poet-engine -C tcp://validator-3:5050 --component tcp://validator-3:4004 \ + \"" + + poet-engine-4: + image: hyperledger/sawtooth-poet-engine:nightly + container_name: sawtooth-poet-engine-4 + volumes: + - poet-shared:/poet-shared + command: "bash -c \"\ + while [ ! -f /poet-shared/validator-4/keys/validator.priv ]; do sleep 1; done && \ + cp -a /poet-shared/validator-4/keys /etc/sawtooth && \ + poet-engine -C tcp://validator-4:5050 --component tcp://validator-4:4004 \ + \"" + + poet-validator-registry-tp-0: + image: hyperledger/sawtooth-poet-validator-registry-tp:nightly + container_name: sawtooth-poet-validator-registry-tp-0 + expose: + - 4004 + command: poet-validator-registry-tp -C tcp://validator-0:4004 + environment: + PYTHONPATH: /project/sawtooth-core/consensus/poet/common + stop_signal: SIGKILL + + poet-validator-registry-tp-1: + image: hyperledger/sawtooth-poet-validator-registry-tp:nightly + container_name: sawtooth-poet-validator-registry-tp-1 + expose: + - 4004 + command: poet-validator-registry-tp -C tcp://validator-1:4004 + environment: + PYTHONPATH: /project/sawtooth-core/consensus/poet/common + stop_signal: SIGKILL + + poet-validator-registry-tp-2: + image: hyperledger/sawtooth-poet-validator-registry-tp:nightly + container_name: sawtooth-poet-validator-registry-tp-2 + expose: + - 4004 + command: poet-validator-registry-tp -C tcp://validator-2:4004 + environment: + PYTHONPATH: /project/sawtooth-core/consensus/poet/common + stop_signal: SIGKILL + + poet-validator-registry-tp-3: + image: hyperledger/sawtooth-poet-validator-registry-tp:nightly + container_name: sawtooth-poet-validator-registry-tp-3 + expose: + - 4004 + command: poet-validator-registry-tp -C tcp://validator-3:4004 + environment: + PYTHONPATH: /project/sawtooth-core/consensus/poet/common + stop_signal: SIGKILL + + poet-validator-registry-tp-4: + image: hyperledger/sawtooth-poet-validator-registry-tp:nightly + container_name: sawtooth-poet-validator-registry-tp-4 + expose: + - 4004 + command: poet-validator-registry-tp -C tcp://validator-4:4004 + environment: + PYTHONPATH: /project/sawtooth-core/consensus/poet/common + stop_signal: SIGKILL diff --git a/tools/docker/sawtooth-testnet/sawtooth-default.yaml b/tools/docker/sawtooth-testnet/sawtooth-default.yaml new file mode 100644 index 0000000000..56d3b864c8 --- /dev/null +++ b/tools/docker/sawtooth-testnet/sawtooth-default.yaml @@ -0,0 +1,90 @@ +# Copyright 2017 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ------------------------------------------------------------------------------ + +version: "2.1" + +services: + + settings-tp: + image: hyperledger/sawtooth-settings-tp:nightly + container_name: sawtooth-settings-tp-default + depends_on: + - validator + entrypoint: settings-tp -vv -C tcp://validator:4004 + + intkey-tp-python: + image: hyperledger/sawtooth-intkey-tp-python:nightly + container_name: sawtooth-intkey-tp-python-default + depends_on: + - validator + entrypoint: intkey-tp-python -vv -C tcp://validator:4004 + + xo-tp-python: + image: hyperledger/sawtooth-xo-tp-python:nightly + container_name: sawtooth-xo-tp-python-default + depends_on: + - validator + entrypoint: xo-tp-python -vv -C tcp://validator:4004 + + validator: + image: hyperledger/sawtooth-validator:nightly + container_name: sawtooth-validator-default + expose: + - 4004 + ports: + - "4004:4004" + # start the validator with an empty genesis batch + entrypoint: "bash -c \"\ + sawadm keygen && \ + sawtooth keygen my_key && \ + sawset genesis -k /root/.sawtooth/keys/my_key.priv && \ + sawset proposal create \ + -k /root/.sawtooth/keys/my_key.priv \ + sawtooth.consensus.algorithm.name=Devmode \ + sawtooth.consensus.algorithm.version=0.1 \ + -o config.batch && \ + sawadm genesis config-genesis.batch config.batch && \ + sawtooth-validator -vv \ + --endpoint tcp://validator:8800 \ + --bind component:tcp://eth0:4004 \ + --bind network:tcp://eth0:8800 \ + --bind consensus:tcp://eth0:5050 \ + \"" + + devmode-engine: + image: hyperledger/sawtooth-devmode-engine-rust:nightly + container_name: sawtooth-devmode-engine-rust-default + depends_on: + - validator + entrypoint: devmode-engine-rust -C tcp://validator:5050 + + rest-api: + image: hyperledger/sawtooth-rest-api:nightly + container_name: sawtooth-rest-api-default + ports: + - "8008:8008" + depends_on: + - validator + entrypoint: sawtooth-rest-api -C tcp://validator:4004 --bind rest-api:8008 + + shell: + image: hyperledger/sawtooth-shell:nightly + container_name: sawtooth-shell-default + depends_on: + - rest-api + entrypoint: "bash -c \"\ + sawtooth keygen && \ + tail -f /dev/null \ + \"" diff --git a/tools/docker/sawtooth-testnet/sawtooth-local.yaml b/tools/docker/sawtooth-testnet/sawtooth-local.yaml new file mode 100644 index 0000000000..61109321fd --- /dev/null +++ b/tools/docker/sawtooth-testnet/sawtooth-local.yaml @@ -0,0 +1,89 @@ +# Copyright 2017 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ------------------------------------------------------------------------------ + +version: "2.1" + +services: + + settings-tp: + image: sawtooth-settings-tp:latest + container_name: sawtooth-settings-tp-local + volumes: + - ../../:/project/sawtooth-core + depends_on: + - validator + command: settings-tp -vv -C tcp://validator:4004 + stop_signal: SIGKILL + + intkey-tp-python: + image: hyperledger/sawtooth-intkey-tp-python:nightly + container_name: sawtooth-intkey-tp-python-local + depends_on: + - validator + command: intkey-tp-python -vv -C tcp://validator:4004 + stop_signal: SIGKILL + + xo-tp-python: + image: hyperledger/sawtooth-xo-tp-python:nightly + container_name: sawtooth-xo-tp-python-local + depends_on: + - validator + command: xo-tp-python -vv -C tcp://validator:4004 + stop_signal: SIGKILL + + validator: + image: sawtooth-validator:latest + container_name: sawtooth-validator-local + volumes: + - ../../:/project/sawtooth-core + expose: + - 4004 + - 8800 + ports: + - "4004:4004" + # start the validator with an empty genesis batch + command: "bash -c \"\ + sawadm keygen && \ + sawadm genesis && \ + sawtooth-validator -vv \ + --endpoint tcp://validator:8800 \ + --bind component:tcp://eth0:4004 \ + --bind network:tcp://eth0:8800 \ + \"" + stop_signal: SIGKILL + + rest-api: + image: sawtooth-rest-api:latest + container_name: sawtooth-rest-api-local + volumes: + - ../../:/project/sawtooth-core + ports: + - "8008:8008" + depends_on: + - validator + command: sawtooth-rest-api -v --connect tcp://validator:4004 --bind rest-api:8008 + stop_signal: SIGKILL + + client: + image: sawtooth-dev-python:latest + container_name: sawtooth-client-local + volumes: + - ../../:/project/sawtooth-core + depends_on: + - rest-api + entrypoint: "bash -c \"\ + sawtooth keygen && \ + tail -f /dev/null \ + \"" diff --git a/tools/docker/sawtooth-testnet/script-start-docker.sh b/tools/docker/sawtooth-testnet/script-start-docker.sh new file mode 100755 index 0000000000..555708ba31 --- /dev/null +++ b/tools/docker/sawtooth-testnet/script-start-docker.sh @@ -0,0 +1,2 @@ +echo "[process] start docker environment for Sawtooth testnet" +docker-compose -f sawtooth-default.yaml up -d \ No newline at end of file diff --git a/tools/docker/sawtooth-testnet/smallbank-local-mounted.yaml b/tools/docker/sawtooth-testnet/smallbank-local-mounted.yaml new file mode 100644 index 0000000000..d4c6956db2 --- /dev/null +++ b/tools/docker/sawtooth-testnet/smallbank-local-mounted.yaml @@ -0,0 +1,88 @@ +# Copyright 2017 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ------------------------------------------------------------------------------ + +version: "2.1" + +services: + + settings-tp: + image: sawtooth-settings-tp:latest + volumes: + - ../../:/project/sawtooth-core + container_name: sawtooth-settings-tp-default + depends_on: + - validator + command: settings-tp -vv --connect tcp://validator:4004 + + smallbank-tp-rust: + image: sawtooth-smallbank-tp-rust:latest + container_name: sawtooth-smallbank-tp-rust-default + volumes: + - ../../:/project/sawtooth-core + depends_on: + - validator + command: smallbank_rust -vv -C tcp://validator:4004 + + validator: + image: sawtooth-validator-mounted:latest + container_name: sawtooth-validator-mounted + volumes: + - ../../:/project/sawtooth-core + expose: + - 4004 + ports: + - "4004:4004" + command: "bash -c \"\ + (telegraf &) && \ + sawadm keygen && \ + sawtooth keygen && \ + sawset genesis && \ + sawadm genesis config-genesis.batch && \ + sawtooth-validator -vv \ + --endpoint tcp://validator:8800 \ + --bind component:tcp://eth0:4004 \ + --bind network:tcp://eth0:8800 \ + --opentsdb-url http://influxdb:8086 \ + --opentsdb-db metrics + \"" + + rest-api: + image: sawtooth-rest-api:latest + container_name: sawtooth-rest-api-default + volumes: + - ../../:/project/sawtooth-core + expose: + - 8008 + ports: + - "8008:8008" + depends_on: + - validator + command: sawtooth-rest-api -v --connect tcp://validator:4004 --bind rest-api:8008 --opentsdb-url http://influxdb:8086 --opentsdb-db metrics + + influxdb: + image: sawtooth-stats-influxdb:latest + container_name: sawtooth-stats-influxdb-default + ports: + - "8086:8086" + stop_signal: SIGKILL + + grafana: + image: sawtooth-stats-grafana:latest + container_name: sawtooth-stats-grafana-default + ports: + - "3000:3000" + volumes: + - ../../:/project/sawtooth-core + stop_signal: SIGKILL