Skip to content

Commit

Permalink
refactor(Go-Ethereum Validator): add getNonceHex on Go-Ethereum Valid…
Browse files Browse the repository at this point in the history
…ator

Signed-off-by: Takuma TAKEUCHI <takeuchi.takuma@fujitsu.com>
  • Loading branch information
takeutak committed May 25, 2021
1 parent 4c0b0bf commit 43d399a
Show file tree
Hide file tree
Showing 9 changed files with 425 additions and 50 deletions.
1 change: 0 additions & 1 deletion examples/cartrade/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,3 @@ Before you begin, you need to check that you have all the prerequisites installe
1. Stop the docker containers of Ethereum and Fabric
- Press the command `docker stop <CONTAINER ID>` to stop the container corresponding to the above containers which were launched by `./script-start-ledgers.sh` on the boot method. If you want to destroy the docker containers, press the command `docker rm <CONTAINER ID>` after the above.
- If any other docker containers are not running on your machine, you can destroy the Docker containers only with `docker ps -aq | xargs docker stop` and `docker ps -aq | xargs docker rm`.

128 changes: 92 additions & 36 deletions examples/cartrade/TransactionEthereum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* TransactionEthereum.ts
*/

import { LPInfoHolder } from '../../packages/routing-interface/util/LPInfoHolder';
import { VerifierBase } from '../../packages/ledger-plugin/VerifierBase';
import { TransactionSigner } from '../../packages/ledger-plugin/util/TransactionSigner';

const ethJsCommon = require('ethereumjs-common').default;
Expand All @@ -20,51 +22,103 @@ const logger = getLogger(`${moduleName}`);
logger.level = config.logLevel;

const mapFromAddressNonce: Map<string, number> = new Map();
let xConnectInfo: LPInfoHolder = null; // connection information
let xVerifierEthereum: VerifierBase = null;

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.cartradeInfo.ethereum.gethURL);
const provider = new libWeb3.providers.HttpProvider(config.cartradeInfo.ethereum.gethURL);
const web3 = new libWeb3(provider);
logger.debug(`makeRawTransaction: txParam: ${JSON.stringify(txParam)}`);

getNewNonce(txParam.fromAddress)
.then(result => {
logger.debug(`##makeRawTransaction(A): result: ${JSON.stringify(result)}`);

const txnCountHex: string = result.txnCountHex;

const rawTx: { nonce: string, to: string, value: number, gas: number } = {
"nonce": txnCountHex,
"to": txParam.toAddress,
"value": txParam.amount,
"gas": txParam.gas,
}
logger.debug(`##makeRawTransaction(B), rawTx: ${JSON.stringify(rawTx)}`);

// web3_v1.2.9_support
web3.eth.getTransactionCount(txParam.fromAddress)
.then(_nonce => {
let txnCount: number = _nonce;
// NOTE: No need to count up.
const signedTx = TransactionSigner.signTxEthereum(rawTx, txParam.fromAddressPkey);
const resp: { data: {}, txId: string } = {
data: { serializedTx: signedTx["serializedTx"] },
txId: signedTx["txId"]
}

// 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 rawTx: { nonce: number, to: string, value: number, gas: number } = {
"nonce": web3.utils.toHex(txnCount),
"to": txParam.toAddress,
"value": txParam.amount,
"gas": txParam.gas,
}
return resolve(resp);
})
} catch (err) {
logger.error(err);
return reject(err);
};
});
}

const signedTx = TransactionSigner.signTxEthereum(rawTx, txParam.fromAddressPkey);

