From 1050ecdf3c9e0dbc881342b8ff377180ed1b0dad Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 5 Jul 2018 00:36:01 +0200 Subject: Refactor Web3Wrapper to no longer use Web3.js & add more test coverage --- packages/web3-wrapper/src/marshaller.ts | 177 ++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 packages/web3-wrapper/src/marshaller.ts (limited to 'packages/web3-wrapper/src/marshaller.ts') diff --git a/packages/web3-wrapper/src/marshaller.ts b/packages/web3-wrapper/src/marshaller.ts new file mode 100644 index 000000000..06556ce90 --- /dev/null +++ b/packages/web3-wrapper/src/marshaller.ts @@ -0,0 +1,177 @@ +import { addressUtils, BigNumber } from '@0xproject/utils'; +import { + BlockParam, + BlockParamLiteral, + BlockWithoutTransactionData, + BlockWithTransactionData, + CallData, + CallTxDataBase, + LogEntry, + RawLogEntry, + Transaction, + TxData, +} from 'ethereum-types'; +import ethUtil = require('ethereumjs-util'); +import * as _ from 'lodash'; +import web3Utils = require('web3-utils'); + +import { utils } from './utils'; + +import { + AbstractBlockRPC, + BlockWithoutTransactionDataRPC, + BlockWithTransactionDataRPC, + CallDataRPC, + CallTxDataBaseRPC, + TransactionRPC, + TxDataRPC, +} from './types'; + +export const marshaller = { + unmarshalIntoBlockWithoutTransactionData( + blockWithHexValues: BlockWithoutTransactionDataRPC, + ): BlockWithoutTransactionData { + const block = { + ...blockWithHexValues, + gasLimit: web3Utils.toDecimal(blockWithHexValues.gasLimit), + gasUsed: web3Utils.toDecimal(blockWithHexValues.gasUsed), + size: web3Utils.toDecimal(blockWithHexValues.size), + timestamp: web3Utils.toDecimal(blockWithHexValues.timestamp), + number: _.isNull(blockWithHexValues.number) ? null : web3Utils.toDecimal(blockWithHexValues.number), + difficulty: this._convertAmountToBigNumber(blockWithHexValues.difficulty), + totalDifficulty: this._convertAmountToBigNumber(blockWithHexValues.totalDifficulty), + }; + return block; + }, + unmarshalIntoBlockWithTransactionData(blockWithHexValues: BlockWithTransactionDataRPC): BlockWithTransactionData { + const block = { + ...blockWithHexValues, + gasLimit: web3Utils.toDecimal(blockWithHexValues.gasLimit), + gasUsed: web3Utils.toDecimal(blockWithHexValues.gasUsed), + size: web3Utils.toDecimal(blockWithHexValues.size), + timestamp: web3Utils.toDecimal(blockWithHexValues.timestamp), + number: _.isNull(blockWithHexValues.number) ? null : web3Utils.toDecimal(blockWithHexValues.number), + difficulty: this._convertAmountToBigNumber(blockWithHexValues.difficulty), + totalDifficulty: this._convertAmountToBigNumber(blockWithHexValues.totalDifficulty), + transactions: [] as Transaction[], + }; + block.transactions = _.map(blockWithHexValues.transactions, (tx: TransactionRPC) => { + const transaction = this.unmarshalTransaction(tx); + return transaction; + }); + return block; + }, + unmarshalTransaction(txRpc: TransactionRPC): Transaction { + const tx = { + ...txRpc, + blockNumber: !_.isNull(txRpc.blockNumber) ? web3Utils.toDecimal(txRpc.blockNumber) : null, + transactionIndex: !_.isNull(txRpc.transactionIndex) ? web3Utils.toDecimal(txRpc.transactionIndex) : null, + nonce: web3Utils.toDecimal(txRpc.nonce), + gas: web3Utils.toDecimal(txRpc.gas), + gasPrice: this._convertAmountToBigNumber(txRpc.gasPrice), + value: this._convertAmountToBigNumber(txRpc.value), + }; + return tx; + }, + marshalTxData(txData: Partial): Partial { + if (_.isUndefined(txData.from)) { + throw new Error(`txData is missing required "from" address.`); + } + const callTxDataBase = { + ...txData, + }; + delete callTxDataBase.from; + const callTxDataBaseRPC = this._marshalCallTxDataBase(callTxDataBase); + const txDataRPC = { + ...callTxDataBaseRPC, + from: this.marshalAddress(txData.from), + }; + const prunableIfUndefined = ['gasPrice', 'gas', 'value', 'nonce']; + _.each(txDataRPC, (value: any, key: string) => { + if (_.isUndefined(value) && _.includes(prunableIfUndefined, key)) { + delete (txDataRPC as any)[key]; + } + }); + return txDataRPC; + }, + marshalCallData(callData: Partial): Partial { + const callTxDataBase = { + ...callData, + }; + delete callTxDataBase.from; + const callTxDataBaseRPC = this._marshalCallTxDataBase(callTxDataBase); + const callDataRPC = { + ...callTxDataBaseRPC, + from: _.isUndefined(callData.from) ? undefined : this.marshalAddress(callData.from), + }; + return callDataRPC; + }, + marshalAddress(address: string): string { + if (addressUtils.isAddress(address)) { + return ethUtil.addHexPrefix(address); + } + throw new Error(`Invalid address encountered: ${address}`); + }, + marshalBlockParam(blockParam: BlockParam | string | number | undefined): string | undefined { + if (_.isUndefined(blockParam)) { + return BlockParamLiteral.Latest; + } + const encodedBlockParam = _.isNumber(blockParam) ? web3Utils.toHex(blockParam) : blockParam; + return encodedBlockParam; + }, + unmarshalLog(rawLog: RawLogEntry): LogEntry { + const formattedLog = { + ...rawLog, + logIndex: this.convertHexToNumberOrNull(rawLog.logIndex), + blockNumber: this.convertHexToNumberOrNull(rawLog.blockNumber), + transactionIndex: this.convertHexToNumberOrNull(rawLog.transactionIndex), + }; + return formattedLog; + }, + _marshalCallTxDataBase(callTxDataBase: Partial): Partial { + const callTxDataBaseRPC = { + ...callTxDataBase, + to: _.isUndefined(callTxDataBase.to) ? undefined : this.marshalAddress(callTxDataBase.to), + gasPrice: _.isUndefined(callTxDataBase.gasPrice) + ? undefined + : this._encodeAmountAsHexString(callTxDataBase.gasPrice), + gas: _.isUndefined(callTxDataBase.gas) ? undefined : this._encodeAmountAsHexString(callTxDataBase.gas), + value: _.isUndefined(callTxDataBase.value) + ? undefined + : this._encodeAmountAsHexString(callTxDataBase.value), + nonce: _.isUndefined(callTxDataBase.nonce) + ? undefined + : this._encodeAmountAsHexString(callTxDataBase.nonce), + }; + + return callTxDataBaseRPC; + }, + convertHexToNumberOrNull(hex: string | null): number | null { + if (_.isNull(hex)) { + return null; + } + const decimal = web3Utils.toDecimal(hex); + return decimal; + }, + _convertAmountToBigNumber(value: string | number | BigNumber): BigNumber { + const num = value || 0; + const isBigNumber = utils.isBigNumber(num); + if (isBigNumber) { + return num as BigNumber; + } + + if (_.isString(num) && (num.indexOf('0x') === 0 || num.indexOf('-0x') === 0)) { + return new BigNumber(num.replace('0x', ''), 16); + } + + const baseTen = 10; + return new BigNumber((num as number).toString(baseTen), baseTen); + }, + _encodeAmountAsHexString(value: string | number | BigNumber): string { + const valueBigNumber = this._convertAmountToBigNumber(value); + const hexBase = 16; + const valueHex = valueBigNumber.toString(hexBase); + + return valueBigNumber.lessThan(0) ? '-0x' + valueHex.substr(1) : '0x' + valueHex; + }, +}; -- cgit v1.2.3 From fd242a9cba7516f08579f0e97923a15740ef4d7a Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 5 Jul 2018 01:38:14 +0200 Subject: Remove web3Utils dep and write necessary utility methods --- packages/web3-wrapper/src/marshaller.ts | 87 ++++++++++++--------------------- 1 file changed, 30 insertions(+), 57 deletions(-) (limited to 'packages/web3-wrapper/src/marshaller.ts') diff --git a/packages/web3-wrapper/src/marshaller.ts b/packages/web3-wrapper/src/marshaller.ts index 06556ce90..d0cf6ff2d 100644 --- a/packages/web3-wrapper/src/marshaller.ts +++ b/packages/web3-wrapper/src/marshaller.ts @@ -13,7 +13,6 @@ import { } from 'ethereum-types'; import ethUtil = require('ethereumjs-util'); import * as _ from 'lodash'; -import web3Utils = require('web3-utils'); import { utils } from './utils'; @@ -33,26 +32,26 @@ export const marshaller = { ): BlockWithoutTransactionData { const block = { ...blockWithHexValues, - gasLimit: web3Utils.toDecimal(blockWithHexValues.gasLimit), - gasUsed: web3Utils.toDecimal(blockWithHexValues.gasUsed), - size: web3Utils.toDecimal(blockWithHexValues.size), - timestamp: web3Utils.toDecimal(blockWithHexValues.timestamp), - number: _.isNull(blockWithHexValues.number) ? null : web3Utils.toDecimal(blockWithHexValues.number), - difficulty: this._convertAmountToBigNumber(blockWithHexValues.difficulty), - totalDifficulty: this._convertAmountToBigNumber(blockWithHexValues.totalDifficulty), + gasLimit: utils.convertHexToNumber(blockWithHexValues.gasLimit), + gasUsed: utils.convertHexToNumber(blockWithHexValues.gasUsed), + size: utils.convertHexToNumber(blockWithHexValues.size), + timestamp: utils.convertHexToNumber(blockWithHexValues.timestamp), + number: _.isNull(blockWithHexValues.number) ? null : utils.convertHexToNumber(blockWithHexValues.number), + difficulty: utils.convertAmountToBigNumber(blockWithHexValues.difficulty), + totalDifficulty: utils.convertAmountToBigNumber(blockWithHexValues.totalDifficulty), }; return block; }, unmarshalIntoBlockWithTransactionData(blockWithHexValues: BlockWithTransactionDataRPC): BlockWithTransactionData { const block = { ...blockWithHexValues, - gasLimit: web3Utils.toDecimal(blockWithHexValues.gasLimit), - gasUsed: web3Utils.toDecimal(blockWithHexValues.gasUsed), - size: web3Utils.toDecimal(blockWithHexValues.size), - timestamp: web3Utils.toDecimal(blockWithHexValues.timestamp), - number: _.isNull(blockWithHexValues.number) ? null : web3Utils.toDecimal(blockWithHexValues.number), - difficulty: this._convertAmountToBigNumber(blockWithHexValues.difficulty), - totalDifficulty: this._convertAmountToBigNumber(blockWithHexValues.totalDifficulty), + gasLimit: utils.convertHexToNumber(blockWithHexValues.gasLimit), + gasUsed: utils.convertHexToNumber(blockWithHexValues.gasUsed), + size: utils.convertHexToNumber(blockWithHexValues.size), + timestamp: utils.convertHexToNumber(blockWithHexValues.timestamp), + number: _.isNull(blockWithHexValues.number) ? null : utils.convertHexToNumber(blockWithHexValues.number), + difficulty: utils.convertAmountToBigNumber(blockWithHexValues.difficulty), + totalDifficulty: utils.convertAmountToBigNumber(blockWithHexValues.totalDifficulty), transactions: [] as Transaction[], }; block.transactions = _.map(blockWithHexValues.transactions, (tx: TransactionRPC) => { @@ -64,12 +63,14 @@ export const marshaller = { unmarshalTransaction(txRpc: TransactionRPC): Transaction { const tx = { ...txRpc, - blockNumber: !_.isNull(txRpc.blockNumber) ? web3Utils.toDecimal(txRpc.blockNumber) : null, - transactionIndex: !_.isNull(txRpc.transactionIndex) ? web3Utils.toDecimal(txRpc.transactionIndex) : null, - nonce: web3Utils.toDecimal(txRpc.nonce), - gas: web3Utils.toDecimal(txRpc.gas), - gasPrice: this._convertAmountToBigNumber(txRpc.gasPrice), - value: this._convertAmountToBigNumber(txRpc.value), + blockNumber: !_.isNull(txRpc.blockNumber) ? utils.convertHexToNumber(txRpc.blockNumber) : null, + transactionIndex: !_.isNull(txRpc.transactionIndex) + ? utils.convertHexToNumber(txRpc.transactionIndex) + : null, + nonce: utils.convertHexToNumber(txRpc.nonce), + gas: utils.convertHexToNumber(txRpc.gas), + gasPrice: utils.convertAmountToBigNumber(txRpc.gasPrice), + value: utils.convertAmountToBigNumber(txRpc.value), }; return tx; }, @@ -116,15 +117,15 @@ export const marshaller = { if (_.isUndefined(blockParam)) { return BlockParamLiteral.Latest; } - const encodedBlockParam = _.isNumber(blockParam) ? web3Utils.toHex(blockParam) : blockParam; + const encodedBlockParam = _.isNumber(blockParam) ? utils.numberToHex(blockParam) : blockParam; return encodedBlockParam; }, unmarshalLog(rawLog: RawLogEntry): LogEntry { const formattedLog = { ...rawLog, - logIndex: this.convertHexToNumberOrNull(rawLog.logIndex), - blockNumber: this.convertHexToNumberOrNull(rawLog.blockNumber), - transactionIndex: this.convertHexToNumberOrNull(rawLog.transactionIndex), + logIndex: utils.convertHexToNumberOrNull(rawLog.logIndex), + blockNumber: utils.convertHexToNumberOrNull(rawLog.blockNumber), + transactionIndex: utils.convertHexToNumberOrNull(rawLog.transactionIndex), }; return formattedLog; }, @@ -134,44 +135,16 @@ export const marshaller = { to: _.isUndefined(callTxDataBase.to) ? undefined : this.marshalAddress(callTxDataBase.to), gasPrice: _.isUndefined(callTxDataBase.gasPrice) ? undefined - : this._encodeAmountAsHexString(callTxDataBase.gasPrice), - gas: _.isUndefined(callTxDataBase.gas) ? undefined : this._encodeAmountAsHexString(callTxDataBase.gas), + : utils.encodeAmountAsHexString(callTxDataBase.gasPrice), + gas: _.isUndefined(callTxDataBase.gas) ? undefined : utils.encodeAmountAsHexString(callTxDataBase.gas), value: _.isUndefined(callTxDataBase.value) ? undefined - : this._encodeAmountAsHexString(callTxDataBase.value), + : utils.encodeAmountAsHexString(callTxDataBase.value), nonce: _.isUndefined(callTxDataBase.nonce) ? undefined - : this._encodeAmountAsHexString(callTxDataBase.nonce), + : utils.encodeAmountAsHexString(callTxDataBase.nonce), }; return callTxDataBaseRPC; }, - convertHexToNumberOrNull(hex: string | null): number | null { - if (_.isNull(hex)) { - return null; - } - const decimal = web3Utils.toDecimal(hex); - return decimal; - }, - _convertAmountToBigNumber(value: string | number | BigNumber): BigNumber { - const num = value || 0; - const isBigNumber = utils.isBigNumber(num); - if (isBigNumber) { - return num as BigNumber; - } - - if (_.isString(num) && (num.indexOf('0x') === 0 || num.indexOf('-0x') === 0)) { - return new BigNumber(num.replace('0x', ''), 16); - } - - const baseTen = 10; - return new BigNumber((num as number).toString(baseTen), baseTen); - }, - _encodeAmountAsHexString(value: string | number | BigNumber): string { - const valueBigNumber = this._convertAmountToBigNumber(value); - const hexBase = 16; - const valueHex = valueBigNumber.toString(hexBase); - - return valueBigNumber.lessThan(0) ? '-0x' + valueHex.substr(1) : '0x' + valueHex; - }, }; -- cgit v1.2.3 From f5b1fe0e6b47e18e10ca42f734639482c5a03239 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 5 Jul 2018 01:45:56 +0200 Subject: Fix linter issues --- packages/web3-wrapper/src/marshaller.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'packages/web3-wrapper/src/marshaller.ts') diff --git a/packages/web3-wrapper/src/marshaller.ts b/packages/web3-wrapper/src/marshaller.ts index d0cf6ff2d..84c351387 100644 --- a/packages/web3-wrapper/src/marshaller.ts +++ b/packages/web3-wrapper/src/marshaller.ts @@ -1,4 +1,4 @@ -import { addressUtils, BigNumber } from '@0xproject/utils'; +import { addressUtils } from '@0xproject/utils'; import { BlockParam, BlockParamLiteral, @@ -17,7 +17,6 @@ import * as _ from 'lodash'; import { utils } from './utils'; import { - AbstractBlockRPC, BlockWithoutTransactionDataRPC, BlockWithTransactionDataRPC, CallDataRPC, -- cgit v1.2.3 From 3d67f122a501e49a005c4ebdb0a68be0f67fcea8 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 5 Jul 2018 12:03:34 +0200 Subject: Move 'from' check to sendTransaction --- packages/web3-wrapper/src/marshaller.ts | 3 --- 1 file changed, 3 deletions(-) (limited to 'packages/web3-wrapper/src/marshaller.ts') diff --git a/packages/web3-wrapper/src/marshaller.ts b/packages/web3-wrapper/src/marshaller.ts index 84c351387..7af61752d 100644 --- a/packages/web3-wrapper/src/marshaller.ts +++ b/packages/web3-wrapper/src/marshaller.ts @@ -74,9 +74,6 @@ export const marshaller = { return tx; }, marshalTxData(txData: Partial): Partial { - if (_.isUndefined(txData.from)) { - throw new Error(`txData is missing required "from" address.`); - } const callTxDataBase = { ...txData, }; -- cgit v1.2.3 From 11747c6cf47a2f75d32953c84ccdf66f6f2f70a3 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 5 Jul 2018 12:34:15 +0200 Subject: Make sure from is included in txData --- packages/web3-wrapper/src/marshaller.ts | 3 +++ 1 file changed, 3 insertions(+) (limited to 'packages/web3-wrapper/src/marshaller.ts') diff --git a/packages/web3-wrapper/src/marshaller.ts b/packages/web3-wrapper/src/marshaller.ts index 7af61752d..e9fd35a11 100644 --- a/packages/web3-wrapper/src/marshaller.ts +++ b/packages/web3-wrapper/src/marshaller.ts @@ -74,6 +74,9 @@ export const marshaller = { return tx; }, marshalTxData(txData: Partial): Partial { + if (_.isUndefined(txData.from)) { + throw new Error(`txData must include valid 'from' value.`); + } const callTxDataBase = { ...txData, }; -- cgit v1.2.3