Skip to content

Commit

Permalink
[sdks] new Pay transaction type for generic payment
Browse files Browse the repository at this point in the history
This API is intended to be the one-stop shop for any kind of payment: as input, take:
- an arbitrary number of coins
- an arbitrary number of recipient addresses
- a vector of amounts (must be same length as # of recipient addresses)

and do the obvious thing: use the input coins to pay each recipient the desired amount.
  • Loading branch information
sblackshear committed Sep 23, 2022
1 parent ab2309d commit b8b6872
Show file tree
Hide file tree
Showing 12 changed files with 704 additions and 47 deletions.
59 changes: 56 additions & 3 deletions crates/sui-adapter/src/temporary_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,43 @@ pub struct InnerTemporaryStore {
pub deleted: BTreeMap<ObjectID, (SequenceNumber, DeleteKind)>,
}

impl InnerTemporaryStore {
/// Return the written object value with the given ID (if any)
pub fn get_written_object(&self, id: &ObjectID) -> Option<&Object> {
self.written.get(id).map(|o| &o.1)
}

/// Return the set of object ID's created during the current tx
pub fn created(&self) -> Vec<ObjectID> {
self.written
.values()
.filter_map(|(obj_ref, _, w)| {
if *w == WriteKind::Create {
Some(obj_ref.0)
} else {
None
}
})
.collect()
}

/// Get the written objects owned by `address`
pub fn get_written_objects_owned_by(&self, address: &SuiAddress) -> Vec<ObjectID> {
self.written
.values()
.filter_map(|(_, o, _)| {
if o.get_single_owner()
.map_or(false, |owner| &owner == address)
{
Some(o.id())
} else {
None
}
})
.collect()
}
}

pub struct TemporaryStore<S> {
// The backing store for retrieving Move packages onchain.
// When executing a Move call, the dependent packages are not going to be
Expand Down Expand Up @@ -299,7 +336,7 @@ impl<S> TemporaryStore<S> {

pub fn write_object(&mut self, mut object: Object, kind: WriteKind) {
// there should be no write after delete
debug_assert!(self.deleted.get(&object.id()) == None);
debug_assert!(self.deleted.get(&object.id()).is_none());
// Check it is not read-only
#[cfg(test)] // Movevm should ensure this
if let Some(existing_object) = self.read_object(&object.id()) {
Expand All @@ -318,7 +355,7 @@ impl<S> TemporaryStore<S> {

pub fn delete_object(&mut self, id: &ObjectID, version: SequenceNumber, kind: DeleteKind) {
// there should be no deletion after write
debug_assert!(self._written.get(id) == None);
debug_assert!(self._written.get(id).is_none());
// Check it is not read-only
#[cfg(test)] // Movevm should ensure this
if let Some(object) = self.read_object(id) {
Expand All @@ -345,7 +382,7 @@ impl<S> Storage for TemporaryStore<S> {

fn read_object(&self, id: &ObjectID) -> Option<&Object> {
// there should be no read after delete
debug_assert!(self.deleted.get(id) == None);
debug_assert!(self.deleted.get(id).is_none());
self._written
.get(id)
.map(|(obj, _kind)| obj)
Expand Down Expand Up @@ -435,3 +472,19 @@ impl<S: ParentSync> ParentSync for TemporaryStore<S> {
self.store.get_latest_parent_entry_ref(object_id)
}
}

/// Create an empty `TemporaryStore` with no backing storage for module resolution.
/// For testing purposes only.
pub fn empty_for_testing() -> TemporaryStore<()> {
TemporaryStore::new(
(),
InputObjects::new(Vec::new()),
TransactionDigest::genesis(),
)
}

/// Create a `TemporaryStore` with the given inputs and no backing storage for module resolution.
/// For testing purposes only.
pub fn with_input_objects_for_testing(input_objects: InputObjects) -> TemporaryStore<()> {
TemporaryStore::new((), input_objects, TransactionDigest::genesis())
}
Loading

0 comments on commit b8b6872

Please sign in to comment.