const result: { data: {}, txId: string } = {
data: { serializedTx: signedTx["serializedTx"] },
txId: signedTx["txId"]
}
function getNewNonce(fromAddress: string): Promise<{txnCountHex: string}> {
return new Promise(async (resolve, reject) => {
try {
logger.debug(`getNewNonce start: fromAddress: ${fromAddress}`);

if (xConnectInfo === null) {
xConnectInfo = new LPInfoHolder();
}

if (xVerifierEthereum === null) {
logger.debug("create verifierEthereum");
const ledgerPluginInfo: string = xConnectInfo.getLegerPluginInfo("84jUisrs");
xVerifierEthereum = new VerifierBase(ledgerPluginInfo);
}


// Get the number of transactions in account
const contract = {}; // NOTE: Since contract does not need to be specified, specify an empty object.
let method = {type: "function", command: "getNonce"};
const template = "default";
let args = {"args": {"args": [fromAddress]}};

return resolve(result);
})
logger.debug(`##getNewNonce(A): call validator#getNonce()`);
xVerifierEthereum.execSyncFunction(contract, method, template, args)
.then(result => {
// logger.debug(`##getNewNonce(A): result: ${JSON.stringify(result)}`);

let txnCount: number = result.data.nonce;
let txnCountHex: string = result.data.nonceHex;

const latestNonce = getLatestNonce(fromAddress);
// logger.debug(`##getNewNonce(B): fromAddress: ${fromAddress}, txnCount: ${txnCount}, latestNonce: ${latestNonce}`);
if (txnCount <= latestNonce) {
// nonce correction
txnCount = latestNonce + 1;
logger.debug(`##getNewNonce(C): Adjust txnCount, fromAddress: ${fromAddress}, txnCount: ${txnCount}, latestNonce: ${latestNonce}`);

const method = {type: "function", command: "toHex"};
const args = {"args": {"args": [txnCount]}};

logger.debug(`##getNewNonce(D): call validator#toHex()`);
xVerifierEthereum.execSyncFunction(contract, method, template, args)
.then(result => {
txnCountHex = result.data.hexStr;
logger.debug(`##getNewNonce(E): txnCountHex: ${txnCountHex}`);

// logger.debug(`##getNewNonce(F) _nonce: ${txnCount}, latestNonce: ${latestNonce}`);
setLatestNonce(fromAddress, txnCount);

return resolve({txnCountHex: txnCountHex});
})
} else {
// logger.debug(`##getNewNonce(F) _nonce: ${txnCount}, latestNonce: ${latestNonce}`);
setLatestNonce(fromAddress, txnCount);

logger.debug(`##getNewNonce(G): txnCountHex: ${txnCountHex}`);
return resolve({txnCountHex: txnCountHex});
}
})
} catch (err) {
logger.error(err);
return reject(err);
Expand All @@ -81,6 +135,8 @@ function getLatestNonce(fromAddress: string): number {
return -1;
}


function setLatestNonce(fromAddress: string, nonce: number): void {
mapFromAddressNonce.set(fromAddress, nonce);
}

1 change: 1 addition & 0 deletions packages/ledger-plugin/ValidatorAuthentication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export class ValidatorAuthentication {
expiresIn: '1000'
}

// logger.debug(`payload = ${JSON.stringify(payload)}`);
const signature: string = jwt.sign(payload, privateKey, option);
logger.debug(`signature = ${signature}`);
return signature;
Expand Down
28 changes: 28 additions & 0 deletions packages/ledger-plugin/go-ethereum/validator/src/core/bin/www.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,34 @@ io.on('connection', function(client) {
logger.error('Detail :' + JSON.stringify(errObj));
client.emit("connector_error", errObj);
});
} else if (methodType === "function") {
const func = args["method"].command;
// Check for the existence of the specified function and call it if it exists.
if (Splug.isExistFunction(func)) {
// Can be called with Server plugin function name.
Splug[func](args)
.then((respObj) => {
logger.info('*** RESPONSE ***');
logger.info('Client ID :' + client.id);
logger.info('Response :' + JSON.stringify(respObj));
client.emit("response", respObj);
})
.catch((errObj) => {
logger.error('*** ERROR ***');
logger.error('Client ID :' + client.id);
logger.error('Detail :' + JSON.stringify(errObj));
client.emit("connector_error", errObj);
});
} else {
// No such function
const emsg = "Function " + func + " not found!";
logger.error(emsg);
const retObj = {
"status" : 504,
"errorDetail" : emsg
};
client.emit("connector_error", retObj);
}
} else {
// No such function
const emsg = "method.type " + methodType + " not found!";
Expand Down
Loading

0 comments on commit 43d399a

Please sign in to comment.