Skip to content

Commit c13b54a

Browse files
Use object macro for object formation and iterators for array formation
1 parent 24f6a2e commit c13b54a

File tree

11 files changed

+162
-256
lines changed

11 files changed

+162
-256
lines changed

wasm/src/ledger/transaction.rs

Lines changed: 75 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
use crate::{
1818
input_to_js_value,
19+
object,
1920
output_to_js_value,
2021
types::native::{FromBytes, ToBytes, TransactionNative, U64Native},
2122
Field,
@@ -77,9 +78,7 @@ impl Transaction {
7778
#[wasm_bindgen(js_name = toBytesLe)]
7879
pub fn to_bytes_le(&self) -> Result<Uint8Array, String> {
7980
let bytes = self.0.to_bytes_le().map_err(|e| e.to_string())?;
80-
let array = Uint8Array::new_with_length(bytes.len() as u32);
81-
array.copy_from(bytes.as_slice());
82-
Ok(array)
81+
Ok(Uint8Array::from(bytes.as_slice()))
8382
}
8483

8584
/// Returns true if the transaction contains the given serial number.
@@ -145,30 +144,33 @@ impl Transaction {
145144
///
146145
/// @returns {Array<RecordPlaintext>} Array of record plaintext objects
147146
pub fn owned_records(&self, view_key: &ViewKey) -> Array {
148-
let array = Array::new();
149-
self.0.records().for_each(|(_, record_ciphertext)| {
150-
if let Ok(record_plaintext) = record_ciphertext.decrypt(view_key) {
151-
let record_ciphertext = RecordPlaintext::from(record_plaintext);
152-
array.push(&JsValue::from(record_ciphertext));
153-
}
154-
});
155-
array
147+
self.0
148+
.records()
149+
.filter_map(|(_, record_ciphertext)| {
150+
if let Ok(record_plaintext) = record_ciphertext.decrypt(view_key) {
151+
Some(JsValue::from(RecordPlaintext::from(record_plaintext)))
152+
} else {
153+
None
154+
}
155+
})
156+
.collect::<Array>()
156157
}
157158

158159
/// Get the records present in a transaction and their commitments.
159160
///
160161
/// @returns {Array<{commitment: Field, record: RecordCiphertext}>} Array of record ciphertext objects
161162
pub fn records(&self) -> Array {
162-
let array = Array::new();
163-
self.0.records().for_each(|(commitment, record_ciphertext)| {
164-
let object = Object::new();
165-
let commitment = Field::from(commitment);
166-
let record_ciphertext = RecordCiphertext::from(record_ciphertext);
167-
Reflect::set(&object, &JsValue::from_str("commitment"), &JsValue::from(commitment)).unwrap();
168-
Reflect::set(&object, &JsValue::from_str("record"), &JsValue::from(record_ciphertext)).unwrap();
169-
array.push(&object);
170-
});
171-
array
163+
self.0
164+
.records()
165+
.map(|(commitment, record_ciphertext)| {
166+
let commitment = Field::from(commitment);
167+
let record_ciphertext = RecordCiphertext::from(record_ciphertext);
168+
object! {
169+
"commitment" : commitment,
170+
"record" : record_ciphertext,
171+
}
172+
})
173+
.collect::<Array>()
172174
}
173175

174176
/// Get a summary of the transaction within a javascript object.
@@ -183,139 +185,62 @@ impl Transaction {
183185
/// if false the inputs and outputs will be in wasm format.
184186
///
185187
/// @returns {Object} Transaction summary
186-
pub fn summary(&self, convert_to_js: bool) -> Result<Object, String> {
187-
// Create a transaction object.
188-
let transaction = Object::new();
189-
let fee = *self.0.fee_amount().unwrap_or(U64Native::new(0));
190-
let base_fee = *self.0.base_fee_amount().unwrap_or(U64Native::new(0));
191-
let priority_fee = *self.0.priority_fee_amount().unwrap_or(U64Native::new(0));
192-
Reflect::set(
193-
&transaction,
194-
&JsValue::from_str("transactionId"),
195-
&JsValue::from_str(&self.transaction_id().to_string()),
196-
)
197-
.unwrap();
198-
Reflect::set(
199-
&transaction,
200-
&JsValue::from_str("transactionType"),
201-
&JsValue::from_str(&self.transaction_type().to_string()),
202-
)
203-
.unwrap();
204-
Reflect::set(&transaction, &JsValue::from_str("baseFee"), &JsValue::from(base_fee)).unwrap();
205-
Reflect::set(&transaction, &JsValue::from_str("fee"), &JsValue::from(fee)).unwrap();
206-
Reflect::set(&transaction, &JsValue::from_str("priorityFee"), &JsValue::from(priority_fee)).unwrap();
207-
188+
pub fn summary(&self, convert_to_js: bool) -> Object {
208189
// If the transaction is an execution, create an array of transitions.
209-
if self.0.is_execute() {
210-
let transitions = Array::new();
211-
for transition in self.0.transitions() {
212-
let transition_object = Object::new();
213-
Reflect::set(
214-
&transition_object,
215-
&JsValue::from_str("programId"),
216-
&JsValue::from_str(&transition.program_id().to_string()),
217-
)
218-
.unwrap();
219-
Reflect::set(
220-
&transition_object,
221-
&JsValue::from_str("functionName"),
222-
&JsValue::from_str(&transition.function_name().to_string()),
223-
)
224-
.unwrap();
225-
Reflect::set(
226-
&transition_object,
227-
&JsValue::from_str("transitionId"),
228-
&JsValue::from_str(&transition.id().to_string()),
229-
)
230-
.unwrap();
231-
232-
let tpk = Group::from(transition.tpk());
233-
let tcm = Field::from(transition.tcm());
234-
let scm = Field::from(transition.scm());
235-
if convert_to_js {
236-
Reflect::set(&transition_object, &JsValue::from_str("tpk"), &JsValue::from_str(&tpk.to_string()))
237-
.unwrap();
238-
Reflect::set(&transition_object, &JsValue::from_str("tcm"), &JsValue::from_str(&tcm.to_string()))
239-
.unwrap();
240-
Reflect::set(&transition_object, &JsValue::from_str("scm"), &JsValue::from_str(&scm.to_string()))
241-
.unwrap();
242-
} else {
243-
Reflect::set(&transition_object, &JsValue::from_str("tpk"), &JsValue::from(tpk)).unwrap();
244-
Reflect::set(&transition_object, &JsValue::from_str("tcm"), &JsValue::from(tcm)).unwrap();
245-
Reflect::set(&transition_object, &JsValue::from_str("scm"), &JsValue::from(scm)).unwrap();
190+
let transitions = if self.0.is_execute() {
191+
let transitions = self.0.transitions().map(|transition| {
192+
// Collect the inputs and outputs.
193+
let inputs = transition.inputs().iter().map(|input| {
194+
input_to_js_value(input, convert_to_js)
195+
}).collect::<Array>();
196+
let outputs = transition.outputs().iter().map(|output| {
197+
output_to_js_value(output, convert_to_js)
198+
}).collect::<Array>();
199+
object! {
200+
"programId" : transition.program_id().to_string(),
201+
"functionName" : transition.function_name().to_string(),
202+
"transitionID" : transition.id().to_string(),
203+
"inputs" : inputs,
204+
"outputs" : outputs,
205+
"tpk" : if convert_to_js { JsValue::from_str(&transition.tpk().to_string()) } else { JsValue::from(Group::from(transition.tpk())) },
206+
"tcm" : if convert_to_js { JsValue::from_str(&transition.tcm().to_string()) } else { JsValue::from(Field::from(transition.tcm())) },
207+
"scm" : if convert_to_js { JsValue::from_str(&transition.scm().to_string()) } else { JsValue::from(Field::from(transition.scm())) },
246208
}
247-
248-
// Get the inputs.
249-
let inputs = Array::new();
250-
for input in transition.inputs() {
251-
inputs.push(&input_to_js_value(input, convert_to_js));
252-
}
253-
Reflect::set(&transition_object, &JsValue::from_str("inputs"), &inputs).unwrap();
254-
255-
// Get the outputs.
256-
let outputs = Array::new();
257-
for output in transition.outputs() {
258-
outputs.push(&output_to_js_value(output, convert_to_js)?);
259-
}
260-
Reflect::set(&transition_object, &JsValue::from_str("outputs"), &outputs).unwrap();
261-
transitions.push(&transition_object);
262-
}
263-
Reflect::set(&transaction, &JsValue::from_str("transitions"), &transitions).unwrap();
264-
}
209+
}).collect::<Array>();
210+
JsValue::from(transitions)
211+
} else {
212+
JsValue::NULL
213+
};
265214

266215
// If the transaction is a deployment, summarize the deployment.
267-
if let Some(deployment) = self.0.deployment() {
268-
let deployment_object = Object::new();
269-
Reflect::set(
270-
&deployment_object,
271-
&JsValue::from_str("programId"),
272-
&JsValue::from_str(&deployment.program_id().to_string()),
273-
)
274-
.unwrap();
275-
let functions = Array::new();
276-
for (function_name, (verifying_key, _)) in deployment.verifying_keys() {
277-
let function = Object::new();
278-
Reflect::set(
279-
&function,
280-
&JsValue::from_str("functionName"),
281-
&JsValue::from_str(&function_name.to_string()),
282-
)
283-
.unwrap();
284-
if convert_to_js {
285-
Reflect::set(
286-
&function,
287-
&JsValue::from_str("verifyingKey"),
288-
&JsValue::from_str(&verifying_key.to_string()),
289-
)
290-
.unwrap();
291-
} else {
292-
Reflect::set(
293-
&function,
294-
&JsValue::from_str("verifyingKey"),
295-
&JsValue::from(VerifyingKey::from(verifying_key)),
296-
)
297-
.unwrap();
216+
let deployment = if let Some(deployment) = self.0.deployment() {
217+
let functions = deployment.verifying_keys().iter().map(|(function_name, (verifying_key, _))| {
218+
// Create the initial function object.
219+
object! {
220+
"functionName" : function_name.to_string(),
221+
"constraints" : verifying_key.circuit_info.num_constraints as u32,
222+
"variables" : verifying_key.num_variables() as u32,
223+
"verifyingKey": if convert_to_js { JsValue::from_str(&verifying_key.to_string()) } else { JsValue::from(VerifyingKey::from(verifying_key)) },
298224
}
299-
Reflect::set(
300-
&function,
301-
&JsValue::from_str("constraints"),
302-
&JsValue::from(verifying_key.circuit_info.num_constraints as u32),
303-
)
304-
.unwrap();
305-
Reflect::set(
306-
&function,
307-
&JsValue::from_str("variables"),
308-
&JsValue::from(verifying_key.num_variables() as u32),
309-
)
310-
.unwrap();
311-
functions.push(&function);
312-
}
313-
Reflect::set(&deployment_object, &JsValue::from_str("functions"), &functions).unwrap();
314-
Reflect::set(&transaction, &JsValue::from_str("deployment"), &deployment_object).unwrap();
225+
}).collect::<Array>();
226+
// Create the deployment object.
227+
JsValue::from(object! {
228+
"programId" : deployment.program_id().to_string(),
229+
"functions" : functions,
230+
})
231+
} else {
232+
JsValue::NULL
233+
};
234+
235+
object! {
236+
"transactionId" : self.transaction_id().to_string(),
237+
"transactionType" : self.transaction_type().to_string(),
238+
"fee" : *self.0.fee_amount().unwrap_or(U64Native::new(0)),
239+
"baseFee" : *self.0.base_fee_amount().unwrap_or(U64Native::new(0)),
240+
"priorityFee" : *self.0.priority_fee_amount().unwrap_or(U64Native::new(0)),
241+
"transitions" : transitions,
242+
"deployment" : deployment,
315243
}
316-
317-
// Return the transaction summary.
318-
Ok(transaction)
319244
}
320245

321246
/// Get the id of the transaction. This is the merkle root of the transaction's inclusion proof.
@@ -346,11 +271,7 @@ impl Transaction {
346271

347272
/// Get the transitions in a transaction.
348273
pub fn transitions(&self) -> Array {
349-
let transitions = Array::new();
350-
self.0.transitions().for_each(|transition| {
351-
transitions.push(&JsValue::from(Transition::from(transition)));
352-
});
353-
transitions
274+
self.0.transitions().map(|transition| JsValue::from(Transition::from(transition))).collect::<Array>()
354275
}
355276
}
356277

@@ -450,7 +371,7 @@ mod tests {
450371
#[wasm_bindgen_test]
451372
fn test_transaction_summary_provides_expected_values() {
452373
let transaction = Transaction::from_string(TRANSACTION_STRING).unwrap();
453-
let summary = transaction.summary(true).unwrap();
374+
let summary = transaction.summary(true);
454375
let transaction_id = Reflect::get(&summary, &JsValue::from_str("transactionId")).unwrap().as_string().unwrap();
455376
assert_eq!(transaction_id, TRANSACTION_ID);
456377
let transaction_type =

0 commit comments

Comments
 (0)