Skip to content

Commit

Permalink
Add distribution via receipt
Browse files Browse the repository at this point in the history
  • Loading branch information
pugachAG committed Dec 20, 2024
1 parent 32c567c commit d9b9e91
Show file tree
Hide file tree
Showing 13 changed files with 106 additions and 22 deletions.
4 changes: 2 additions & 2 deletions core/primitives/src/action/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use serde_with::base64::Base64;
use serde_with::serde_as;
use std::fmt;

fn base64(s: &[u8]) -> String {
pub fn base64(s: &[u8]) -> String {
use base64::Engine;
base64::engine::general_purpose::STANDARD.encode(s)
}
Expand Down Expand Up @@ -121,7 +121,7 @@ impl fmt::Debug for DeployContractAction {
pub struct DeployGlobalContractAction {
/// WebAssembly binary
#[serde_as(as = "Base64")]
pub code: Vec<u8>
pub code: Vec<u8>,
}

impl fmt::Debug for DeployGlobalContractAction {
Expand Down
35 changes: 35 additions & 0 deletions core/primitives/src/receipt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,15 @@ impl Receipt {
}),
}
}

pub fn new_global_contract_distribution(predecessor_id: AccountId, code: Vec<u8>) -> Self {
Self::V0(ReceiptV0 {
predecessor_id,
receiver_id: "system".parse().unwrap(),
receipt_id: CryptoHash::default(),
receipt: ReceiptEnum::GlobalContractDitribution(GlobalContractData { code: code }),
})
}
}

/// Receipt could be either ActionReceipt or DataReceipt
Expand All @@ -590,6 +599,7 @@ pub enum ReceiptEnum {
Data(DataReceipt),
PromiseYield(ActionReceipt),
PromiseResume(DataReceipt),
GlobalContractDitribution(GlobalContractData),
}

/// ActionReceipt is derived from an Action from `Transaction or from Receipt`
Expand Down Expand Up @@ -670,6 +680,31 @@ impl fmt::Debug for ReceivedData {
}
}

#[serde_as]
#[derive(
BorshSerialize,
BorshDeserialize,
Hash,
PartialEq,
Eq,
Clone,
serde::Serialize,
serde::Deserialize,
ProtocolSchema,
)]
pub struct GlobalContractData {
#[serde_as(as = "Base64")]
pub code: Vec<u8>,
}

impl fmt::Debug for GlobalContractData {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("GlobalContractData")
//.field("code", &format_args!("{}", base64(&self.code)))
.finish()
}
}

/// Stores indices for a persistent queue for delayed receipts that didn't fit into a block.
#[derive(Default, BorshSerialize, BorshDeserialize, Clone, PartialEq, Debug, ProtocolSchema)]
pub struct DelayedReceiptIndices {
Expand Down
1 change: 1 addition & 0 deletions core/primitives/src/views.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1954,6 +1954,7 @@ impl From<Receipt> for ReceiptView {
is_promise_resume,
}
}
ReceiptEnum::GlobalContractDitribution(_) => todo!("#12639"),
},
priority,
}
Expand Down
4 changes: 3 additions & 1 deletion core/store/src/genesis/state_applier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,9 @@ impl GenesisStateApplier {
set_promise_yield_receipt(state_update, &receipt);
});
}
ReceiptEnum::Data(_) | ReceiptEnum::PromiseResume(_) => {
ReceiptEnum::Data(_)
| ReceiptEnum::PromiseResume(_)
| ReceiptEnum::GlobalContractDitribution(_) => {
panic!("Expected action receipt")
}
}
Expand Down
18 changes: 12 additions & 6 deletions runtime/runtime/src/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -655,11 +655,15 @@ pub(crate) fn action_deploy_contract(
}

pub(crate) fn action_deploy_global_contract(
_state_update: &mut TrieUpdate,
_account: &mut Account,
_account_id: &AccountId,
_deploy_contract: &DeployGlobalContractAction,
account_id: &AccountId,
deploy_contract: &DeployGlobalContractAction,
result: &mut ActionResult,
) -> Result<(), StorageError> {
let _span = tracing::debug_span!(target: "runtime", "action_deploy_global_contract").entered();
result.new_receipts.push(Receipt::new_global_contract_distribution(
account_id.clone(),
deploy_contract.code.clone(),
));
Ok(())
}

