Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scripts for verifying bytecodes #5111

Merged
merged 81 commits into from Oct 8, 2020
Merged
Show file tree
Hide file tree
Changes from 78 commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
b6ae41f
Move metadata stripping to new lib
m-chrzan Aug 5, 2020
a798bbb
Implement library linking
m-chrzan Aug 18, 2020
bdc401d
Implement collection of linked library addresses
m-chrzan Aug 18, 2020
827fe47
Implement library DFS
m-chrzan Aug 23, 2020
3568686
Handle contracts as deployed before first upgrades
m-chrzan Aug 24, 2020
6673ac3
Add script for verifying bytecode
m-chrzan Aug 24, 2020
fadeeb5
Commit yarn.lock
m-chrzan Aug 25, 2020
3dc1f5b
Fix promise handling
m-chrzan Aug 25, 2020
5db2d97
Appease the linter
m-chrzan Aug 25, 2020
2378b6c
Test testing baklava bytecodes in CI
m-chrzan Aug 25, 2020
d7739e9
Handle pre-release 1 verification with parameter
m-chrzan Aug 25, 2020
1264332
Disable lint checks for CI testing
m-chrzan Aug 25, 2020
d5ca2bc
Fix typo
m-chrzan Aug 25, 2020
b0c5c4a
Execute command in correct directory
m-chrzan Aug 25, 2020
fb1d449
Add truffle config for rc1-forno
m-chrzan Aug 26, 2020
6dd5589
Attempt to verify rc1
m-chrzan Aug 26, 2020
dc1abfb
Point script to rc1 contracts
m-chrzan Aug 26, 2020
ae8ac94
Add flag for artifacts directory
m-chrzan Aug 26, 2020
4f28ed7
Finalize CI config
m-chrzan Aug 26, 2020
9806368
Appease the linter
m-chrzan Aug 26, 2020
8826f37
Add test contracts
m-chrzan Aug 26, 2020
0810249
Verify proposed bytecode changes
m-chrzan Aug 30, 2020
297ccb0
Add tests
m-chrzan Aug 31, 2020
268491b
Use values from context
m-chrzan Sep 4, 2020
a2458f8
Take commandline arguments in script
m-chrzan Sep 4, 2020
3d3c92d
Verify bytecodes in CI
m-chrzan Sep 6, 2020
2e6c8da
Remove other tests for CI testing
m-chrzan Sep 6, 2020
1d81b76
Fetch rc1 branch in CI
m-chrzan Sep 6, 2020
572a11c
Fetch rc1 via HTTPS
m-chrzan Sep 7, 2020
b3939b9
Increase wait time for ganache
m-chrzan Sep 7, 2020
e6f3b1a
Always build contracts from fresh
m-chrzan Sep 7, 2020
bae1c71
Add logging
m-chrzan Sep 7, 2020
31f50a4
Add test initialization data
m-chrzan Sep 7, 2020
c0ef4a3
Revert "Remove other tests for CI testing"
m-chrzan Sep 7, 2020
8e96be0
Appease the linter
m-chrzan Sep 7, 2020
4f46769
Increase wait time for ganache
m-chrzan Sep 8, 2020
7b9028a
Remove rc1_forno flag
m-chrzan Sep 8, 2020
2eeb20f
Organize LibraryAddresses into class
m-chrzan Sep 16, 2020
123b253
Refactor LibraryAddresses into a class
m-chrzan Sep 16, 2020
db44368
Ignore class limit linting rule
m-chrzan Sep 16, 2020
cb2a732
Document interface
m-chrzan Sep 16, 2020
4300300
Fix typos in CI command
m-chrzan Sep 17, 2020
fd646d3
Fix typo
m-chrzan Sep 17, 2020
7d56970
Frontload filtering
m-chrzan Sep 17, 2020
515f636
Rename initialize data to make clear it's not official
m-chrzan Sep 17, 2020
79e54ee
Update comment
m-chrzan Sep 17, 2020
e66e792
Abstract functions identifying transaction types
m-chrzan Sep 17, 2020
8298483
Update supported version
m-chrzan Sep 17, 2020
1c22db6
Document regex flag usage
m-chrzan Sep 17, 2020
4cd6a59
Raise gas limit in test
m-chrzan Sep 19, 2020
b275e38
Refactor verify-bytecode
yorhodes Sep 25, 2020
b32b67c
Merge branch 'master' into m-chrzan/verify-release
mergify[bot] Sep 29, 2020
e263326
Add bash script to verify existing network
m-chrzan Sep 15, 2020
0e42bc8
Fix comment
m-chrzan Sep 15, 2020
e5ad600
Rename to verify-deployed
m-chrzan Sep 17, 2020
1f5d83d
Add verify-release npm script
m-chrzan Sep 17, 2020
ea3c882
Add bash script
m-chrzan Sep 17, 2020
1d956d8
Make input proposal filepath relative to protocol root
m-chrzan Sep 17, 2020
ae82ed0
Revert gasLimit decrease
m-chrzan Sep 17, 2020
d1c7a44
Fix comment
m-chrzan Sep 17, 2020
e8ca6f8
Add Forno support in Truffle scripts
m-chrzan Sep 19, 2020
a598575
Fix comments
m-chrzan Sep 20, 2020
b7945dc
Add comment explaining script
m-chrzan Sep 18, 2020
9056cb0
Remove unnecessary flag
m-chrzan Sep 18, 2020
c47a560
Clarify CLI option
m-chrzan Sep 19, 2020
685b6eb
Use long form options in script
m-chrzan Sep 19, 2020
dd2f624
Revert gas limit increase
m-chrzan Sep 20, 2020
973c462
Add proposal json output to CLI governance:show command
yorhodes Sep 28, 2020
9b8479d
Parse tx returns contract proxy name on proxy function
yorhodes Sep 28, 2020
180d5d8
Update make-release to take a single branch
yorhodes Sep 29, 2020
cc3c1b3
Merge remote-tracking branch 'origin' into m-chrzan/bytecode-scripts
yorhodes Oct 7, 2020
6ec5343
Simplify contract release process and verify release commands and doc…
yorhodes Oct 7, 2020
0d322e8
Make jsonTransactions flag consistent across propose and show commands
yorhodes Oct 7, 2020
8241a48
Clarify docs for instructions versus summarization of scripts
yorhodes Oct 7, 2020
c733041
Update generated docs
yorhodes Oct 7, 2020
24ea9fb
Address pr comments
yorhodes Oct 7, 2020
f3a4db5
Document before first release and forno flags
yorhodes Oct 7, 2020
f09dd79
Merge remote-tracking branch 'origin' into m-chrzan/bytecode-scripts
yorhodes Oct 7, 2020
225a0a8
Disable verify-bytecodes temporarily
yorhodes Oct 8, 2020
477d4d7
Address pr comments
yorhodes Oct 8, 2020
43b6762
Merge branch 'master' into m-chrzan/bytecode-scripts
mergify[bot] Oct 8, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
53 changes: 53 additions & 0 deletions .circleci/config.yml
Expand Up @@ -491,6 +491,56 @@ jobs:
name: Unit tests
command: yarn --cwd packages/protocol test common/

