Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fees for Tx building #37

Merged
merged 52 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
9eec15a
Initialize fees
mpizenberg Aug 11, 2024
491d3f3
Process Tx other info
mpizenberg Aug 11, 2024
9b9d688
Handle manual fees
mpizenberg Aug 12, 2024
ca99f5b
Improve reference inputs and auxiliary data
mpizenberg Aug 12, 2024
cab794f
Add one round of tx building with fee estimation
mpizenberg Aug 13, 2024
a122bb0
Refactor buildTxRound
mpizenberg Aug 13, 2024
d461032
Simple rename
mpizenberg Aug 13, 2024
f86521a
Use utxo index in example 3 redeemer
mpizenberg Aug 13, 2024
a196c22
Add comments in example 3
mpizenberg Aug 13, 2024
6d776d7
Typo
mpizenberg Aug 13, 2024
0ef1677
Add a preprocess step to prepare more checks
mpizenberg Aug 20, 2024
501b3e7
Move duplicate metadata check in processOtherInfo
mpizenberg Aug 20, 2024
3ae8a1a
Move min ada check into processIntents
mpizenberg Aug 21, 2024
de731e4
Validate time range
mpizenberg Aug 21, 2024
61b0cd0
Use dummy bytes for script data hash
mpizenberg Aug 21, 2024
69ff3f5
Add link to blaze impl for script data hash
mpizenberg Aug 21, 2024
36a4bbd
Move some let bindings around
mpizenberg Aug 21, 2024
8e822b9
Rename initialFee into feeAmount
mpizenberg Aug 21, 2024
df90447
Move feeAmount computation outside buildTx
mpizenberg Aug 21, 2024
fc26568
Add collateral automatically when building Tx
mpizenberg Aug 22, 2024
5c563ad
Create the first Tx building test (only fee)
mpizenberg Aug 22, 2024
538f34f
Use directly newBody and newWitnessSet helpers
mpizenberg Aug 22, 2024
265b53a
Use directly newBody and newWitnessSet helpers
mpizenberg Aug 22, 2024
4652692
Add test with autofee
mpizenberg Aug 22, 2024
b67a593
Factor some testing code
mpizenberg Aug 22, 2024
e6643af
Add spending/sending same address test
mpizenberg Aug 22, 2024
f11867b
Add test with 1 ada transfer from me to you
mpizenberg Aug 22, 2024
79415e7
Add mint/burn test
mpizenberg Aug 22, 2024
2f0e264
Prepare Tx failure tests
mpizenberg Aug 22, 2024
607294d
Start adding proper Tx finalization errors
mpizenberg Aug 22, 2024
00545fe
Fix txbuild example
mpizenberg Aug 22, 2024
9fbd128
Add test for unbalanced Tx intents
mpizenberg Aug 22, 2024
5db3e61
Add test for not enough minAda in Tx intents
mpizenberg Aug 22, 2024
cc79171
Add test for duplicated metadata tag
mpizenberg Aug 22, 2024
0ac0df3
Add test for incorrect validity range
mpizenberg Aug 22, 2024
a9c54d1
Inline the code to find potential collateral sources
mpizenberg Aug 23, 2024
af7be0b
Pre-split selectable inputs by address
mpizenberg Aug 23, 2024
ebb3c57
Handle minAda in generated outputs
mpizenberg Aug 24, 2024
cf75b5a
Small refactor
mpizenberg Aug 24, 2024
3ee6251
Check for insufficient manual fee
mpizenberg Aug 24, 2024
9ecb7f9
Check that all referenced inputs are in local state
mpizenberg Aug 30, 2024
5b17470
Move some comments
mpizenberg Aug 30, 2024
7f36529
Deduplicate required signers
mpizenberg Aug 30, 2024
4a1abcd
Deduplicate witness sources
mpizenberg Aug 30, 2024
3caed91
Fix txbuild example (missing ref for mints)
mpizenberg Aug 30, 2024
4dae6a3
Improve duplicate tag error
mpizenberg Aug 30, 2024
730e302
Small refactor
mpizenberg Aug 30, 2024
e759a3f
Handle ref inputs when updating inputs/outputs
mpizenberg Aug 30, 2024
015f273
Add dummy pub key witness in Tx
mpizenberg Aug 30, 2024
5588973
Simplify dummy vkey witness in tx
mpizenberg Aug 30, 2024
4f9ccc9
Do some small todos
mpizenberg Aug 30, 2024
8a55e4d
Add todo comment
mpizenberg Aug 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions examples/txbuild/Main.elm
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ main =
example ex =
case ex () of
Err error ->
error
Debug.toString error

