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

Transaction estimateMaxNumberOfInputs #495

Merged
merged 5 commits into from
Jul 8, 2019

Conversation

rvl
Copy link
Contributor

@rvl rvl commented Jul 2, 2019

Relates to #462

Overview

  • Implementation of estimateMaxNumberOfInputs for jormungandr and http-bridge.

Comments

The estimation formula is the same regardless of backend, just with different variables. But it was a hassle sharing the estimation function between backends.

@rvl rvl self-assigned this Jul 2, 2019
@rvl rvl force-pushed the rvl/462/estimate-max-number-of-inputs branch 2 times, most recently from 9c08891 to 2b2f833 Compare July 3, 2019 08:45
@rvl rvl marked this pull request as ready for review July 3, 2019 08:49
@rvl rvl force-pushed the rvl/462/estimate-max-number-of-inputs branch 2 times, most recently from 38f90db to 65ce9bd Compare July 3, 2019 09:17
lib/jormungandr/src/Cardano/Wallet/Jormungandr/Binary.hs Outdated Show resolved Hide resolved
-- There are no attributes.
, estAddressSample =
let xpub = XPub (BS.replicate 32 0) (ChainCode $ BS.replicate 32 0)
in Address $ toByteString $ encodeAddress xpub mempty
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that the size of the Byron addresses is different between 'Mainnet and 'Testnet. There are actually some attributes for 'Testnet addresses (cf: keyToAddress)

This means that estimateMaxNumberOfInputsParams probably requires a type parameter t. (KeyToAddress t) => in order to correctly compute the size. The difference isn't much but, on many inputs it is significant enough to not be ignored.

This isn't a problem for Jörmungandr since the discrimination happens on a single byte, present in both mainnet and testnet!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I have added the type parameter.

lib/core/src/Cardano/Wallet/Transaction.hs Outdated Show resolved Hide resolved
data EstimateMaxNumberOfInputsParams = EstimateMaxNumberOfInputsParams
{ estMeasureTx :: [TxIn] -> [TxOut] -> [TxWitness] -> Int
-- ^ Finds the size of a serialized transaction.
, estAddressSample :: Address -- ^ Address to use in tx output
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder why not have an Int here too and only deal with an address size like you do for BlockHashSize and TxWitnessSize. In the end, both the bridge and jormungandr creates an improper address filled with null bytes, so passing a size would be less-confusing and more consistent with the rest I think ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would have liked to use a plain estAddressSize :: Int but the Tx serializer wants to deserialize the addresses it is given...

Copy link
Member

@KtorZ KtorZ Jul 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see 🤔 .. This is only in the bridge I guess but that makes sense.
Though, the record parameter is now superfluous since we have access to t. We can construct a valid address for a target network using only a public key, and public keys always have the same size. Hence:

baseAddr = keyToAddress @t <$> (xpub $ chaff 64) 

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes, that simplifies things. Fixed.

lib/core/src/Cardano/Wallet/Transaction.hs Outdated Show resolved Hide resolved
lib/core/test/unit/Cardano/Wallet/TransactionSpecShared.hs Outdated Show resolved Hide resolved
(isIncreasingFunction .&&. estIsSmallerThanSize)
where
isIncreasingFunction = if (ma < mb) then (est qa <= est qb) else (est qa >= est qb)
estIsSmallerThanSize = (est qa <= ma) .&&. (est qb <= mb)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is ... dubious 🤔 We are comparing items that have different dimensions. One is a max size in bytes, the other one a number of inputs. And here, it happens to hold because every part of a transaction is more than one byte, though I am not sure that this buys us really anything 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't think of many more properties. This one doesn't buy much, but it doesn't cost much either. We can't test absolute values, only the relationship between estimates with different inputs. This one is like saying, for all functions f x = x * x, then f x > x holds, or the area of a square is greater than the length of its side, if you are willing to compare different units.

lib/core/src/Cardano/Wallet/Transaction.hs Outdated Show resolved Hide resolved
@rvl rvl force-pushed the rvl/462/estimate-max-number-of-inputs branch from 0d354d5 to 2079d29 Compare July 4, 2019 07:25
@rvl rvl force-pushed the rvl/462/estimate-max-number-of-inputs branch from 2079d29 to a289889 Compare July 5, 2019 01:00
Copy link
Member

@KtorZ KtorZ left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

-> Property
propMaxNumberOfInputsEstimation tl qa@(Quantity ma) qb@(Quantity mb) oa ob =
counterexample debug
(isIncreasingFunction .&&. moreOutputsLessInputs .&&. estIsSmallerThanSize)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, I'd be more in favor of having three properties here instead of a conjunction of assertions. The error reporting from QuickCheck isn't ideal with .&&. (or conjoin), whereas, with separate properties, we immediately know which property is failing.

@KtorZ KtorZ merged commit 00b1567 into master Jul 8, 2019
@KtorZ KtorZ deleted the rvl/462/estimate-max-number-of-inputs branch July 8, 2019 13:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants