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

feat(sozo): support multicall for execute command #2897

Merged
merged 4 commits into from
Jan 16, 2025
Merged
Changes from 1 commit
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
Prev Previous commit
fix: reword error message for entrypoint
glihm committed Jan 16, 2025
commit 6101109f5fe985f6b6907bd6ddb7b41ea11c8d66
4 changes: 2 additions & 2 deletions bin/sozo/src/commands/execute.rs
Original file line number Diff line number Diff line change
@@ -48,7 +48,7 @@
Executes the run function of the contract at the address 0x1234 without calldata,
and the move function of the ns-Actions contract, with the calldata [1,2].")]
pub calls: Vec<String>,

Check warning on line 51 in bin/sozo/src/commands/execute.rs

Codecov / codecov/patch

bin/sozo/src/commands/execute.rs#L51

Added line #L51 was not covered by tests

#[arg(long)]
#[arg(help = "If true, sozo will compute the diff of the world from the chain to translate \
@@ -87,79 +87,79 @@
config.tokio_handle().block_on(async {
let (provider, _) = self.starknet.provider(profile_config.env.as_ref())?;

let contracts = utils::contracts_from_manifest_or_diff(
self.account.clone(),
self.starknet.clone(),
self.world,
&ws,
self.diff,
)
.await?;

Check warning on line 97 in bin/sozo/src/commands/execute.rs

Codecov / codecov/patch

bin/sozo/src/commands/execute.rs#L90-L97

Added lines #L90 - L97 were not covered by tests

let account = self
.account
.account(provider, profile_config.env.as_ref(), &self.starknet, &contracts)
.await?;

let mut invoker = Invoker::new(&account, txn_config);

let mut arg_iter = self.calls.into_iter();

Check warning on line 106 in bin/sozo/src/commands/execute.rs

Codecov / codecov/patch

bin/sozo/src/commands/execute.rs#L104-L106

Added lines #L104 - L106 were not covered by tests

while let Some(arg) = arg_iter.next() {
let tag_or_address = arg;
let descriptor = ResourceDescriptor::from_string(&tag_or_address)?
.ensure_namespace(&profile_config.namespace.default);

Check warning on line 111 in bin/sozo/src/commands/execute.rs

Codecov / codecov/patch

bin/sozo/src/commands/execute.rs#L108-L111

Added lines #L108 - L111 were not covered by tests

let contract_address = match &descriptor {
ResourceDescriptor::Address(address) => Some(*address),
ResourceDescriptor::Tag(tag) => contracts.get(tag).map(|c| c.address),

Check warning on line 115 in bin/sozo/src/commands/execute.rs

Codecov / codecov/patch

bin/sozo/src/commands/execute.rs#L113-L115

Added lines #L113 - L115 were not covered by tests
ResourceDescriptor::Name(_) => {
unimplemented!("Expected to be a resolved tag with default namespace.")

Check warning on line 117 in bin/sozo/src/commands/execute.rs

Codecov / codecov/patch

bin/sozo/src/commands/execute.rs#L117

Added line #L117 was not covered by tests
}
};

let contract_address = contract_address.ok_or_else(|| {
let mut message = format!("Contract {descriptor} not found in the manifest.");
if self.diff {
message.push_str(
" Run the command again with `--diff` to force the fetch of data from \
the chain.",
);
}
anyhow!(message)
})?;

Check warning on line 130 in bin/sozo/src/commands/execute.rs

Codecov / codecov/patch

bin/sozo/src/commands/execute.rs#L121-L130

Added lines #L121 - L130 were not covered by tests

let entrypoint = arg_iter.next().ok_or_else(|| {
anyhow!(
"You must specify the entry point of {tag_or_address} to call, and \
optionally the calldata."
"You must specify the entry point of the contract `{tag_or_address}` to \
invoke, and optionally the calldata."
)
})?;

Check warning on line 137 in bin/sozo/src/commands/execute.rs

Codecov / codecov/patch

bin/sozo/src/commands/execute.rs#L132-L137

Added lines #L132 - L137 were not covered by tests

let mut calldata = vec![];
for arg in &mut arg_iter {
let arg = match arg.as_str() {
"/" | "-" | "\\" => break,
_ => calldata_decoder::decode_single_calldata(&arg)?,

Check warning on line 143 in bin/sozo/src/commands/execute.rs

Codecov / codecov/patch

bin/sozo/src/commands/execute.rs#L139-L143

Added lines #L139 - L143 were not covered by tests
};
calldata.extend(arg);

Check warning on line 145 in bin/sozo/src/commands/execute.rs

Codecov / codecov/patch

bin/sozo/src/commands/execute.rs#L145

Added line #L145 was not covered by tests
}

trace!(

Check warning on line 148 in bin/sozo/src/commands/execute.rs

Codecov / codecov/patch

bin/sozo/src/commands/execute.rs#L148

Added line #L148 was not covered by tests
contract=?descriptor,
entrypoint=entrypoint,
calldata=?calldata,
"Decoded call."

Check warning on line 152 in bin/sozo/src/commands/execute.rs

Codecov / codecov/patch

bin/sozo/src/commands/execute.rs#L152

Added line #L152 was not covered by tests
);

invoker.add_call(Call {
to: contract_address,
selector: snutils::get_selector_from_name(&entrypoint)?,
calldata,

Check warning on line 158 in bin/sozo/src/commands/execute.rs

Codecov / codecov/patch

bin/sozo/src/commands/execute.rs#L155-L158

Added lines #L155 - L158 were not covered by tests
});
}

let tx_result = invoker.multicall().await?;

Check warning on line 162 in bin/sozo/src/commands/execute.rs

Codecov / codecov/patch

bin/sozo/src/commands/execute.rs#L162

Added line #L162 was not covered by tests
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Ohayo, sensei! Add transaction size validation

Before executing the multicall, validate the total transaction size.

+            // Validate total transaction size
+            const MAX_TRANSACTION_SIZE: usize = 5000; // Adjust based on chain limits
+            let total_size = invoker.get_calls().iter().map(|call| call.calldata.len()).sum::<usize>();
+            if total_size > MAX_TRANSACTION_SIZE {
+                return Err(anyhow!(
+                    "Total transaction size {} exceeds maximum limit {}",
+                    total_size,
+                    MAX_TRANSACTION_SIZE
+                ));
+            }
+
             let tx_result = invoker.multicall().await?;

Committable suggestion skipped: line range outside the PR's diff.


#[cfg(feature = "walnut")]
if let Some(walnut_debugger) = walnut_debugger {