Ok tx ->
Cardano.prettyTx tx
Expand All @@ -31,10 +31,11 @@ example ex =
view : () -> Html ()
view _ =
div []
[ div [] [ text "Example transaction 1: send 1 ada from me to you" ]
[ div [] [ text "Example transaction 1: send 1 ada from me to you." ]
, Html.pre [] [ text <| example Cardano.example1 ]
, div [] [ text "Example transaction 2: mint dog & burn 1 cat" ]
, div [] [ text "Example transaction 2: mint 1 dog & burn 1 cat." ]
, Html.pre [] [ text <| example Cardano.example2 ]
, div [] [ text "Example transaction 3: spend 1 ada from a plutus script with 2 ada" ]
, div [] [ text "Example transaction 3: spend 1 ada from a plutus script with 2 ada." ]
, div [] [ text "Spent UTxO index is passed as argument in the redeemer." ]
, Html.pre [] [ text <| example Cardano.example3 ]
]
1,287 changes: 965 additions & 322 deletions src/Cardano.elm

Large diffs are not rendered by default.

53 changes: 47 additions & 6 deletions src/Cardano/Address.elm
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ module Cardano.Address exposing
( Address(..), StakeAddress, NetworkId(..), ByronAddress
, Credential(..), StakeCredential(..), StakeCredentialPointer, CredentialHash
, enterprise, script, base, pointer
, extractPubKeyHash, extractStakeCredential
, Dict, emptyDict
, StakeDict, emptyStakeDict
, isShelleyWallet, extractPubKeyHash, extractStakeCredential
, Dict, emptyDict, dictFromList
, StakeDict, emptyStakeDict, stakeDictFromList
, toCbor, stakeAddressToCbor, credentialToCbor, encodeNetworkId
, decode, decodeReward
)
Expand All @@ -17,11 +17,11 @@ module Cardano.Address exposing

@docs enterprise, script, base, pointer

@docs extractPubKeyHash, extractStakeCredential
@docs isShelleyWallet, extractPubKeyHash, extractStakeCredential

@docs Dict, emptyDict
@docs Dict, emptyDict, dictFromList

@docs StakeDict, emptyStakeDict
@docs StakeDict, emptyStakeDict, stakeDictFromList

@docs toCbor, stakeAddressToCbor, credentialToCbor, encodeNetworkId

Expand Down Expand Up @@ -155,6 +155,13 @@ pointer networkId paymentCredential p =
}


{-| Check if an [Address] is of the Shelley type, with a wallet payment key, not a script.
-}
isShelleyWallet : Address -> Bool
isShelleyWallet address =
extractPubKeyHash address /= Nothing


{-| Extract the pubkey hash of a Shelley wallet address.
-}
extractPubKeyHash : Address -> Maybe (Bytes CredentialHash)
Expand Down Expand Up @@ -186,34 +193,68 @@ extractStakeCredential address =

{-| Convenient alias for a `Dict` with [Address] keys.
When converting to a `List`, its keys are sorted by address.

WARNING: do not compare them with `==` since they contain functions.

-}
type alias Dict a =
AnyDict String Address a


{-| Initialize an empty address dictionary.
For other operations, use the `AnyDict` module directly.

WARNING: do not compare them with `==` since they contain functions.

-}
emptyDict : Dict a
emptyDict =
Dict.Any.empty (toCbor >> E.encode >> Bytes.fromBytes >> Bytes.toString)


