Properly unmarshall TransactionReceiptRPC to TransactionReceipt
This commit is contained in:
parent
953f8c119b
commit
22cfdd9f0b
@ -1,4 +1,17 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"version": "3.1.5",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Add unmarshalling of transaction receipts",
|
||||||
|
"pr": 1291
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Return `undefined` instead of `null` if transaction receipt not found",
|
||||||
|
"pr": 1291
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1542208198,
|
"timestamp": 1542208198,
|
||||||
"version": "3.1.4",
|
"version": "3.1.4",
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc -b",
|
"build": "tsc -b",
|
||||||
"build:ci": "yarn build",
|
"build:ci": "yarn build",
|
||||||
|
"watch_without_deps": "tsc -w",
|
||||||
"clean": "shx rm -rf lib generated_docs",
|
"clean": "shx rm -rf lib generated_docs",
|
||||||
"lint": "tslint --format stylish --project .",
|
"lint": "tslint --format stylish --project .",
|
||||||
"test": "yarn run_mocha",
|
"test": "yarn run_mocha",
|
||||||
|
@ -52,6 +52,9 @@ export {
|
|||||||
CallDataRPC,
|
CallDataRPC,
|
||||||
BlockWithoutTransactionDataRPC,
|
BlockWithoutTransactionDataRPC,
|
||||||
BlockWithTransactionDataRPC,
|
BlockWithTransactionDataRPC,
|
||||||
|
TransactionReceiptStatusRPC,
|
||||||
|
TransactionReceiptRPC,
|
||||||
|
LogEntryRPC,
|
||||||
TransactionRPC,
|
TransactionRPC,
|
||||||
TxDataRPC,
|
TxDataRPC,
|
||||||
} from './types';
|
} from './types';
|
||||||
|
@ -9,6 +9,7 @@ import {
|
|||||||
LogEntry,
|
LogEntry,
|
||||||
RawLogEntry,
|
RawLogEntry,
|
||||||
Transaction,
|
Transaction,
|
||||||
|
TransactionReceipt,
|
||||||
TxData,
|
TxData,
|
||||||
} from 'ethereum-types';
|
} from 'ethereum-types';
|
||||||
import ethUtil = require('ethereumjs-util');
|
import ethUtil = require('ethereumjs-util');
|
||||||
@ -21,6 +22,7 @@ import {
|
|||||||
BlockWithTransactionDataRPC,
|
BlockWithTransactionDataRPC,
|
||||||
CallDataRPC,
|
CallDataRPC,
|
||||||
CallTxDataBaseRPC,
|
CallTxDataBaseRPC,
|
||||||
|
TransactionReceiptRPC,
|
||||||
TransactionRPC,
|
TransactionRPC,
|
||||||
TxDataRPC,
|
TxDataRPC,
|
||||||
} from './types';
|
} from './types';
|
||||||
@ -91,6 +93,22 @@ export const marshaller = {
|
|||||||
};
|
};
|
||||||
return tx;
|
return tx;
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Unmarshall transaction receipt
|
||||||
|
* @param txReceiptRpc transaction receipt to unmarshall
|
||||||
|
* @return unmarshalled transaction receipt
|
||||||
|
*/
|
||||||
|
unmarshalTransactionReceipt(txReceiptRpc: TransactionReceiptRPC): TransactionReceipt {
|
||||||
|
const txReceipt = {
|
||||||
|
...txReceiptRpc,
|
||||||
|
blockNumber: utils.convertHexToNumber(txReceiptRpc.blockNumber),
|
||||||
|
transactionIndex: utils.convertHexToNumber(txReceiptRpc.transactionIndex),
|
||||||
|
cumulativeGasUsed: utils.convertHexToNumber(txReceiptRpc.cumulativeGasUsed),
|
||||||
|
gasUsed: utils.convertHexToNumber(txReceiptRpc.gasUsed),
|
||||||
|
logs: _.map(txReceiptRpc.logs, marshaller.unmarshalLog.bind(marshaller)),
|
||||||
|
};
|
||||||
|
return txReceipt;
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* Unmarshall transaction data
|
* Unmarshall transaction data
|
||||||
* @param txDataRpc transaction data to unmarshall
|
* @param txDataRpc transaction data to unmarshall
|
||||||
|
@ -41,6 +41,33 @@ export interface TransactionRPC {
|
|||||||
input: string;
|
input: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TransactionReceiptRPC {
|
||||||
|
blockHash: string;
|
||||||
|
blockNumber: string;
|
||||||
|
transactionHash: string;
|
||||||
|
transactionIndex: string;
|
||||||
|
from: string;
|
||||||
|
to: string;
|
||||||
|
status: TransactionReceiptStatusRPC;
|
||||||
|
cumulativeGasUsed: string;
|
||||||
|
gasUsed: string;
|
||||||
|
contractAddress: string | null;
|
||||||
|
logs: LogEntryRPC[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LogEntryRPC {
|
||||||
|
logIndex: string | null;
|
||||||
|
transactionIndex: string | null;
|
||||||
|
transactionHash: string;
|
||||||
|
blockHash: string | null;
|
||||||
|
blockNumber: string | null;
|
||||||
|
address: string;
|
||||||
|
data: string;
|
||||||
|
topics: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TransactionReceiptStatusRPC = null | string | 0 | 1;
|
||||||
|
|
||||||
export interface CallTxDataBaseRPC {
|
export interface CallTxDataBaseRPC {
|
||||||
to?: string;
|
to?: string;
|
||||||
value?: string;
|
value?: string;
|
||||||
|
@ -27,6 +27,7 @@ import {
|
|||||||
BlockWithoutTransactionDataRPC,
|
BlockWithoutTransactionDataRPC,
|
||||||
BlockWithTransactionDataRPC,
|
BlockWithTransactionDataRPC,
|
||||||
NodeType,
|
NodeType,
|
||||||
|
TransactionReceiptRPC,
|
||||||
TransactionRPC,
|
TransactionRPC,
|
||||||
Web3WrapperErrors,
|
Web3WrapperErrors,
|
||||||
} from './types';
|
} from './types';
|
||||||
@ -212,20 +213,23 @@ export class Web3Wrapper {
|
|||||||
return networkId;
|
return networkId;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Retrieves the transaction receipt for a given transaction hash
|
* Retrieves the transaction receipt for a given transaction hash if found
|
||||||
* @param txHash Transaction hash
|
* @param txHash Transaction hash
|
||||||
* @returns The transaction receipt, including it's status (0: failed, 1: succeeded or undefined: not found)
|
* @returns The transaction receipt, including it's status (0: failed, 1: succeeded). Returns undefined if transaction not found.
|
||||||
*/
|
*/
|
||||||
public async getTransactionReceiptAsync(txHash: string): Promise<TransactionReceipt> {
|
public async getTransactionReceiptIfExistsAsync(txHash: string): Promise<TransactionReceipt | undefined> {
|
||||||
assert.isHexString('txHash', txHash);
|
assert.isHexString('txHash', txHash);
|
||||||
const transactionReceipt = await this.sendRawPayloadAsync<TransactionReceipt>({
|
const transactionReceiptRpc = await this.sendRawPayloadAsync<TransactionReceiptRPC>({
|
||||||
method: 'eth_getTransactionReceipt',
|
method: 'eth_getTransactionReceipt',
|
||||||
params: [txHash],
|
params: [txHash],
|
||||||
});
|
});
|
||||||
if (!_.isNull(transactionReceipt)) {
|
if (!_.isNull(transactionReceiptRpc)) {
|
||||||
transactionReceipt.status = Web3Wrapper._normalizeTxReceiptStatus(transactionReceipt.status);
|
transactionReceiptRpc.status = Web3Wrapper._normalizeTxReceiptStatus(transactionReceiptRpc.status);
|
||||||
}
|
const transactionReceipt = marshaller.unmarshalTransactionReceipt(transactionReceiptRpc);
|
||||||
return transactionReceipt;
|
return transactionReceipt;
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Retrieves the transaction data for a given transaction
|
* Retrieves the transaction data for a given transaction
|
||||||
@ -572,8 +576,8 @@ export class Web3Wrapper {
|
|||||||
assert.isNumber('timeoutMs', timeoutMs);
|
assert.isNumber('timeoutMs', timeoutMs);
|
||||||
}
|
}
|
||||||
// Immediately check if the transaction has already been mined.
|
// Immediately check if the transaction has already been mined.
|
||||||
let transactionReceipt = await this.getTransactionReceiptAsync(txHash);
|
let transactionReceipt = await this.getTransactionReceiptIfExistsAsync(txHash);
|
||||||
if (!_.isNull(transactionReceipt) && !_.isNull(transactionReceipt.blockNumber)) {
|
if (!_.isUndefined(transactionReceipt) && !_.isNull(transactionReceipt.blockNumber)) {
|
||||||
const logsWithDecodedArgs = _.map(
|
const logsWithDecodedArgs = _.map(
|
||||||
transactionReceipt.logs,
|
transactionReceipt.logs,
|
||||||
this.abiDecoder.tryToDecodeLogOrNoop.bind(this.abiDecoder),
|
this.abiDecoder.tryToDecodeLogOrNoop.bind(this.abiDecoder),
|
||||||
@ -600,8 +604,8 @@ export class Web3Wrapper {
|
|||||||
return reject(Web3WrapperErrors.TransactionMiningTimeout);
|
return reject(Web3WrapperErrors.TransactionMiningTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
transactionReceipt = await this.getTransactionReceiptAsync(txHash);
|
transactionReceipt = await this.getTransactionReceiptIfExistsAsync(txHash);
|
||||||
if (!_.isNull(transactionReceipt)) {
|
if (!_.isUndefined(transactionReceipt)) {
|
||||||
intervalUtils.clearAsyncExcludingInterval(intervalId);
|
intervalUtils.clearAsyncExcludingInterval(intervalId);
|
||||||
const logsWithDecodedArgs = _.map(
|
const logsWithDecodedArgs = _.map(
|
||||||
transactionReceipt.logs,
|
transactionReceipt.logs,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import * as chai from 'chai';
|
import * as chai from 'chai';
|
||||||
import { BlockParamLiteral, JSONRPCErrorCallback, JSONRPCRequestPayload } from 'ethereum-types';
|
import { BlockParamLiteral, JSONRPCErrorCallback, JSONRPCRequestPayload, TransactionReceipt } from 'ethereum-types';
|
||||||
import * as Ganache from 'ganache-core';
|
import * as Ganache from 'ganache-core';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import 'mocha';
|
import 'mocha';
|
||||||
@ -98,6 +98,18 @@ describe('Web3Wrapper tests', () => {
|
|||||||
expect(typeof blockNumber).to.be.equal('number');
|
expect(typeof blockNumber).to.be.equal('number');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
describe('#getTransactionReceiptAsync/awaitTransactionSuccessAsync', () => {
|
||||||
|
it('get block number', async () => {
|
||||||
|
const payload = { from: addresses[0], to: addresses[1], value: 1 };
|
||||||
|
const txHash = await web3Wrapper.sendTransactionAsync(payload);
|
||||||
|
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
|
||||||
|
const receiptIfExists = await web3Wrapper.getTransactionReceiptIfExistsAsync(txHash);
|
||||||
|
expect(receiptIfExists).to.not.be.undefined();
|
||||||
|
const receipt = receiptIfExists as TransactionReceipt;
|
||||||
|
expect(receipt.transactionIndex).to.be.a('number');
|
||||||
|
expect(receipt.transactionHash).to.be.equal(txHash);
|
||||||
|
});
|
||||||
|
});
|
||||||
describe('#getBlockIfExistsAsync', () => {
|
describe('#getBlockIfExistsAsync', () => {
|
||||||
it('gets block when supplied a valid BlockParamLiteral value', async () => {
|
it('gets block when supplied a valid BlockParamLiteral value', async () => {
|
||||||
const blockParamLiteral = BlockParamLiteral.Earliest;
|
const blockParamLiteral = BlockParamLiteral.Earliest;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user