Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Consensus upgrade to allow contracts to read code version of any account #6168

Open
arhag opened this issue Oct 26, 2018 · 3 comments
Open
Assignees
Labels
CONSENSUS Introduces a change that may modify consensus protocol rules on an existing blockchain. enhancement track-in-jira

Comments

@arhag
Copy link
Contributor

arhag commented Oct 26, 2018

Background

A smart contract deployed on an EOSIO blockchain may depend on another contract deployed to another account. The dependency can be in the form of read-only access to the tables of the other contract directly or in the form of calling certain actions of the other contract and expecting them to behave in a certain way. However, smart contracts will typically be upgraded over time to fix bugs and add features.

While it is possible for the account that the contract is deployed on to nullify its permissions in a way that makes the contract immutable (short of privileged actions taken by a super-majority of BPs), this is not recommended practice since there will always be bugs discovered or reasons to need to update the contract code in order to just maintain the same behavior that users of the contract expect (note that giving up one extreme of immutability does not require going to the other extreme of a single developer unilaterally and instantly being able to update the contract; EOSIO enables the possibility of middle-ground solutions, but that is beyond the scope of this document). Even for smart contracts that are not meant to change, the specific behavior of the code may need to be tweaked either because: a bug was discovered and the code needs to be modified to match the intent of the code that both the developers and users of the contract agreed upon (as described by the Ricardian contract); or a dependency of the contract (or the platform itself) changes behavior after a sufficient deprecation period in a way that requires the contract to be updated to use new patterns/intrinsics/actions to maintain its same behavior going forward.

A smart contract that depends on another smart contract may wish to play it safe and automatically shut down its functionality (in an effort to protect its users) if a smart contract that it depends on but does not fully control has changed compared to the pinned version that it knows was safe (perhaps because auditors it trusts have fed in a specific version of the contract dependency as safe to use).

For example, it may be desirable for a contract deployed on account contracta to only send an inline action contractb::foo authorized with the contracta@active permission to the contract deployed on account contractb if it is confident that the behavior of contractb::bar will be identical to that which was concluded by the contract developer at the time of writing the contract. Perhaps they are concerned about contractb changing its behavior during the contractb::bar action to bill contracta more RAM than expected. So the contract developer may want to include the hash of the WASM code that is deployed on contractb in a table accessible to contracta and write code in the contract deployed on contracta to actually assert that the current code hash of contractb matches the store hash in the table prior to sending the inline action.

Or perhaps checking the code hash is not conservative enough. An audit of the contract code that was deployed to contractb may have led to the conclusion that calling the contractb::foo action is safe (for whatever definition of safety that the developer chose) assuming the deployed contract is the exact same code as the one that was audited AND only that specific code had write access to a specific subset of the contract's tables for the entire lifetime of those particular tables. This may be because the audited code was only proven to be safe if certain invariants about the table records held true. However, a malicious controller of the contractb account could replace the original contract (that has hash H1) with another contract (that has hash H2) which messes up the tables before then resetting the contract back to the original contract with hash H1. This would fool the contract deployed to contracta if it only pinned to the code hash H1. However, if the contract instead pinned to a code sequence number (something that incremented on every eosio::setcode call), it would be safe from this scenario as well.

Furthermore, the ability to check the code hash and/or code sequence number of an arbitrary account (or at least assert that they hold specified values) can be used by an assertion smart contract that assists clients/wallets. A client could craft a transaction to assert that the contract code of the other actions used in the transaction have not changed since the time the transaction was signed.

Consensus upgrade feature

The goal of this consensus upgrade feature is to allow any contract to read the current code hash and code sequence number of any account.

A new consensus upgrade feature will be added to trigger the changes described in this consensus upgrade proposal. The actual digest for the feature understood at the blockchain level is to be determined. For the purposes of this proposal the codename CODE_VERSION will be use to stand-in for whatever the feature identifier will actually end up being.

New intrinsic get_code_version

A new intrinsic uint64_t get_code_version( const account_name& account, int64_t& last_code_update_time, fc::sha256& code_hash ) should be added to the authorization_api.

The get_code_version intrinsic will assert that the specified account exists, set the specified account's code_version value from account_object into code_hash, set the specified account's last_code_update.time_since_epoch().count() value from account_object into last_code_update_time, and return the specified account's code_sequence value from account_sequence_object.

Contracts should only be able to link with this intrinsic after CODE_VERSION activation.

@arhag
Copy link
Contributor Author

arhag commented Dec 7, 2018

This issue depends on #6429 and #6437. It will also be setup by default to be a protocol feature requiring pre-activation, thus it also depends on #6431.

@learnforpractice
Copy link
Contributor

Does anyone know why this issue is still open?

@jgiszczak
Copy link
Contributor

Documentation reference: For the read-only queries feature, one of the fields returned from a query is the code hash, so users of that (upcoming) API can track the contract version across queries.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
CONSENSUS Introduces a change that may modify consensus protocol rules on an existing blockchain. enhancement track-in-jira
Projects
None yet
Development

No branches or pull requests

6 participants