diff --git a/inspector/package-lock.json b/inspector/package-lock.json index 4e7b149..b9c7163 100644 --- a/inspector/package-lock.json +++ b/inspector/package-lock.json @@ -7689,6 +7689,14 @@ "web3-utils": "1.2.2" }, "dependencies": { + "@web3-js/scrypt-shim": { + "version": "github:web3-js/scrypt-shim#aafdadda13e660e25e1c525d1f5b2443f5eb1ebb", + "from": "github:web3-js/scrypt-shim", + "requires": { + "scryptsy": "^2.1.0", + "semver": "^6.3.0" + } + }, "eth-lib": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz", @@ -7699,6 +7707,11 @@ "xhr-request-promise": "^0.1.2" } }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", diff --git a/inspector/scripts/inspect-beacon.js b/inspector/scripts/inspect-beacon.js new file mode 100644 index 0000000..002a7d4 --- /dev/null +++ b/inspector/scripts/inspect-beacon.js @@ -0,0 +1,86 @@ +const truffleContract = require("@truffle/contract") +const KeepRandomBeaconOperatorJson = require("@keep-network/keep-core/artifacts/KeepRandomBeaconOperator.json") + +const contractHelper = require("./lib/contract-helper") + +module.exports = async function() { + try { + const deploymentBlock = await contractHelper.getDeploymentBlockNumber(KeepRandomBeaconOperatorJson, web3) + + const KeepRandomBeaconOperator = truffleContract(KeepRandomBeaconOperatorJson) + KeepRandomBeaconOperator.setProvider(web3.currentProvider) + + const keepRandomBeaconOperator = await KeepRandomBeaconOperator.deployed() + + const numberOfGroups = await keepRandomBeaconOperator.numberOfGroups() + const entryRequestedEvents = await keepRandomBeaconOperator.getPastEvents( + "RelayEntryRequested", + { + fromBlock: deploymentBlock, + toBlock: "latest", + } + ) + const entrySubmittedEvents = await keepRandomBeaconOperator.getPastEvents( + "RelayEntrySubmitted", + { + fromBlock: deploymentBlock, + toBlock: "latest", + } + ) + const timeoutEvents = await keepRandomBeaconOperator.getPastEvents( + "RelayEntryTimeoutReported", + { + fromBlock: deploymentBlock, + toBlock: "latest", + } + ) + + console.log(`Number of groups: ${numberOfGroups}`) + console.log(`Relay entries requested: ${entryRequestedEvents.length}`) + console.log(`Relay entries submitted: ${entrySubmittedEvents.length}`) + console.log(`Number of timed-out entries: ${timeoutEvents.length}`) + console.log(``) + + const dkgSubmittedEvents = (await keepRandomBeaconOperator.getPastEvents( + "DkgResultSubmittedEvent", + { + fromBlock: deploymentBlock, + toBlock: "latest", + } + )) + + const allOperators = new Set() + + for (i = 0; i < numberOfGroups; i++) { + const groupPubKey = await keepRandomBeaconOperator.getGroupPublicKey(i) + const groupMembers = await keepRandomBeaconOperator.getGroupMembers(groupPubKey) + + const uniqueMembers = new Set() + groupMembers.forEach((member) => { + uniqueMembers.add(member) + allOperators.add(member) + }) + + const dkgSubmittedEvent = dkgSubmittedEvents.find((event) => { + return event.returnValues.groupPubKey == groupPubKey + }) + + const {memberIndex, misbehaved} = dkgSubmittedEvent.returnValues + + console.log(`Group ${groupPubKey}:`) + console.log(` - has index ${i}`) + console.log(` - has ${groupMembers.length} members`) + console.log(` - its DKG result was submitted by member ${memberIndex}`) + console.log(` - misbehaved members bytes: ${misbehaved}`) + console.log(` - has ${uniqueMembers.size} unique members`) + console.log(``) + } + + console.log(`There are ${allOperators.size} unique operators in all groups`) + + process.exit() + } catch (error) { + console.log(error) + process.exit() + } +} \ No newline at end of file diff --git a/inspector/scripts/inspect-ecdsa-keep.js b/inspector/scripts/inspect-ecdsa-keep.js new file mode 100644 index 0000000..a282ebe --- /dev/null +++ b/inspector/scripts/inspect-ecdsa-keep.js @@ -0,0 +1,67 @@ +const truffleContract = require("@truffle/contract") + +const BondedECDSAKeepFactoryJson = require("@keep-network/keep-ecdsa/artifacts/BondedECDSAKeepFactory.json") +const BondedECDSAKeepJson = require("@keep-network/keep-ecdsa/artifacts/BondedECDSAKeep.json") + +module.exports = async function () { + try { + const BondedECDSAKeepFactory = truffleContract(BondedECDSAKeepFactoryJson) + BondedECDSAKeepFactory.setProvider(web3.currentProvider) + const BondedECDSAKeep = truffleContract(BondedECDSAKeepJson) + BondedECDSAKeep.setProvider(web3.currentProvider) + + const factory = await BondedECDSAKeepFactory.deployed() + + const keepCount = await factory.getKeepCount() + console.log(`created keeps count: ${keepCount}`) + + const allOperators = new Set() + const goodOperators = new Set() + + for (i = 0; i < keepCount; i++) { + const keepAddress = await callWithRetry(() => factory.getKeepAtIndex(i)) + const keep = await BondedECDSAKeep.at(keepAddress) + const keepPublicKey = await callWithRetry(() => keep.publicKey()) + const members = await callWithRetry(() => keep.getMembers()) + const isActive = await callWithRetry(() => keep.isActive()) + const bond = await callWithRetry(()=> keep.checkBondAmount()) + + console.log(`keep address: ${keepAddress}`) + console.log(`keep index: ${i}`) + console.log(`pubkey: ${keepPublicKey}`) + console.log(`members: ${members}`) + console.log(`isActive: ${isActive}`) + console.log(`bond [wei]: ${bond}`) + console.log(`bond [eth]: ${web3.utils.fromWei(bond)}`) + + members.forEach((member) => allOperators.add(member)) + if (keepPublicKey) { + members.forEach((member) => goodOperators.add(member)) + } + + console.log(``) + } + + // if the operator is a member of at least one keep and that operator + // is NOT a member of at least one keep which successfully generated + // a public key, this operator is here + let potentiallyBadOperators = new Set(allOperators) + for (let goodOperator of goodOperators) { + potentiallyBadOperators.delete(goodOperator) + } + console.log(`potentially bad operators = ${new Array(...potentiallyBadOperators).join(', ')}`) + + process.exit() + } catch (error) { + console.log(error) + } +} + +async function callWithRetry(fn) { + try { + return await fn() + } catch (error) { + console.log(`Error ${error} occurred; retrying...`) + return await fn() + } +} \ No newline at end of file diff --git a/inspector/scripts/inspect-tbtc.js b/inspector/scripts/inspect-tbtc.js new file mode 100644 index 0000000..831683e --- /dev/null +++ b/inspector/scripts/inspect-tbtc.js @@ -0,0 +1,71 @@ +const DepositJson = require("@keep-network/tbtc/artifacts/Deposit.json") +const DepositFactoryJson = require("@keep-network/tbtc/artifacts/DepositFactory.json") + +const truffleContract = require("@truffle/contract") +const contractHelper = require("./lib/contract-helper") + +module.exports = async function() { + try { + const factoryDeploymentBlock = await contractHelper.getDeploymentBlockNumber(DepositFactoryJson, web3) + + const DepositFactory = truffleContract(DepositFactoryJson) + DepositFactory.setProvider(web3.currentProvider) + const Deposit = truffleContract(DepositJson) + Deposit.setProvider(web3.currentProvider) + + const factory = await DepositFactory.deployed() + + const depositCreatedEvents = await factory.getPastEvents( + "DepositCloneCreated", + { + fromBlock: factoryDeploymentBlock, + toBlock: "latest", + } + ) + + console.log(`Number of created deposits: ${depositCreatedEvents.length} \n`) + + const depositAddresses = [] + depositCreatedEvents.forEach((event) => + depositAddresses.push(event.args.depositCloneAddress) + ) + + for (i = 0; i < depositAddresses.length; i++) { + const deposit = await Deposit.at(depositAddresses[i]) + const state = await deposit.currentState() + let stateString = "" + switch(state.toString()) { + case "0": stateString = "START"; break + case "1": stateString = "AWAITING_SIGNER_SETUP"; break + case "2": stateString = "AWAITING_BTC_FUNDING_PROOF"; break + case "3": stateString = "FAILED_SETUP"; break + case "4": stateString = "ACTIVE"; break + case "5": stateString = "AWAITING_WITHDRAWAL_SIGNATURE"; break + case "6": stateString = "AWAITING_WITHDRAWAL_PROOF"; break + case "7": stateString = "REDEEMED"; break + case "8": stateString = "COURTESY_CALL"; break + case "9": stateString = "FRAUD_LIQUIDATION_IN_PROGRESS"; break + case "10": stateString = "LIQUIDATION_IN_PROGRESS"; break + case "11": stateString = "LIQUIDATED"; break + default: stateString = "<< UNKNOWN >>"; break + } + const keepAddress = await deposit.keepAddress() + const lotSizeSatoshis = await deposit.lotSizeSatoshis() + const lotSizeTbtc = await deposit.lotSizeTbtc() + + console.log(`deposit address: ${depositAddresses[i]}`) + console.log(`deposit index: ${i}`) + console.log(`deposit state: ${stateString}`) + console.log(`keep address: ${keepAddress}`) + console.log(`lot size [sat]: ${lotSizeSatoshis}`) + console.log(`lot size [tbtc]: ${lotSizeTbtc}`) + + console.log(``) + } + + process.exit() + } catch (error) { + console.log(error) + process.exit() + } +} diff --git a/inspector/scripts/lib/contract-helper.js b/inspector/scripts/lib/contract-helper.js new file mode 100644 index 0000000..a3bde53 --- /dev/null +++ b/inspector/scripts/lib/contract-helper.js @@ -0,0 +1,11 @@ +const getDeploymentBlockNumber = async function(contractJSON, web3) { + const networkId = Object.keys(contractJSON.networks)[0] + const transactionHash = contractJSON.networks[networkId].transactionHash + const transaction = await web3.eth.getTransaction(transactionHash) + + return transaction.blockNumber +} + +module.exports = { + getDeploymentBlockNumber: getDeploymentBlockNumber +}