Skip to content

Commit 1c364da

Browse files
committed
Additional updates to reputation miner
1 parent dd967a5 commit 1c364da

File tree

4 files changed

+50
-20
lines changed

4 files changed

+50
-20
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,5 @@ truffle-security-output.json
2828
.coverage_contracts
2929
etherrouter-address.json
3030
ganache-chain-db
31+
.DS_Store
32+
*.sqlite*

packages/reputation-miner/ReputationMiner.js

+27-12
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,11 @@ class ReputationMiner {
6262
if (minerAddress) {
6363
this.realWallet = this.realProvider.getSigner(minerAddress);
6464
} else {
65+
// TODO: Check that this wallet can stake?
6566
this.realWallet = new ethers.Wallet(privateKey, this.realProvider);
66-
console.log("Transactions will be signed from ", this.realWallet.address);
67+
this.minerAddress = this.realWallet.address;
6768
}
69+
console.log(`Transactions will be signed from ${this.realWallet.address}`);
6870
}
6971

7072
/**
@@ -1347,20 +1349,28 @@ class ReputationMiner {
13471349
* @param { Bool } saveHistoricalStates Whether to save historical (valid) states while syncing
13481350
* @return {Promise} A promise that resolves once the state is up-to-date
13491351
*/
1350-
async sync(blockNumber, saveHistoricalStates = false) {
1351-
if (!blockNumber) {
1352-
throw new Error("Block number not supplied to sync");
1353-
}
1352+
async sync(blockNumber = 1, saveHistoricalStates = false) {
1353+
13541354
// Get the events
13551355
const filter = this.colonyNetwork.filters.ReputationMiningCycleComplete(null, null);
13561356
filter.fromBlock = blockNumber;
13571357
const events = await this.realProvider.getLogs(filter);
13581358
let localHash = await this.reputationTree.getRootHash();
1359+
1360+
console.log(`Beginning sync from block ${blockNumber} and hash ${localHash} with ${events.length} cycles to go`)
1361+
13591362
let applyLogs = false;
1363+
// We're going to apply logs if:
1364+
// - We're syncing from a user-provided hash (which is this conditional)
1365+
// - We find a match for an on-chain state in our db (which is the loop below)
1366+
// - We are syncing from scratch (e.g. no user-given or on-chain state is found, localHash is 0)
1367+
if (localHash !== `0x${new BN(0).toString(16, 64)}`) {
1368+
applyLogs = true;
1369+
}
13601370

13611371
// Run through events backwards find the most recent one that we know...
13621372
let syncFromIndex = 0;
1363-
for (let i = events.length - 1 ; i >= 0 ; i -= 1){
1373+
for (let i = events.length - 1 ; i >= 0 ; i -= 1) {
13641374
const event = events[i];
13651375
const hash = event.data.slice(0, 66);
13661376
const nLeaves = ethers.BigNumber.from(`0x${event.data.slice(66, 130)}`);
@@ -1369,22 +1379,24 @@ class ReputationMiner {
13691379
if (res.n === 1){
13701380
// We know that state! We can just sync from the next one...
13711381
syncFromIndex = i + 1;
1382+
localHash = hash;
13721383
await this.loadState(hash);
13731384
applyLogs = true;
13741385
break;
13751386
}
13761387
}
13771388

1378-
// We're not going to apply the logs unless we're syncing from scratch (which is this if statement)
1379-
// or we find a hash that we recognise as our current state, and we're going to sync from there (which
1380-
// is the if statement at the end of the loop below
1389+
console.log(`Syncing forward from index ${syncFromIndex} with local hash ${localHash}`)
1390+
13811391
if (localHash === `0x${new BN(0).toString(16, 64)}`) {
13821392
applyLogs = true;
13831393
}
13841394

13851395
for (let i = syncFromIndex; i < events.length; i += 1) {
1386-
console.log(`${new Date().toLocaleTimeString()}: Syncing mining cycle ${i + 1} of ${events.length}...`)
13871396
const event = events[i];
1397+
const time = new Date().toLocaleTimeString();
1398+
console.log(`${time}: Syncing mining cycle ${i + 1} of ${events.length}, from block ${event.blockNumber} and localHash ${localHash}`);
1399+
13881400
if (i === 0) {
13891401
// If we are syncing from the very start of the reputation history, the block
13901402
// before the very first 'ReputationMiningCycleComplete' does not have an
@@ -1433,7 +1445,8 @@ class ReputationMiner {
14331445
localHash = await this.reputationTree.getRootHash();
14341446
const localNLeaves = await this.nReputations;
14351447
if (localHash !== currentHash || !currentNLeaves.eq(localNLeaves)) {
1436-
console.log("ERROR: Sync failed and did not recover");
1448+
console.log(`Error: Sync failed and did not recover, final hash does not match ${currentHash}.`);
1449+
console.log("If the miner has been syncing for a while, try restarting, as the mining cycle may have advanced.");
14371450
} else {
14381451
console.log("Sync successful, even if there were warnings above");
14391452
}
@@ -1504,7 +1517,9 @@ class ReputationMiner {
15041517
}
15051518
const currentStateHash = await this.reputationTree.getRootHash();
15061519
if (currentStateHash !== reputationRootHash) {
1507-
console.log("WARNING: The supplied state failed to be recreated successfully. Are you sure it was saved?");
1520+
console.log(`WARNING: The supplied state ${reputationRootHash} failed to be recreated successfully. Are you sure it was saved?`);
1521+
} else {
1522+
console.log(`Reputation state ${reputationRootHash} was loaded successfully.`);
15081523
}
15091524
}
15101525

packages/reputation-miner/ReputationMinerClient.js

+14-4
Original file line numberDiff line numberDiff line change
@@ -211,14 +211,18 @@ class ReputationMinerClient {
211211
* @param {string} colonyNetworkAddress The address of the current `ColonyNetwork` contract
212212
* @return {Promise}
213213
*/
214-
async initialise(colonyNetworkAddress, startingBlock) {
214+
async initialise(colonyNetworkAddress, startingBlock, startingHash) {
215215
this.resolveBlockChecksFinished = undefined;
216216
await this._miner.initialise(colonyNetworkAddress);
217217

218218
const minerStake = await this._miner.getMiningStake();
219219
const numEntries = minerStake.amount.div(this._miner.getMinStake());
220220
this._adapter.log(`Miner has staked ${minerStake.amount} CLNY, allowing up to ${numEntries} entries per cycle`);
221221

222+
if (minerStake.amount.eq(0)) {
223+
this._adapter.log(`Stake for mining by depositing ${minStake} in tokenLocking then calling stakeForMining on the network`);
224+
}
225+
222226
let resumedSuccessfully = false;
223227
// If we have a JRH saved, and it goes from the current (on chain) state to
224228
// a state that we know, then let's assume it's correct
@@ -268,9 +272,14 @@ class ReputationMinerClient {
268272

269273
// Get latest state from database if available, otherwise sync to current state on-chain
270274
await this._miner.createDB();
275+
this._adapter.log(`Attempting to load latest on-chain state ${latestConfirmedReputationHash}`);
271276
await this._miner.loadState(latestConfirmedReputationHash);
272277
if (this._miner.nReputations.eq(0)) {
273278
this._adapter.log("Latest state not found - need to sync");
279+
if (startingHash !== undefined) {
280+
this._adapter.log(`Loading starting hash ${startingHash}`);
281+
await this._miner.loadState(startingHash);
282+
}
274283
await this._miner.sync(startingBlock, true);
275284
}
276285

@@ -460,7 +469,7 @@ class ReputationMinerClient {
460469
const {entryIndex} = this.best12Submissions[this.submissionIndex];
461470
const canSubmit = await this._miner.submissionPossible(entryIndex);
462471
if (canSubmit) {
463-
this._adapter.log("⏰ Looks like it's time to submit an entry to the current cycle");
472+
this._adapter.log(`⏰ ${new Date().toLocaleTimeString()}: Looks like it's time to submit an entry to the current cycle`);
464473
this.submissionIndex += 1;
465474
await this.updateGasEstimate('average');
466475
await this.submitEntry(entryIndex);
@@ -730,7 +739,7 @@ class ReputationMinerClient {
730739

731740
async submitEntry(entryIndex) {
732741
const rootHash = await this._miner.getRootHash();
733-
this._adapter.log(`#️⃣ Miner ${this._miner.minerAddress} submitting new reputation hash ${rootHash} at entry index ${entryIndex.toNumber()}`);
742+
this._adapter.log(`#️⃣ Submitting new reputation hash ${rootHash} at entry index ${entryIndex.toNumber()}`);
734743

735744
// Submit hash
736745
let submitRootHashTx = await this._miner.submitRootHash(entryIndex);
@@ -745,8 +754,9 @@ class ReputationMinerClient {
745754
}
746755

747756
async confirmEntry() {
748-
this._adapter.log("⏰ Looks like it's time to confirm the new hash");
757+
this._adapter.log(`⏰ ${new Date().toLocaleTimeString()}: Looks like it's time to confirm the new hash`);
749758
// Confirm hash if possible
759+
750760
const [round] = await this._miner.getMySubmissionRoundAndIndex();
751761
if (round && round.gte(0)) {
752762
await this.updateGasEstimate('average');

packages/reputation-miner/bin/index.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const { argv } = require("yargs")
88
.option('privateKey', {string:true})
99
.option('colonyNetworkAddress', {string:true})
1010
.option('minerAddress', {string:true})
11+
.option('startingHash', {string:true})
1112
.option('providerAddress', {type: "array", default: []});
1213
const ethers = require("ethers");
1314
const backoff = require("exponential-backoff").backOff;
@@ -33,6 +34,7 @@ const {
3334
oraclePort,
3435
processingDelay,
3536
adapterLabel,
37+
startingHash,
3638
} = argv;
3739

3840
class RetryProvider extends ethers.providers.StaticJsonRpcProvider {
@@ -53,16 +55,16 @@ class RetryProvider extends ethers.providers.StaticJsonRpcProvider {
5355
return backoff(() => super.getNetwork(), {retry: RetryProvider.attemptCheck});
5456
}
5557

56-
// This should return a Promise (and may throw erros)
58+
// This should return a Promise (and may throw errors)
5759
// method is the method name (e.g. getBalance) and params is an
5860
// object with normalized values passed in, depending on the method
5961
perform(method, params) {
6062
return backoff(() => super.perform(method, params), {retry: RetryProvider.attemptCheck, startingDelay: 1000});
6163
}
6264
}
6365

64-
if ((!minerAddress && !privateKey) || !colonyNetworkAddress || !syncFrom) {
65-
console.log("❗️ You have to specify all of ( --minerAddress or --privateKey ) and --colonyNetworkAddress and --syncFrom on the command line!");
66+
if ((!minerAddress && !privateKey) || !colonyNetworkAddress) {
67+
console.log("❗️ You have to specify all of ( --minerAddress or --privateKey ) and --colonyNetworkAddress on the command line!");
6668
process.exit();
6769
}
6870

@@ -126,4 +128,5 @@ const client = new ReputationMinerClient({
126128
oraclePort,
127129
processingDelay
128130
});
129-
client.initialise(colonyNetworkAddress, syncFrom);
131+
132+
client.initialise(colonyNetworkAddress, syncFrom, startingHash);

0 commit comments

Comments
 (0)