-
Notifications
You must be signed in to change notification settings - Fork 374
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into aaronmgdr/static
* master: (26 commits) Added new lint rule (#2349) [Slashing] Slash locked gold (#2317) [Slashing] Allow voting gold to be slashable (#2302) 1666 precompiles assembly rewrite (#2324) Small fixes to deploy web (#2343) Governance, downtime and double signing slasher contracts (#2267) Added daily limit for reserve spending (#2303) Fixing multisig tests (#2342) [Wallet] Implement new send & import flow (#2332) Limechain/16xx (#1982) Add infinite pagination to Leaderboard (#2339) cli: Add rewards:show (#2160) Correct broken link formatting Celotool command for deploying hotfixes (#2142) Governance ContractKit + CLI changes (#2139) Complete codependent slashing precompile PRs (#2333) Add new and modified precompiles to UsingPrecompiles.sol (#2318) Adding error messages to contracts (#1182) Upgrade i18next and react-i18next to latest across monorepo (#2311) [Wallet] Fix exchange input on iOS and feed item display (#2319) ... # Conflicts: # yarn.lock
- Loading branch information
Showing
332 changed files
with
8,078 additions
and
2,967 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
// This is a more unusual Celotool command. It basically helps you to execute Hotfixes on testnets. Because constructing proposals is difficult to do via a CLI, you should define them here in code. There are two examples below that you can start from. | ||
|
||
import { newKit } from '@celo/contractkit' | ||
import { | ||
ProposalBuilder, | ||
proposalToHash, | ||
proposalToJSON, | ||
} from '@celo/contractkit/lib/governance/proposals' | ||
import { privateKeyToAddress } from '@celo/utils/lib/address' | ||
import { concurrentMap } from '@celo/utils/lib/async' | ||
import { getFornoUrl } from 'src/lib/endpoints' | ||
import { envVar, fetchEnv } from 'src/lib/env-utils' | ||
import { AccountType, getPrivateKeysFor } from 'src/lib/generate_utils' | ||
import yargs from 'yargs' | ||
import { UpgradeArgv } from '../../deploy/upgrade' | ||
|
||
export const command = 'hotfix' | ||
|
||
export const describe = 'runs a hotfix' | ||
|
||
type EthstatsArgv = UpgradeArgv & {} | ||
|
||
export const builder = (argv: yargs.Argv) => { | ||
return argv | ||
} | ||
|
||
export const handler = async (argv: EthstatsArgv) => { | ||
try { | ||
const kit = newKit(getFornoUrl(argv.celoEnv)) | ||
const governance = await kit.contracts.getGovernance() | ||
const keys = getPrivateKeysFor( | ||
AccountType.VALIDATOR, | ||
fetchEnv(envVar.MNEMONIC), | ||
parseInt(fetchEnv(envVar.VALIDATORS), 10) | ||
) | ||
const addresses = keys.map(privateKeyToAddress) | ||
|
||
console.info('Add keys to ContractKit') | ||
for (const key of keys) { | ||
kit.addAccount(key) | ||
} | ||
|
||
// Here you'll want to assert the current state | ||
// Example A: Update a var on a Celo Core Contract | ||
// const attestations = await kit.contracts.getAttestations() | ||
// const currentNumber = await attestations.attestationExpiryBlocks() | ||
// if (currentNumber !== 727) { | ||
// throw new Error(`Expected current number to be 727, but was ${currentNumber}`) | ||
// } | ||
|
||
// Example B: Repoint a Celo Core Contract proxy | ||
// const validatorsProxyAddress = await kit.registry.addressFor(CeloContract.Validators) | ||
// const currentValidatorsImplementationAddress = await getImplementationOfProxy( | ||
// kit.web3, | ||
// validatorsProxyAddress | ||
// ) | ||
// const desiredImplementationAddress = '0xd18620a5eBE0235023602bB4d490E1e96703EddD' | ||
// console.info('Current Implementation Address: ', currentValidatorsImplementationAddress) | ||
|
||
// console.info('\nBuild Proposal') | ||
|
||
const proposalBuilder = new ProposalBuilder(kit) | ||
|
||
// Example A | ||
// proposalBuilder.addJsonTx({ | ||
// contract: CeloContract.Attestations, | ||
// function: 'setAttestationExpiryBlocks', | ||
// // @ts-ignore | ||
// args: [728], | ||
// value: '0', | ||
// }) | ||
|
||
// Example B | ||
// proposalBuilder.addProxyRepointingTx(validatorsProxyAddress, desiredImplementationAddress) | ||
|
||
const proposal = await proposalBuilder.build() | ||
if (proposal.length === 0) { | ||
console.error('\nPlease see examples in hotfix.ts and add transactions') | ||
process.exit(1) | ||
} | ||
const proposalHash = proposalToHash(kit, proposal) | ||
|
||
// If your proposal is just made of Celo Registry contract methods, you can print it out | ||
console.info('Proposal: ', await proposalToJSON(kit, proposal)) | ||
console.info(`Proposal Hash: ${proposalHash.toString('hex')}`) | ||
|
||
console.info('\nWhitelist the hotfix') | ||
await concurrentMap(25, addresses, async (address, index) => { | ||
try { | ||
await governance.whitelistHotfix(proposalHash).sendAndWaitForReceipt({ from: address }) | ||
} catch (error) { | ||
console.error(`Error whitelisting for validator ${index} (${address}): ${error}`) | ||
} | ||
}) | ||
|
||
let hotfixRecord = await governance.getHotfixRecord(proposalHash) | ||
console.info('Hotfix Record: ', hotfixRecord) | ||
|
||
console.info('\nApprove the hotfix') | ||
await governance.approveHotfix(proposalHash).sendAndWaitForReceipt({ from: addresses[0] }) | ||
hotfixRecord = await governance.getHotfixRecord(proposalHash) | ||
console.info('Hotfix Record: ', hotfixRecord) | ||
|
||
// This is on master, but not on baklava yet | ||
const canPass = await governance.isHotfixPassing(proposalHash) | ||
const tally = await governance.hotfixWhitelistValidatorTally(proposalHash) | ||
|
||
if (!canPass) { | ||
throw new Error(`Hotfix cannot pass. Currently tally is ${tally}`) | ||
} | ||
|
||
console.info('\nPrepare the hotfix') | ||
await governance.prepareHotfix(proposalHash).sendAndWaitForReceipt({ from: addresses[0] }) | ||
hotfixRecord = await governance.getHotfixRecord(proposalHash) | ||
console.info('\nHotfix Record: ', hotfixRecord) | ||
|
||
if (hotfixRecord.preparedEpoch.toNumber() === 0) { | ||
console.error('Hotfix could not be prepared') | ||
throw new Error() | ||
} | ||
console.info('\nExecute the hotfix') | ||
await governance.executeHotfix(proposal).sendAndWaitForReceipt({ from: addresses[0] }) | ||
|
||
hotfixRecord = await governance.getHotfixRecord(proposalHash) | ||
console.info('\nHotfix Record: ', hotfixRecord) | ||
|
||
if (!hotfixRecord.executed) { | ||
console.error('Hotfix could somehow not be executed') | ||
throw new Error() | ||
} | ||
|
||
// Assert any state to be sure it worked | ||
|
||
// Example A | ||
// const newNumber = await attestations.attestationExpiryBlocks() | ||
// if (newNumber !== 728) { | ||
// throw new Error(`Expected current number to be 728, but was ${newNumber}`) | ||
// } | ||
|
||
// Example B | ||
// const newValidatorsImplementationAddress = await getImplementationOfProxy( | ||
// kit.web3, | ||
// validatorsProxyAddress | ||
// ) | ||
// if (!eqAddress(newValidatorsImplementationAddress, desiredImplementationAddress)) { | ||
// throw new Error( | ||
// `Expected new implementation address to be ${desiredImplementationAddress}, but was ${newValidatorsImplementationAddress}` | ||
// ) | ||
// } | ||
|
||
console.info('Hotfix successfully executed!') | ||
process.exit(0) | ||
} catch (error) { | ||
console.error(error) | ||
process.exit(1) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.