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

Parse resource group #4380

Merged
merged 9 commits into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 53 additions & 27 deletions rpc/api/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

use anyhow::bail;
use bcs_ext::BCSCodec;
use bytes::Bytes;
use hex::FromHex;
use jsonrpc_core_client::RpcChannel;
use move_core_types::u256;
Expand Down Expand Up @@ -36,7 +37,7 @@ use starcoin_types::transaction::authenticator::{AuthenticationKey, TransactionA
use starcoin_types::transaction::{EntryFunction, RawUserTransaction, TransactionArgument};
use starcoin_types::vm_error::AbortLocation;
use starcoin_types::U256;
use starcoin_vm_types::access_path::AccessPath;
use starcoin_vm_types::access_path::{AccessPath, DataPath};
use starcoin_vm_types::block_metadata::BlockMetadata;
use starcoin_vm_types::identifier::Identifier;
use starcoin_vm_types::language_storage::{parse_module_id, FunctionId, ModuleId, StructTag};
Expand Down Expand Up @@ -1205,6 +1206,48 @@ pub struct TransactionOutputView {
pub table_item_write_set: Vec<TransactionOutputTableItemAction>,
}

fn merge_ap_write_set(
output: &mut Vec<TransactionOutputAction>,
access_path: AccessPath,
op: WriteOp,
) {
match op {
WriteOp::Deletion { .. } => output.push(TransactionOutputAction {
access_path,
action: WriteOpView::Deletion,
value: None,
}),
WriteOp::Modification { data, .. } | WriteOp::Creation { data, .. } => {
match access_path.path {
DataPath::Resource(_) => output.push(TransactionOutputAction {
access_path,
action: WriteOpView::Value,
value: Some(WriteOpValueView::Resource(data.to_vec().into())),
}),
// Parsing resources in group and expanding them into individual actions.
DataPath::ResourceGroup(_) => {
let group_data: BTreeMap<StructTag, Bytes> =
bcs_ext::from_bytes(&data).expect("resource group data must be valid");
for (struct_tag, data) in group_data {
let resource_ap =
AccessPath::resource_access_path(access_path.address, struct_tag);
output.push(TransactionOutputAction {
access_path: resource_ap,
action: WriteOpView::Value,
value: Some(WriteOpValueView::Resource(data.to_vec().into())),
});
}
}
DataPath::Code(_) => output.push(TransactionOutputAction {
access_path,
action: WriteOpView::Value,
value: Some(WriteOpValueView::Code(data.to_vec().into())),
}),
}
}
};
}

impl From<TransactionOutput> for TransactionOutputView {
fn from(txn_output: TransactionOutput) -> Self {
let (write_set, events, gas_used, status, _) = txn_output.into_inner();
Expand All @@ -1225,14 +1268,19 @@ impl From<TransactionOutput> for TransactionOutputView {
StateKeyInner::Raw(_) => todo!("not support raw key"),
}
}
let write_set =
access_write_set
.into_iter()
.fold(Vec::new(), |mut acc, (access_path, op)| {
merge_ap_write_set(&mut acc, access_path, op);
acc
});

Self {
events: events.into_iter().map(Into::into).collect(),
gas_used: gas_used.into(),
status: status.into(),
write_set: access_write_set
.into_iter()
.map(TransactionOutputAction::from)
.collect(),
write_set,
table_item_write_set: table_item_write_set
.into_iter()
.map(TransactionOutputTableItemAction::from)
Expand All @@ -1241,28 +1289,6 @@ impl From<TransactionOutput> for TransactionOutputView {
}
}

impl From<(AccessPath, WriteOp)> for TransactionOutputAction {
fn from((access_path, op): (AccessPath, WriteOp)) -> Self {
let (action, value) = match op {
WriteOp::Deletion { .. } => (WriteOpView::Deletion, None),
WriteOp::Modification { data, .. } | WriteOp::Creation { data, .. } => (
WriteOpView::Value,
Some(if access_path.path.is_resource() {
WriteOpValueView::Resource(data.to_vec().into())
} else {
WriteOpValueView::Code(data.to_vec().into())
}),
),
};

Self {
access_path,
action,
value,
}
}
}

#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct TransactionOutputAction {
pub access_path: AccessPath,
Expand Down
2 changes: 1 addition & 1 deletion rpc/server/src/module/contract_rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ pub fn dry_run<S: StateView>(
view.abi = Some(resolver.resolve_module_code(view.code.0.as_slice())?);
}
WriteOpValueView::Resource(view) => {
let struct_tag = access_path.path.as_struct_tag().ok_or_else(|| {
let struct_tag = access_path.path.resource_tag().ok_or_else(|| {
format_err!("invalid resource access path: {}", access_path)
})?;
let struct_abi = resolver.resolve_struct_tag(struct_tag)?;
Expand Down
10 changes: 6 additions & 4 deletions state/statedb/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,12 @@ impl AccountStateObject {
if data_path.is_code() {
bail!("Not supported remove code currently.");
}
let struct_tag = data_path
.as_struct_tag()
.expect("DataPath must been struct tag at here.");
self.resource_tree.lock().remove(struct_tag);
if let Some(struct_tag) = data_path.resource_tag() {
self.resource_tree.lock().remove(struct_tag);
}
if let Some(struct_tag) = data_path.resource_group_tag() {
self.resource_tree.lock().remove(struct_tag);
}
Ok(())
}

Expand Down
2 changes: 1 addition & 1 deletion vm/dev/src/playground.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ pub fn dry_run_explain<S: StateView>(
view.abi = Some(resolver.resolve_module_code(view.code.0.as_slice())?);
}
WriteOpValueView::Resource(view) => {
let struct_tag = access_path.path.as_struct_tag().ok_or_else(|| {
let struct_tag = access_path.path.resource_tag().ok_or_else(|| {
format_err!("invalid resource access path: {}", access_path)
})?;
let struct_abi = resolver.resolve_struct_tag(struct_tag)?;
Expand Down
16 changes: 8 additions & 8 deletions vm/types/src/access_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
use starcoin_crypto::hash::HashValue;
use std::fmt;
use std::str::FromStr;

#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, JsonSchema)]
#[cfg_attr(any(test, feature = "fuzzing"), derive(Arbitrary))]
#[schemars(with = "String")]
Expand Down Expand Up @@ -328,19 +329,18 @@ impl DataPath {
pub fn is_code(&self) -> bool {
matches!(self, Self::Code(_))
}
pub fn is_resource(&self) -> bool {
matches!(self, Self::Resource(_))
}
pub fn is_resource_group(&self) -> bool {
matches!(self, Self::ResourceGroup(_))
}
// todo(simon): handle ResourceGroup
pub fn as_struct_tag(&self) -> Option<&StructTag> {
pub fn resource_tag(&self) -> Option<&StructTag> {
match self {
Self::Resource(struct_tag) => Some(struct_tag),
_ => None,
}
}
pub fn resource_group_tag(&self) -> Option<&StructTag> {
match self {
Self::ResourceGroup(struct_tag) => Some(struct_tag),
_ => None,
}
}
pub fn data_type(&self) -> DataType {
match self {
Self::Code(_) => DataType::CODE,
Expand Down
Loading