Skip to content

Commit

Permalink
[NEP-491] Permanent storage bytes (#10701)
Browse files Browse the repository at this point in the history
According to the discussion:
near/NEPs#491 (comment)
we decided to use `permanent_storage_bytes` account field instead of
`nonrefundable`.
Non-refundable storage transfer amount will now we explicitly burnt and
the nonrefundable storage will now be reflected as
`permanent_storage_bytes`. This way is much less confusing for users and
integration partners.
  • Loading branch information
staffik authored Mar 28, 2024
1 parent 6a45ef9 commit 589ff5f
Show file tree
Hide file tree
Showing 16 changed files with 404 additions and 195 deletions.
4 changes: 2 additions & 2 deletions chain/chain/src/tests/simple_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ fn build_chain() {
// cargo insta test --accept -p near-chain --features nightly -- tests::simple_chain::build_chain
let hash = chain.head().unwrap().last_block_hash;
if cfg!(feature = "nightly") {
insta::assert_snapshot!(hash, @"Dnn7UkUiRfMu13jheAbcoJvQ66gKBgAoynRdEkMTkX58");
insta::assert_snapshot!(hash, @"CyVdmcpdfz8VAqZFN4zbZLTRcbcnAUzRJwNgxbgeEUMU");
} else {
insta::assert_snapshot!(hash, @"EsUNazp4zR2XgiwZSuQnX9dsaFk1VDhdRwGYt1YHpu5b");
}
Expand All @@ -51,7 +51,7 @@ fn build_chain() {

let hash = chain.head().unwrap().last_block_hash;
if cfg!(feature = "nightly") {
insta::assert_snapshot!(hash, @"8xU6fbbdGeYmQRaAbsszMHDM88KSAaniHykowTUDYXpm");
insta::assert_snapshot!(hash, @"72j1xRcBZpPtyo2rpPBPRspL6Q9LCju2Doa8KFhYPNJt");
} else {
insta::assert_snapshot!(hash, @"CJ5p62dVTMVgRADQrWPkFLrozDN8KxbKMGqjVkPXBD7W");
}
Expand Down
6 changes: 3 additions & 3 deletions chain/jsonrpc/res/rpc_errors_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"DelegateActionAccessKeyError",
"DelegateActionInvalidNonce",
"DelegateActionNonceTooLarge",
"NonRefundableBalanceToExistingAccount"
"NonRefundableTransferToExistingAccount"
],
"props": {
"index": ""
Expand Down Expand Up @@ -641,8 +641,8 @@
"subtypes": [],
"props": {}
},
"NonRefundableBalanceToExistingAccount": {
"name": "NonRefundableBalanceToExistingAccount",
"NonRefundableTransferToExistingAccount": {
"name": "NonRefundableTransferToExistingAccount",
"subtypes": [],
"props": {
"account_id": ""
Expand Down
85 changes: 36 additions & 49 deletions chain/rosetta-rpc/src/adapters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,8 +353,7 @@ impl From<NearActions> for Vec<crate::models::Operation> {
}

#[cfg(feature = "protocol_feature_nonrefundable_transfer_nep491")]
// Both refundable and non-refundable transfers are considered as available balance.
// TODO(nonrefundable) Merge with the arm above on stabilization.
// Non-refundable transfer deposit is burnt for permanent storage bytes on the receiving account.
near_primitives::transaction::Action::NonrefundableStorageTransfer(action) => {
let transfer_amount = crate::models::Amount::from_yoctonear(action.deposit);

Expand All @@ -368,18 +367,6 @@ impl From<NearActions> for Vec<crate::models::Operation> {
}
.into_operation(sender_transfer_operation_id.clone()),
);

operations.push(
validated_operations::TransferOperation {
account: receiver_account_identifier.clone(),
amount: transfer_amount,
predecessor_id: Some(sender_account_identifier.clone()),
}
.into_related_operation(
crate::models::OperationIdentifier::new(&operations),
vec![sender_transfer_operation_id],
),
);
}

near_primitives::transaction::Action::Stake(action) => {
Expand Down Expand Up @@ -868,35 +855,6 @@ mod tests {
use near_primitives::action::delegate::{DelegateAction, SignedDelegateAction};
use near_primitives::transaction::{Action, TransferAction};

#[cfg(feature = "protocol_feature_nonrefundable_transfer_nep491")]
#[test]
fn test_convert_nonrefundable_storage_transfer_action() {
let transfer_actions = vec![near_primitives::transaction::TransferAction {
deposit: near_primitives::types::Balance::MAX,
}
.into()];
let nonrefundable_transfer_actions =
vec![near_primitives::transaction::NonrefundableStorageTransferAction {
deposit: near_primitives::types::Balance::MAX,
}
.into()];
let near_transfer_actions = NearActions {
sender_account_id: "sender.near".parse().unwrap(),
receiver_account_id: "receiver.near".parse().unwrap(),
actions: transfer_actions,
};
let near_nonrefundable_transfer_actions = NearActions {
sender_account_id: "sender.near".parse().unwrap(),
receiver_account_id: "receiver.near".parse().unwrap(),
actions: nonrefundable_transfer_actions,
};
let transfer_operations_converted: Vec<crate::models::Operation> =
near_transfer_actions.into();
let nonrefundable_transfer_operations_converted: Vec<crate::models::Operation> =
near_nonrefundable_transfer_actions.into();
assert_eq!(transfer_operations_converted, nonrefundable_transfer_operations_converted);
}

#[test]
fn test_convert_block_changes_to_transactions() {
run_actix(async {
Expand All @@ -922,7 +880,7 @@ mod tests {
code_hash: near_primitives::hash::CryptoHash::default(),
locked: 400000000000000000000000000000,
#[cfg(feature = "protocol_feature_nonrefundable_transfer_nep491")]
nonrefundable: 0,
permanent_storage_bytes: 0,
storage_paid_at: 0,
storage_usage: 200000,
},
Expand All @@ -939,7 +897,7 @@ mod tests {
code_hash: near_primitives::hash::CryptoHash::default(),
locked: 400000000000000000000000000000,
#[cfg(feature = "protocol_feature_nonrefundable_transfer_nep491")]
nonrefundable: 0,
permanent_storage_bytes: 0,
storage_paid_at: 0,
storage_usage: 200000,
},
Expand All @@ -954,7 +912,7 @@ mod tests {
code_hash: near_primitives::hash::CryptoHash::default(),
locked: 400000000000000000000000000000,
#[cfg(feature = "protocol_feature_nonrefundable_transfer_nep491")]
nonrefundable: 0,
permanent_storage_bytes: 0,
storage_paid_at: 0,
storage_usage: 200000,
},
Expand All @@ -971,7 +929,7 @@ mod tests {
code_hash: near_primitives::hash::CryptoHash::default(),
locked: 400000000000000000000000000000,
#[cfg(feature = "protocol_feature_nonrefundable_transfer_nep491")]
nonrefundable: 0,
permanent_storage_bytes: 0,
storage_paid_at: 0,
storage_usage: 200000,
},
Expand All @@ -986,7 +944,7 @@ mod tests {
code_hash: near_primitives::hash::CryptoHash::default(),
locked: 400000000000000000000000000000,
#[cfg(feature = "protocol_feature_nonrefundable_transfer_nep491")]
nonrefundable: 0,
permanent_storage_bytes: 0,
storage_paid_at: 0,
storage_usage: 200000,
},
Expand All @@ -998,7 +956,7 @@ mod tests {
code_hash: near_primitives::hash::CryptoHash::default(),
locked: 400000000000000000000000000000,
#[cfg(feature = "protocol_feature_nonrefundable_transfer_nep491")]
nonrefundable: 0,
permanent_storage_bytes: 0,
storage_paid_at: 0,
storage_usage: 200000,
},
Expand Down Expand Up @@ -1629,4 +1587,33 @@ mod tests {
Err(crate::errors::ErrorKind::InvalidInput(_))
));
}

#[cfg(feature = "protocol_feature_nonrefundable_transfer_nep491")]
#[test]
fn test_convert_nonrefundable_storage_transfer_action() {
let deposit = near_primitives::types::Balance::MAX - 1;
let nonrefundable_transfer_actions = vec![
near_primitives::transaction::NonrefundableStorageTransferAction { deposit }.into(),
];
let near_nonrefundable_transfer_actions = NearActions {
sender_account_id: "sender.near".parse().unwrap(),
receiver_account_id: "receiver.near".parse().unwrap(),
actions: nonrefundable_transfer_actions,
};
let nonrefundable_transfer_operations_converted: Vec<crate::models::Operation> =
near_nonrefundable_transfer_actions.into();
assert_eq!(nonrefundable_transfer_operations_converted.len(), 1);
assert_eq!(
nonrefundable_transfer_operations_converted[0].type_,
crate::models::OperationType::Transfer
);
assert_eq!(
nonrefundable_transfer_operations_converted[0].account,
"sender.near".parse().unwrap()
);
assert_eq!(
nonrefundable_transfer_operations_converted[0].amount,
Some(-crate::models::Amount::from_yoctonear(deposit))
);
}
}
2 changes: 2 additions & 0 deletions core/chain-configs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ near-primitives.workspace = true
near-config-utils.workspace = true

[features]
protocol_feature_nonrefundable_transfer_nep491 = []
nightly_protocol = [
"near-async/nightly_protocol",
"near-o11y/nightly_protocol",
Expand All @@ -45,6 +46,7 @@ nightly = [
"near-parameters/nightly",
"near-primitives/nightly",
"nightly_protocol",
"protocol_feature_nonrefundable_transfer_nep491",
]
default = []
metrics = ["near-o11y"]
6 changes: 3 additions & 3 deletions core/chain-configs/src/genesis_validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ impl<'a> GenesisValidator<'a> {
format!("Duplicate account id {} in genesis records", account_id);
self.validation_errors.push_genesis_semantics_error(error_message)
}
self.total_supply += account.locked() + account.amount() + account.nonrefundable();
self.total_supply += account.locked() + account.amount();
self.account_ids.insert(account_id.clone());
if account.locked() > 0 {
self.staked_accounts.insert(account_id.clone(), account.locked());
Expand Down Expand Up @@ -210,10 +210,10 @@ mod test {

#[cfg(feature = "protocol_feature_nonrefundable_transfer_nep491")]
#[test]
fn test_total_supply_includes_nonrefundable_amount() {
fn test_total_supply_does_not_depend_on_permanent_storage_bytes() {
let mut config = GenesisConfig::default();
config.epoch_length = 42;
config.total_supply = 111;
config.total_supply = 110;
config.validators = vec![AccountInfo {
account_id: "test".parse().unwrap(),
public_key: VALID_ED25519_RISTRETTO_KEY.parse().unwrap(),
Expand Down
Loading

0 comments on commit 589ff5f

Please sign in to comment.