-
Notifications
You must be signed in to change notification settings - Fork 678
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
feat: global contract support for accounts #12877
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #12877 +/- ##
==========================================
+ Coverage 70.41% 70.44% +0.03%
==========================================
Files 854 854
Lines 174571 174765 +194
Branches 174571 174765 +194
==========================================
+ Hits 122927 123117 +190
- Misses 46408 46409 +1
- Partials 5236 5239 +3
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
core/primitives-core/src/account.rs
Outdated
None, | ||
LocalContract(CryptoHash), | ||
GlobalContract(CryptoHash), | ||
GlobalContractByAccount(AccountId, CryptoHash), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does CryptoHash
correspond to here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The hash of the contract deployed from the AccountId
. I was thinking we need to know if the account has an older contract version deployed from the AccountId
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do not want to store that information as part of user's account. That is not needed, but also we would have to update all accounts when the contract is updated which is not feasible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we would have to update all accounts when the contract is updated which is not feasible
actually aren't automated upgrades a security concern? shouldn't users manually upgrade after they check the new code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nope, user accepts such risk when using contract deployed by AccountId, otherwise they should use global contract hash
core/primitives-core/src/account.rs
Outdated
Self::V1(account) => account.code_hash = code_hash, | ||
Self::V2(account) => account.code_hash = code_hash, | ||
Self::V1(_) => { | ||
let account_v2 = AccountV2 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AccountV2 has serialization overhead comparing to V1, so we should avoid conversion when possible. So please add additional check for contract
being None
or Local
and do not convert to v2 in such cases. Also would be nice to add tests for that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should it also get downgraded if possible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good question! let's not do that for now to keep it simple since I don't expect that to happen frequently
core/primitives-core/src/account.rs
Outdated
} | ||
|
||
impl AccountContract { | ||
pub fn to_code_hash(&self) -> CryptoHash { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
replacing all previous usages of Account::code_hash
with to_code_hash
is very dangerous since existing clients only expect local code to be there. For example runtime might issues storage reads for TrieKey::ContractCode
which would not be correct for global contract. Please replace this with fn local_code(&self) -> Option<CryptoHash>
and update clients accordingly.
runtime/runtime/src/pipelining.rs
Outdated
@@ -136,7 +136,7 @@ impl ReceiptPreparationPipeline { | |||
} | |||
Action::FunctionCall(function_call) => { | |||
let Some(account) = &**account else { continue }; | |||
let code_hash = account.code_hash(); | |||
let Some(code_hash) = account.contract().local_code() else { continue }; // TODO: deal with global contract call |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pugachAG I am supposed to deal with global contract function calls here right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add todo!
referencing #12884
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made it a comment with a continue because a test was failing
please add a detailed description for this PR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
overall LGTM, a couple more nits to address
@@ -45,6 +46,7 @@ nightly = [ | |||
"near-jsonrpc/nightly", | |||
"near-network/nightly", | |||
"near-o11y/nightly", | |||
"near-primitives-core/nightly", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need dependency updates?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this script was complaining
core/store/src/db/colddb.rs
Outdated
@@ -208,7 +208,7 @@ mod test { | |||
} | |||
} | |||
fn hash(chunk: &[u8]) -> String { | |||
crate::CryptoHash::from(chunk.try_into().unwrap()).to_string() | |||
crate::CryptoHash::try_from(chunk).unwrap().to_string() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this change belong to this pr? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh not anymore, will revert. It was needed before when I added a new From
trait implementation for CryptoHash
because the compiler did not know which from
implementation to use
…ear/nearcore into stefan/global_contract_account_support
core/primitives/src/views.rs
Outdated
let (global_contract_hash, global_contract_account_id) = match account.contract() { | ||
AccountContract::Global(contract) => (Some(contract), None), | ||
AccountContract::GlobalByAccount(account_id) => (None, Some(account_id)), | ||
_ => (None, None), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please explicitly list all other variants, using _ =>
is a dangerous patter since adding new enum variant which might be relevant here can be missed
core/primitives-core/src/account.rs
Outdated
|
||
#[inline] | ||
pub fn local_contract_hash(&self) -> Option<CryptoHash> { | ||
match self.contract() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: in the current implementation calling self.contract()
results in potentially copying AccountId
, would be nice to address that somehow
This PR introduces a new
AccountContract
field in theAccountV2
struct, replacingcode_hash
and being defined as follows:It is being used to differentiate between the types of contracts stored for the
Account
, if any.To maintain backward compatibility, two new optional fields for global contracts are also added in the
SerdeAccount
struct.Part of #12716