-
Notifications
You must be signed in to change notification settings - Fork 84
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
Use a faucet to distribute funds #227
Conversation
61d90fb
to
c6592db
Compare
|
||
-- | Directly retrieve the amount of 'Lovelace' stored in a 'TxOut'. | ||
txOutLovelace :: TxOut ctx era -> Lovelace | ||
txOutLovelace (TxOut _ v _) = txOutValueToLovelace v |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure about this one. Just saw that there exists selectLovelace
recently. You opinions?
160add8
to
1a650f2
Compare
let addr = buildAddress vk defaultNetworkId | ||
bytes = serialiseToRawBytes addr | ||
in (encodeBase16 bytes, availableInitialFunds) | ||
|
||
copyCredential parentDir file = do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice cleanup in this module 🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly minor comments and suggestions to clarify naming/usage and improve readability.
I have one major concern though regarding the semantics of the genDatasetConstantUTxO
which seems incorrect to me, probably because I am missing something.
demo/seed-devnet.sh
Outdated
seedCommit "bob" 500000000 | ||
seedCommit "carol" 250000000 | ||
seedFaucet "alice" 1000000000 # 1000 Ada to commit | ||
seedFaucet "alice" 100000000 true # 100 Ada marked as "fuel" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: Avoid "boolean blindness" and use some variable or string instead of true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anything evaluating to "truthy" by bash's if
would work here. Bash is not really typed, but I suppose I can make this "fuel"
or so?
seedNetwork :: RunningNode -> Dataset -> IO () | ||
seedNetwork node@(RunningNode _ nodeSocket) Dataset{fundingTransaction, clientDatasets} = do | ||
-- Submit the funding transaction first | ||
submit defaultNetworkId nodeSocket fundingTransaction |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: remove the comment which is just paraphrasing the quite explicit line of code below
submit defaultNetworkId nodeSocket fundingTransaction | ||
void $ waitForTransaction defaultNetworkId nodeSocket fundingTransaction | ||
-- Then, fuel all clients with some 100 ADA | ||
forM_ clientDatasets $ \ClientDataset{signingKey} -> do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: rather than having a comment, how about
forM_ clientDatasets fuelClientWith100Ada
where
fuelClientWith100Ada = ...
mconcat <$> mapConcurrently (uncurry clientProcessTransactionsSequence) processors | ||
where | ||
clientProcessTransactionsSequence (Dataset{transactionsSequence}, client) clientId = do | ||
let numberOfTxs = length transactionsSequence | ||
clientProcessTransactionsSequence (ClientDataset{txSequence}, client) clientId = do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: why rename the field transactionsSequence
to txSequence
? Now the clientProcessTransactionsSequence
feels a bit odd.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's true. I should have renamed also the function or not rename at all. Why rename? I typed it a couple times during this change and typed it wrong > 50% of those times. The plural s
just before Sequence
somehow trips my typing. Also we use the abbreviation transaction -> tx
pervasively in this code base, so I thought I'll shorten it up.
I will change it back if you insist!?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I am fine with tx
but then perhaps rename the other function which is also a mouthful
@@ -76,6 +72,19 @@ queryUTxOByTxIn networkId socket inputs = | |||
) | |||
in UTxO.fromApi <$> runQuery networkId socket query | |||
|
|||
-- | Query the whole UTxO from node. Useful for debugging, but should obviously | |||
-- not be used in production code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😂
let cardanoKeys = [aliceCardanoVk] | ||
withIOManager $ \iocp -> do | ||
withDirectChain (contramap (FromDirectChain "alice") tracer) magic iocp nodeSocket aliceKeys alice cardanoKeys (putMVar alicesCallback) $ \Chain{postTx} -> do | ||
postSeedPayment (Testnet magic) pparams availableInitialFunds nodeSocket aliceCardanoSk 100_000_000 | ||
void $ seedFromFaucet (Testnet magic) node aliceCardanoVk 100_000_000 Marked |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Proposal: Rather than exposing the seedFromFaucet
function with an additional parameter, expose 2 different functions with explicit names, eg. createFuelUTxO
and createCommitUTxO
or something. Additional parameters controlling the branching of a function increases the cognitive load of the function's user or reader
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about this. The parameter does not control the branching of this function, rather what the thing you get from the faucet will be. Similar to the amount or whom it is payed to. I admit that the naming is not good and maybe data Marked = Fuel | NotMarked
would be a better name?
waitForNodesConnected tracer [n1] | ||
withHydraNode tracer bobSkPath [aliceVkPath, carolVkPath] tmpDir nodeSocket 2 bobSk [aliceVk, carolVk] allNodeIds $ \n2 -> | ||
withHydraNode tracer carolSkPath [aliceVkPath, bobVkPath] tmpDir nodeSocket 3 carolSk [aliceVk, bobVk] allNodeIds $ \n3 -> do | ||
-- Funds to be used as fuel by Hydra protocol transactions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comment: This comment here strengthens my belief an explicit function would be better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or a better name for the Marked
data constructor. In my book having more functions is not making things strictly less complex.
What do you think about this invocation and dropping the comment (as it should be clear from the names):
seedFromFaucet_ defaultNetworkId node aliceCardanoVk 100_000_000 Fuel
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer less parameters, plus the _
is a haskell convention which is widespread but maybe not that explicit in the long run. And it's repeated several times across different files. But I won't make it a casus belli so will let you decide.
& counterexample ("\ntransactions: " <> jsonString transactionsSequence) | ||
& counterexample ("\nutxo: " <> jsonString initialUTxO) | ||
forAll arbitrary $ \(Positive n) -> do | ||
idempotentIOProperty $ do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
discovery: Did not know about this function, looks interesting and useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Me neither.. before yesterday :)
void $ waitForPayment networkId socket amountToPay addr | ||
(RunningCluster ClusterConfig{networkId} (node : _)) -> do | ||
(vk, _) <- keysFor Alice | ||
void $ seedFromFaucet networkId node vk 100_000_000 Normal |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice improvement in the size and complexity of the function 🎉
As the third exception to the rule
Rationale: not needing to maintain two ways to set-up the devnet for the demo is desirable and a non-docker option can be provided to users which have cardano-cli in scope
Both are not used anymore
We use the faucet now instead
This also changes the definition of 'Dataset' to include all the sub-per-client-datasets.
withCreateProcess seems not to be a graceful shutdown so the node.socket file lingers in the state directory
This way, the init does not accidentally spend some output intended to be committed later.
1a650f2
to
2bfd258
Compare
where | ||
generateEnvironment = do | ||
refreshSystemStart cfg args | ||
let topology = mkTopology $ peers $ ports cfg | ||
Aeson.encodeFile (stateDirectory </> nodeTopologyFile args) topology | ||
|
||
cleanupSocketFile = | ||
whenM (doesFileExist socketFile) $ | ||
removeFile socketFile |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this now necessary 🤔 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work. I've got maybe one side question: what happens if the faucet runs out of the money? Not the practical implications of it but, what sort of errors are we welcomed with? Is it made clear that we are running out of money?
Asking this because of a bad memory of several hours debugging some failing e2e tests in cardano-wallet only to figure out that we had no more funds in the faucet which was causing tests to fail.
Good question. Haven't tried. I fear it would block because it |
❄️ Introduce well-known
Actor = Faucet | Alice | Bob | Carol
keys as data type❄️ Introduce
seedFromFaucet
to distribute funds from theFaucet
actor, eitherMarked
(as fuel) orNormal
, which queries the faucet UTXO and spends it as requested.❄️ Update all tests to use
seedFromFaucet
instead of the genesis/prepare commit transactions❄️ Update the demo to use the same style of fund distribution in
seed-devnet.sh
. Drop the haskell exe for seeding to only have one way to maintain.❄️ Benchmarks are working now. Needed to keep using
mkGenesisTx
and distribute funds to all clients in the benchmark dataset in one transaction.