From 5b7c49d43e6b269b78b3641f28cf342a63d6fa11 Mon Sep 17 00:00:00 2001 From: KtorZ Date: Fri, 20 Sep 2024 16:04:40 +0200 Subject: [PATCH] Rename modules, move generic functions to upstream dependencies. --- lib/aiken/collection/list/extra.ak | 17 ++ lib/aiken/collection/list/extra.test.ak | 15 ++ lib/aiken/fuzz/scenario.ak | 20 +- lib/cardano/generator.ak | 185 +----------------- .../proxy.ak => zhuli/predicate.ak} | 2 +- .../proxy.test.ak => zhuli/predicate.test.ak} | 2 +- .../credential/proxy => zhuli}/state.ak | 0 lib/zhuli/state.test.ak | 74 +++++++ validators/{proxy.ak => zhuli.ak} | 24 +-- validators/{proxy.test.ak => zhuli.test.ak} | 55 ++---- 10 files changed, 154 insertions(+), 240 deletions(-) create mode 100644 lib/aiken/collection/list/extra.ak create mode 100644 lib/aiken/collection/list/extra.test.ak rename lib/{cardano/credential/proxy.ak => zhuli/predicate.ak} (99%) rename lib/{cardano/credential/proxy.test.ak => zhuli/predicate.test.ak} (96%) rename lib/{cardano/credential/proxy => zhuli}/state.ak (100%) create mode 100644 lib/zhuli/state.test.ak rename validators/{proxy.ak => zhuli.ak} (88%) rename validators/{proxy.test.ak => zhuli.test.ak} (96%) diff --git a/lib/aiken/collection/list/extra.ak b/lib/aiken/collection/list/extra.ak new file mode 100644 index 0000000..003c4f0 --- /dev/null +++ b/lib/aiken/collection/list/extra.ak @@ -0,0 +1,17 @@ +//// This Source Code Form is subject to the terms of the Mozilla Public +//// License, v. 2.0. If a copy of the MPL was not distributed with this +//// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +/// Insert an element in a list at the given position. +pub fn insert(self: List, ix: Int, elem: a) -> List { + when self is { + [] -> + [elem] + [head, ..tail] -> + if ix == 0 { + [elem, head, ..tail] + } else { + [head, ..insert(tail, ix - 1, elem)] + } + } +} diff --git a/lib/aiken/collection/list/extra.test.ak b/lib/aiken/collection/list/extra.test.ak new file mode 100644 index 0000000..6eb5d06 --- /dev/null +++ b/lib/aiken/collection/list/extra.test.ak @@ -0,0 +1,15 @@ +//// This Source Code Form is subject to the terms of the Mozilla Public +//// License, v. 2.0. If a copy of the MPL was not distributed with this +//// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +use aiken/collection/list/extra.{insert} + +test insert_examples() { + and { + (insert([], 0, elem: 0) == [0])?, + (insert([], 2, elem: 0) == [0])?, + (insert([1, 2], 0, elem: 0) == [0, 1, 2])?, + (insert([1, 2], 2, elem: 0) == [1, 2, 0])?, + (insert([1, 2], -1, elem: 0) == [1, 2, 0])?, + } +} diff --git a/lib/aiken/fuzz/scenario.ak b/lib/aiken/fuzz/scenario.ak index 880519a..39136c1 100644 --- a/lib/aiken/fuzz/scenario.ak +++ b/lib/aiken/fuzz/scenario.ak @@ -1,6 +1,6 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. +//// This Source Code Form is subject to the terms of the Mozilla Public +//// License, v. 2.0. If a copy of the MPL was not distributed with this +//// file, You can obtain one at http://mozilla.org/MPL/2.0/. use aiken/cbor.{serialise} use aiken/collection/dict @@ -255,22 +255,22 @@ fn publish_handlers( True, fn(ix, certificate, st) { when certificate is { - UnregisterCredential { credential, .. } | - DelegateCredential { credential, .. } | - RegisterAndDelegateCredential { credential, .. } | + UnregisterCredential { credential, .. } | + DelegateCredential { credential, .. } | + RegisterAndDelegateCredential { credential, .. } | RegisterDelegateRepresentative { delegate_representative: credential, .. - } | - UpdateDelegateRepresentative { delegate_representative: credential } | + } | + UpdateDelegateRepresentative { delegate_representative: credential } | UnregisterDelegateRepresentative { delegate_representative: credential, .. - } | + } | AuthorizeConstitutionalCommitteeProxy { constitutional_committee_member: credential, .. - } | + } | RetireFromConstitutionalCommittee { constitutional_committee_member: credential, } -> diff --git a/lib/cardano/generator.ak b/lib/cardano/generator.ak index 70a7709..40cd1d7 100644 --- a/lib/cardano/generator.ak +++ b/lib/cardano/generator.ak @@ -1,11 +1,11 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. +//// This Source Code Form is subject to the terms of the Mozilla Public +//// License, v. 2.0. If a copy of the MPL was not distributed with this +//// file, You can obtain one at http://mozilla.org/MPL/2.0/. use aiken/collection/list use aiken/crypto.{ScriptHash} use aiken/fuzz.{ - and_then, byte, bytearray_between, constant, int, int_at_least, int_between, + and_then, bytearray_between, constant, int, int_at_least, int_between, list_between, map, option, } use cardano/address.{Address, Inline, Script, VerificationKey} @@ -14,183 +14,6 @@ use cardano/transaction.{ Datum, DatumHash, InlineDatum, Input, NoDatum, Output, OutputReference, } -// ---------------------------------------------- TODO: Move to the fuzz library - -pub fn pick(xs: List) -> Fuzzer<(Int, a)> { - let ix <- map(int_between(0, list.length(xs) - 1)) - expect Some(x) = list.at(xs, ix) - (ix, x) -} - -pub fn either3( - a: Fuzzer, - b: Fuzzer, - c: Fuzzer, -) -> Fuzzer { - let ix <- and_then(byte()) - if ix < 85 { - a - } else if ix < 170 { - b - } else { - c - } -} - -pub fn either4( - a: Fuzzer, - b: Fuzzer, - c: Fuzzer, - d: Fuzzer, -) -> Fuzzer { - let ix <- and_then(byte()) - if ix < 128 { - if ix < 64 { - a - } else { - b - } - } else { - if ix < 192 { - c - } else { - d - } - } -} - -pub fn either5( - a: Fuzzer, - b: Fuzzer, - c: Fuzzer, - d: Fuzzer, - e: Fuzzer, -) -> Fuzzer { - let ix <- and_then(byte()) - if ix < 102 { - if ix < 51 { - a - } else { - b - } - } else if ix < 204 { - if ix < 153 { - c - } else { - d - } - } else { - e - } -} - -pub fn either6( - a: Fuzzer, - b: Fuzzer, - c: Fuzzer, - d: Fuzzer, - e: Fuzzer, - f: Fuzzer, -) -> Fuzzer { - let ix <- and_then(byte()) - if ix < 127 { - if ix < 42 { - a - } else if ix < 85 { - b - } else { - c - } - } else { - if ix < 170 { - d - } else if ix < 212 { - e - } else { - f - } - } -} - -pub fn either7( - a: Fuzzer, - b: Fuzzer, - c: Fuzzer, - d: Fuzzer, - e: Fuzzer, - f: Fuzzer, - g: Fuzzer, -) -> Fuzzer { - let ix <- and_then(byte()) - if ix < 109 { - if ix < 36 { - a - } else if ix < 72 { - b - } else { - c - } - } else { - if ix < 182 { - if ix < 145 { - d - } else { - e - } - } else { - if ix < 218 { - f - } else { - g - } - } - } -} - -pub fn either8( - a: Fuzzer, - b: Fuzzer, - c: Fuzzer, - d: Fuzzer, - e: Fuzzer, - f: Fuzzer, - g: Fuzzer, - h: Fuzzer, -) -> Fuzzer { - let ix <- and_then(byte()) - if ix < 128 { - if ix < 64 { - if ix < 32 { - a - } else { - b - } - } else { - if ix < 96 { - c - } else { - d - } - } - } else { - if ix < 192 { - if ix < 160 { - e - } else { - f - } - } else { - if ix < 224 { - g - } else { - h - } - } - } -} - -// ----------------------------------------------------------------------------- - pub fn any_asset_name() -> Fuzzer { bytearray_between(0, 32) } diff --git a/lib/cardano/credential/proxy.ak b/lib/zhuli/predicate.ak similarity index 99% rename from lib/cardano/credential/proxy.ak rename to lib/zhuli/predicate.ak index 51fee63..a0c6861 100644 --- a/lib/cardano/credential/proxy.ak +++ b/lib/zhuli/predicate.ak @@ -10,9 +10,9 @@ use cardano/assets.{Lovelace, PolicyId, Value, ada_policy_id} use cardano/certificate.{ RegisterDelegateRepresentative, UnregisterDelegateRepresentative, } -use cardano/credential/proxy/state.{DelegateKind} use cardano/transaction.{Input, NoDatum, Output, Transaction} use sundae/multisig.{MultisigScript} +use zhuli/state.{DelegateKind} pub type Update { Register diff --git a/lib/cardano/credential/proxy.test.ak b/lib/zhuli/predicate.test.ak similarity index 96% rename from lib/cardano/credential/proxy.test.ak rename to lib/zhuli/predicate.test.ak index 43e59a5..ce480a8 100644 --- a/lib/cardano/credential/proxy.test.ak +++ b/lib/zhuli/predicate.test.ak @@ -6,9 +6,9 @@ use aiken/crypto.{ScriptHash} use aiken/fuzz.{both} use cardano/address.{Address} use cardano/assets.{ada_policy_id} -use cardano/credential/proxy.{must_forward_strict_assets} use cardano/generator.{any_ada_only_value, any_value_with} use sundae/multisig.{MultisigScript} +use zhuli/predicate.{must_forward_strict_assets} // NOTE: Needs not to be an actual policy id, as we never re-hash anything. So // we might as well make it something we can easily recognize. diff --git a/lib/cardano/credential/proxy/state.ak b/lib/zhuli/state.ak similarity index 100% rename from lib/cardano/credential/proxy/state.ak rename to lib/zhuli/state.ak diff --git a/lib/zhuli/state.test.ak b/lib/zhuli/state.test.ak new file mode 100644 index 0000000..d634b7c --- /dev/null +++ b/lib/zhuli/state.test.ak @@ -0,0 +1,74 @@ +//// This Source Code Form is subject to the terms of the Mozilla Public +//// License, v. 2.0. If a copy of the MPL was not distributed with this +//// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +use aiken/collection/list +use aiken/fuzz.{ + and_then, both, bytearray_between, constant, either, int, int_between, + label_when, list_between, map, +} +use sundae/multisig.{ + After, AllOf, AnyOf, AtLeast, Before, MultisigScript, Script, Signature, +} +use zhuli/state.{ + BlockProduction, DelegateKind, Governance, into_asset_name, match_prefix, +} + +test prop_prefix( + (kind, script) via both(any_delegate_kind(), any_multisig_script()), +) { + label_when(kind == Governance, @"Governance", @"BlockProduction") + match_prefix(kind, into_asset_name(kind, script)) +} + +fn any_delegate_kind() -> Fuzzer { + either(constant(BlockProduction), constant(Governance)) +} + +fn any_multisig_script() -> Fuzzer { + any_multisig_script_at_depth(3) +} + +fn any_multisig_script_at_depth(depth: Int) -> Fuzzer { + if depth <= 0 { + map(bytearray_between(28, 28), Signature) + } else { + let variant <- and_then(int_between(0, 7)) + if variant < 4 { + if variant < 2 { + if variant < 1 { + map(bytearray_between(28, 28), Signature) + } else { + map( + list_between(any_multisig_script_at_depth(depth - 1), 0, depth), + AllOf, + ) + } + } else { + if variant == 2 { + map( + list_between(any_multisig_script_at_depth(depth - 1), 0, depth), + AnyOf, + ) + } else { + let scripts <- + and_then( + list_between(any_multisig_script_at_depth(depth - 1), 0, depth), + ) + let required <- map(int_between(0, list.length(scripts))) + AtLeast { required, scripts } + } + } + } else { + if variant < 6 { + if variant < 5 { + map(int(), Before) + } else { + map(int(), After) + } + } else { + map(bytearray_between(28, 28), Script) + } + } + } +} diff --git a/validators/proxy.ak b/validators/zhuli.ak similarity index 88% rename from validators/proxy.ak rename to validators/zhuli.ak index f34e412..ef0e955 100644 --- a/validators/proxy.ak +++ b/validators/zhuli.ak @@ -1,6 +1,6 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. +//// This Source Code Form is subject to the terms of the Mozilla Public +//// License, v. 2.0. If a copy of the MPL was not distributed with this +//// file, You can obtain one at http://mozilla.org/MPL/2.0/. use aiken/collection/dict use aiken/collection/list @@ -10,15 +10,15 @@ use cardano/certificate.{ Certificate, RegisterDelegateRepresentative, UnregisterDelegateRepresentative, UpdateDelegateRepresentative, } -use cardano/credential/proxy.{ - must_be_approved_by_administrator, must_be_approved_by_delegate, - must_forward_script, update_delegate, -} -use cardano/credential/proxy/state.{Governance} use cardano/governance.{DelegateRepresentative, Voter} use cardano/transaction.{Input, OutputReference, Transaction} use config use sundae/multisig.{MultisigScript} +use zhuli/predicate.{ + Register, Unregister, must_be_approved_by_administrator, + must_be_approved_by_delegate, must_forward_script, update_delegate, +} +use zhuli/state.{Governance} const administrator: MultisigScript = multisig.AtLeast { @@ -26,7 +26,7 @@ const administrator: MultisigScript = scripts: list.map(config.administrators, multisig.Signature), } -validator direct_proxy { +validator zhuli { // The minting and burning of tokens is mostly delegated and tied to the registration/unregistration of // the delegate script credential. The ledger enforces that one can only register a DRep once, which gives // us the uniqueness property necessary to issue an NFT. @@ -43,7 +43,7 @@ validator direct_proxy { RegisterDelegateRepresentative { delegate_representative: credential, .. - } | + } | UnregisterDelegateRepresentative { delegate_representative: credential, .. @@ -110,13 +110,13 @@ validator direct_proxy { RegisterDelegateRepresentative { delegate_representative: delegate, .. } -> and { must_be_approved_by_administrator(self, administrator)?, - update_delegate(self, rules, delegate, Governance, proxy.Register)?, + update_delegate(self, rules, delegate, Governance, Register)?, } UnregisterDelegateRepresentative { delegate_representative: delegate, .. } -> and { must_be_approved_by_administrator(self, administrator)?, - update_delegate(self, rules, delegate, Governance, proxy.Unregister)?, + update_delegate(self, rules, delegate, Governance, Unregister)?, } // The UpdateDelegateRepresentative certificate is only used to update diff --git a/validators/proxy.test.ak b/validators/zhuli.test.ak similarity index 96% rename from validators/proxy.test.ak rename to validators/zhuli.test.ak index 0c6252a..2b7263f 100644 --- a/validators/proxy.test.ak +++ b/validators/zhuli.test.ak @@ -1,9 +1,10 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. +//// This Source Code Form is subject to the terms of the Mozilla Public +//// License, v. 2.0. If a copy of the MPL was not distributed with this +//// file, You can obtain one at http://mozilla.org/MPL/2.0/. use aiken/collection/dict use aiken/collection/list.{for_each} +use aiken/collection/list/extra.{insert} use aiken/collection/pairs use aiken/crypto.{ScriptHash, VerificationKeyHash} use aiken/fuzz.{ @@ -19,9 +20,6 @@ use cardano/assets.{ use cardano/certificate.{ Certificate, RegisterDelegateRepresentative, UnregisterDelegateRepresentative, } -use cardano/credential/proxy/state.{ - BlockProduction, Governance, into_asset_name, match_prefix, prefix, -} use cardano/generator.{ any_address, any_asset_name, any_policy_id, any_value_extending, any_zero_output, @@ -31,8 +29,11 @@ use cardano/transaction.{ } use cardano/transaction/script_purpose use config -use proxy as handlers use sundae/multisig.{MultisigScript} +use zhuli as handlers +use zhuli/state.{ + BlockProduction, Governance, into_asset_name, match_prefix, prefix, +} const validator_hash: ScriptHash = #"0123456789abcedf" @@ -124,30 +125,28 @@ test prop_scenario_coverage( label_when(outcome == scenario.Ok, @"O.K.", @"K.O.") } -test prop_proxy_drep_ok(ok via scenario.ok(default_state, step)) { +test prop_zhuli_ok(ok via scenario.ok(default_state, step)) { scenario.run( ok, validator_hash, - handlers.direct_proxy.mint, - handlers.direct_proxy.spend, - handlers.direct_proxy.withdraw, - handlers.direct_proxy.publish, - cast_redeemer(handlers.direct_proxy.vote), + handlers.zhuli.mint, + handlers.zhuli.spend, + handlers.zhuli.withdraw, + handlers.zhuli.publish, + cast_redeemer(handlers.zhuli.vote), ) } -test prop_proxy_drep_ko( - (labels, scenario) via scenario.ko(default_state, step), -) fail { +test prop_zhuli_ko((labels, scenario) via scenario.ko(default_state, step)) fail { for_each(list.unique(labels), fuzz.label) scenario.run( scenario, validator_hash, - handlers.direct_proxy.mint, - handlers.direct_proxy.spend, - handlers.direct_proxy.withdraw, - handlers.direct_proxy.publish, - cast_redeemer(handlers.direct_proxy.vote), + handlers.zhuli.mint, + handlers.zhuli.spend, + handlers.zhuli.withdraw, + handlers.zhuli.publish, + cast_redeemer(handlers.zhuli.vote), ) } @@ -1101,17 +1100,3 @@ fn our_value_restricted_to(utxo: List, mask: List) -> Value { }, ) } - -/// Insert an element in a list at the given position. -fn insert(self: List, ix: Int, elem: a) -> List { - when self is { - [] -> - [elem] - [head, ..tail] -> - if ix == 0 { - [elem, head, ..tail] - } else { - [head, ..insert(tail, ix - 1, elem)] - } - } -}