Skip to content

Commit

Permalink
Fix issues with API
Browse files Browse the repository at this point in the history
  • Loading branch information
stefan-mysten committed Dec 4, 2024
1 parent aaa0110 commit 4f34a89
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 84 deletions.
8 changes: 8 additions & 0 deletions crates/sui-sdk-types/src/types/object.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::collections::BTreeMap;

use super::unresolved::Input;
use super::Address;
use super::Identifier;
use super::ObjectDigest;
Expand Down Expand Up @@ -322,6 +323,13 @@ impl Object {
pub fn storage_rebate(&self) -> u64 {
self.storage_rebate
}

/// Convert this object into an [`unresolved::Input`] with the object id, digest, and version.
pub fn as_input(&self) -> Input {
Input::by_id(self.object_id())
.with_digest(self.digest())
.with_version(self.version())
}
}

fn id_opt(contents: &[u8]) -> Option<ObjectId> {
Expand Down
107 changes: 82 additions & 25 deletions crates/sui-sdk-types/src/types/transaction/unresolved.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::types::object::Version;
use crate::types::Address;
use crate::types::Object;
use crate::types::ObjectDigest;
use crate::types::ObjectId;
use crate::types::Owner;

use super::Command;
use super::TransactionExpiration;
Expand Down Expand Up @@ -207,12 +209,12 @@ impl Input {
/// Return a shared object.
/// - `mutable` controls whether a command can accept the object by value or mutable reference.
/// - `initial_shared_version` is the first version the object was shared at.
pub fn shared(object_id: ObjectId, initial_shared_version: u64, mutable: Option<bool>) -> Self {
pub fn shared(object_id: ObjectId, initial_shared_version: u64, mutable: bool) -> Self {
Self {
kind: Some(InputKind::Shared),
object_id: Some(object_id),
version: Some(initial_shared_version),
mutable,
mutable: Some(mutable),
..Default::default()
}
}
Expand All @@ -226,60 +228,91 @@ impl Input {
}

/// Set the object kind to immutable.
pub fn with_immutable_kind(&mut self) {
self.kind = Some(InputKind::ImmutableOrOwned);
pub fn with_immutable_kind(self) -> Self {
Self {
kind: Some(InputKind::ImmutableOrOwned),
..self
}
}

/// Set the object kind to owned.
pub fn with_owned_kind(&mut self) {
self.kind = Some(InputKind::ImmutableOrOwned);
pub fn with_owned_kind(self) -> Self {
Self {
kind: Some(InputKind::ImmutableOrOwned),
..self
}
}

/// Set the object kind to receiving.
pub fn with_receiving_kind(&mut self) {
self.kind = Some(InputKind::Receiving);
pub fn with_receiving_kind(self) -> Self {
Self {
kind: Some(InputKind::Receiving),
..self
}
}

/// Set the object kind to shared.
pub fn with_shared_kind(&mut self) {
self.kind = Some(InputKind::Shared);
pub fn with_shared_kind(self) -> Self {
Self {
kind: Some(InputKind::Shared),
..self
}
}

/// Set the specified version.
pub fn with_version(&mut self, version: u64) {
self.version = Some(version);
pub fn with_version(self, version: u64) -> Self {
Self {
version: Some(version),
..self
}
}

/// Set the specified digest.
pub fn with_digest(&mut self, digest: ObjectDigest) {
self.digest = Some(digest);
pub fn with_digest(self, digest: ObjectDigest) -> Self {
Self {
digest: Some(digest),
..self
}
}

// Shared fields

/// Set the initial shared version.
pub fn with_initial_shared_version(&mut self, initial: u64) {
self.version = Some(initial);
pub fn with_initial_shared_version(self, initial_version: u64) -> Self {
Self {
version: Some(initial_version),
kind: Some(InputKind::Shared),
..self
}
}

/// Make the object shared and set `mutable` to true when the input is used by value.
pub fn by_val(&mut self) {
self.kind = Some(InputKind::Shared);
self.mutable = Some(true);
pub fn by_val(self) -> Self {
Self {
kind: Some(InputKind::Shared),
mutable: Some(true),
..self
}
}

/// Make the object shared and set `mutable` to false when the input is used by
/// reference.
pub fn by_ref(&mut self) {
self.kind = Some(InputKind::Shared);
self.mutable = Some(false);
pub fn by_ref(self) -> Self {
Self {
kind: Some(InputKind::Shared),
mutable: Some(false),
..self
}
}

/// Make the object shared and set `mutable` to true when the input is used by mutable
/// reference.
pub fn by_mut(&mut self) {
self.kind = Some(InputKind::Shared);
self.mutable = Some(true);
pub fn by_mut(self) -> Self {
Self {
kind: Some(InputKind::Shared),
mutable: Some(true),
..self
}
}
}

Expand Down Expand Up @@ -321,3 +354,27 @@ impl From<Value> for serde_json::Value {
}
}
}

impl From<&Object> for Input {
fn from(object: &Object) -> Self {
match object.owner() {
Owner::Address(_) => Input::by_id(object.object_id())
.with_version(object.version())
.with_digest(object.digest()),
Owner::Object(_) => Input::owned(object.object_id(), object.version(), object.digest()),

Owner::Shared(at_version) => {
Input::by_id(object.object_id()).with_initial_shared_version(*at_version)
}
Owner::Immutable => {
Input::immutable(object.object_id(), object.version(), object.digest())
}
}
}
}

impl From<&ObjectId> for Input {
fn from(object_id: &ObjectId) -> Self {
Input::by_id(*object_id)
}
}
69 changes: 10 additions & 59 deletions crates/sui-transaction-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ use sui_types::types::Input;
use sui_types::types::MakeMoveVector;
use sui_types::types::MergeCoins;
use sui_types::types::MoveCall;
use sui_types::types::Object;
use sui_types::types::ObjectId;
use sui_types::types::ObjectReference;
use sui_types::types::Publish;
Expand All @@ -27,7 +26,6 @@ use sui_types::types::Upgrade;

use base64ct::Encoding;
use serde::Serialize;
use sui_types::types::Owner;

/// A builder for creating transactions. Use [`resolve`] to finalize the transaction data.
#[derive(Clone, Default, Debug)]
Expand Down Expand Up @@ -75,10 +73,10 @@ pub struct Function {
/// A trait to convert a type into an [`unresolved::Input`]. This is mostly used for gas objects,
/// to pass them either as literals, as an object id, as a reference to an object, or as a
/// [`unresolved::Input`] object.
pub trait IntoInput {
/// Convert the type into an [`unresolved::Input`].
fn into_input(self) -> unresolved::Input;
}
// pub trait IntoInput {
// /// Convert the type into an [`unresolved::Input`].
// fn into_input(self) -> unresolved::Input;
// }

/// A transaction builder to build transactions.
impl TransactionBuilder {
Expand Down Expand Up @@ -120,10 +118,10 @@ impl TransactionBuilder {
/// tx.add_gas(vec![&gas_obj]);
pub fn add_gas<O, I>(&mut self, gas: I)
where
O: IntoInput,
O: Into<unresolved::Input>,
I: IntoIterator<Item = O>,
{
self.gas.extend(gas.into_iter().map(IntoInput::into_input));
self.gas.extend(gas.into_iter().map(|x| x.into()));
}

/// Set the gas budget for the transaction.
Expand Down Expand Up @@ -392,44 +390,6 @@ impl<'a, T: Serialize> From<Serialized<'a, T>> for unresolved::Input {
}
}

impl IntoInput for unresolved::Input {
/// Pass the input as is
fn into_input(self) -> unresolved::Input {
self
}
}

impl IntoInput for &Object {
fn into_input(self) -> unresolved::Input {
match self.owner() {
Owner::Address(_) => {
let mut input = unresolved::Input::by_id(self.object_id());
input.with_version(self.version());
input.with_digest(self.digest());
input
}
Owner::Object(_) => {
unresolved::Input::owned(self.object_id(), self.version(), self.digest())
}

Owner::Shared(at_version) => {
unresolved::Input::shared(self.object_id(), *at_version, None)
}
Owner::Immutable => {
unresolved::Input::immutable(self.object_id(), self.version(), self.digest())
}
}
}
}

impl IntoInput for ObjectId {
/// Convert the [`ObjectId`] type into an [`unresolved::Input`] with only object id as partial
/// information.
fn into_input(self) -> unresolved::Input {
unresolved::Input::by_id(self)
}
}

/// Convert from an [`unresolved::Input`] to a [`unresolved::ObjectReference`]. This is used to
/// convert gas objects into unresolved object references.
fn try_from_gas_unresolved_input_to_unresolved_obj_ref(
Expand Down Expand Up @@ -635,14 +595,9 @@ mod tests {
.unwrap()
.sent;
let gas = coins.last().unwrap().id;
// TODO when we have tx resolution, we can just pass an ObjectId
let gas_obj = client.object(gas.into(), None).await.unwrap().unwrap();
// we'll be able to pass in the gas coin id when we have transaction resolution
// until then we need to pass an immutable or owned object with id, version, and digest.
tx.add_gas(vec![unresolved::Input::owned(
gas_obj.object_id(),
gas_obj.version(),
gas_obj.digest(),
)]);
tx.add_gas(vec![gas_obj.as_input().with_owned_kind()]);
tx.add_gas_budget(500000000);
tx.add_gas_price(1000);
tx.set_sender(address);
Expand Down Expand Up @@ -964,7 +919,7 @@ mod tests {
tx.input(unresolved::Input::immutable(o, obj.version(), obj.digest())));
}
sui_types::types::Owner::Shared(x) => {
upgrade_cap = Some(tx.input(unresolved::Input::shared(o, *x, Some(true))));
upgrade_cap = Some(tx.input(unresolved::Input::shared(o, *x, true)));
}
// If the capability is owned by an object, then the module defining the owning
// object gets to decide how the upgrade capability should be used.
Expand Down Expand Up @@ -1014,11 +969,7 @@ mod tests {

let gas = coins.last().unwrap().id;
let gas_obj = client.object(gas.into(), None).await.unwrap().unwrap();
tx.add_gas(vec![unresolved::Input::owned(
gas_obj.object_id(),
gas_obj.version(),
gas_obj.digest(),
)]);
tx.add_gas(vec![gas_obj.as_input().with_owned_kind()]);
tx.add_gas_budget(500000000);
tx.add_gas_price(1000);
tx.set_sender(address);
Expand Down

0 comments on commit 4f34a89

Please sign in to comment.