Skip to content

Commit 1fe274c

Browse files
Merge pull request #64 from SundaeSwap-finance/francolq/count_orders_optimization
Optimization for count_orders
2 parents 30f4d17 + ebedf62 commit 1fe274c

File tree

1 file changed

+72
-11
lines changed

1 file changed

+72
-11
lines changed

lib/shared.ak

Lines changed: 72 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ use aiken/transaction.{
1010
use aiken/transaction/credential.{Credential, ScriptCredential}
1111
use aiken/transaction/value.{AssetName, PolicyId}
1212

13+
use tests/examples/ex_shared.{
14+
script_address, wallet_address, mk_output_reference
15+
}
16+
1317
/// An alias type for the pool identifier, to make it slightly easier to reason about
1418
pub type Ident = ByteArray
1519

@@ -112,20 +116,20 @@ pub fn is_script(credential: Credential) -> Bool {
112116
/// without knowing the exact script address they will use
113117
/// This is quite subtle, so see the note above
114118
pub fn count_orders(tx_inputs: List<Input>) -> Int {
115-
// Can be done as a simple fold
116-
list.foldl(
117-
tx_inputs,
118-
// Note: by starting at -exact_non_order_script_inputs, it's the same as if we subtracted this at the end,
119-
// but saves one mathematical operation.
120-
-exact_non_order_script_inputs,
121-
fn(input, total) {
119+
when tx_inputs is {
120+
// Note: by using -exact_non_order_script_inputs for the base case,
121+
// it's equivalent to subtracting at the end
122+
[] -> -exact_non_order_script_inputs
123+
[input, ..rest] ->
122124
// The reason this is important is twofold:
123125
// - We count them in the first place to ensure that we process every order by the end of the transaction
124126
// - and we compare the script this way so that if we implement a new order script, with additional logic,
125127
// and the correct datum format, it can be processed the pool just fine
126-
total + if is_script(input.output.address.payment_credential) { 1 } else { 0 }
127-
},
128-
)
128+
when input.output.address.payment_credential is {
129+
ScriptCredential(_) -> count_orders(rest) + 1
130+
_ -> count_orders(rest)
131+
}
132+
}
129133
}
130134

131135
/// Check whether a specific value has *exactly* the right amount of tokens
@@ -192,4 +196,61 @@ pub fn pool_token_names(pool_ident: Ident) {
192196
pool_nft_name(pool_ident),
193197
pool_lp_name(pool_ident),
194198
)
195-
}
199+
}
200+
201+
// Test for count_orders, with 16 inputs of which 10 are orders.
202+
test count_orders_test() {
203+
let hash_of_pool_script =
204+
#"00000000000000000000000000000000000000000000000000000000"
205+
let pool_address = script_address(hash_of_pool_script)
206+
let pool_input =
207+
Input {
208+
output_reference: mk_output_reference(0),
209+
output: Output {
210+
address: pool_address,
211+
value: value.from_lovelace(0),
212+
datum: NoDatum,
213+
reference_script: None,
214+
},
215+
}
216+
217+
let hash_of_escrow_script =
218+
#"00000000000000000000000000000000000000000000000000000000"
219+
let escrow_address = script_address(hash_of_escrow_script)
220+
let escrow1_in = Input {
221+
output_reference: mk_output_reference(2),
222+
output: Output {
223+
address: escrow_address,
224+
value: value.from_lovelace(0),
225+
datum: NoDatum,
226+
reference_script: None,
227+
},
228+
}
229+
let escrow2_in = Input {
230+
output_reference: mk_output_reference(3),
231+
output: Output {
232+
address: escrow_address,
233+
value: value.from_lovelace(0),
234+
datum: NoDatum,
235+
reference_script: None,
236+
},
237+
}
238+
let other_address = wallet_address(#"fede0000000000000000000000000000000000000000000000000000")
239+
let other_in = Input {
240+
output_reference: mk_output_reference(4),
241+
output: Output {
242+
address: other_address,
243+
value: value.from_lovelace(0),
244+
datum: NoDatum,
245+
reference_script: None,
246+
},
247+
}
248+
249+
let inputs = [
250+
pool_input, other_in, escrow1_in, escrow2_in, other_in, escrow1_in,
251+
escrow2_in, other_in, escrow1_in, escrow2_in, other_in, escrow1_in,
252+
escrow2_in, other_in, escrow1_in, escrow2_in
253+
]
254+
255+
count_orders(inputs) == 10
256+
}

0 commit comments

Comments
 (0)