{-| Create an address dictionary from a list.
For other operations, use the `AnyDict` module directly.

WARNING: do not compare them with `==` since they contain functions.

-}
dictFromList : List ( Address, a ) -> Dict a
dictFromList =
Dict.Any.fromList (toCbor >> E.encode >> Bytes.fromBytes >> Bytes.toString)


{-| Convenient alias for a `Dict` with [StakeAddress] keys.
When converting to a `List`, its keys are sorted by stake address.

WARNING: do not compare them with `==` since they contain functions.

-}
type alias StakeDict a =
AnyDict String StakeAddress a


{-| Initialize an empty stake address dictionary.
For other operations, use the `AnyDict` module directly.

WARNING: do not compare them with `==` since they contain functions.

-}
emptyStakeDict : StakeDict a
emptyStakeDict =
Dict.Any.empty (stakeAddressToCbor >> E.encode >> Bytes.fromBytes >> Bytes.toString)


{-| Create a stake address dictionary from a list.
For other operations, use the `AnyDict` module directly.

WARNING: do not compare them with `==` since they contain functions.

-}
stakeDictFromList : List ( StakeAddress, a ) -> StakeDict a
stakeDictFromList =
Dict.Any.fromList (stakeAddressToCbor >> E.encode >> Bytes.fromBytes >> Bytes.toString)


{-| Encode an [Address] to CBOR.

Byron addresses are left untouched as we don't plan to have full support of Byron era.
Expand Down
18 changes: 15 additions & 3 deletions src/Cardano/CoinSelection.elm
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import Natural as N exposing (Natural)
-}
type Error
= MaximumInputCountExceeded
| UTxOBalanceInsufficient
| UTxOBalanceInsufficient { selectedUtxos : List ( OutputReference, Output ), missingValue : Value }


{-| Represents the result of a successful coin selection.
Expand Down Expand Up @@ -77,6 +77,8 @@ largestFirst maxInputCount context =
MultiAsset.split context.targetAmount.assets

sortedAvailableUtxoByLovelace =
-- TODO: actually use the "free" lovelace, by substracting the UTxO minAda for sorting
-- Create and use a function called "Utxo.compareFreeLovelace"
List.sortWith (\( _, o1 ) ( _, o2 ) -> reverseOrder Utxo.compareLovelace o1 o2) context.availableUtxos
in
-- Select for Ada first
Expand All @@ -98,9 +100,12 @@ largestFirst maxInputCount context =
Nothing

else
Just (Value.substract state.accumulatedAmount context.targetAmount)
Just (Value.substract state.accumulatedAmount context.targetAmount |> Value.normalize)
}
)
-- TODO: if possible, remove extraneous inputs.
-- Indeed, when selecting later CNT, they might contain enough previous CNT too.
|> identity


type alias SelectionState =
Expand Down Expand Up @@ -163,7 +168,14 @@ accumOutputsUntilDone ({ maxInputCount, selectedInputCount, accumulatedAmount, t
else if not (Value.atLeast targetAmount accumulatedAmount) then
case availableOutputs of
[] ->
Err UTxOBalanceInsufficient
Err
(UTxOBalanceInsufficient
{ selectedUtxos = selectedOutputs
, missingValue =
Value.substract targetAmount accumulatedAmount
|> Value.normalize
}
)

utxo :: utxos ->
accumOutputsUntilDone
Expand Down
6 changes: 3 additions & 3 deletions src/Cardano/MultiAsset.elm
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@ onlyToken policy name amount =

{-| Remove assets with 0 amounts.
-}
normalize : MultiAsset Natural -> MultiAsset Natural
normalize multiAsset =
normalize : (int -> Bool) -> MultiAsset int -> MultiAsset int
normalize deletionCheck multiAsset =
multiAsset
|> Bytes.Map.map (Bytes.Map.filter (not << Natural.isZero))
|> Bytes.Map.map (Bytes.Map.filter (not << deletionCheck))
|> Bytes.Map.filter (not << Bytes.Map.isEmpty)


Expand Down
Loading
Loading