diff --git a/CHANGELOG.md b/CHANGELOG.md index df72f62af..7e656e608 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,77 +7,103 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +- [[v9.3.1]](#v931) + - [Fixed](#fixed) +- [[v9.3.0]](#v930) + - [Fixed](#fixed-1) + - [Changed](#changed) - [[v9.2.0]](#v920) - [Added](#added) - - [Changed](#changed) + - [Changed](#changed-1) - [Removed](#removed) - - [Fixed](#fixed) + - [Fixed](#fixed-2) - [[v9.1.0]](#v910) - [Added](#added-1) - - [Changed](#changed-1) + - [Changed](#changed-2) - [Removed](#removed-1) - - [Fixed](#fixed-1) + - [Fixed](#fixed-3) - [[v9.0.0]](#v900) - [Deprecated](#deprecated) - [Added](#added-2) - [Removed](#removed-2) - - [Changed](#changed-2) - - [Fixed](#fixed-2) + - [Changed](#changed-3) + - [Fixed](#fixed-4) - [[v8.0.0]](#v800) - [Added](#added-3) - - [Changed](#changed-3) - - [Fixed](#fixed-3) + - [Changed](#changed-4) + - [Fixed](#fixed-5) - [Removed](#removed-3) - [[v7.0.0]](#v700) - [Added](#added-4) - - [Changed](#changed-4) - - [Fixed](#fixed-4) + - [Changed](#changed-5) + - [Fixed](#fixed-6) - [Removed](#removed-4) - [[v6.0.0]](#v600) - [Added](#added-5) - - [Changed](#changed-5) - - [Fixed](#fixed-5) + - [Changed](#changed-6) + - [Fixed](#fixed-7) - [Removed](#removed-5) - [[v5.0.0]](#v500) - [Added](#added-6) - - [Changed](#changed-6) + - [Changed](#changed-7) - [Removed](#removed-6) - - [Fixed](#fixed-6) + - [Fixed](#fixed-8) - [Runtime Dependencies](#runtime-dependencies) - [[v4.0.2] - 2023-01-17](#v402---2023-01-17) - - [Fixed](#fixed-7) + - [Fixed](#fixed-9) - [[v4.0.1] - 2022-12-20](#v401---2022-12-20) - [Added](#added-7) - [[v4.0.0] - 2022-12-15](#v400---2022-12-15) - [Added](#added-8) - - [Changed](#changed-7) + - [Changed](#changed-8) - [Removed](#removed-7) - - [Fixed](#fixed-8) + - [Fixed](#fixed-10) - [Runtime Dependencies](#runtime-dependencies-1) - [[3.0.0] - 2022-11-21](#300---2022-11-21) - [Added](#added-9) - - [Changed](#changed-8) + - [Changed](#changed-9) - [Removed](#removed-8) - - [Fixed](#fixed-9) + - [Fixed](#fixed-11) - [Runtime Dependencies](#runtime-dependencies-2) - [[2.0.0] - 2022-09-12](#200---2022-09-12) - [Added](#added-10) - - [Changed](#changed-9) + - [Changed](#changed-10) - [Removed](#removed-9) - - [Fixed](#fixed-10) + - [Fixed](#fixed-12) - [[2.0.0-alpha] - 2022-07-05](#200-alpha---2022-07-05) - [Added](#added-11) - [Removed](#removed-10) - - [Changed](#changed-10) - - [Fixed](#fixed-11) + - [Changed](#changed-11) + - [Fixed](#fixed-13) - [[1.1.0] - 2022-06-30](#110---2022-06-30) - - [Fixed](#fixed-12) + - [Fixed](#fixed-14) - [[1.0.1] - 2022-06-17](#101---2022-06-17) - - [Fixed](#fixed-13) + - [Fixed](#fixed-15) - [[1.0.0] - 2022-06-10](#100---2022-06-10) +## [v9.3.1] + +### Fixed + +- cardano-testnet Lovelace supply has been raised to uint64 max value ([#1644](https://github.com/Plutonomicon/cardano-transaction-lib/pull/1644)) + +- cardano-testnet cleanup logic: nodes spawned by cardano-testnet should now be correctly cleaned up after test execution or upon receiving `SIGINT` or `SIGTERM` signals ([#1644](https://github.com/Plutonomicon/cardano-transaction-lib/pull/1644)) + +- Nix shell for darwin platforms (`x86_64-darwin` and `aarch64-darwin`). **Note that the CTL runtime is not provided for darwin due to the lack of support in `cardano.nix`** ([#1644](https://github.com/Plutonomicon/cardano-transaction-lib/pull/1644)) + +## [v9.3.0] + +### Fixed + +- Updated fee structure that takes [reference script size fee requirements into account](https://github.com/IntersectMBO/cardano-ledger/blob/cardano-ledger-shelley-ma-test-1.2.2.3/docs/adr/2024-08-14_009-refscripts-fee-change.md) ([#1647](https://github.com/Plutonomicon/cardano-transaction-lib/pull/1647)) +- Fixed Blockfrost PlutusV3 cost model decoding (preprod and preview return cost models in different formats) ([#1647](https://github.com/Plutonomicon/cardano-transaction-lib/pull/1647)) + +### Changed + +- `cardano-serialization-lib` has been updated to `v12.0.0` ([#1647](https://github.com/Plutonomicon/cardano-transaction-lib/pull/1647)) + ## [v9.2.0] ### Added diff --git a/examples/MintsMultipleTokens.purs b/examples/MintsMultipleTokens.purs index c3b8d414f..c87f5b625 100644 --- a/examples/MintsMultipleTokens.purs +++ b/examples/MintsMultipleTokens.purs @@ -64,6 +64,10 @@ contract = do ( PlutusScriptCredential (ScriptValue mp1) $ RedeemerDatum $ Integer (BigInt.fromInt 1) ) + , MintAsset cs1 tn2 Int.one + ( PlutusScriptCredential (ScriptValue mp1) $ RedeemerDatum $ Integer + (BigInt.fromInt 1) + ) , MintAsset cs2 tn2 Int.one ( PlutusScriptCredential (ScriptValue mp2) $ RedeemerDatum $ Integer (BigInt.fromInt 2) diff --git a/fixtures/test/blockfrost/getProtocolParameters/getProtocolParameters-6ac22050d53def4302608de2fa695f02.json b/fixtures/test/blockfrost/getProtocolParameters/getProtocolParameters-6ac22050d53def4302608de2fa695f02.json deleted file mode 100644 index 6643a5d83..000000000 --- a/fixtures/test/blockfrost/getProtocolParameters/getProtocolParameters-6ac22050d53def4302608de2fa695f02.json +++ /dev/null @@ -1 +0,0 @@ -{"epoch":406,"min_fee_a":44,"min_fee_b":155381,"max_block_size":90112,"max_tx_size":16384,"max_block_header_size":1100,"key_deposit":"2000000","pool_deposit":"500000000","e_max":18,"n_opt":500,"a0":0.3,"rho":0.003,"tau":0.2,"decentralisation_param":0,"extra_entropy":null,"protocol_major_ver":10,"protocol_minor_ver":0,"min_utxo":"4310","min_pool_cost":"340000000","nonce":"20a149dea03f4a8ee32d30db9219ee61628ccefdf0be517f96302bef35bd4cd7","cost_models":{"PlutusV1":{"addInteger-cpu-arguments-intercept":205665,"addInteger-cpu-arguments-slope":812,"addInteger-memory-arguments-intercept":1,"addInteger-memory-arguments-slope":1,"appendByteString-cpu-arguments-intercept":1000,"appendByteString-cpu-arguments-slope":571,"appendByteString-memory-arguments-intercept":0,"appendByteString-memory-arguments-slope":1,"appendString-cpu-arguments-intercept":1000,"appendString-cpu-arguments-slope":24177,"appendString-memory-arguments-intercept":4,"appendString-memory-arguments-slope":1,"bData-cpu-arguments":1000,"bData-memory-arguments":32,"blake2b_256-cpu-arguments-intercept":117366,"blake2b_256-cpu-arguments-slope":10475,"blake2b_256-memory-arguments":4,"cekApplyCost-exBudgetCPU":23000,"cekApplyCost-exBudgetMemory":100,"cekBuiltinCost-exBudgetCPU":23000,"cekBuiltinCost-exBudgetMemory":100,"cekConstCost-exBudgetCPU":23000,"cekConstCost-exBudgetMemory":100,"cekDelayCost-exBudgetCPU":23000,"cekDelayCost-exBudgetMemory":100,"cekForceCost-exBudgetCPU":23000,"cekForceCost-exBudgetMemory":100,"cekLamCost-exBudgetCPU":23000,"cekLamCost-exBudgetMemory":100,"cekStartupCost-exBudgetCPU":100,"cekStartupCost-exBudgetMemory":100,"cekVarCost-exBudgetCPU":23000,"cekVarCost-exBudgetMemory":100,"chooseData-cpu-arguments":19537,"chooseData-memory-arguments":32,"chooseList-cpu-arguments":175354,"chooseList-memory-arguments":32,"chooseUnit-cpu-arguments":46417,"chooseUnit-memory-arguments":4,"consByteString-cpu-arguments-intercept":221973,"consByteString-cpu-arguments-slope":511,"consByteString-memory-arguments-intercept":0,"consByteString-memory-arguments-slope":1,"constrData-cpu-arguments":89141,"constrData-memory-arguments":32,"decodeUtf8-cpu-arguments-intercept":497525,"decodeUtf8-cpu-arguments-slope":14068,"decodeUtf8-memory-arguments-intercept":4,"decodeUtf8-memory-arguments-slope":2,"divideInteger-cpu-arguments-constant":196500,"divideInteger-cpu-arguments-model-arguments-intercept":453240,"divideInteger-cpu-arguments-model-arguments-slope":220,"divideInteger-memory-arguments-intercept":0,"divideInteger-memory-arguments-minimum":1,"divideInteger-memory-arguments-slope":1,"encodeUtf8-cpu-arguments-intercept":1000,"encodeUtf8-cpu-arguments-slope":28662,"encodeUtf8-memory-arguments-intercept":4,"encodeUtf8-memory-arguments-slope":2,"equalsByteString-cpu-arguments-constant":245000,"equalsByteString-cpu-arguments-intercept":216773,"equalsByteString-cpu-arguments-slope":62,"equalsByteString-memory-arguments":1,"equalsData-cpu-arguments-intercept":1060367,"equalsData-cpu-arguments-slope":12586,"equalsData-memory-arguments":1,"equalsInteger-cpu-arguments-intercept":208512,"equalsInteger-cpu-arguments-slope":421,"equalsInteger-memory-arguments":1,"equalsString-cpu-arguments-constant":187000,"equalsString-cpu-arguments-intercept":1000,"equalsString-cpu-arguments-slope":52998,"equalsString-memory-arguments":1,"fstPair-cpu-arguments":80436,"fstPair-memory-arguments":32,"headList-cpu-arguments":43249,"headList-memory-arguments":32,"iData-cpu-arguments":1000,"iData-memory-arguments":32,"ifThenElse-cpu-arguments":80556,"ifThenElse-memory-arguments":1,"indexByteString-cpu-arguments":57667,"indexByteString-memory-arguments":4,"lengthOfByteString-cpu-arguments":1000,"lengthOfByteString-memory-arguments":10,"lessThanByteString-cpu-arguments-intercept":197145,"lessThanByteString-cpu-arguments-slope":156,"lessThanByteString-memory-arguments":1,"lessThanEqualsByteString-cpu-arguments-intercept":197145,"lessThanEqualsByteString-cpu-arguments-slope":156,"lessThanEqualsByteString-memory-arguments":1,"lessThanEqualsInteger-cpu-arguments-intercept":204924,"lessThanEqualsInteger-cpu-arguments-slope":473,"lessThanEqualsInteger-memory-arguments":1,"lessThanInteger-cpu-arguments-intercept":208896,"lessThanInteger-cpu-arguments-slope":511,"lessThanInteger-memory-arguments":1,"listData-cpu-arguments":52467,"listData-memory-arguments":32,"mapData-cpu-arguments":64832,"mapData-memory-arguments":32,"mkCons-cpu-arguments":65493,"mkCons-memory-arguments":32,"mkNilData-cpu-arguments":22558,"mkNilData-memory-arguments":32,"mkNilPairData-cpu-arguments":16563,"mkNilPairData-memory-arguments":32,"mkPairData-cpu-arguments":76511,"mkPairData-memory-arguments":32,"modInteger-cpu-arguments-constant":196500,"modInteger-cpu-arguments-model-arguments-intercept":453240,"modInteger-cpu-arguments-model-arguments-slope":220,"modInteger-memory-arguments-intercept":0,"modInteger-memory-arguments-minimum":1,"modInteger-memory-arguments-slope":1,"multiplyInteger-cpu-arguments-intercept":69522,"multiplyInteger-cpu-arguments-slope":11687,"multiplyInteger-memory-arguments-intercept":0,"multiplyInteger-memory-arguments-slope":1,"nullList-cpu-arguments":60091,"nullList-memory-arguments":32,"quotientInteger-cpu-arguments-constant":196500,"quotientInteger-cpu-arguments-model-arguments-intercept":453240,"quotientInteger-cpu-arguments-model-arguments-slope":220,"quotientInteger-memory-arguments-intercept":0,"quotientInteger-memory-arguments-minimum":1,"quotientInteger-memory-arguments-slope":1,"remainderInteger-cpu-arguments-constant":196500,"remainderInteger-cpu-arguments-model-arguments-intercept":453240,"remainderInteger-cpu-arguments-model-arguments-slope":220,"remainderInteger-memory-arguments-intercept":0,"remainderInteger-memory-arguments-minimum":1,"remainderInteger-memory-arguments-slope":1,"sha2_256-cpu-arguments-intercept":806990,"sha2_256-cpu-arguments-slope":30482,"sha2_256-memory-arguments":4,"sha3_256-cpu-arguments-intercept":1927926,"sha3_256-cpu-arguments-slope":82523,"sha3_256-memory-arguments":4,"sliceByteString-cpu-arguments-intercept":265318,"sliceByteString-cpu-arguments-slope":0,"sliceByteString-memory-arguments-intercept":4,"sliceByteString-memory-arguments-slope":0,"sndPair-cpu-arguments":85931,"sndPair-memory-arguments":32,"subtractInteger-cpu-arguments-intercept":205665,"subtractInteger-cpu-arguments-slope":812,"subtractInteger-memory-arguments-intercept":1,"subtractInteger-memory-arguments-slope":1,"tailList-cpu-arguments":41182,"tailList-memory-arguments":32,"trace-cpu-arguments":212342,"trace-memory-arguments":32,"unBData-cpu-arguments":31220,"unBData-memory-arguments":32,"unConstrData-cpu-arguments":32696,"unConstrData-memory-arguments":32,"unIData-cpu-arguments":43357,"unIData-memory-arguments":32,"unListData-cpu-arguments":32247,"unListData-memory-arguments":32,"unMapData-cpu-arguments":38314,"unMapData-memory-arguments":32,"verifyEd25519Signature-cpu-arguments-intercept":57996947,"verifyEd25519Signature-cpu-arguments-slope":18975,"verifyEd25519Signature-memory-arguments":10},"PlutusV2":{"addInteger-cpu-arguments-intercept":205665,"addInteger-cpu-arguments-slope":812,"addInteger-memory-arguments-intercept":1,"addInteger-memory-arguments-slope":1,"appendByteString-cpu-arguments-intercept":1000,"appendByteString-cpu-arguments-slope":571,"appendByteString-memory-arguments-intercept":0,"appendByteString-memory-arguments-slope":1,"appendString-cpu-arguments-intercept":1000,"appendString-cpu-arguments-slope":24177,"appendString-memory-arguments-intercept":4,"appendString-memory-arguments-slope":1,"bData-cpu-arguments":1000,"bData-memory-arguments":32,"blake2b_256-cpu-arguments-intercept":117366,"blake2b_256-cpu-arguments-slope":10475,"blake2b_256-memory-arguments":4,"cekApplyCost-exBudgetCPU":23000,"cekApplyCost-exBudgetMemory":100,"cekBuiltinCost-exBudgetCPU":23000,"cekBuiltinCost-exBudgetMemory":100,"cekConstCost-exBudgetCPU":23000,"cekConstCost-exBudgetMemory":100,"cekDelayCost-exBudgetCPU":23000,"cekDelayCost-exBudgetMemory":100,"cekForceCost-exBudgetCPU":23000,"cekForceCost-exBudgetMemory":100,"cekLamCost-exBudgetCPU":23000,"cekLamCost-exBudgetMemory":100,"cekStartupCost-exBudgetCPU":100,"cekStartupCost-exBudgetMemory":100,"cekVarCost-exBudgetCPU":23000,"cekVarCost-exBudgetMemory":100,"chooseData-cpu-arguments":19537,"chooseData-memory-arguments":32,"chooseList-cpu-arguments":175354,"chooseList-memory-arguments":32,"chooseUnit-cpu-arguments":46417,"chooseUnit-memory-arguments":4,"consByteString-cpu-arguments-intercept":221973,"consByteString-cpu-arguments-slope":511,"consByteString-memory-arguments-intercept":0,"consByteString-memory-arguments-slope":1,"constrData-cpu-arguments":89141,"constrData-memory-arguments":32,"decodeUtf8-cpu-arguments-intercept":497525,"decodeUtf8-cpu-arguments-slope":14068,"decodeUtf8-memory-arguments-intercept":4,"decodeUtf8-memory-arguments-slope":2,"divideInteger-cpu-arguments-constant":196500,"divideInteger-cpu-arguments-model-arguments-intercept":453240,"divideInteger-cpu-arguments-model-arguments-slope":220,"divideInteger-memory-arguments-intercept":0,"divideInteger-memory-arguments-minimum":1,"divideInteger-memory-arguments-slope":1,"encodeUtf8-cpu-arguments-intercept":1000,"encodeUtf8-cpu-arguments-slope":28662,"encodeUtf8-memory-arguments-intercept":4,"encodeUtf8-memory-arguments-slope":2,"equalsByteString-cpu-arguments-constant":245000,"equalsByteString-cpu-arguments-intercept":216773,"equalsByteString-cpu-arguments-slope":62,"equalsByteString-memory-arguments":1,"equalsData-cpu-arguments-intercept":1060367,"equalsData-cpu-arguments-slope":12586,"equalsData-memory-arguments":1,"equalsInteger-cpu-arguments-intercept":208512,"equalsInteger-cpu-arguments-slope":421,"equalsInteger-memory-arguments":1,"equalsString-cpu-arguments-constant":187000,"equalsString-cpu-arguments-intercept":1000,"equalsString-cpu-arguments-slope":52998,"equalsString-memory-arguments":1,"fstPair-cpu-arguments":80436,"fstPair-memory-arguments":32,"headList-cpu-arguments":43249,"headList-memory-arguments":32,"iData-cpu-arguments":1000,"iData-memory-arguments":32,"ifThenElse-cpu-arguments":80556,"ifThenElse-memory-arguments":1,"indexByteString-cpu-arguments":57667,"indexByteString-memory-arguments":4,"lengthOfByteString-cpu-arguments":1000,"lengthOfByteString-memory-arguments":10,"lessThanByteString-cpu-arguments-intercept":197145,"lessThanByteString-cpu-arguments-slope":156,"lessThanByteString-memory-arguments":1,"lessThanEqualsByteString-cpu-arguments-intercept":197145,"lessThanEqualsByteString-cpu-arguments-slope":156,"lessThanEqualsByteString-memory-arguments":1,"lessThanEqualsInteger-cpu-arguments-intercept":204924,"lessThanEqualsInteger-cpu-arguments-slope":473,"lessThanEqualsInteger-memory-arguments":1,"lessThanInteger-cpu-arguments-intercept":208896,"lessThanInteger-cpu-arguments-slope":511,"lessThanInteger-memory-arguments":1,"listData-cpu-arguments":52467,"listData-memory-arguments":32,"mapData-cpu-arguments":64832,"mapData-memory-arguments":32,"mkCons-cpu-arguments":65493,"mkCons-memory-arguments":32,"mkNilData-cpu-arguments":22558,"mkNilData-memory-arguments":32,"mkNilPairData-cpu-arguments":16563,"mkNilPairData-memory-arguments":32,"mkPairData-cpu-arguments":76511,"mkPairData-memory-arguments":32,"modInteger-cpu-arguments-constant":196500,"modInteger-cpu-arguments-model-arguments-intercept":453240,"modInteger-cpu-arguments-model-arguments-slope":220,"modInteger-memory-arguments-intercept":0,"modInteger-memory-arguments-minimum":1,"modInteger-memory-arguments-slope":1,"multiplyInteger-cpu-arguments-intercept":69522,"multiplyInteger-cpu-arguments-slope":11687,"multiplyInteger-memory-arguments-intercept":0,"multiplyInteger-memory-arguments-slope":1,"nullList-cpu-arguments":60091,"nullList-memory-arguments":32,"quotientInteger-cpu-arguments-constant":196500,"quotientInteger-cpu-arguments-model-arguments-intercept":453240,"quotientInteger-cpu-arguments-model-arguments-slope":220,"quotientInteger-memory-arguments-intercept":0,"quotientInteger-memory-arguments-minimum":1,"quotientInteger-memory-arguments-slope":1,"remainderInteger-cpu-arguments-constant":196500,"remainderInteger-cpu-arguments-model-arguments-intercept":453240,"remainderInteger-cpu-arguments-model-arguments-slope":220,"remainderInteger-memory-arguments-intercept":0,"remainderInteger-memory-arguments-minimum":1,"remainderInteger-memory-arguments-slope":1,"serialiseData-cpu-arguments-intercept":1159724,"serialiseData-cpu-arguments-slope":392670,"serialiseData-memory-arguments-intercept":0,"serialiseData-memory-arguments-slope":2,"sha2_256-cpu-arguments-intercept":806990,"sha2_256-cpu-arguments-slope":30482,"sha2_256-memory-arguments":4,"sha3_256-cpu-arguments-intercept":1927926,"sha3_256-cpu-arguments-slope":82523,"sha3_256-memory-arguments":4,"sliceByteString-cpu-arguments-intercept":265318,"sliceByteString-cpu-arguments-slope":0,"sliceByteString-memory-arguments-intercept":4,"sliceByteString-memory-arguments-slope":0,"sndPair-cpu-arguments":85931,"sndPair-memory-arguments":32,"subtractInteger-cpu-arguments-intercept":205665,"subtractInteger-cpu-arguments-slope":812,"subtractInteger-memory-arguments-intercept":1,"subtractInteger-memory-arguments-slope":1,"tailList-cpu-arguments":41182,"tailList-memory-arguments":32,"trace-cpu-arguments":212342,"trace-memory-arguments":32,"unBData-cpu-arguments":31220,"unBData-memory-arguments":32,"unConstrData-cpu-arguments":32696,"unConstrData-memory-arguments":32,"unIData-cpu-arguments":43357,"unIData-memory-arguments":32,"unListData-cpu-arguments":32247,"unListData-memory-arguments":32,"unMapData-cpu-arguments":38314,"unMapData-memory-arguments":32,"verifyEcdsaSecp256k1Signature-cpu-arguments":35892428,"verifyEcdsaSecp256k1Signature-memory-arguments":10,"verifyEd25519Signature-cpu-arguments-intercept":57996947,"verifyEd25519Signature-cpu-arguments-slope":18975,"verifyEd25519Signature-memory-arguments":10,"verifySchnorrSecp256k1Signature-cpu-arguments-intercept":38887044,"verifySchnorrSecp256k1Signature-cpu-arguments-slope":32947,"verifySchnorrSecp256k1Signature-memory-arguments":10},"PlutusV3":{"0":100788,"1":420,"2":1,"3":1,"4":1000,"5":173,"6":0,"7":1,"8":1000,"9":59957,"10":4,"11":1,"12":11183,"13":32,"14":201305,"15":8356,"16":4,"17":16000,"18":100,"19":16000,"20":100,"21":16000,"22":100,"23":16000,"24":100,"25":16000,"26":100,"27":16000,"28":100,"29":100,"30":100,"31":16000,"32":100,"33":94375,"34":32,"35":132994,"36":32,"37":61462,"38":4,"39":72010,"40":178,"41":0,"42":1,"43":22151,"44":32,"45":91189,"46":769,"47":4,"48":2,"49":85848,"50":123203,"51":7305,"52":-900,"53":1716,"54":549,"55":57,"56":85848,"57":0,"58":1,"59":1,"60":1000,"61":42921,"62":4,"63":2,"64":24548,"65":29498,"66":38,"67":1,"68":898148,"69":27279,"70":1,"71":51775,"72":558,"73":1,"74":39184,"75":1000,"76":60594,"77":1,"78":141895,"79":32,"80":83150,"81":32,"82":15299,"83":32,"84":76049,"85":1,"86":13169,"87":4,"88":22100,"89":10,"90":28999,"91":74,"92":1,"93":28999,"94":74,"95":1,"96":43285,"97":552,"98":1,"99":44749,"100":541,"101":1,"102":33852,"103":32,"104":68246,"105":32,"106":72362,"107":32,"108":7243,"109":32,"110":7391,"111":32,"112":11546,"113":32,"114":85848,"115":123203,"116":7305,"117":-900,"118":1716,"119":549,"120":57,"121":85848,"122":0,"123":1,"124":90434,"125":519,"126":0,"127":1,"128":74433,"129":32,"130":85848,"131":123203,"132":7305,"133":-900,"134":1716,"135":549,"136":57,"137":85848,"138":0,"139":1,"140":1,"141":85848,"142":123203,"143":7305,"144":-900,"145":1716,"146":549,"147":57,"148":85848,"149":0,"150":1,"151":955506,"152":213312,"153":0,"154":2,"155":270652,"156":22588,"157":4,"158":1457325,"159":64566,"160":4,"161":20467,"162":1,"163":4,"164":0,"165":141992,"166":32,"167":100788,"168":420,"169":1,"170":1,"171":81663,"172":32,"173":59498,"174":32,"175":20142,"176":32,"177":24588,"178":32,"179":20744,"180":32,"181":25933,"182":32,"183":24623,"184":32,"185":43053543,"186":10,"187":53384111,"188":14333,"189":10,"190":43574283,"191":26308,"192":10,"193":16000,"194":100,"195":16000,"196":100,"197":962335,"198":18,"199":2780678,"200":6,"201":442008,"202":1,"203":52538055,"204":3756,"205":18,"206":267929,"207":18,"208":76433006,"209":8868,"210":18,"211":52948122,"212":18,"213":1995836,"214":36,"215":3227919,"216":12,"217":901022,"218":1,"219":166917843,"220":4307,"221":36,"222":284546,"223":36,"224":158221314,"225":26549,"226":36,"227":74698472,"228":36,"229":333849714,"230":1,"231":254006273,"232":72,"233":2174038,"234":72,"235":2261318,"236":64571,"237":4,"238":207616,"239":8310,"240":4,"241":1293828,"242":28716,"243":63,"244":0,"245":1,"246":1006041,"247":43623,"248":251,"249":0,"250":1}},"price_mem":0.0577,"price_step":0.0000721,"max_tx_ex_mem":"14000000","max_tx_ex_steps":"10000000000","max_block_ex_mem":"62000000","max_block_ex_steps":"20000000000","max_val_size":"5000","collateral_percent":150,"max_collateral_inputs":3,"coins_per_utxo_size":"4310","coins_per_utxo_word":"4310","pvt_motion_no_confidence":0.6,"pvt_committee_normal":0.65,"pvt_committee_no_confidence":0.65,"pvt_hard_fork_initiation":0.51,"dvt_motion_no_confidence":0.67,"dvt_committee_normal":0.67,"dvt_committee_no_confidence":0.65,"dvt_update_to_constitution":0.75,"dvt_hard_fork_initiation":0.6,"dvt_p_p_network_group":0.67,"dvt_p_p_economic_group":0.67,"dvt_p_p_technical_group":0.67,"dvt_p_p_gov_group":0.75,"dvt_treasury_withdrawal":0.67,"committee_min_size":"5","committee_max_term_length":"146","gov_action_lifetime":"14","gov_action_deposit":"100000000000","drep_deposit":"500000000","drep_activity":"20"} \ No newline at end of file diff --git a/flake.nix b/flake.nix index b4ce89933..5e696ebdc 100644 --- a/flake.nix +++ b/flake.nix @@ -168,7 +168,7 @@ shellHook = exportOgmiosFixtures; packageLockOnly = true; packages = with pkgs; - (if (builtins.elem system linuxSystems) then [ psmisc ] else [ ]) ++ + (if (builtins.elem system linuxSystems) then [ psmisc procps ] else [ ]) ++ [ arion fd diff --git a/nix/default.nix b/nix/default.nix index 55f0f8af2..731cb9b6d 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -356,6 +356,7 @@ let cardano-node cardano-cli psmisc + procps ] ++ (args.buildInputs or [ ]); } diff --git a/package-lock.json b/package-lock.json index d3ebd7d73..1bc9b5a50 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "license": "MIT", "dependencies": { "@mlabs-haskell/cardano-message-signing": "^1.0.1", - "@mlabs-haskell/cardano-serialization-lib-gc": "12.0.0-alpha.31", + "@mlabs-haskell/cardano-serialization-lib-gc": "12.0.0", "@mlabs-haskell/json-bigint": "2.0.0", "@mlabs-haskell/uplc-apply-args": "1.0.29-alpha", "@noble/secp256k1": "^1.7.0", @@ -62,14 +62,14 @@ "integrity": "sha512-PoKh1tQnJX18f8iEr8Jk1KXxKCn9eqaSslMI1pyOJvYRJhQVDLCh0+9YReufjp0oFJIY1ShcrR+4/WnECVZUKQ==" }, "node_modules/@emurgo/cardano-serialization-lib-browser": { - "version": "12.0.0-alpha.32", - "resolved": "https://registry.npmjs.org/@emurgo/cardano-serialization-lib-browser/-/cardano-serialization-lib-browser-12.0.0-alpha.32.tgz", - "integrity": "sha512-Pe2cUB69zLRKLsk0orj2C6drntJXK3P9l9rBmK3tzJTlUUuYWECPY8IhnLNmax3YborYOxY3bJBucTf/zqBHeA==" + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@emurgo/cardano-serialization-lib-browser/-/cardano-serialization-lib-browser-12.0.0.tgz", + "integrity": "sha512-sAVjtaSwujQ3WaJY7OnsOt9mGbMF6YVFg/D4SWLr666zo3ESmislH0FLD932yFTOSJtOQV1oF+Pk8Ee2lR7X5A==" }, "node_modules/@emurgo/cardano-serialization-lib-nodejs": { - "version": "12.0.0-alpha.32", - "resolved": "https://registry.npmjs.org/@emurgo/cardano-serialization-lib-nodejs/-/cardano-serialization-lib-nodejs-12.0.0-alpha.32.tgz", - "integrity": "sha512-HykivQs8K4f2KNRcXFw+D91llAxZhu1neKPVYwyWe6nYZPW/9Tn1A9p602ceGmF0LxIeiJBg0GYOufAA5yVsUQ==" + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@emurgo/cardano-serialization-lib-nodejs/-/cardano-serialization-lib-nodejs-12.0.0.tgz", + "integrity": "sha512-r7ZFYMr1N/i2GbhPAmz7JjKhfjEu7q8sa5beX2rLoV+xTkKGfknCTOsVvT0LqgKOUXAzcSQhNNHUKFd27+sLiw==" }, "node_modules/@esbuild/android-arm": { "version": "0.18.11", @@ -512,12 +512,12 @@ } }, "node_modules/@mlabs-haskell/cardano-serialization-lib-gc": { - "version": "12.0.0-alpha.31", - "resolved": "https://registry.npmjs.org/@mlabs-haskell/cardano-serialization-lib-gc/-/cardano-serialization-lib-gc-12.0.0-alpha.31.tgz", - "integrity": "sha512-QQBzl7rNRy7wk37uxzWJXCZfZRt3aTlfQb3kmb10ulY/janlUNETmS09OtiJbK/BdV5Fu7Gv+Mdda3ggMIL/bg==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@mlabs-haskell/cardano-serialization-lib-gc/-/cardano-serialization-lib-gc-12.0.0.tgz", + "integrity": "sha512-8qwkJzDV1CEjbpZZ3sX5gkP6Tug0mzBSeO9ppHBT6wFEqyi5HXA5oxmN0TGoFecvWVG5f6JmRVeBS0sDqsi20A==", "dependencies": { - "@emurgo/cardano-serialization-lib-browser": "^12.0.0-alpha.31", - "@emurgo/cardano-serialization-lib-nodejs": "^12.0.0-alpha.31", + "@emurgo/cardano-serialization-lib-browser": "12.0.0", + "@emurgo/cardano-serialization-lib-nodejs": "12.0.0", "@mlabs-haskell/csl-gc-wrapper": "^1.0.2" } }, @@ -6414,14 +6414,14 @@ "integrity": "sha512-PoKh1tQnJX18f8iEr8Jk1KXxKCn9eqaSslMI1pyOJvYRJhQVDLCh0+9YReufjp0oFJIY1ShcrR+4/WnECVZUKQ==" }, "@emurgo/cardano-serialization-lib-browser": { - "version": "12.0.0-alpha.32", - "resolved": "https://registry.npmjs.org/@emurgo/cardano-serialization-lib-browser/-/cardano-serialization-lib-browser-12.0.0-alpha.32.tgz", - "integrity": "sha512-Pe2cUB69zLRKLsk0orj2C6drntJXK3P9l9rBmK3tzJTlUUuYWECPY8IhnLNmax3YborYOxY3bJBucTf/zqBHeA==" + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@emurgo/cardano-serialization-lib-browser/-/cardano-serialization-lib-browser-12.0.0.tgz", + "integrity": "sha512-sAVjtaSwujQ3WaJY7OnsOt9mGbMF6YVFg/D4SWLr666zo3ESmislH0FLD932yFTOSJtOQV1oF+Pk8Ee2lR7X5A==" }, "@emurgo/cardano-serialization-lib-nodejs": { - "version": "12.0.0-alpha.32", - "resolved": "https://registry.npmjs.org/@emurgo/cardano-serialization-lib-nodejs/-/cardano-serialization-lib-nodejs-12.0.0-alpha.32.tgz", - "integrity": "sha512-HykivQs8K4f2KNRcXFw+D91llAxZhu1neKPVYwyWe6nYZPW/9Tn1A9p602ceGmF0LxIeiJBg0GYOufAA5yVsUQ==" + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@emurgo/cardano-serialization-lib-nodejs/-/cardano-serialization-lib-nodejs-12.0.0.tgz", + "integrity": "sha512-r7ZFYMr1N/i2GbhPAmz7JjKhfjEu7q8sa5beX2rLoV+xTkKGfknCTOsVvT0LqgKOUXAzcSQhNNHUKFd27+sLiw==" }, "@esbuild/android-arm": { "version": "0.18.11", @@ -6654,12 +6654,12 @@ } }, "@mlabs-haskell/cardano-serialization-lib-gc": { - "version": "12.0.0-alpha.31", - "resolved": "https://registry.npmjs.org/@mlabs-haskell/cardano-serialization-lib-gc/-/cardano-serialization-lib-gc-12.0.0-alpha.31.tgz", - "integrity": "sha512-QQBzl7rNRy7wk37uxzWJXCZfZRt3aTlfQb3kmb10ulY/janlUNETmS09OtiJbK/BdV5Fu7Gv+Mdda3ggMIL/bg==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@mlabs-haskell/cardano-serialization-lib-gc/-/cardano-serialization-lib-gc-12.0.0.tgz", + "integrity": "sha512-8qwkJzDV1CEjbpZZ3sX5gkP6Tug0mzBSeO9ppHBT6wFEqyi5HXA5oxmN0TGoFecvWVG5f6JmRVeBS0sDqsi20A==", "requires": { - "@emurgo/cardano-serialization-lib-browser": "^12.0.0-alpha.31", - "@emurgo/cardano-serialization-lib-nodejs": "^12.0.0-alpha.31", + "@emurgo/cardano-serialization-lib-browser": "12.0.0", + "@emurgo/cardano-serialization-lib-nodejs": "12.0.0", "@mlabs-haskell/csl-gc-wrapper": "^1.0.2" } }, diff --git a/package.json b/package.json index cc09665ec..8753e118e 100755 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "license": "MIT", "dependencies": { "@mlabs-haskell/cardano-message-signing": "^1.0.1", - "@mlabs-haskell/cardano-serialization-lib-gc": "12.0.0-alpha.31", + "@mlabs-haskell/cardano-serialization-lib-gc": "12.0.0", "@mlabs-haskell/json-bigint": "2.0.0", "@mlabs-haskell/uplc-apply-args": "1.0.29-alpha", "@noble/secp256k1": "^1.7.0", diff --git a/packages.dhall b/packages.dhall index 0b8e8cc05..11742a599 100644 --- a/packages.dhall +++ b/packages.dhall @@ -118,7 +118,7 @@ let additions = , "untagged-union" ] , repo = "https://github.com/mlabs-haskell/purescript-cip30" - , version = "v1.0.0" + , version = "v1.0.1" } , cip30-typesafe = { dependencies = @@ -214,7 +214,7 @@ let additions = ] , repo = "https://github.com/mlabs-haskell/purescript-cardano-serialization-lib" - , version = "v1.0.0" + , version = "v2.0.0" } , cardano-plutus-data-schema = { dependencies = [ "prelude" ] @@ -372,7 +372,7 @@ let additions = , "unsafe-coerce" ] , repo = "https://github.com/mlabs-haskell/purescript-cardano-types" - , version = "v2.0.1" + , version = "v3.0.0" } , cardano-message-signing = { dependencies = @@ -453,7 +453,7 @@ let additions = ] , repo = "https://github.com/mlabs-haskell/purescript-cardano-transaction-builder" - , version = "a9c033b9a2bb78b134ae5309209f73e47f3d5791" + , version = "v2.0.0" } , mote-testplan = { dependencies = diff --git a/spago-packages.nix b/spago-packages.nix index a2689809b..6ac9df12a 100644 --- a/spago-packages.nix +++ b/spago-packages.nix @@ -271,11 +271,11 @@ let "cardano-serialization-lib" = pkgs.stdenv.mkDerivation { name = "cardano-serialization-lib"; - version = "v1.0.0"; + version = "v2.0.0"; src = pkgs.fetchgit { url = "https://github.com/mlabs-haskell/purescript-cardano-serialization-lib"; - rev = "903bf0adeefedc4d065ad6523ad079433bdd8e32"; - sha256 = "0jlfxrx037hyd4v0j7l2b16yxlm6nw6qlnr992hj9nzip36vbpfg"; + rev = "d6ca2f9463b3d4e1cfa98e9964edbe7bfed02905"; + sha256 = "05f26v1xr7lkiw57rcqhjng299p7ly90wxqq9jay743pwvrysq0b"; }; phases = "installPhase"; installPhase = "ln -s $src $out"; @@ -283,10 +283,10 @@ let "cardano-transaction-builder" = pkgs.stdenv.mkDerivation { name = "cardano-transaction-builder"; - version = "a9c033b9a2bb78b134ae5309209f73e47f3d5791"; + version = "v2.0.0"; src = pkgs.fetchgit { url = "https://github.com/mlabs-haskell/purescript-cardano-transaction-builder"; - rev = "a9c033b9a2bb78b134ae5309209f73e47f3d5791"; + rev = "2a31258a85e441b6747582ab35d7d86fc866c749"; sha256 = "1xz6k56kwghq9nl0iwrqs6m05wja0xfj34iicmlhwvdp7k4nc65w"; }; phases = "installPhase"; @@ -295,11 +295,11 @@ let "cardano-types" = pkgs.stdenv.mkDerivation { name = "cardano-types"; - version = "v2.0.1"; + version = "v3.0.0"; src = pkgs.fetchgit { url = "https://github.com/mlabs-haskell/purescript-cardano-types"; - rev = "5b16e9571167e9889605d3aecdd0ccce24d38696"; - sha256 = "1052lknpkhcq86lj8aavfwzr9ybrirjighsjccpgrcaq2jn4kcmj"; + rev = "71b204c7c9c83b8280ed3ed14837d76b8ac0a6fe"; + sha256 = "1kffscail4kp5pygdv8nd2bclwd6c0cygkn5mn5sllnn29a63mpf"; }; phases = "installPhase"; installPhase = "ln -s $src $out"; @@ -331,11 +331,11 @@ let "cip30" = pkgs.stdenv.mkDerivation { name = "cip30"; - version = "v1.0.0"; + version = "v1.0.1"; src = pkgs.fetchgit { url = "https://github.com/mlabs-haskell/purescript-cip30"; - rev = "8f1b34b48825fcec5e9c67f33e255770b1e0bc45"; - sha256 = "1rb7kv99rd50b6vhl90sirmzh43wgnyafpmn7w45n3d4nrvf1046"; + rev = "8de9bbcc6728237e3aec418c2c88bfcb519fc176"; + sha256 = "18ms7kyd98zmimvnjyixxhqrw5d68cpi3ya351hy2p4r7mmf7vy7"; }; phases = "installPhase"; installPhase = "ln -s $src $out"; diff --git a/spago.dhall b/spago.dhall index dd58114a5..2068e77f5 100644 --- a/spago.dhall +++ b/spago.dhall @@ -1,7 +1,3 @@ -{- -Welcome to a Spago project! -You can edit this file as you like. --} { name = "cardano-transaction-lib" , dependencies = [ "aeson" diff --git a/src/Internal/BalanceTx/BalanceTx.purs b/src/Internal/BalanceTx/BalanceTx.purs index 18050d2a5..b1910282c 100644 --- a/src/Internal/BalanceTx/BalanceTx.purs +++ b/src/Internal/BalanceTx/BalanceTx.purs @@ -22,6 +22,7 @@ import Cardano.Types , Transaction , TransactionBody , TransactionOutput + , TransactionUnspentOutput , UtxoMap , Value(Value) , _amount @@ -38,12 +39,15 @@ import Cardano.Types , _witnessSet ) import Cardano.Types.Address (Address) +import Cardano.Types.Address (getPaymentCredential) as Address import Cardano.Types.BigNum as BigNum import Cardano.Types.Coin as Coin +import Cardano.Types.Credential (asPubKeyHash) as Credential import Cardano.Types.OutputDatum (OutputDatum(OutputDatum)) -import Cardano.Types.TransactionBody (_votingProposals) +import Cardano.Types.TransactionBody (_collateral, _votingProposals) import Cardano.Types.TransactionInput (TransactionInput) -import Cardano.Types.TransactionUnspentOutput as TransactionUnspentOutputs +import Cardano.Types.TransactionUnspentOutput (_output) +import Cardano.Types.TransactionUnspentOutput as TransactionUnspentOutput import Cardano.Types.TransactionWitnessSet (_redeemers) import Cardano.Types.UtxoMap (pprintUtxoMap) import Cardano.Types.Value (getMultiAsset, mkValue, pprintValue) @@ -65,7 +69,10 @@ import Ctl.Internal.BalanceTx.Collateral ( addTxCollateral , addTxCollateralReturn ) -import Ctl.Internal.BalanceTx.Collateral.Select (selectCollateral) +import Ctl.Internal.BalanceTx.Collateral.Select + ( minRequiredCollateral + , selectCollateral + ) as Collateral import Ctl.Internal.BalanceTx.Constraints ( BalanceTxConstraintsBuilder , _collateralUtxos @@ -137,7 +144,7 @@ import Data.Array.NonEmpty import Data.Array.NonEmpty as NEA import Data.Bitraversable (ltraverse) import Data.Either (Either, hush, note) -import Data.Foldable (any, fold, foldMap, foldr, length, null, or, sum) +import Data.Foldable (any, foldMap, foldr, length, null, or, sum) import Data.Lens (view) import Data.Lens.Getter ((^.)) import Data.Lens.Setter ((%~), (.~), (?~)) @@ -210,11 +217,6 @@ balanceTxWithConstraints transaction extraUtxos constraintsBuilder = <#> traverse (note CouldNotGetUtxos) >>> map (foldr Map.union Map.empty) -- merge all utxos into one map - unbalancedCollTx <- transactionWithNetworkId >>= - if Array.null (transaction ^. _witnessSet <<< _redeemers) - -- Don't set collateral if tx doesn't contain phase-2 scripts: - then pure - else setTransactionCollateral changeAddress let allUtxos :: UtxoMap allUtxos = @@ -224,6 +226,12 @@ balanceTxWithConstraints transaction extraUtxos constraintsBuilder = availableUtxos <- liftContract $ filterLockedUtxos allUtxos + unbalancedCollTx <- transactionWithNetworkId >>= + if Array.null (transaction ^. _witnessSet <<< _redeemers) + -- Don't set collateral if tx doesn't contain phase-2 scripts: + then pure + else setTransactionCollateral changeAddress availableUtxos + Logger.info (pprintUtxoMap allUtxos) "balanceTxWithConstraints: all UTxOs" Logger.info (pprintUtxoMap availableUtxos) "balanceTxWithConstraints: available UTxOs" @@ -254,8 +262,9 @@ balanceTxWithConstraints transaction extraUtxos constraintsBuilder = (transaction ^. _body <<< _networkId) pure (transaction # _body <<< _networkId ?~ networkId) -setTransactionCollateral :: Address -> Transaction -> BalanceTxM Transaction -setTransactionCollateral changeAddr transaction = do +setTransactionCollateral + :: Address -> UtxoMap -> Transaction -> BalanceTxM Transaction +setTransactionCollateral changeAddr availableUtxos transaction = do nonSpendableSet <- asksConstraints Constraints._nonSpendableInputs nonSpendableInputsPredicates <- asksConstraints Constraints._nonSpendableInputsPredicates @@ -280,23 +289,49 @@ setTransactionCollateral changeAddr transaction = do when (not $ Array.null filteredUtxos) do logWarn' $ pprintTagSet "Some of the collateral UTxOs returned by the wallet were marked as non-spendable and ignored" - (pprintUtxoMap (TransactionUnspentOutputs.toUtxoMap filteredUtxos)) - pure spendableUtxos + (pprintUtxoMap (TransactionUnspentOutput.toUtxoMap filteredUtxos)) + let + collVal = + foldMap (Val.fromValue <<< view (_output <<< _amount)) + spendableUtxos + minRequiredCollateral = + BigNum.toBigInt $ + unwrap Collateral.minRequiredCollateral + if (Val.getCoin collVal < minRequiredCollateral) then do + logWarn' $ pprintTagSet + "Filtered collateral UTxOs do not cover the minimum required \ + \collateral, reselecting collateral using CTL algorithm." + (pprintUtxoMap (TransactionUnspentOutput.toUtxoMap spendableUtxos)) + let + isPkhUtxo txOut = isJust do + cred <- Address.getPaymentCredential $ (unwrap txOut).address + Credential.asPubKeyHash $ unwrap cred + availableUtxos' <- liftContract $ + Map.filter isPkhUtxo <<< Map.filterWithKey isSpendable <$> + filterLockedUtxos availableUtxos + selectCollateral availableUtxos' + else pure spendableUtxos -- otherwise, get all the utxos, filter out unspendable, and select -- collateral using internal algo, that is also used in KeyWallet - Just utxoMap -> do - ProtocolParameters params <- liftContract getProtocolParameters - let - maxCollateralInputs = UInt.toInt $ params.maxCollateralInputs - utxoMap' = Map.filterWithKey isSpendable utxoMap - mbCollateral = - Array.fromFoldable <$> - selectCollateral params.coinsPerUtxoByte maxCollateralInputs - utxoMap' - liftEither $ note (InsufficientCollateralUtxos utxoMap') mbCollateral + Just utxoMap -> selectCollateral utxoMap addTxCollateralReturn collateral (addTxCollateral collateral transaction) changeAddr +-- | Select collateral from the provided utxos using internal CTL +-- | collateral selection algorithm. +selectCollateral :: UtxoMap -> BalanceTxM (Array TransactionUnspentOutput) +selectCollateral utxos = do + pparams <- unwrap <$> liftContract getProtocolParameters + let + maxCollateralInputs = UInt.toInt $ pparams.maxCollateralInputs + mbCollateral = + Array.fromFoldable <$> Collateral.selectCollateral + pparams.coinsPerUtxoByte + maxCollateralInputs + utxos + liftEither $ note (InsufficientCollateralUtxos utxos) + mbCollateral + -------------------------------------------------------------------------------- -- Balancing Algorithm -------------------------------------------------------------------------------- @@ -356,11 +391,11 @@ runBalancer p = do isCip30 <- liftContract $ isCip30Wallet -- Get collateral inputs to mark them as unspendable. -- Some CIP-30 wallets don't allow to sign Txs that spend it. - nonSpendableCollateralInputs <- - if isCip30 then - liftContract $ Wallet.getWalletCollateral <#> - fold >>> map (unwrap >>> _.input) >>> Set.fromFoldable - else mempty + let + nonSpendableCollateralInputs = + if isCip30 then + Set.fromFoldable $ p.transaction ^. _body <<< _collateral + else mempty constraints <- unwrap <$> asks _.constraints let nonSpendableInputs = diff --git a/src/Internal/BalanceTx/Error.purs b/src/Internal/BalanceTx/Error.purs index a644f57f8..44d7e9275 100644 --- a/src/Internal/BalanceTx/Error.purs +++ b/src/Internal/BalanceTx/Error.purs @@ -17,6 +17,7 @@ module Ctl.Internal.BalanceTx.Error , UtxoLookupFailedFor , UtxoMinAdaValueCalculationFailed , NumericOverflowError + , CouldNotComputeRefScriptsFee ) , Expected(Expected) , printTxEvaluationFailure @@ -92,6 +93,7 @@ data BalanceTxError | UtxoLookupFailedFor TransactionInput UtxoMap | UtxoMinAdaValueCalculationFailed | NumericOverflowError (Maybe Val) + | CouldNotComputeRefScriptsFee TransactionInput derive instance Generic BalanceTxError _ @@ -147,6 +149,9 @@ explainBalanceTxError = case _ of NumericOverflowError mbVal -> "Could not compute output value due to numeric overflow. Decrease the quantity of assets. " <> fold (prettyVal "Value:" <$> mbVal) + CouldNotComputeRefScriptsFee input -> + "Could not compute reference script size fees introduced in Conway. Ensure that all reference scripts are present in a UtxoMap provided to the balancer. " + <> pprintTagSet "Missing input: " (pprintTransactionInput input) where prettyVal :: String -> Val -> String prettyVal str = pprintVal >>> pprintTagSet str diff --git a/src/Internal/BalanceTx/ExUnitsAndMinFee.purs b/src/Internal/BalanceTx/ExUnitsAndMinFee.purs index f82298db8..0bb347caf 100644 --- a/src/Internal/BalanceTx/ExUnitsAndMinFee.purs +++ b/src/Internal/BalanceTx/ExUnitsAndMinFee.purs @@ -5,6 +5,7 @@ module Ctl.Internal.BalanceTx.ExUnitsAndMinFee import Prelude +import Cardano.AsCbor (encodeCbor) import Cardano.Types ( Coin , CostModel @@ -19,7 +20,9 @@ import Cardano.Types , TransactionWitnessSet , UtxoMap , _body + , _inputs , _isValid + , _referenceInputs , _witnessSet ) import Cardano.Types.BigNum as BigNum @@ -30,7 +33,11 @@ import Control.Monad.Error.Class (throwError) import Control.Monad.Except.Trans (except) import Ctl.Internal.BalanceTx.Constraints (_additionalUtxos, _collateralUtxos) as Constraints import Ctl.Internal.BalanceTx.Error - ( BalanceTxError(UtxoLookupFailedFor, ExUnitsEvaluationFailed) + ( BalanceTxError + ( UtxoLookupFailedFor + , ExUnitsEvaluationFailed + , CouldNotComputeRefScriptsFee + ) ) import Ctl.Internal.BalanceTx.Types ( BalanceTxM @@ -40,7 +47,7 @@ import Ctl.Internal.BalanceTx.Types ) import Ctl.Internal.Contract.MinFee (calculateMinFee) as Contract.MinFee import Ctl.Internal.Contract.Monad (getQueryHandle) -import Ctl.Internal.Helpers (unsafeFromJust) +import Ctl.Internal.Helpers (liftEither, unsafeFromJust) import Ctl.Internal.QueryM.Ogmios ( AdditionalUtxoSet , TxEvaluationFailure(AdditionalUtxoOverlap) @@ -54,18 +61,26 @@ import Ctl.Internal.TxOutput ) import Data.Array (catMaybes) import Data.Array (fromFoldable, notElem) as Array -import Data.Bifunctor (bimap) +import Data.Bifunctor (bimap, lmap) +import Data.ByteArray as ByteArray import Data.Either (Either(Left, Right), note) import Data.Foldable (foldMap) import Data.Lens ((.~)) import Data.Lens.Getter ((^.)) import Data.Map (Map) -import Data.Map (empty, filterKeys, fromFoldable, lookup, toUnfoldable, union) as Map -import Data.Maybe (Maybe(Just, Nothing), fromMaybe) +import Data.Map + ( empty + , filterKeys + , fromFoldable + , lookup + , toUnfoldable + , union + ) as Map +import Data.Maybe (Maybe(Just, Nothing), fromMaybe, maybe) import Data.Newtype (unwrap, wrap) import Data.Set (Set) import Data.Set as Set -import Data.Traversable (for) +import Data.Traversable (for, sum) import Data.Tuple (snd) import Data.Tuple.Nested (type (/\), (/\)) import Data.UInt as UInt @@ -127,10 +142,27 @@ evalExUnitsAndMinFee transaction allUtxos = do additionalUtxos <- asksConstraints Constraints._additionalUtxos collateralUtxos <- fromMaybe Map.empty <$> asksConstraints Constraints._collateralUtxos + refScriptsTotalSize <- liftEither $ lmap CouldNotComputeRefScriptsFee $ + calculateRefScriptsTotalSize finalizedTx allUtxos minFee <- liftContract $ Contract.MinFee.calculateMinFee finalizedTx (Map.union additionalUtxos collateralUtxos) + (UInt.fromInt refScriptsTotalSize) pure $ txWithExUnits /\ minFee +calculateRefScriptsTotalSize + :: Transaction -> UtxoMap -> Either TransactionInput Int +calculateRefScriptsTotalSize tx utxoMap = do + let + refInputs = tx ^. _body <<< _referenceInputs + inputs = tx ^. _body <<< _inputs + allInputs = refInputs <> inputs + outputs <- for allInputs \input -> + note input $ Map.lookup input utxoMap + let + refScriptSizes = outputs <#> \(TransactionOutput { scriptRef }) -> + maybe zero (ByteArray.byteLength <<< unwrap <<< encodeCbor) scriptRef + pure $ sum refScriptSizes + -- | Attaches datums and redeemers, sets the script integrity hash, -- | for use after reindexing. finalizeTransaction diff --git a/src/Internal/Contract/MinFee.purs b/src/Internal/Contract/MinFee.purs index 677abf3f2..b3f3fd845 100644 --- a/src/Internal/Contract/MinFee.purs +++ b/src/Internal/Contract/MinFee.purs @@ -42,7 +42,7 @@ import Ctl.Internal.Contract (getProtocolParameters) import Ctl.Internal.Contract.Monad (Contract, getQueryHandle) import Ctl.Internal.Contract.Wallet (getWalletAddresses) import Ctl.Internal.Helpers (liftM, liftedM) -import Ctl.Internal.Serialization.MinFee (calculateMinFeeCsl) +import Ctl.Internal.MinFee (calculateMinFeeCsl) import Data.Array (fromFoldable, mapMaybe) import Data.Array as Array import Data.Either (hush) @@ -63,15 +63,16 @@ import Data.Set , union ) as Set import Data.Traversable (for) +import Data.UInt (UInt) import Effect.Aff (error) import Effect.Aff.Class (liftAff) -- | Calculate the minimum transaction fee. -calculateMinFee :: Transaction -> UtxoMap -> Contract Coin -calculateMinFee tx additionalUtxos = do +calculateMinFee :: Transaction -> UtxoMap -> UInt -> Contract Coin +calculateMinFee tx additionalUtxos refScriptsSize = do selfSigners <- getSelfSigners tx additionalUtxos pparams <- getProtocolParameters - calculateMinFeeCsl pparams selfSigners tx + calculateMinFeeCsl pparams selfSigners tx refScriptsSize -- | This function estimates the set of keys that must be used -- | for signing to make the transaction valid for the network. diff --git a/src/Internal/Serialization/MinFee.purs b/src/Internal/MinFee.purs similarity index 75% rename from src/Internal/Serialization/MinFee.purs rename to src/Internal/MinFee.purs index d5bf69e5a..0d78839c5 100644 --- a/src/Internal/Serialization/MinFee.purs +++ b/src/Internal/MinFee.purs @@ -1,9 +1,14 @@ -- | `min_fee` calculation using CSL. -module Ctl.Internal.Serialization.MinFee (calculateMinFeeCsl) where +module Ctl.Internal.MinFee (calculateMinFeeCsl) where import Prelude -import Cardano.Serialization.Lib (linearFee_new, minFee, minScriptFee) +import Cardano.Serialization.Lib + ( linearFee_new + , minFee + , minRefScriptFee + , minScriptFee + ) import Cardano.Types ( Coin , Ed25519KeyHash @@ -19,6 +24,7 @@ import Cardano.Types.ExUnitPrices as ExUnitPrices import Cardano.Types.NativeScript (NativeScript(ScriptAll)) import Cardano.Types.PublicKey as PublicKey import Cardano.Types.Transaction as Transaction +import Cardano.Types.UnitInterval as UnitInterval import Contract.Prim.ByteArray (hexToRawBytes) import Control.Monad.Error.Class (class MonadThrow) import Ctl.Internal.Helpers (unsafeFromJust) @@ -26,16 +32,19 @@ import Ctl.Internal.NativeScripts (getMaximumSigners) import Ctl.Internal.Types.ProtocolParameters ( ProtocolParameters(ProtocolParameters) ) +import Ctl.Internal.Types.Rational as Rational import Data.Array (range, replicate) as Array import Data.Foldable (fold) import Data.Int (hexadecimal) as Radix -import Data.Int (toStringAs) as Int +import Data.Int (toNumber, toStringAs) as Int import Data.Lens ((.~)) import Data.Maybe (fromJust) import Data.Newtype (unwrap, wrap) import Data.Set (Set) import Data.Set (fromFoldable, isEmpty, size) as Set import Data.String (length) as String +import Data.UInt (UInt) +import Data.UInt as UInt import Effect.Class (class MonadEffect) import Effect.Exception (Error) import Partial.Unsafe (unsafePartial) @@ -47,22 +56,34 @@ calculateMinFeeCsl => ProtocolParameters -> Set Ed25519KeyHash -> Transaction + -> UInt -> m Coin -calculateMinFeeCsl (ProtocolParameters pparams) selfSigners txNoSigs = do - let tx = addFakeSignatures selfSigners txNoSigs - let cslTx = Transaction.toCsl tx +calculateMinFeeCsl + (ProtocolParameters pparams) + selfSigners + txNoSigs + refScriptsSize = do let + tx = addFakeSignatures selfSigners txNoSigs + cslTx = Transaction.toCsl tx cslLinearFee = linearFee_new (unwrap $ BigNum.fromUInt pparams.txFeePerByte) (unwrap $ unwrap pparams.txFeeFixed) - - let fee = minFee cslTx cslLinearFee - let exUnitPrices = pparams.prices - let exUnitPricesCsl = ExUnitPrices.toCsl exUnitPrices - let scriptFee = minScriptFee cslTx exUnitPricesCsl + fee = minFee cslTx cslLinearFee + exUnitPrices = pparams.prices + exUnitPricesCsl = ExUnitPrices.toCsl exUnitPrices + scriptFee = minScriptFee cslTx exUnitPricesCsl + refScriptFee = + minRefScriptFee + (Int.toNumber $ UInt.toInt refScriptsSize) + ( UnitInterval.toCsl + $ unsafeFromJust "calculateMinFeeCsl: refScriptCoinsPerByte" + $ Rational.toUnitInterval pparams.refScriptCoinsPerByte + ) -- Ignore the overflow here: fees are much lower - pure $ wrap $ unsafeFromJust "calculateMinFeeCsl" $ BigNum.add (wrap fee) - (wrap scriptFee) + pure $ wrap $ unsafeFromJust "calculateMinFeeCsl" $ + BigNum.add (wrap fee) + (wrap scriptFee) >>= BigNum.add (wrap refScriptFee) -- | Adds fake signatures for each expected signature of a transaction. addFakeSignatures :: Set Ed25519KeyHash -> Transaction -> Transaction diff --git a/src/Internal/QueryM/Ogmios.purs b/src/Internal/QueryM/Ogmios.purs index 9390021b3..cad1030ee 100644 --- a/src/Internal/QueryM/Ogmios.purs +++ b/src/Internal/QueryM/Ogmios.purs @@ -1038,6 +1038,11 @@ type ProtocolParametersRaw = , "maxCollateralInputs" :: UInt , "governanceActionDeposit" :: Maybe OgmiosAdaLovelace , "delegateRepresentativeDeposit" :: Maybe OgmiosAdaLovelace + , "minFeeReferenceScripts" :: + { range :: UInt + , base :: Number + , multiplier :: Number + } } newtype OgmiosProtocolParameters = OgmiosProtocolParameters ProtocolParameters @@ -1053,6 +1058,9 @@ instance DecodeAeson OgmiosProtocolParameters where decodeAeson aeson = do ps :: ProtocolParametersRaw <- decodeAeson aeson prices <- decodePrices ps + minFeeReferenceScriptsBase <- + note (TypeMismatch "minFeeReferenceScripts.multiplier: expected a number") + $ Rational.fromNumber ps.minFeeReferenceScripts.base pure $ OgmiosProtocolParameters $ ProtocolParameters { protocolVersion: ps.version.major /\ ps.version.minor -- The following two parameters were removed from Babbage @@ -1094,6 +1102,7 @@ instance DecodeAeson OgmiosProtocolParameters where , drepDeposit: maybe mempty (wrap <<< _.ada.lovelace) ps.delegateRepresentativeDeposit + , refScriptCoinsPerByte: minFeeReferenceScriptsBase } where decodeExUnits diff --git a/src/Internal/Service/Blockfrost.purs b/src/Internal/Service/Blockfrost.purs index 54c9b2994..8d9f7b64d 100644 --- a/src/Internal/Service/Blockfrost.purs +++ b/src/Internal/Service/Blockfrost.purs @@ -203,6 +203,7 @@ import Ctl.Internal.Types.ProtocolParameters , convertUnnamedPlutusCostModel ) import Ctl.Internal.Types.Rational (Rational, reduce) +import Ctl.Internal.Types.Rational as Rational import Ctl.Internal.Types.StakeValidatorHash (StakeValidatorHash) import Ctl.Internal.Types.SystemStart (SystemStart(SystemStart)) import Data.Array (catMaybes) @@ -1536,6 +1537,7 @@ type BlockfrostProtocolParametersRaw = , "coins_per_utxo_size" :: Maybe (Stringed BigNum) , "gov_action_deposit" :: Stringed BigNum , "drep_deposit" :: Stringed BigNum + , "min_fee_ref_script_cost_per_byte" :: UInt } toFraction' :: BigNumber -> String /\ String @@ -1589,6 +1591,13 @@ instance DecodeAeson BlockfrostProtocolParameters where maybe (Left $ AtKey "coins_per_utxo_size" $ MissingValue) pure $ (Coin <<< unwrap <$> raw.coins_per_utxo_size) + refScriptCoinsPerByte <- + note (AtKey "min_fee_ref_script_cost_per_byte" $ TypeMismatch "Integer") $ + Rational.reduce + ( BigNum.toBigInt $ BigNum.fromUInt + raw.min_fee_ref_script_cost_per_byte + ) + one let plutusV3CostModelRaw = raw.cost_models."PlutusV3" plutusV3CostModel <- note (AtKey "cost_models" $ AtKey "PlutusV3" $ TypeMismatch "CostModel") @@ -1634,6 +1643,7 @@ instance DecodeAeson BlockfrostProtocolParameters where , maxCollateralInputs: raw.max_collateral_inputs , govActionDeposit: Coin $ unwrap raw.gov_action_deposit , drepDeposit: Coin $ unwrap raw.drep_deposit + , refScriptCoinsPerByte } -------------------------------------------------------------------------------- diff --git a/src/Internal/Test/E2E/Runner.purs b/src/Internal/Test/E2E/Runner.purs index ab4be97ee..c560f59e7 100644 --- a/src/Internal/Test/E2E/Runner.purs +++ b/src/Internal/Test/E2E/Runner.purs @@ -77,7 +77,7 @@ import Ctl.Internal.Test.E2E.Wallets ) import Ctl.Internal.Test.UtxoDistribution (withStakeKey) import Ctl.Internal.Testnet.Contract (withTestnetContractEnv) -import Ctl.Internal.Testnet.Types (Era(Babbage), TestnetConfig) +import Ctl.Internal.Testnet.Types (Era(Conway), TestnetConfig) import Data.Array (catMaybes, mapMaybe, nub) import Data.Array as Array import Data.ByteArray (hexToByteArray) @@ -215,7 +215,7 @@ buildLocalTestnetConfig options = , hooks: emptyHooks , clusterConfig: { testnetMagic: 2 - , era: Babbage + , era: Conway , slotLength: Seconds 0.05 , epochSize: Nothing } diff --git a/src/Internal/Testnet/Contract.purs b/src/Internal/Testnet/Contract.purs index 123394c9a..98180a48d 100644 --- a/src/Internal/Testnet/Contract.purs +++ b/src/Internal/Testnet/Contract.purs @@ -11,6 +11,7 @@ import Contract.Prelude import Cardano.Serialization.Lib (privateKey_generateEd25519) as Csl import Cardano.Types (NetworkId(TestnetId)) import Cardano.Types.Address (Address, getPaymentCredential, getStakeCredential) +import Cardano.Types.Address (toBech32) as Address import Cardano.Types.BigInt (BigInt) import Cardano.Types.BigInt (fromInt) as BigInt import Cardano.Types.BigNum (fromBigInt, toBigInt) as BigNum @@ -24,7 +25,6 @@ import Contract.Log (logInfo') import Contract.Monad ( Contract , ContractEnv - , liftContractE , liftContractM , liftedM , runContractInEnv @@ -40,6 +40,7 @@ import Contract.Wallet , mkKeyWalletFromPrivateKeys , withKeyWallet ) +import Control.Monad.Error.Class (throwError) import Control.Monad.State (State, execState, modify_) import Control.Monad.Trans.Class (lift) import Control.Monad.Writer (censor, execWriterT, tell) @@ -55,8 +56,12 @@ import Ctl.Internal.Test.UtxoDistribution , encodeDistribution , keyWallets ) -import Ctl.Internal.Testnet.DistributeFunds (DistrFundsParams) -import Ctl.Internal.Testnet.DistributeFunds (Tx(Tx), makeDistributionPlan) as DistrFunds +import Ctl.Internal.Testnet.DistributeFunds + ( DistrFundsParams + , explainDistrFundsError + , makeDistributionPlan + ) +import Ctl.Internal.Testnet.DistributeFunds (Tx(Tx)) as DistrFunds import Ctl.Internal.Testnet.Server ( StartedTestnetCluster , makeClusterContractEnv @@ -305,12 +310,21 @@ execDistrFundsPlan withCardanoCliUtxos rounds = do ) roundsFixed -newtype KeyWalletShow = KeyWalletShow KeyWallet +newtype KeyWalletShow = KeyWalletShow + { kw :: KeyWallet + , address :: Address + } derive instance Newtype KeyWalletShow _ instance Show KeyWalletShow where - show _ = "(KeyWallet )" + show kw = "(KeyWallet " <> Address.toBech32 (unwrap kw).address <> ")" + +toKeyWalletShow :: KeyWallet -> Contract KeyWalletShow +toKeyWalletShow kw = do + network <- getNetworkId + address <- liftAff $ (unwrap kw).address network + pure $ wrap { kw, address } makeDistrFundsPlan :: forall (distr :: Type) (wallets :: Type) @@ -328,17 +342,21 @@ makeDistrFundsPlan withCardanoCliUtxos genesisWallets distr = do liftContractM "Impossible happened: could not decode wallets. Please report as bug" $ decodeWallets distr privateKeys - let - kws = KeyWalletShow <$> keyWallets (Proxy :: _ distr) wallets - targets = Array.concat $ sequence <$> Array.zip kws distrArray + kws <- traverse toKeyWalletShow $ keyWallets (Proxy :: _ distr) wallets + let targets = Array.concat $ sequence <$> Array.zip kws distrArray sources <- Array.concat <$> - parTraverse (\kw -> map (Tuple (KeyWalletShow kw)) <$> getGenesisUtxos kw) - genesisWallets + ( parTraverse (\kw -> map (Tuple kw) <$> getGenesisUtxos (unwrap kw).kw) + =<< traverse toKeyWalletShow genesisWallets + ) -- traceM $ "genesis sources: " <> show sources distrPlan <- - liftContractE $ - DistrFunds.makeDistributionPlan distrFundsParams sources targets - pure $ wallets /\ (map (lmap unwrap) <$> distrPlan) + makeDistributionPlan distrFundsParams sources targets # + either + ( throwError <<< error <<< append "DistrFunds: " <<< + explainDistrFundsError + ) + pure + pure $ wallets /\ (map (lmap (_.kw <<< unwrap)) <$> distrPlan) where getGenesisUtxos :: KeyWallet -> Contract (Array BigInt) getGenesisUtxos genesisWallet = diff --git a/src/Internal/Testnet/DistributeFunds.purs b/src/Internal/Testnet/DistributeFunds.purs index 1990693b1..cfef87678 100644 --- a/src/Internal/Testnet/DistributeFunds.purs +++ b/src/Internal/Testnet/DistributeFunds.purs @@ -1,4 +1,25 @@ -module Ctl.Internal.Testnet.DistributeFunds where +module Ctl.Internal.Testnet.DistributeFunds + ( DistrFundsError + ( DistrFunds_MaxUtxosPerTxLowerLimitError + , DistrFunds_AssignUtxoError + , DistrFunds_MaxRoundsExceededError + ) + , DistrFundsParams + , SourceState + , Tx(Tx) + , explainDistrFundsError + , makeDistributionPlan + + -- exported for testing -------------------------------------------- + , AssignUtxoResult + ( AssignUtxo_Unassigned + , AssignUtxo_Deferred + , AssignUtxo_AssignedToSource + ) + , assignUtxoToSource + , initSourceState + , runDistrFundsRound + ) where import Prelude @@ -113,11 +134,15 @@ resetSourceTx src = src { currentTx = emptyTx src.srcWallet } data DistrFundsError wallet amount = DistrFunds_MaxUtxosPerTxLowerLimitError + { maxUtxosPerTx :: Int + } | DistrFunds_AssignUtxoError { utxoToAssign :: wallet /\ amount , currentSources :: List (SourceState wallet amount) } | DistrFunds_MaxRoundsExceededError + { maxRounds :: Int + } derive instance Generic (DistrFundsError wallet amount) _ derive instance (Eq wallet, Eq amount) => Eq (DistrFundsError wallet amount) @@ -125,22 +150,35 @@ derive instance (Eq wallet, Eq amount) => Eq (DistrFundsError wallet amount) instance (Show wallet, Show amount) => Show (DistrFundsError wallet amount) where show = genericShow +explainDistrFundsError + :: forall wallet amount + . Show wallet + => Show amount + => DistrFundsError wallet amount + -> String +explainDistrFundsError = case _ of + DistrFunds_MaxUtxosPerTxLowerLimitError { maxUtxosPerTx } -> + "Each DistributeFunds transaction should have space for at least \ + \one target utxo, current maxUtxosPerTx value: " + <> show maxUtxosPerTx + <> "." + DistrFunds_AssignUtxoError { utxoToAssign, currentSources } -> + "None of the sources are sufficient to cover target utxo: " + <> show utxoToAssign + <> ", current sources: " + <> show currentSources + <> "." + DistrFunds_MaxRoundsExceededError { maxRounds } -> + "Exceeded the upper limit for the maximum number of fund \ + \distribution rounds, current maxRounds value: " + <> show maxRounds + <> "." + type DistrFundsRoundResult wallet amount = { sources :: List (SourceState wallet amount) , deferredTargets :: List (wallet /\ amount) } -data AssignUtxoResult wallet amount - = AssignUtxo_Unassigned - | AssignUtxo_Deferred - | AssignUtxo_AssignedToSource (SourceState wallet amount) - -derive instance Generic (AssignUtxoResult wallet amount) _ -derive instance (Eq wallet, Eq amount) => Eq (AssignUtxoResult wallet amount) - -instance (Show wallet, Show amount) => Show (AssignUtxoResult wallet amount) where - show = genericShow - makeDistributionPlan :: forall wallet amount . Ord amount @@ -150,7 +188,10 @@ makeDistributionPlan -> Array (wallet /\ amount) -> Either (DistrFundsError wallet amount) (Array (Array (Tx wallet amount))) makeDistributionPlan params initSources initTargets - | params.maxUtxosPerTx < one = Left DistrFunds_MaxUtxosPerTxLowerLimitError + | params.maxUtxosPerTx < one = + Left $ DistrFunds_MaxUtxosPerTxLowerLimitError + { maxUtxosPerTx: params.maxUtxosPerTx + } | otherwise = tailRecM worker { sources: List.fromFoldable $ uncurry initSourceState <$> initSources @@ -161,7 +202,9 @@ makeDistributionPlan params initSources initTargets where worker { sources, targets, rounds, roundIdx } | roundIdx == params.maxRounds = - Left DistrFunds_MaxRoundsExceededError + Left $ DistrFunds_MaxRoundsExceededError + { maxRounds: params.maxRounds + } | otherwise = runDistrFundsRound params sources targets <#> \res -> let @@ -178,6 +221,15 @@ makeDistributionPlan params initSources initTargets , roundIdx: roundIdx + one } +-- | Executes a single round of funds distribution, assigning the +-- | provided target utxos to the sources. +-- | +-- | Some utxo may be deferred until the next round if they cannot be +-- | immediately covered by the sources due to the algorithm's +-- | parameters, even though the sources are sufficient. +-- | +-- | If some of the target utxos cannot be covered by any source, a +-- | `DistrFunds_AssignUtxoError` will be returned. runDistrFundsRound :: forall wallet amount . Ord amount @@ -197,6 +249,8 @@ runDistrFundsRound params initSources targets = in case assignUtxoRes of AssignUtxo_Unassigned -> + -- Throw an error if none of the sources have a sufficient + -- `amount` (e.g. of Lovelace) to cover the target. Left $ DistrFunds_AssignUtxoError { utxoToAssign: target , currentSources: distrFundsAcc.sources @@ -215,6 +269,10 @@ runDistrFundsRound params initSources targets = } targets +-- | Determines whether an attempt should be made to assign the +-- | specified target utxo to the next source based on its current +-- | assignment status. Updates the status if it represents an +-- | improvement over the previous one. tryNextSource :: forall wallet amount . Ord amount @@ -227,7 +285,7 @@ tryNextSource tryNextSource params (targetWallet /\ amount) source (acc /\ sources) = case acc of AssignUtxo_AssignedToSource _ -> - -- utxo already assigned, skip other sources + -- Utxo has already been assigned, skip other sources. acc /\ Cons source sources _ -> let @@ -237,14 +295,34 @@ tryNextSource params (targetWallet /\ amount) source (acc /\ sources) = in case acc, assignUtxoToSource params source targetNormalized of AssignUtxo_Deferred, AssignUtxo_Unassigned -> - -- utxo marked as deferred that cannot fit into the current tx - -- should remain deferred + -- Utxo marked as deferred that cannot be covered by the + -- current tx should remain deferred. AssignUtxo_Deferred /\ Cons source sources _, new@(AssignUtxo_AssignedToSource sourceUpdated) -> new /\ Cons sourceUpdated sources _, new -> new /\ Cons source sources +data AssignUtxoResult wallet amount + -- Utxo cannot be covered by given source / sources. + = AssignUtxo_Unassigned + -- Utxo cannot be included in the current transaction, as doing + -- so would exceed the specified upper limit on the number of + -- utxos allowed per transaction (maxUtxosPerTx). This utxo will + -- be deferred until the next round. + | AssignUtxo_Deferred + -- Utxo has been successfully assigned to a source. + | AssignUtxo_AssignedToSource (SourceState wallet amount) + +derive instance Generic (AssignUtxoResult wallet amount) _ +derive instance (Eq wallet, Eq amount) => Eq (AssignUtxoResult wallet amount) + +instance (Show wallet, Show amount) => Show (AssignUtxoResult wallet amount) where + show = genericShow + +-- | Attempts to assign the specified target utxo to the given source. +-- | ADA value of the target utxo is expected to be normalized, i.e. +-- | utxo min-ada requirement should be taken into account. assignUtxoToSource :: forall wallet amount . Ord amount diff --git a/src/Internal/Testnet/Server.purs b/src/Internal/Testnet/Server.purs index 561c0aba1..5611f445f 100644 --- a/src/Internal/Testnet/Server.purs +++ b/src/Internal/Testnet/Server.purs @@ -306,8 +306,6 @@ spawnCardanoTestnet workdir params = do params.epochSize , [ flag "slot-length", show (unwrap params.slotLength) ] , [ flag "testnet-magic", show params.testnetMagic ] - -- FIXME: max-lovelace-supply option has no effect, should be fixed upstream - -- https://github.com/IntersectMBO/cardano-node/issues/5953 , [ flag "max-lovelace-supply", BigNum.toString BigNum.maxValue ] ] diff --git a/src/Internal/Types/ProtocolParameters.purs b/src/Internal/Types/ProtocolParameters.purs index 01574f726..9540e6953 100644 --- a/src/Internal/Types/ProtocolParameters.purs +++ b/src/Internal/Types/ProtocolParameters.purs @@ -60,6 +60,7 @@ newtype ProtocolParameters = ProtocolParameters , maxCollateralInputs :: UInt , govActionDeposit :: Coin , drepDeposit :: Coin + , refScriptCoinsPerByte :: Rational } derive instance Newtype ProtocolParameters _ diff --git a/src/Internal/Types/Rational.js b/src/Internal/Types/Rational.js new file mode 100644 index 000000000..f1396e699 --- /dev/null +++ b/src/Internal/Types/Rational.js @@ -0,0 +1,21 @@ +export const decimalToFraction = decimal => { + if (decimal % 1 === 0) { + return { + numerator: decimal, + denominator: 1 + }; + } + + let gcd = (a, b) => (b ? gcd(b, a % b) : a); + + let len = decimal.toString().length - 2; + let denominator = Math.pow(10, len); + let numerator = decimal * denominator; + + let divisor = gcd(numerator, denominator); + + return { + numerator: numerator / divisor, + denominator: denominator / divisor + }; +}; diff --git a/src/Internal/Types/Rational.purs b/src/Internal/Types/Rational.purs index 69a92563f..cc1a2e9f8 100644 --- a/src/Internal/Types/Rational.purs +++ b/src/Internal/Types/Rational.purs @@ -6,6 +6,8 @@ module Ctl.Internal.Types.Rational , recip , numerator , denominator + , toUnitInterval + , fromNumber ) where import Prelude @@ -21,10 +23,11 @@ import Aeson ) import Cardano.FromData (class FromData) import Cardano.ToData (class ToData) +import Cardano.Types (PlutusData(Constr, Integer), UnitInterval) import Cardano.Types.BigNum as BigNum -import Cardano.Types.PlutusData (PlutusData(Constr, Integer)) import Data.Either (Either(Left)) import Data.Maybe (Maybe(Just, Nothing), maybe) +import Data.Newtype (wrap) import Data.Ratio (Ratio) import Data.Ratio (denominator, numerator, (%)) as Ratio import JS.BigInt (BigInt) @@ -124,3 +127,19 @@ instance RationalComponent BigInt where instance RationalComponent Int where reduce n d = reduce (BigInt.fromInt n) (BigInt.fromInt d) + +toUnitInterval :: Rational -> Maybe UnitInterval +toUnitInterval (Rational r) = do + numerator' <- BigNum.fromBigInt $ Ratio.numerator r + denominator' <- BigNum.fromBigInt $ Ratio.denominator r + pure $ wrap { numerator: numerator', denominator: denominator' } + +foreign import decimalToFraction + :: Number -> { numerator :: Int, denominator :: Int } + +fromNumber :: Number -> Maybe Rational +fromNumber n = + let + { numerator, denominator } = decimalToFraction n + in + reduce (BigInt.fromInt numerator) (BigInt.fromInt denominator) diff --git a/src/Internal/Types/Val.purs b/src/Internal/Types/Val.purs index 5ac1f1b82..f7209b949 100644 --- a/src/Internal/Types/Val.purs +++ b/src/Internal/Types/Val.purs @@ -15,9 +15,10 @@ import Cardano.Types import Cardano.Types.AssetName (fromAssetName) import Cardano.Types.BigNum as BigNum import Cardano.Types.Int as Int -import Cardano.Types.Mint (Mint(Mint)) +import Cardano.Types.Mint (Mint) +import Cardano.Types.Mint as Mint import Cardano.Types.MultiAsset as MultiAsset -import Data.Array (cons) +import Data.Array (cons, foldr) import Data.Bifunctor (bimap) import Data.ByteArray (byteArrayToHex) import Data.Foldable (all) @@ -31,7 +32,7 @@ import Data.Map as Map import Data.Maybe (Maybe, fromMaybe) import Data.Newtype (unwrap, wrap) import Data.Show.Generic (genericShow) -import Data.These (These(This, That, Both)) +import Data.These (These(This, That, Both), these) import Data.Traversable (traverse) import Data.Tuple.Nested (type (/\), (/\)) import JS.BigInt as BigInt @@ -171,7 +172,29 @@ fromMultiAsset :: MultiAsset -> Val fromMultiAsset (MultiAsset ma) = Val zero $ map (map BigNum.toBigInt) ma fromMint :: Mint -> Val -fromMint (Mint ma) = Val zero $ map (map Int.toBigInt) $ ma +fromMint mint = + Val zero $ foldr insert Map.empty $ Mint.flatten mint + where + insert + :: (ScriptHash /\ AssetName /\ Int.Int) + -> Map ScriptHash (Map AssetName BigInt) + -> Map ScriptHash (Map AssetName BigInt) + insert (scriptHash /\ assetName /\ amount) ma = + map joinAssets $ + MultiAsset.union + ma + ( Map.singleton scriptHash $ Map.singleton assetName $ Int.toBigInt + amount + ) + + joinAssets + :: These (Map AssetName BigInt) (Map AssetName BigInt) + -> Map AssetName BigInt + joinAssets = these identity identity + (\x y -> map unBoth $ MultiAsset.union x y) + unBoth (Both a b) = add a b + unBoth (This a) = a + unBoth (That b) = b minus :: Val -> Val -> Val minus (Val a ma) (Val b mb) = Val (a - b) (unionWithNonAda (-) ma mb) diff --git a/templates/ctl-scaffold/flake.lock b/templates/ctl-scaffold/flake.lock index 600f05c0b..9b7a74654 100644 --- a/templates/ctl-scaffold/flake.lock +++ b/templates/ctl-scaffold/flake.lock @@ -2124,17 +2124,17 @@ "utils": "utils_7" }, "locked": { - "lastModified": 1721843629, - "narHash": "sha256-F5wgRA820x16f+8c/LlEEBG0rMJIA1XWw6X0ZwX5UWs=", + "lastModified": 1722955151, + "narHash": "sha256-pZUg2PbhK35QdMcEP0or6IyKXBr544KyebQ+xiNc6PE=", "owner": "input-output-hk", "repo": "cardano-node", - "rev": "176f99e51155cb3eaa0711db1c3c969d67438958", + "rev": "4f4e372a1641ac68cd09fb0339e6f55bef1ab85d", "type": "github" }, "original": { "owner": "input-output-hk", - "ref": "9.1.0", "repo": "cardano-node", + "rev": "4f4e372a1641ac68cd09fb0339e6f55bef1ab85d", "type": "github" } }, @@ -2781,17 +2781,17 @@ "ogmios": "ogmios_2" }, "locked": { - "lastModified": 1722613689, - "narHash": "sha256-CACNiPCxPpKNUZpW9Mq7IDa3YwMUqymFIr2bzMWc5bA=", + "lastModified": 1725554236, + "narHash": "sha256-KVOytx/7s9J0zZuN9Cb34VXBC17b8hclpBdZnwhIb3Q=", "owner": "Plutonomicon", "repo": "cardano-transaction-lib", - "rev": "01708d64e858a2ed3cbbc7a9a235d3acf79a7b91", + "rev": "c55856ce2bd191e522329718bd5324107e4f97f4", "type": "github" }, "original": { "owner": "Plutonomicon", "repo": "cardano-transaction-lib", - "rev": "01708d64e858a2ed3cbbc7a9a235d3acf79a7b91", + "rev": "c55856ce2bd191e522329718bd5324107e4f97f4", "type": "github" } }, diff --git a/templates/ctl-scaffold/flake.nix b/templates/ctl-scaffold/flake.nix index 1a2ea7735..219436708 100644 --- a/templates/ctl-scaffold/flake.nix +++ b/templates/ctl-scaffold/flake.nix @@ -16,7 +16,7 @@ type = "github"; owner = "Plutonomicon"; repo = "cardano-transaction-lib"; - rev = "01708d64e858a2ed3cbbc7a9a235d3acf79a7b91"; + rev = "c55856ce2bd191e522329718bd5324107e4f97f4"; }; # To use the same version of `nixpkgs` as we do nixpkgs.follows = "ctl/nixpkgs"; diff --git a/templates/ctl-scaffold/package-lock.json b/templates/ctl-scaffold/package-lock.json index 95b691692..4790ea640 100644 --- a/templates/ctl-scaffold/package-lock.json +++ b/templates/ctl-scaffold/package-lock.json @@ -10,7 +10,7 @@ "license": "MIT", "dependencies": { "@mlabs-haskell/cardano-message-signing": "^1.0.1", - "@mlabs-haskell/cardano-serialization-lib-gc": "12.0.0-alpha.31", + "@mlabs-haskell/cardano-serialization-lib-gc": "12.0.0", "@mlabs-haskell/json-bigint": "2.0.0", "@mlabs-haskell/uplc-apply-args": "1.0.29-alpha", "@noble/secp256k1": "^1.7.0", @@ -58,14 +58,14 @@ "integrity": "sha512-PoKh1tQnJX18f8iEr8Jk1KXxKCn9eqaSslMI1pyOJvYRJhQVDLCh0+9YReufjp0oFJIY1ShcrR+4/WnECVZUKQ==" }, "node_modules/@emurgo/cardano-serialization-lib-browser": { - "version": "12.0.0-beta.1", - "resolved": "https://registry.npmjs.org/@emurgo/cardano-serialization-lib-browser/-/cardano-serialization-lib-browser-12.0.0-beta.1.tgz", - "integrity": "sha512-Fj56XnZe+ilFVgf66SB6ajQXf0rtH9o0GmICLM9qahLDZ2kAPsVu31PbbQ0YWpQB8SlDGLZE5f9Pf3Lx7cc7oA==" + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@emurgo/cardano-serialization-lib-browser/-/cardano-serialization-lib-browser-12.0.0.tgz", + "integrity": "sha512-sAVjtaSwujQ3WaJY7OnsOt9mGbMF6YVFg/D4SWLr666zo3ESmislH0FLD932yFTOSJtOQV1oF+Pk8Ee2lR7X5A==" }, "node_modules/@emurgo/cardano-serialization-lib-nodejs": { - "version": "12.0.0-beta.1", - "resolved": "https://registry.npmjs.org/@emurgo/cardano-serialization-lib-nodejs/-/cardano-serialization-lib-nodejs-12.0.0-beta.1.tgz", - "integrity": "sha512-4BE7mSvSDWAmTXbzvNZg7NnaBoECv/QxsrNVKXdbaom5J9OhnnwvX3xhbEv98FAU2Awma8tLn9sHELZ46p2zbg==" + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@emurgo/cardano-serialization-lib-nodejs/-/cardano-serialization-lib-nodejs-12.0.0.tgz", + "integrity": "sha512-r7ZFYMr1N/i2GbhPAmz7JjKhfjEu7q8sa5beX2rLoV+xTkKGfknCTOsVvT0LqgKOUXAzcSQhNNHUKFd27+sLiw==" }, "node_modules/@esbuild/android-arm": { "version": "0.18.11", @@ -499,12 +499,12 @@ } }, "node_modules/@mlabs-haskell/cardano-serialization-lib-gc": { - "version": "12.0.0-alpha.31", - "resolved": "https://registry.npmjs.org/@mlabs-haskell/cardano-serialization-lib-gc/-/cardano-serialization-lib-gc-12.0.0-alpha.31.tgz", - "integrity": "sha512-QQBzl7rNRy7wk37uxzWJXCZfZRt3aTlfQb3kmb10ulY/janlUNETmS09OtiJbK/BdV5Fu7Gv+Mdda3ggMIL/bg==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@mlabs-haskell/cardano-serialization-lib-gc/-/cardano-serialization-lib-gc-12.0.0.tgz", + "integrity": "sha512-8qwkJzDV1CEjbpZZ3sX5gkP6Tug0mzBSeO9ppHBT6wFEqyi5HXA5oxmN0TGoFecvWVG5f6JmRVeBS0sDqsi20A==", "dependencies": { - "@emurgo/cardano-serialization-lib-browser": "^12.0.0-alpha.31", - "@emurgo/cardano-serialization-lib-nodejs": "^12.0.0-alpha.31", + "@emurgo/cardano-serialization-lib-browser": "12.0.0", + "@emurgo/cardano-serialization-lib-nodejs": "12.0.0", "@mlabs-haskell/csl-gc-wrapper": "^1.0.2" } }, @@ -5518,14 +5518,14 @@ "integrity": "sha512-PoKh1tQnJX18f8iEr8Jk1KXxKCn9eqaSslMI1pyOJvYRJhQVDLCh0+9YReufjp0oFJIY1ShcrR+4/WnECVZUKQ==" }, "@emurgo/cardano-serialization-lib-browser": { - "version": "12.0.0-beta.1", - "resolved": "https://registry.npmjs.org/@emurgo/cardano-serialization-lib-browser/-/cardano-serialization-lib-browser-12.0.0-beta.1.tgz", - "integrity": "sha512-Fj56XnZe+ilFVgf66SB6ajQXf0rtH9o0GmICLM9qahLDZ2kAPsVu31PbbQ0YWpQB8SlDGLZE5f9Pf3Lx7cc7oA==" + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@emurgo/cardano-serialization-lib-browser/-/cardano-serialization-lib-browser-12.0.0.tgz", + "integrity": "sha512-sAVjtaSwujQ3WaJY7OnsOt9mGbMF6YVFg/D4SWLr666zo3ESmislH0FLD932yFTOSJtOQV1oF+Pk8Ee2lR7X5A==" }, "@emurgo/cardano-serialization-lib-nodejs": { - "version": "12.0.0-beta.1", - "resolved": "https://registry.npmjs.org/@emurgo/cardano-serialization-lib-nodejs/-/cardano-serialization-lib-nodejs-12.0.0-beta.1.tgz", - "integrity": "sha512-4BE7mSvSDWAmTXbzvNZg7NnaBoECv/QxsrNVKXdbaom5J9OhnnwvX3xhbEv98FAU2Awma8tLn9sHELZ46p2zbg==" + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@emurgo/cardano-serialization-lib-nodejs/-/cardano-serialization-lib-nodejs-12.0.0.tgz", + "integrity": "sha512-r7ZFYMr1N/i2GbhPAmz7JjKhfjEu7q8sa5beX2rLoV+xTkKGfknCTOsVvT0LqgKOUXAzcSQhNNHUKFd27+sLiw==" }, "@esbuild/android-arm": { "version": "0.18.11", @@ -5752,12 +5752,12 @@ } }, "@mlabs-haskell/cardano-serialization-lib-gc": { - "version": "12.0.0-alpha.31", - "resolved": "https://registry.npmjs.org/@mlabs-haskell/cardano-serialization-lib-gc/-/cardano-serialization-lib-gc-12.0.0-alpha.31.tgz", - "integrity": "sha512-QQBzl7rNRy7wk37uxzWJXCZfZRt3aTlfQb3kmb10ulY/janlUNETmS09OtiJbK/BdV5Fu7Gv+Mdda3ggMIL/bg==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@mlabs-haskell/cardano-serialization-lib-gc/-/cardano-serialization-lib-gc-12.0.0.tgz", + "integrity": "sha512-8qwkJzDV1CEjbpZZ3sX5gkP6Tug0mzBSeO9ppHBT6wFEqyi5HXA5oxmN0TGoFecvWVG5f6JmRVeBS0sDqsi20A==", "requires": { - "@emurgo/cardano-serialization-lib-browser": "^12.0.0-alpha.31", - "@emurgo/cardano-serialization-lib-nodejs": "^12.0.0-alpha.31", + "@emurgo/cardano-serialization-lib-browser": "12.0.0", + "@emurgo/cardano-serialization-lib-nodejs": "12.0.0", "@mlabs-haskell/csl-gc-wrapper": "^1.0.2" } }, diff --git a/templates/ctl-scaffold/package.json b/templates/ctl-scaffold/package.json index 4ec30b311..b4f267727 100644 --- a/templates/ctl-scaffold/package.json +++ b/templates/ctl-scaffold/package.json @@ -26,7 +26,7 @@ "license": "MIT", "dependencies": { "@mlabs-haskell/cardano-message-signing": "^1.0.1", - "@mlabs-haskell/cardano-serialization-lib-gc": "12.0.0-alpha.31", + "@mlabs-haskell/cardano-serialization-lib-gc": "12.0.0", "@mlabs-haskell/json-bigint": "2.0.0", "@mlabs-haskell/uplc-apply-args": "1.0.29-alpha", "@noble/secp256k1": "^1.7.0", diff --git a/templates/ctl-scaffold/packages.dhall b/templates/ctl-scaffold/packages.dhall index f0b785071..0aa1c50e4 100644 --- a/templates/ctl-scaffold/packages.dhall +++ b/templates/ctl-scaffold/packages.dhall @@ -118,7 +118,7 @@ let additions = , "untagged-union" ] , repo = "https://github.com/mlabs-haskell/purescript-cip30" - , version = "v1.0.0" + , version = "v1.0.1" } , cip30-typesafe = { dependencies = @@ -214,7 +214,7 @@ let additions = ] , repo = "https://github.com/mlabs-haskell/purescript-cardano-serialization-lib" - , version = "v1.0.0" + , version = "v2.0.0" } , cardano-plutus-data-schema = { dependencies = [ "prelude" ] @@ -372,7 +372,7 @@ let additions = , "unsafe-coerce" ] , repo = "https://github.com/mlabs-haskell/purescript-cardano-types" - , version = "v2.0.1" + , version = "v3.0.0" } , cardano-message-signing = { dependencies = @@ -453,7 +453,7 @@ let additions = ] , repo = "https://github.com/mlabs-haskell/purescript-cardano-transaction-builder" - , version = "a9c033b9a2bb78b134ae5309209f73e47f3d5791" + , version = "v2.0.0" } , mote-testplan = { dependencies = @@ -584,7 +584,7 @@ let additions = , "web-storage" ] , repo = "https://github.com/Plutonomicon/cardano-transaction-lib.git" - , version = "01708d64e858a2ed3cbbc7a9a235d3acf79a7b91" + , version = "c55856ce2bd191e522329718bd5324107e4f97f4" } } diff --git a/templates/ctl-scaffold/spago-packages.nix b/templates/ctl-scaffold/spago-packages.nix index 8428b9676..3c7baf126 100644 --- a/templates/ctl-scaffold/spago-packages.nix +++ b/templates/ctl-scaffold/spago-packages.nix @@ -271,11 +271,11 @@ let "cardano-serialization-lib" = pkgs.stdenv.mkDerivation { name = "cardano-serialization-lib"; - version = "v1.0.0"; + version = "v2.0.0"; src = pkgs.fetchgit { url = "https://github.com/mlabs-haskell/purescript-cardano-serialization-lib"; - rev = "903bf0adeefedc4d065ad6523ad079433bdd8e32"; - sha256 = "0jlfxrx037hyd4v0j7l2b16yxlm6nw6qlnr992hj9nzip36vbpfg"; + rev = "d6ca2f9463b3d4e1cfa98e9964edbe7bfed02905"; + sha256 = "05f26v1xr7lkiw57rcqhjng299p7ly90wxqq9jay743pwvrysq0b"; }; phases = "installPhase"; installPhase = "ln -s $src $out"; @@ -283,10 +283,10 @@ let "cardano-transaction-builder" = pkgs.stdenv.mkDerivation { name = "cardano-transaction-builder"; - version = "a9c033b9a2bb78b134ae5309209f73e47f3d5791"; + version = "v2.0.0"; src = pkgs.fetchgit { url = "https://github.com/mlabs-haskell/purescript-cardano-transaction-builder"; - rev = "a9c033b9a2bb78b134ae5309209f73e47f3d5791"; + rev = "2a31258a85e441b6747582ab35d7d86fc866c749"; sha256 = "1xz6k56kwghq9nl0iwrqs6m05wja0xfj34iicmlhwvdp7k4nc65w"; }; phases = "installPhase"; @@ -295,11 +295,11 @@ let "cardano-transaction-lib" = pkgs.stdenv.mkDerivation { name = "cardano-transaction-lib"; - version = "01708d64e858a2ed3cbbc7a9a235d3acf79a7b91"; + version = "c55856ce2bd191e522329718bd5324107e4f97f4"; src = pkgs.fetchgit { url = "https://github.com/Plutonomicon/cardano-transaction-lib.git"; - rev = "01708d64e858a2ed3cbbc7a9a235d3acf79a7b91"; - sha256 = "1c75kk2wr6xx4a2jkaql0divfdi0pg5g8mlsa66r4gmiy248s008"; + rev = "c55856ce2bd191e522329718bd5324107e4f97f4"; + sha256 = "0x3g9049yn8plhjigwnvbq5w2mg1ywkg93cvrmsd5czv3yvv4lr9"; }; phases = "installPhase"; installPhase = "ln -s $src $out"; @@ -307,11 +307,11 @@ let "cardano-types" = pkgs.stdenv.mkDerivation { name = "cardano-types"; - version = "v2.0.1"; + version = "v3.0.0"; src = pkgs.fetchgit { url = "https://github.com/mlabs-haskell/purescript-cardano-types"; - rev = "5b16e9571167e9889605d3aecdd0ccce24d38696"; - sha256 = "1052lknpkhcq86lj8aavfwzr9ybrirjighsjccpgrcaq2jn4kcmj"; + rev = "71b204c7c9c83b8280ed3ed14837d76b8ac0a6fe"; + sha256 = "1kffscail4kp5pygdv8nd2bclwd6c0cygkn5mn5sllnn29a63mpf"; }; phases = "installPhase"; installPhase = "ln -s $src $out"; @@ -343,11 +343,11 @@ let "cip30" = pkgs.stdenv.mkDerivation { name = "cip30"; - version = "v1.0.0"; + version = "v1.0.1"; src = pkgs.fetchgit { url = "https://github.com/mlabs-haskell/purescript-cip30"; - rev = "8f1b34b48825fcec5e9c67f33e255770b1e0bc45"; - sha256 = "1rb7kv99rd50b6vhl90sirmzh43wgnyafpmn7w45n3d4nrvf1046"; + rev = "8de9bbcc6728237e3aec418c2c88bfcb519fc176"; + sha256 = "18ms7kyd98zmimvnjyixxhqrw5d68cpi3ya351hy2p4r7mmf7vy7"; }; phases = "installPhase"; installPhase = "ln -s $src $out"; diff --git a/test/Fixtures.purs b/test/Fixtures.purs index dbd26864f..440ebd8ca 100644 --- a/test/Fixtures.purs +++ b/test/Fixtures.purs @@ -16,7 +16,6 @@ module Test.Ctl.Fixtures , ed25519KeyHashFixture1 , fullyAppliedScriptFixture , int1 - , mint0 , mint1 , mkSampleTx , mkTxInput @@ -346,16 +345,9 @@ txFixture1 = mint1 :: Mint mint1 = Mint $ Map.fromFoldable - [ currencySymbol1 /\ Map.fromFoldable - [ tokenName2 /\ Int.newPositive BigNum.one - ] - ] - -mint0 :: Mint -mint0 = Mint $ Map.fromFoldable - [ currencySymbol1 /\ Map.fromFoldable - [ tokenName2 /\ Int.newPositive BigNum.zero - ] + [ currencySymbol1 /\ + Map.fromFoldable + [ tokenName2 /\ Int.newPositive BigNum.one ] ] int1 :: Int.Int diff --git a/test/Testnet/Contract.purs b/test/Testnet/Contract.purs index b95a05bce..bcfdb3823 100644 --- a/test/Testnet/Contract.purs +++ b/test/Testnet/Contract.purs @@ -50,10 +50,7 @@ import Contract.BalanceTxConstraints , mustUseCollateralUtxos ) import Contract.Chain (currentTime, waitUntilSlot) -import Contract.Config - ( KnownWallet(Nami, Gero, Flint, Lode, NuFi) - , walletName - ) +import Contract.Config (KnownWallet(Nami, Gero, Flint, Lode, NuFi), walletName) import Contract.Hashing (datumHash, nativeScriptHash) import Contract.Keys (privateKeyFromBytes) import Contract.Log (logInfo') @@ -62,7 +59,6 @@ import Contract.Monad (Contract, liftContractE, liftContractM, liftedM) import Contract.Numeric.BigNum as BigNum import Contract.PlutusData ( PlutusData(Bytes, Integer, List) - , RedeemerDatum(RedeemerDatum) , getDatumByHash , getDatumsByHashes , getDatumsByHashesWithErrors @@ -149,11 +145,7 @@ import Ctl.Examples.Helpers (mkAssetName, mustPayToPubKeyStakeAddress) import Ctl.Examples.IncludeDatum as IncludeDatum import Ctl.Examples.Lose7Ada as AlwaysFails import Ctl.Examples.ManyAssets as ManyAssets -import Ctl.Examples.MintsMultipleTokens - ( mintingPolicyRdmrInt1 - , mintingPolicyRdmrInt2 - , mintingPolicyRdmrInt3 - ) +import Ctl.Examples.MintsMultipleTokens (contract) as MintsMultipleTokens import Ctl.Examples.NativeScriptMints (contract) as NativeScriptMints import Ctl.Examples.OneShotMinting (contract) as OneShotMinting import Ctl.Examples.PaysWithDatum (contract) as PaysWithDatum @@ -174,7 +166,7 @@ import Data.Either (Either(Left, Right), hush, isLeft, isRight) import Data.Foldable (fold, foldM, length) import Data.Lens (view) import Data.Map as Map -import Data.Maybe (Maybe(Just, Nothing), fromJust, fromMaybe, isJust) +import Data.Maybe (Maybe(Just, Nothing), fromJust, fromMaybe, isJust, maybe) import Data.Newtype (unwrap, wrap) import Data.Traversable (traverse, traverse_) import Data.Tuple (Tuple(Tuple)) @@ -231,7 +223,7 @@ suite = do withWallets distribution \alice -> do withKeyWallet alice ManyAssets.contract test - "#1509 - Collateral set to one of the inputs in mustNotSpendUtxosWithOutRefs " + "#1509 - Collateral set to one of the inputs in mustNotSpendUtxosWithOutRefs" do let someUtxos = @@ -261,6 +253,57 @@ suite = do ) res `shouldSatisfy` isLeft + test + "#1581 - Fallback to CTL collateral selection when all collateral inputs are non-spendable" + do + let + distribution = + [ BigNum.fromInt 10_000_000 + , BigNum.fromInt 10_000_000 + ] + withWallets distribution \alice -> + withKeyWallet alice do + validator <- AlwaysSucceeds.alwaysSucceedsScript + let vhash = validatorHash validator + logInfo' "Attempt to lock value" + txId <- AlwaysSucceeds.payToAlwaysSucceeds vhash + awaitTxConfirmed txId + logInfo' "Try to spend locked values" + + scriptAddress <- mkAddress (wrap $ ScriptHashCredential vhash) + Nothing + utxos <- utxosAt scriptAddress + scriptUtxo <- + liftM + ( error + ( "The id " + <> show txId + <> " does not have output locked at: " + <> show scriptAddress + ) + ) + $ head (lookupTxHash txId utxos) + + unbalancedTx <- buildTx + [ SpendOutput scriptUtxo $ Just $ PlutusScriptOutput + (ScriptValue validator) + RedeemerDatum.unit + (Just $ DatumValue PlutusData.unit) + ] + + collUtxos <- getWalletCollateral + let + balancerConstraints = + maybe + mempty + (mustNotSpendUtxosWithOutRefs <<< Map.keys <<< toUtxoMap) + collUtxos + + balancedTx <- balanceTx unbalancedTx (toUtxoMap [ scriptUtxo ]) + balancerConstraints + balancedSignedTx <- signTransaction balancedTx + submitAndLog balancedSignedTx + test "#1480 - test that does nothing but fails" do let someUtxos = @@ -1098,47 +1141,8 @@ suite = do [ BigNum.fromInt 5_000_000 , BigNum.fromInt 50_000_000 ] - withWallets distribution \alice -> do - withKeyWallet alice do - tn1 <- mkAssetName "Token with a long name" - tn2 <- mkAssetName "Token" - mp1 <- mintingPolicyRdmrInt1 - mp2 <- mintingPolicyRdmrInt2 - mp3 <- mintingPolicyRdmrInt3 - let - cs1 = PlutusScript.hash mp1 - cs2 = PlutusScript.hash mp2 - cs3 = PlutusScript.hash mp3 - - let - constraints :: Constraints.TxConstraints - constraints = mconcat $ unsafePartial - [ Constraints.mustMintValueWithRedeemer - (RedeemerDatum $ Integer (BigInt.fromInt 1)) - ( Mint.singleton cs1 tn1 Int.one <> Mint.singleton cs1 tn2 - Int.one - ) - , Constraints.mustMintValueWithRedeemer - (RedeemerDatum $ Integer (BigInt.fromInt 2)) - ( Mint.singleton cs2 tn1 Int.one <> Mint.singleton cs2 tn2 - Int.one - ) - , Constraints.mustMintValueWithRedeemer - (RedeemerDatum $ Integer (BigInt.fromInt 3)) - ( Mint.singleton cs3 tn1 Int.one <> Mint.singleton cs3 tn2 - Int.one - ) - ] - - lookups :: Lookups.ScriptLookups - lookups = - Lookups.plutusMintingPolicy mp1 - <> Lookups.plutusMintingPolicy mp2 - <> Lookups.plutusMintingPolicy mp3 - - ubTx /\ usedUtxos <- mkUnbalancedTx lookups constraints - bsTx <- signTransaction =<< balanceTx ubTx usedUtxos mempty - submitAndLog bsTx + withWallets distribution \alice -> + withKeyWallet alice MintsMultipleTokens.contract test "Multi-signature transaction" do let