protocol-verify-bytecodes:
<<: *defaults
resource_class: large
steps:
- attach_workspace:
at: ~/app
- run:
name: Check if the test should run
command: |
./scripts/ci_check_if_test_should_run_v2.sh @celo/protocol
- run:
name: Verify bytecodes between RC1 and current branch
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
name: Verify bytecodes between RC1 and current branch
name: Verify bytecodes between most recent release and current branch

command: |
cd packages/protocol

# deploy RC1 contracts to ganache devchain
# We fetch via HTTPS instead of SSH to avoid the interactive "do you
# trust the RSA key fingerprint" prompt.
git remote add origin-https https://github.com/celo-org/celo-monorepo.git
git fetch origin-https rc1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At this point, this is incorrect, as master needs to compare against release 1.

I believe there are only 3 options:

  1. Adjust the migrations to proxy linked libraries and then checkout the release-1 branch here
  2. Create a special case for release 2, where creating the bytecode involves
    2.1 Deploying RC1
    2.2 Creating the proposal for release 1
    2.3 Get through the proposal for release 1
    2.4 Continue
  3. Not add this to CI until 1. is done

Copy link
Contributor

@yorhodes yorhodes Oct 8, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

went with option 3

git checkout rc1
rm -rf build/contracts
yarn devchain generate-tar devchain.tar.gz --migration_override <(echo '{"downtimeSlasher": { "slashableDowntime": 60 } }')
# store build artifacts in build/rc1
mv build/contracts build/rc1

