Move log decoding to AbiDecoder

This commit is contained in:
Leonid Logvinov
2017-10-03 12:31:46 +03:00
parent a9681072ee
commit 6bbdc98ba2
2 changed files with 38 additions and 54 deletions

View File

@@ -302,7 +302,8 @@ export class ZeroEx {
const transactionReceipt = await this._web3Wrapper.getTransactionReceiptAsync(txHash);
if (!_.isNull(transactionReceipt)) {
intervalUtils.clearAsyncExcludingInterval(intervalId);
const logsWithDecodedArgs = _.map(transactionReceipt.logs, this.tryToDecodeLogOrNoOp.bind(this));
const tryToDecodeLogOrNoOp = this._abiDecoder.tryToDecodeLogOrNoOp.bind(this._abiDecoder);
const logsWithDecodedArgs = _.map(transactionReceipt.logs, tryToDecodeLogOrNoOp);
const transactionReceiptWithDecodedLogArgs: TransactionReceiptWithDecodedLogs = {
...transactionReceipt,
logs: logsWithDecodedArgs,
@@ -313,26 +314,6 @@ export class ZeroEx {
});
return txReceiptPromise;
}
/**
* Gets historical logs without creating a subscription
* @param filter Filter object
* @return Array of logs that match the filter
*/
public async getLogsAsync(filter: FilterObject): Promise<RawLog[]> {
const logs = await this._web3Wrapper.getLogsAsync(filter);
return logs;
}
private tryToDecodeLogOrNoOp(log: Web3.LogEntry): LogWithDecodedArgs|Web3.LogEntry {
const decodedLog = this._abiDecoder.decodeLog(log);
if (_.isUndefined(decodedLog)) {
return log;
}
const logWithDecodedArgs: LogWithDecodedArgs = {
...log,
...decodedLog,
};
return logWithDecodedArgs;
}
/*
* HACK: `TokenWrapper` needs a token transfer proxy address. `TokenTransferProxy` address is fetched from
* an `ExchangeWrapper`. `ExchangeWrapper` needs `TokenWrapper` to validate orders, creating a dependency cycle.

View File

@@ -1,7 +1,7 @@
import * as Web3 from 'web3';
import * as _ from 'lodash';
import * as BigNumber from 'bignumber.js';
import {AbiType, DecodedLogArgs, DecodedArgs} from '../types';
import {AbiType, DecodedLogArgs, DecodedArgs, LogWithDecodedArgs} from '../types';
import * as SolidityCoder from 'web3/lib/solidity/coder';
export class AbiDecoder {
@@ -10,40 +10,43 @@ export class AbiDecoder {
constructor(abiArrays: Web3.AbiDefinition[][]) {
_.map(abiArrays, this.addABI.bind(this));
}
public decodeLog(logItem: Web3.LogEntry): DecodedArgs|undefined {
const methodId = logItem.topics[0];
public tryToDecodeLogOrNoOp(log: Web3.LogEntry): LogWithDecodedArgs|Web3.LogEntry {
const methodId = log.topics[0];
const event = this.methodIds[methodId];
if (!_.isUndefined(event)) {
const logData = logItem.data;
const decodedParams: DecodedLogArgs = {};
let dataIndex = 0;
let topicsIndex = 1;
const nonIndexedInputs = _.filter(event.inputs, input => !input.indexed);
const dataTypes = _.map(nonIndexedInputs, input => input.type);
const decodedData = SolidityCoder.decodeParams(dataTypes, logData.slice(2));
_.map(event.inputs, (param: Web3.EventParameter) => {
let value;
if (param.indexed) {
value = logItem.topics[topicsIndex];
topicsIndex++;
} else {
value = decodedData[dataIndex];
dataIndex++;
}
if (param.type === 'address') {
value = this.padZeros(new BigNumber(value).toString(16));
} else if (param.type === 'uint256' || param.type === 'uint8' || param.type === 'int' ) {
value = new BigNumber(value);
}
decodedParams[param.name] = value;
});
return {
event: event.name,
args: decodedParams,
};
if (_.isUndefined(event)) {
return log;
}
const logData = log.data;
const decodedParams: DecodedLogArgs = {};
let dataIndex = 0;
let topicsIndex = 1;
const nonIndexedInputs = _.filter(event.inputs, input => !input.indexed);
const dataTypes = _.map(nonIndexedInputs, input => input.type);
const decodedData = SolidityCoder.decodeParams(dataTypes, logData.slice(2));
_.map(event.inputs, (param: Web3.EventParameter) => {
let value;
if (param.indexed) {
value = log.topics[topicsIndex];
topicsIndex++;
} else {
value = decodedData[dataIndex];
dataIndex++;
}
if (param.type === 'address') {
value = this.padZeros(new BigNumber(value).toString(16));
} else if (param.type === 'uint256' || param.type === 'uint8' || param.type === 'int' ) {
value = new BigNumber(value);
}
decodedParams[param.name] = value;
});
return {
...log,
event: event.name,
args: decodedParams,
};
}
private addABI(abiArray: Web3.AbiDefinition[]): void {
_.map(abiArray, (abi: Web3.AbiDefinition) => {