Expand Down Expand Up @@ -909,7 +913,9 @@ fn receipt_required_gas(apply_state: &ApplyState, receipt: &Receipt) -> Result<G

required_gas
}
ReceiptEnum::Data(_) | ReceiptEnum::PromiseResume(_) => 0,
ReceiptEnum::Data(_)
| ReceiptEnum::PromiseResume(_)
| ReceiptEnum::GlobalContractDitribution(_) => 0,
})
}

Expand Down Expand Up @@ -1035,7 +1041,7 @@ pub(crate) fn check_actor_permissions(
account_id: &AccountId,
) -> Result<(), ActionError> {
match action {
Action::DeployContract(_)
Action::DeployContract(_)
| Action::DeployGlobalContract(_)
| Action::Stake(_)
| Action::AddKey(_)
Expand Down
8 changes: 7 additions & 1 deletion runtime/runtime/src/balance_checker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ fn receipt_cost(
}
total_cost
}
ReceiptEnum::Data(_) | ReceiptEnum::PromiseResume(_) => 0,
ReceiptEnum::Data(_)
| ReceiptEnum::PromiseResume(_)
| ReceiptEnum::GlobalContractDitribution(_) => 0,
})
}

Expand Down Expand Up @@ -259,6 +261,10 @@ fn potential_postponed_receipt_ids(
account_id.clone(),
data_receipt.data_id,
))),
ReceiptEnum::GlobalContractDitribution(_) => {
// TODO(#12639): handle global contract distribution
None
}
}
})
.collect::<Result<HashSet<_>, StorageError>>()
Expand Down
2 changes: 1 addition & 1 deletion runtime/runtime/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ pub fn total_send_fees(
+ fees.fee(ActionCosts::deploy_contract_byte).send_fee(sender_is_receiver)
* num_bytes
}
DeployGlobalContract(DeployGlobalContractAction{ code }) => {
DeployGlobalContract(DeployGlobalContractAction { code }) => {
let num_bytes = code.len() as u64;
// TODO(#12639): introduce separate fees for global contracts
fees.fee(ActionCosts::deploy_contract_base).send_fee(sender_is_receiver)
Expand Down
1 change: 1 addition & 0 deletions runtime/runtime/src/congestion_control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,7 @@ pub(crate) fn compute_receipt_congestion_gas(
// of it without expensive state lookups.
Ok(0)
}
ReceiptEnum::GlobalContractDitribution(_) => Ok(0),
}
}