# build current contracts (artifacts in build/contracts)
git checkout ${CIRCLE_BRANCH}
rm -rf build/contracts
yarn build

# run ganache, wait for it to start
yarn devchain run-tar devchain.tar.gz &
GANACHE_PID=$!
echo "Waiting for ganache to start"
sleep 30

# verify bytecodes of RC1 deployment
yarn truffle exec --network development ./scripts/truffle/verify-bytecode.js --build_artifacts build/rc1 --before_release_1
# generate report between RC1 and current branch
yarn ts-node scripts/check-backward.ts report --exclude ".*Test|Mock.*|I[A-Z].*|.*Proxy|LinkedList|SortedLinkedList|SortedLinkedListWithMedian|MultiSig.*|ReleaseGold" -o build/rc1 -n build/contracts --output_file report.json
# deploy new contracts and generate Governance proposal for upgrade
# TODO: remove --truffle_override once gas limit is increased
yarn truffle exec --network development ./scripts/truffle/make-release.js --build_directory build/ --report report.json --proposal proposal.json --initialize_data example-initialize-data.json --truffle_override '{"gasLimit": 12500000, "gas": 12500000 }'
# verify bytecode of upgrade deployment
yarn truffle exec --network development ./scripts/truffle/verify-bytecode.js --build_artifacts build/contracts --proposal ../../proposal.json

# stop ganache
kill $GANACHE_PID

