-
Notifications
You must be signed in to change notification settings - Fork 217
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
Make sign tx testable #3022
Make sign tx testable #3022
Conversation
685aa39
to
f284cf8
Compare
@sevanspowell Could we please have a title and description for this PR? |
2c557b0
to
d4b02ee
Compare
d4b02ee
to
5870069
Compare
liftHandler $ W.signTransaction wrk wid pwd sealedTx | ||
sealedTx' <- withWorkerCtx ctx wid liftE liftE $ \wrk -> liftHandler $ do | ||
let | ||
db = wrk ^. W.dbLayer @IO @s @k |
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.
We have those parts in almost all places in where
. Shouldn't we have here also (just for consistency)?
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.
It won't work in this case, because wrk
is not an argument to the outer function, wrk
won't be in scope in the where
block.
import qualified Cardano.Api.Shelley as Cardano | ||
import qualified Cardano.Crypto.Hash.Blake2b as Blake2b |
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.
what about using here as Crypto
?
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 just import without qualification like in other places in codebase?
-- necessary | ||
signTransaction tl era keyLookup (rootKey, rootPwd) utxo = | ||
let | ||
rewardAcnt :: (XPrv, Passphrase "encryption") |
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.
what about exposing this function? It is used also in tests. Maybe it would be good to have code reuse
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.
very nice properties added. It would be great to continue this path of testing when adding test coverage of decodeTx (in some forthcoming PRs).
- We see that signing can add some bits and this is tested.What about properties showing that signing will not change inps, outs, validity, ...., some things' ordering already present in the body?
- I see common patterns in properties. For example, we have the same structure:
case Cardano.THINGSupportedInEra era of
Nothing ->
Just _ ->
I wonder if there is a way to extract that common structure and reuse it in all property tests?
Thanks for the feedback @paweljakubas! I've addressed a number of your points in subsequent commits. |
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.
Excellent work - these are really good tests to have! ⭐
forAll (genTxInEra era) $ \tx -> do | ||
let |
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.
May as well combine the let and where bindings at the deeper level...
forAll (genTxInEra era) $ \tx -> do | |
let | |
forAll (genTxInEra era) $ \tx -> bodyContentBefore == bodyContentAfter | |
where | |
tl = testTxLayer | |
(same goes for the other prop_
functions)
conjoin $ (flip foldMap) elems $ \x -> | ||
[ x `elem` xs | ||
& counterexample ("actual set: " <> show xs) | ||
& counterexample ("expected elem: " <> show x) | ||
] |
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 don't think the foldMap is needed?
conjoin $ (flip foldMap) elems $ \x -> | |
[ x `elem` xs | |
& counterexample ("actual set: " <> show xs) | |
& counterexample ("expected elem: " <> show x) | |
] | |
counterexample ("actual set: " <> show xs) $ conjoin | |
[ x `elem` xs & counterexample ("expected elem: " <> show x) | |
| x <- elems ] |
forAllEras (\era -> it ("signTransaction adds reward account witness when necessary (" <> show era <> ")") $ | ||
property (prop_signTransaction_addsRewardAccountKey era)) |
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 was thinking that it would be nice to have the property description/right beside the property definition, but still exposing the Property
as a standalone function. Something like this...
forAllEras (\era -> it ("signTransaction adds reward account witness when necessary (" <> show era <> ")") $ | |
property (prop_signTransaction_addsRewardAccountKey era)) | |
describe desc_signTransaction_addsRewardAccountKey $ | |
forAllEras $ \era -> it (show era) $ | |
property (prop_signTransaction_addsRewardAccountKey era)) | |
-- ... -- | |
desc_signTransaction_addsRewardAccountKey = "signTransaction adds reward account witness when necessary" :: String |
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.
Agree, could be cool. But I wouldn't want these to be the only tests that do it.
rootK = first liftRawKey rootXPrv | ||
|
||
rawRewardK :: (XPrv, Passphrase "encryption") | ||
rawRewardK = (getRawKey $ deriveRewardAccount (snd rootK) (fst rootK), snd rootK) |
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.
If we find that tests are taking too long to run due to key generation, we could shift these things up into a precooked record of key inputs.
[mkShelleyWitness txBody rawRewardK] | ||
|
||
checkCoverage $ | ||
expectedWits `checkSubsetOf` (getSealedTxWitnesses sealedTx') |
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.
Cool. I was wondering whether the reward account xpub could be used to verify new witnesses, but it seems easier and more effective to just generate the witness directly, as you have done.
- For signTransaction: - Move IO operations out of the wallet layer and into the server handler. We want to move IO operations to the edge of our program, in this case, the "edge" is our server handler. Doing so makes the wallet layer easier to test.
- This update allows the spending witness for a TxIn to be a script witness or a key witness. Previously only key witnesses were supported.
- Add the following property tests for signTransaction: - adds the reward account witness when necessary - adds extra key witnesses when necessary - adds tx in witnesses when necessary - adds collateral witnesses when necessary - never removes witnesses
- Add tests to ensure signTransaction doesn't modify TxBody. - Make "checkSubsetOf" test more concise and reusable.
bc22af0
to
5351ce1
Compare
bors try |
tryBuild succeeded: |
bors r+ |
bors cancel |
Canceled. |
bors r+ |
Build succeeded: |
This PR is primarily about improving the testability of signTransaction, and providing a number of property tests.
Comments
Issue Number
ADP-1047 / ADP-1139