Skip to content

Commit

Permalink
[BUGFIX] Make tracking failed claims more persistent.
Browse files Browse the repository at this point in the history
  • Loading branch information
e00dan committed Aug 8, 2018
1 parent 1d93a97 commit adf0265
Show file tree
Hide file tree
Showing 10 changed files with 1,449 additions and 1,386 deletions.
2,630 changes: 1,322 additions & 1,308 deletions package-lock.json

Large diffs are not rendered by default.

18 changes: 7 additions & 11 deletions src/Actions/Actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,14 @@ export default class Actions {
}

let claimingError;
let from;

try {
const { receipt, from, error } = await this.config.wallet.sendFromNext(opts);
const walletReceipt = await this.config.wallet.sendFromNext(opts);

const { receipt, error } = walletReceipt;

from = walletReceipt.from;

if (!error && isTransactionStatusSuccessful(receipt.status)) {
await txRequest.refreshData();
Expand All @@ -55,16 +60,7 @@ export default class Actions {
claimingError = err;
}

if (this.config.cache.has(txRequest.address)) {
this.config.cache.get(txRequest.address).claimingFailed = true;
} else {
this.config.cache.set(txRequest.address, {
claimedBy: null,
claimingFailed: true,
wasCalled: false,
windowStart: null
});
}
this.config.statsDb.addFailedClaim(from, txRequest.address);

this.config.logger.error(`[${txRequest.address}] error: ${claimingError}`);

Expand Down
1 change: 0 additions & 1 deletion src/Cache/Cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import BigNumber from 'bignumber.js';

export interface ICachedTxDetails {
claimedBy: string;
claimingFailed: boolean;
wasCalled: boolean;
windowStart: BigNumber;
}
Expand Down
90 changes: 46 additions & 44 deletions src/Config/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,24 +79,24 @@ export default class Config implements IConfigParams {
this.economicStrategy = params.economicStrategy;
}

public clientSet (): boolean {
public clientSet(): boolean {
return typeof this.client === 'string';
}

public async awaitClientSet (): Promise<any> {
public async awaitClientSet(): Promise<any> {
if (this.clientSet()) {
return true;
} else {
return new Promise((resolve) => {
return new Promise(resolve => {
setTimeout(() => {
resolve(this.awaitClientSet());
}, 100);
})
resolve(this.awaitClientSet());
}, 100);
});
}
}

public async getConnectedClient(): Promise<any> {
return new Promise( async (resolve, reject) => {
return new Promise(async (resolve, reject) => {
if (!this.web3) {
reject();
}
Expand All @@ -108,54 +108,56 @@ export default class Config implements IConfigParams {
method,
params: [],
id: 0x07a
}, async(err: Error, res: any) => {
},
async (err: Error, res: any) => {
if (!err && !res.error && !this.clientSet()) {
this.client = 'geth';
}
resolve();
}
)
);
} catch (e) {
this.logger.error(e.message);
resolve();
}
})
.then( async () => {
if (this.clientSet()) {
return;
}
return new Promise( async (resolve, reject) => {
try {
const method = 'parity_pendingTransactions';
await this.web3.currentProvider.sendAsync(
{
jsonrpc: '2.0',
method,
params: [],
id: 0x0a7
}, async (err: Error, res: any) => {
if (!err && !res.error && !this.clientSet()) {
this.client = 'parity';
.then(async () => {
if (this.clientSet()) {
return;
}
return new Promise(async (resolve, reject) => {
try {
const method = 'parity_pendingTransactions';
await this.web3.currentProvider.sendAsync(
{
jsonrpc: '2.0',
method,
params: [],
id: 0x0a7
},
async (err: Error, res: any) => {
if (!err && !res.error && !this.clientSet()) {
this.client = 'parity';
}
resolve();
}
resolve();
}
)
} catch (e) {
this.logger.error(e.message);
resolve();
);
} catch (e) {
this.logger.error(e.message);
resolve();
}
});
})
.then(() => {
if (!this.clientSet()) {
this.client = 'unknown';
}
this.logger.debug(`Client: ${this.client.toUpperCase()}`);
return;
})
})
.then( () => {
if (!this.clientSet()) {
this.client = 'unknown';
}
this.logger.debug(`Client: ${this.client.toUpperCase()}`);
return;
})
.catch(() => {
this.client = 'none';
this.logger.error(`Client: ${this.client.toUpperCase()}`);
})
.catch(() => {
this.client = 'none';
this.logger.error(`Client: ${this.client.toUpperCase()}`);
});
}
}
1 change: 0 additions & 1 deletion src/Scanner/Scanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,6 @@ export default class {
public store(request: any) {
this.config.cache.set(request.address, {
claimedBy: null,
claimingFailed: false,
wasCalled: false,
windowStart: request.params[7]
});
Expand Down
30 changes: 25 additions & 5 deletions src/Stats/StatsDB.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import BigNumber from 'bignumber.js';
// import * as EAC from 'eac.js-lib';

declare const require: any;

Expand All @@ -22,7 +21,7 @@ export class StatsDB {

// Takes an array of addresses and stores them as new stats objects.
public initialize(accounts: string[]) {
accounts.forEach(async account => {
accounts.forEach(account => {
const found = this.stats.find({ account })[0];
if (found) {
const bounties = found.bounties || 0;
Expand All @@ -37,14 +36,15 @@ export class StatsDB {
executed: 0,
bounties: new BigNumber(0),
costs: new BigNumber(0),
executedTransactions: []
executedTransactions: [],
failedClaims: []
});
}
});
}

// Takes the account which has claimed a transaction.
public async updateClaimed(account: string, cost: BigNumber) {
public updateClaimed(account: string, cost: BigNumber) {
const found = this.stats.find({ account })[0];
found.claimed += 1;
found.costs = found.costs.plus(cost);
Expand All @@ -53,7 +53,7 @@ export class StatsDB {
}

// Takes the account which has executed a transaction.
public async updateExecuted(account: string, bounty: BigNumber, cost: BigNumber) {
public updateExecuted(account: string, bounty: BigNumber, cost: BigNumber) {
const found = this.stats.find({ account })[0];

if (!found) {
Expand All @@ -74,6 +74,26 @@ export class StatsDB {
this.stats.update(found);
}

public addFailedClaim(account: string, transactionAddress: string) {
const found = this.stats.find({ account })[0];

if (!found) {
return;
}

if (!found.failedClaims) {
found.failedClaims = [];
}

if (found.failedClaims.indexOf(transactionAddress) !== -1) {
return;
}

found.failedClaims.push(transactionAddress);

this.stats.update(found);
}

// Gets the stats
// @returns an array of the DB objs
public getStats() {
Expand Down
15 changes: 3 additions & 12 deletions src/TimeNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,18 +78,9 @@ export default class TimeNode {
}

public getUnsucessfullyClaimedTransactions(): string[] {
const cachedTransactionsAddresses = this.config.cache.stored();
const timenodeAddresses = this.config.wallet.getAddresses();
const transactions = [];

for (const address of cachedTransactionsAddresses) {
const cachedTx = this.config.cache.get(address);
const account = this.config.wallet.getAddresses()[0];
const stats = this.config.statsDb.getStats().find((stat: any) => stat.account === account);

if (cachedTx.claimingFailed && timenodeAddresses.indexOf(cachedTx.claimedBy) === -1) {
transactions.push(address);
}
}

return transactions;
return stats.failedClaims;
}
}
8 changes: 4 additions & 4 deletions test/unit/UnitTestActions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { expect, assert } from 'chai';

import { Config, TimeNode } from '../../src/index';
import { TimeNode } from '../../src/index';
import { mockConfig, MockTxRequest } from '../helpers';
import Actions from '../../src/Actions';
import { shortenAddress } from '../../src/Actions/Actions';
Expand All @@ -15,20 +15,20 @@ describe('shortenAddress()', () => {
const address = '0x487a54e1d033db51c8ee8c03edac2a0f8a6892c6';
const expected = '0x487a...892c6';
expect(shortenAddress(address)).to.equal(expected);
})
});

describe('Actions Unit Tests', async () => {
it('sets claimingFailed to true when claim transaction reverts', async () => {
const config = mockConfig();
const timenode = new TimeNode(config);

config.wallet.sendRawTransaction = async (tx: any) => {
config.wallet.sendRawTransaction = async () => {
return {};
};

config.wallet.getTransactionReceipt = async () => {
return {
from: null,
from: config.wallet.getAddresses()[0],
receipt: {
status: '0x0'
}
Expand Down
24 changes: 24 additions & 0 deletions test/unit/UnitTestStats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,30 @@ describe('Stats Unit Tests', () => {
});
});

describe('addFailedClaim()', () => {
it('before calling it array is empty', () => {
assert.deepEqual(myStats.failedClaims, []);
});

it('adds failed claim', () => {
const failedClaimAddress = '0xe87529a6123a74320e13a6dabf3606630683c029';
config.statsDb.addFailedClaim(myAccount, failedClaimAddress);

assert.deepEqual(myStats.failedClaims, ['0xe87529a6123a74320e13a6dabf3606630683c029']);
});

it('does not allow for duplicates of failed claims', () => {
const failedClaimAddress = '0xe87529a6123a74320e13a6dabf3606630683c029';
config.statsDb.addFailedClaim(myAccount, failedClaimAddress);

assert.deepEqual(myStats.failedClaims, ['0xe87529a6123a74320e13a6dabf3606630683c029']);

config.statsDb.addFailedClaim(myAccount, failedClaimAddress);

assert.deepEqual(myStats.failedClaims, ['0xe87529a6123a74320e13a6dabf3606630683c029']);
});
});

describe('getStats()', () => {
it('returns all stats', async () => {
const stats = config.statsDb.getStats();
Expand Down
18 changes: 18 additions & 0 deletions test/unit/UnitTestTimeNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,22 @@ describe('TimeNode Unit Tests', () => {
assert.equal(txs.length, 1);
});
});

describe('getUnsucessfullyClaimedTransactions()', () => {
it('returns empty array when no failed claims', () => {
const txs = timenode.getUnsucessfullyClaimedTransactions();
assert.equal(txs.length, 0);
});

it('returns failed claims when they are present', () => {
const failedClaimAddress = '0xe87529a6123a74320e13a6dabf3606630683c029';

config.statsDb.addFailedClaim(config.wallet.getAddresses()[0], failedClaimAddress);

const txs = timenode.getUnsucessfullyClaimedTransactions();
assert.equal(txs.length, 1);

assert.deepEqual(txs, ['0xe87529a6123a74320e13a6dabf3606630683c029']);
});
});
});

0 comments on commit adf0265

Please sign in to comment.