protocol-test-compatibility:
<<: *defaults
resource_class: large
Expand Down Expand Up @@ -987,6 +1037,9 @@ workflows:
- protocol-test-common:
requires:
- lint-checks
- protocol-verify-bytecodes:
requires:
- lint-checks
- protocol-test-compatibility:
requires:
- lint-checks
Expand Down
13 changes: 13 additions & 0 deletions packages/cli/src/commands/governance/show.ts
@@ -1,7 +1,9 @@
import { proposalToJSON } from '@celo/contractkit/lib/governance/proposals'
import { concurrentMap } from '@celo/utils/lib/async'
import { flags } from '@oclif/command'
import chalk from 'chalk'
import { toBuffer } from 'ethereumjs-util'
import { writeFileSync } from 'fs'
import { BaseCommand } from '../../base'
import { newCheckBuilder } from '../../utils/checks'
import { printValueMap, printValueMapRecursive } from '../../utils/cli'
Expand All @@ -12,6 +14,10 @@ export default class Show extends BaseCommand {
static flags = {
...BaseCommand.flagsWithoutLocalAddresses(),
raw: flags.boolean({ required: false, description: 'Display proposal in raw bytes format' }),
jsonTransactions: flags.string({
required: false,
description: 'Output proposal JSON to provided file',
}),
proposalID: flags.string({
exclusive: ['account', 'hotfix'],
description: 'UUID of proposal to view',
Expand Down Expand Up @@ -64,6 +70,13 @@ export default class Show extends BaseCommand {
try {
const jsonproposal = await proposalToJSON(this.kit, record.proposal)
record.proposal = jsonproposal as any

if (res.flags.jsonTransactions) {
console.log(
chalk.yellowBright(`Outputting proposal JSON to ${res.flags.jsonTransactions}`)
)
writeFileSync(res.flags.jsonTransactions, JSON.stringify(jsonproposal, null, 2))
}
} catch (error) {
console.warn(`Could not decode proposal, displaying raw data: ${error}`)
}
Expand Down
9 changes: 7 additions & 2 deletions packages/contractkit/src/explorer/block-explorer.ts
@@ -1,7 +1,7 @@
import { Address } from '@celo/utils/lib/address'
import { Block, Transaction } from 'web3-eth'
import abi, { ABIDefinition } from 'web3-eth-abi'
import { PROXY_ABI } from '../governance/proxy'
import { PROXY_ABI, PROXY_SET_IMPLEMENTATION_SIGNATURE } from '../governance/proxy'
import { ContractKit } from '../kit'
import { parseDecodedParams } from '../utils/web3-utils'
import { ContractDetails, mapFromPairs, obtainKitContractDetails } from './base'
Expand Down Expand Up @@ -110,12 +110,17 @@ export class BlockExplorer {
return null
}

const contract =
matchedAbi.signature === PROXY_SET_IMPLEMENTATION_SIGNATURE
? contractMapping.details.name + 'Proxy'
: contractMapping.details.name

const { args, params } = parseDecodedParams(
abi.decodeParameters(matchedAbi.inputs!, encodedParameters)
)

return {
contract: contractMapping.details.name,
contract,
function: matchedAbi.name!,
paramMap: params,
argList: args,
Expand Down
2 changes: 2 additions & 0 deletions packages/contractkit/src/governance/proxy.ts
Expand Up @@ -34,6 +34,8 @@ export const PROXY_ABI: ABIDefinition[] = [
},
]

export const PROXY_SET_IMPLEMENTATION_SIGNATURE = PROXY_ABI[1].signature

export const getImplementationOfProxy = async (
web3: Web3,
proxyContractAddress: string
Expand Down
31 changes: 23 additions & 8 deletions packages/docs/celo-codebase/protocol/governance.md
Expand Up @@ -2,7 +2,7 @@

Celo uses a formal on-chain governance mechanism to manage and upgrade the protocol such as for upgrading smart contracts, adding new stable currencies, or modifying the reserve target asset allocation. All changes must be agreed upon by CELO holders. A quorum threshold model is used to determine the number of votes needed for a proposal to pass.

## How it works
## Stakeholder Proposal Process

Changes are managed via the Celo `Governance` smart contract. This contract acts as an "owner" for making modifications to other protocol smart contracts. Such smart contracts are termed **governable**. The `Governance` contract will at first be owned by a multi-signature wallet. In the future, when the community's experience of DAOs \(Distributed Autonomous Organizations\) has evolved and when the platform has proven to be stable and secure, it will be owned by CELO holders effectively acting as a DAO.

Expand All @@ -17,17 +17,17 @@ The change procedure happens in the following phases:
**Note:** the timings mentioned in the rest of this section are for the Alfajores Testnet. It is expected that mainnet timings will be much longer to allow for proper proposal review and engagement.
{% endhint %}

## Proposal
### Proposal

Any user may submit a “Proposal” to the `Governance` smart contract, along with a small deposit of CELO. This deposit is required to avoid spam proposals, and is refunded to the proposer if the community decides the proposal is worthy of voting on. A “Proposal” consists of a timestamp and the information needed to the “call” the operation code that will run if the proposal is accepted. This information includes an address, data, and value. Submitted proposals are added to the queue of proposals and expire from this list after one week.

Once added to the queue, a proposal needs to get voted on by CELO holders to pass to the next “Approval” phase. Every CELO holder with a Locked Gold account may vote for at most one proposal and in order to be eligible to do so, the account must put up a commitment, which involves sending CELO to a smart contract and specifying a notice period to wait once the withdrawal is requested. This Locked Gold commitment can be the same as the funds used for validator elections and earning epoch rewards. The list of proposals is sorted by the weight of the votes they have received.

## Approval
### Approval

Every day the top three proposals at the head of the queue are popped off and move to the approval phase. At this time, the original proposers are eligible to reclaim their Locked Gold commitment. In this phase graduated proposals need to be approved by the approver within the current approval phase of a day. The approver is initially a multi-signature address and will move to a DAO in the future. If a proposal is not approved within this phase, it is considered expired and does not move on to the “Referendum” phase.

## Referendum
### Referendum

Once the Approval phase is over, approved proposals graduate to the referendum phase. Any user may vote yes, no, or abstain on these proposals. Their vote's weight is determined by the weight of their Locked Gold commitment. After the Referendum phase is over, which lasts two days, each proposal is marked as passed or failed as a function of the votes and the corresponding passing function parameters.

Expand All @@ -36,11 +36,27 @@ In order for a proposal to pass, it must meet a minimum threshold for **particip
* Participation is the minimum portion of Locked Gold which must cast a vote for a proposal to pass. It exists to prevent proposals passing with very low participation. The participation requirement is calculated as a governable portion of the participation baseline, which is an exponential moving average of final participation in past governance proposals.
* Agreement is the portion of votes cast that must be "yes" votes for a proposal to pass. Each contract and function can define a required level of agreement, and the required agreement for a proposal is the maximum requirement among its constituent transactions.

## Execution
### Execution

Proposals that graduate from the Referendum phase to the execution phase may be executed by anyone, triggering a “call” operation code with the arguments defined in the proposal, originating from the `Governance` smart contract. Proposals expire from this phase after two days.

## Hotfix
## Smart Contract Upgradeability
yorhodes marked this conversation as resolved.
Show resolved Hide resolved
Smart contracts deployed to an EVM blockchain like Celo are immutable. To allow
for improvements, new features, and bug fixes, the Celo codebase uses the
[Proxy Upgrade Pattern](https://docs.openzeppelin.com/upgrades-plugins/1.x/proxies). All of the core contracts owned by Governance are proxied. Thus, a smart contract implementation can be upgraded using the standard on-chain governance process.
### Upgrade risks
The core contracts define critical behavior of the Celo network such as CELO and Celo Dollar asset management or validator elections and rewards. Malicious or inadvertent contract bugs could compromise user balances or cause potentially irreversible harm without a blockchain hard fork.

Great care must be taken to ensure that any Governance proposal that modifies smart contract code will not break the existing system. To this end, the contracts have a well defined [release process](../../community/release-process/smart-contracts.md), which includes soliciting security audits from reputable third-party auditors.

As Celo is a decentralized network, all Celo network participants are invited to
participate in the governance proposals discussions on the [forum](https://forum.celo.org/c/governance/12).


## Validator Hotfix Process

The cadence and transparency of the standard on-chain governance protocol make it poorly suited for proposals that patch issues that may compromise the security of the network, especially when the patch would reveal an exploitable bug in one of the core contracts. Instead, these sorts of changes are better suited for the more responsive, and less transparent, hotfix protocol.

Expand All @@ -50,5 +66,4 @@ Note that this means the validators may not always know the contents of the prop

## Celo Blockchain Software Upgrades

Some changes cannot be made through the on-chain governance process alone. Examples include changes to the underlying consensus protocol and changes which would result in a hard-fork. When Celo Blockchain software upgrades are required to continue operating correctly on the network, a "Minimum Client Version" parameter is set to indicate the minimum version that it required.

Some changes cannot be made through the on-chain governance process (via proposal or hotfix) alone. Examples include changes to the underlying consensus protocol and changes which would result in a hard-fork. When Celo Blockchain software upgrades are required to continue operating correctly on the network, a "Minimum Client Version" parameter is set to indicate the minimum version that it required.
2 changes: 2 additions & 0 deletions packages/docs/command-line-interface/governance.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.