Expand Down
14 changes: 8 additions & 6 deletions runtime/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,12 +461,7 @@ impl Runtime {
)?;
}
Action::DeployGlobalContract(deploy_global_contract) => {
action_deploy_global_contract(
state_update,
account.as_mut().expect(EXPECT_ACCOUNT_EXISTS),
account_id,
deploy_global_contract,
)?;
action_deploy_global_contract(account_id, deploy_global_contract, &mut result)?;
}
Action::FunctionCall(function_call) => {
let account = account.as_mut().expect(EXPECT_ACCOUNT_EXISTS);
Expand Down Expand Up @@ -1208,6 +1203,10 @@ impl Runtime {
return Ok(None);
}
}
ReceiptEnum::GlobalContractDitribution(_global_contract_data) => {
// TODO(#12639): save global contract to the state
return Ok(None);
}
};
// We didn't trigger execution, so we need to commit the state.
state_update
Expand Down Expand Up @@ -2684,6 +2683,9 @@ fn schedule_contract_preparation<'b, R: MaybeRefReceipt>(
};
return handle_receipt(mgr, state_update, receiver, account_id, &yr);
}
ReceiptEnum::GlobalContractDitribution(_) => {
return false;
}
}
}
handle_receipt(pipeline_manager, state_update, &receiver, account_id, peek)
Expand Down
8 changes: 6 additions & 2 deletions runtime/runtime/src/pipelining.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,9 @@ impl ReceiptPreparationPipeline {
}
let actions = match receipt.receipt() {
ReceiptEnum::Action(a) | ReceiptEnum::PromiseYield(a) => &a.actions,
ReceiptEnum::Data(_) | ReceiptEnum::PromiseResume(_) => return false,
ReceiptEnum::Data(_)
| ReceiptEnum::PromiseResume(_)
| ReceiptEnum::GlobalContractDitribution(_) => return false,
};
let mut any_function_calls = false;
for (action_index, action) in actions.iter().enumerate() {
Expand Down Expand Up @@ -219,7 +221,9 @@ impl ReceiptPreparationPipeline {
.actions
.get(action_index)
.expect("indexing receipt actions by an action_index failed!"),
ReceiptEnum::Data(_) | ReceiptEnum::PromiseResume(_) => {
ReceiptEnum::Data(_)
| ReceiptEnum::PromiseResume(_)
| ReceiptEnum::GlobalContractDitribution(_) => {
panic!("attempting to get_contract with a non-action receipt!?")
}
};
Expand Down
4 changes: 3 additions & 1 deletion runtime/runtime/src/prefetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@ impl TriePrefetcher {
ReceiptEnum::Action(action_receipt) | ReceiptEnum::PromiseYield(action_receipt) => {
action_receipt
}
ReceiptEnum::Data(_) | ReceiptEnum::PromiseResume(_) => {
ReceiptEnum::Data(_)
| ReceiptEnum::PromiseResume(_)
| ReceiptEnum::GlobalContractDitribution(_) => {
continue;
}
};
Expand Down
24 changes: 23 additions & 1 deletion runtime/runtime/src/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ use near_primitives::checked_feature;
use near_primitives::errors::{
ActionsValidationError, InvalidAccessKeyError, InvalidTxError, ReceiptValidationError,
};
use near_primitives::receipt::{ActionReceipt, DataReceipt, Receipt, ReceiptEnum};
use near_primitives::receipt::{
ActionReceipt, DataReceipt, GlobalContractData, Receipt, ReceiptEnum,
};
use near_primitives::transaction::DeleteAccountAction;
use near_primitives::transaction::{
Action, AddKeyAction, DeployContractAction, FunctionCallAction, SignedTransaction, StakeAction,
Expand Down Expand Up @@ -323,6 +325,9 @@ pub(crate) fn validate_receipt(
ReceiptEnum::Data(data_receipt) | ReceiptEnum::PromiseResume(data_receipt) => {
validate_data_receipt(limit_config, data_receipt)
}
ReceiptEnum::GlobalContractDitribution(data) => {
validate_global_contract_distribution_receipt(limit_config, data)
}
}
}

Expand Down Expand Up @@ -357,6 +362,23 @@ fn validate_data_receipt(
Ok(())
}

fn validate_global_contract_distribution_receipt(
_limit_config: &LimitConfig,
_data: &GlobalContractData,
) -> Result<(), ReceiptValidationError> {
/*
TODO(#12639): maybe validate size here
if data.code.len() as u64 > limit_config.max_contract_size {
return Err(ReceiptValidationError::ContractSizeExceeded {
size: data.code.len() as u64,
limit: limit_config.max_contract_size,
});
}
*/

Ok(())
}

/// Validates given actions:
///
/// - Checks limits if applicable.
Expand Down
5 changes: 4 additions & 1 deletion tools/state-viewer/src/contract_accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,9 @@ fn try_find_actions_spawned_by_receipt(
Action::DeleteKey(_) => ActionType::DeleteKey,
Action::DeleteAccount(_) => ActionType::DeleteAccount,
Action::Delegate(_) => ActionType::Delegate,
Action::DeployGlobalContract(_) => ActionType::DeployGlobalContract,
Action::DeployGlobalContract(_) => {
ActionType::DeployGlobalContract
}
};
entry
.actions
Expand All @@ -363,6 +365,7 @@ fn try_find_actions_spawned_by_receipt(
.get_or_insert_with(Default::default)
.insert(ActionType::DataReceipt);
}
ReceiptEnum::GlobalContractDitribution(_) => {}
}
}
}
Expand Down

0 comments on commit d9b9e91

Please sign in to comment.