-
Notifications
You must be signed in to change notification settings - Fork 213
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
Add servant post transaction endpoint #111
Conversation
src/Cardano/Wallet/Primitive.hs
Outdated
@@ -221,6 +223,15 @@ newtype Address = Address | |||
|
|||
instance NFData Address | |||
|
|||
data AddressError | |||
= AddressDecodeError T.Text |
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 a record with meaningful field to give better meaning to the underlying Text
(also, the qualified import isn't necessary here).
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.
Removed - this type was moved to different module (by other author) https://github.com/input-output-hk/cardano-wallet/blob/5c7d690e5d994c931e5b437c5bdbaf222f6dc675/src/Cardano/Wallet/Api/Types.hs#L205 .
It is not a record but it also doesn't seem to be used as a sum type in future. Rather it looks like a self containing wrapper type where constructor/type name tells the storry (at least for now). So I think we can forget about this until we run into more complicated use case
049fddd
to
a8d7c7d
Compare
c1f20d6
to
40bbd60
Compare
src/Cardano/Wallet/Api/Types.hs
Outdated
@@ -147,15 +149,10 @@ data WalletPutPassphraseData = WalletPutPassphraseData | |||
} deriving (Eq, Generic, Show) | |||
|
|||
data CreateTransactionData = CreateTransactionData | |||
{ _targets :: ![TargetOutput] | |||
{ _targets :: ![TxOut] |
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.
@KtorZ what do you think about reusing tx output here and a bit bellow how aeson instances are handled
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 have abandoned this idea as it didn't quite suite my needs - I had to wrap fields of TxOut
with ApiT
and it was easier to opt for a separate type.
ps - If number of such types increases, we could use template haskell to generate such types, types - but number of types is low so there is no need for such heavy machinery at this point (and I am not sure what is our opinion about template haskell in general).
For example if we had something like:
deriveApiTFor TxOut
something like this would create type
data TxOut = TxOut
{ address :: ApiT Address
, coin :: ApiT Coin
}
As personally I run only to one such use case so far I didn't want to introduce anything like the solution above - but if there were many such examples we might consider it
cd5868e
to
426d374
Compare
specifications/api/swagger.yaml
Outdated
maxLength: 64 | ||
minLength: 64 | ||
maxLength: 128 | ||
minLength: 128 |
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.
According to the comment https://github.com/input-output-hk/cardano-wallet/blob/5c7d690e5d994c931e5b437c5bdbaf222f6dc675/src/Cardano/Wallet/Binary.hs#L569 , Hash "Tx"
is a 64 byte string, which translates to 128 long hex encoded string (because byte is encoded as 2 char 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.
Hmmm no. The hex-encoded version is 64-byte, the hash itself is 32 bytes. The spec was right here (cf current transaction ids..)
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.
ups - ok. Will fix
src/Cardano/Wallet/Api/Types.hs
Outdated
, depth :: !(Quantity "block" Natural) | ||
, direction :: !(ApiT Direction) | ||
, inputs :: !(NonEmpty ApiCoinSelection) | ||
, outputs :: !(NonEmpty ApiCoinSelection) |
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.
inputs and outputs could be sepparate datatypes here such as TxInputs
and TxOutputs
but I decided to merge datatype into one named ApiCoinSelection
. I am not sure is this a good idea or not. They do represent the same idea but I opt for the simplicity here and dropped the extra type safety that we were getting from having two types at this level
Alternitavely we would create two types ApiTxInputs
and ApiTxOutputs
which would look similar to TxIn
and TxOut
from Primitive module (except they will have wrappers for ApiT
). Simiarly we would use ApiTxOut
in PostTransactionData.targets
.
Also ApiCoinSelection
might be unfortunate name pick as it conflicts with coin selection algorithm that we implemented https://github.com/input-output-hk/cardano-wallet/tree/5c7d690e5d994c931e5b437c5bdbaf222f6dc675/src/Cardano/Wallet/CoinSelection although the context is the same
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.
Agreed that keeping types identical here makes sense (from the API perspective, they are the same thing). About the name clash / confusion, I would go for ApiCoins
or ApiResolvedInputs
to makes it slightly less ambiguous though, it's all more-or-less the same thing.
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.
Something other than ApiCoinSelection
👍
If possible, a short doc-comment about what it is would be awesome too. E.g if you were to go with ApiResolvedInputs
, it might be worth knowing that it's used for outputs
, and not just inputs
of ApiTransaction
ApiCoins
sounds reasonable to me. Or with some tweak like ApiOwnedCoins
to indicate that they contain addresses, which I presume are the previous and current owner.
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.
doc-comment
@Anviking I guess you meant to document this in code because this object name doesn't appear in our swagger produced UI
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.
Ah - yeah
src/Cardano/Wallet/Api/Types.hs
Outdated
@@ -159,6 +177,33 @@ data WalletPutPassphraseData = WalletPutPassphraseData | |||
, newPassphrase :: !(ApiT (Passphrase "encryption")) | |||
} deriving (Eq, Generic, Show) | |||
|
|||
data PostTransactionData = PostTransactionData | |||
{ targets :: !(NonEmpty ApiCoinSelection) |
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.
}, | ||
{ | ||
"passphrase": "7ehYx\\==l5𡄩\"RlwoO6R|k`1~;tVP)&𩺄2?!!?ujj{w]meZ]Ti5{TAu(M;%}_E휊Wao<Ji4AC<~w-&+gHH[fBVj⅝jp↯$e𧶥콁P:\".YOmVAQ7t]PpxEoc5;;/ypb<}e R@@F'H=2Y$ZUH[g𦲧XRH (L&!fCRTV/&wPaqWn54D!5gVⷝ-oshW_l)S/XN贂0<YWjjNM\\fu9", | ||
"targets": [ |
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.
arbitrary generates rather big example here - is this ok or should we aim for a smaller golden file (with only one item in lists/arrays which would probably be ok to validate)?
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.
Na it's okay. We aren't "quickchecking" that but actually, we do want to cover the maximum surface with the golden tests. Bigger is better here.
"quantity": 37, | ||
"unit": "lovelace" | ||
}, | ||
"inputs": [ |
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.
"samples": [ | ||
{ | ||
"passphrase": "AR1Q_'7!S?n}Owo`OrO8^OJKiS\"0COj=(vkE}duI떚pw&$h?[+ l9*bW>⫪Y192RaqVPg>X!y\\Xsd<&^fqL/ji>xwl]dd+7!]\\*_H鏨oP'\\$(^li6vZ=}Zg\\Yz胶}r+M/I1S", | ||
"targets": [ |
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.
arbitrary = Quantity . fromIntegral <$> (arbitrary @Word8) | ||
|
||
instance Arbitrary (Hash "Tx") where | ||
arbitrary = Hash . B8.pack <$> replicateM 64 arbitrary |
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.
huge entropy here - do we want to give less entropy then 64 bytes for constructing Hash "Tx"
in order to trigger collisions?
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 see any particular reason to want collision at this level? Any reason I am missing?
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 particular reason. It would be good to have such collision somewhere in tests. If not now top level then probably later somwhere closer to the core/primitives
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.
Diff of this PR is ~250L , rest is mostly golden files produced by our test spec so don't be intemidated
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.
LGTM.
Let's keep the text decoder aligned and consistent with the others and fix the tx id length in the spec and get it merged A.S.A.P.
specifications/api/swagger.yaml
Outdated
maxLength: 64 | ||
minLength: 64 | ||
maxLength: 128 | ||
minLength: 128 |
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.
Hmmm no. The hex-encoded version is 64-byte, the hash itself is 32 bytes. The spec was right here (cf current transaction ids..)
src/Cardano/Wallet/Api/Types.hs
Outdated
, depth :: !(Quantity "block" Natural) | ||
, direction :: !(ApiT Direction) | ||
, inputs :: !(NonEmpty ApiCoinSelection) | ||
, outputs :: !(NonEmpty ApiCoinSelection) |
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.
Agreed that keeping types identical here makes sense (from the API perspective, they are the same thing). About the name clash / confusion, I would go for ApiCoins
or ApiResolvedInputs
to makes it slightly less ambiguous though, it's all more-or-less the same thing.
src/Cardano/Wallet/Api/Types.hs
Outdated
-- | Converts tx hash to a Base16-encoded string. | ||
encodeApiTxHash :: ApiT (Hash "Tx") -> Text | ||
encodeApiTxHash = | ||
T.decodeUtf8 . convertToBase Base16 . getHash . getApiT |
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's define ToText
and FromText
instances for those in Primitive.Types
👍
}, | ||
{ | ||
"passphrase": "7ehYx\\==l5𡄩\"RlwoO6R|k`1~;tVP)&𩺄2?!!?ujj{w]meZ]Ti5{TAu(M;%}_E휊Wao<Ji4AC<~w-&+gHH[fBVj⅝jp↯$e𧶥콁P:\".YOmVAQ7t]PpxEoc5;;/ypb<}e R@@F'H=2Y$ZUH[g𦲧XRH (L&!fCRTV/&wPaqWn54D!5gVⷝ-oshW_l)S/XN贂0<YWjjNM\\fu9", | ||
"targets": [ |
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.
Na it's okay. We aren't "quickchecking" that but actually, we do want to cover the maximum surface with the golden tests. Bigger is better here.
arbitrary = Quantity . fromIntegral <$> (arbitrary @Word8) | ||
|
||
instance Arbitrary (Hash "Tx") where | ||
arbitrary = Hash . B8.pack <$> replicateM 64 arbitrary |
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 see any particular reason to want collision at this level? Any reason I am missing?
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.
lgtm!
Think calling ApiCoinSelection
something else makes sense
src/Cardano/Wallet/Api/Types.hs
Outdated
, depth :: !(Quantity "block" Natural) | ||
, direction :: !(ApiT Direction) | ||
, inputs :: !(NonEmpty ApiCoinSelection) | ||
, outputs :: !(NonEmpty ApiCoinSelection) |
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.
Something other than ApiCoinSelection
👍
If possible, a short doc-comment about what it is would be awesome too. E.g if you were to go with ApiResolvedInputs
, it might be worth knowing that it's used for outputs
, and not just inputs
of ApiTransaction
ApiCoins
sounds reasonable to me. Or with some tweak like ApiOwnedCoins
to indicate that they contain addresses, which I presume are the previous and current owner.
ca612bf
to
6b2d8b3
Compare
"time": "1864-06-04T01:25:12.205046097466Z", | ||
"block": { | ||
"epoch_number": 11863932, | ||
"slot_number": 6928 |
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 love how we are in 1864 but with epoch 11863932
🤷♂️
"bd1b1817695b42134ff5cc7a023972ca5c3d5c500b235c1a5d0a324f7d3c49284d6a1e51289e5031501f394a283720373c490d414f424d45178c4a27412e763d", | ||
"2c47c30f62146920cc32468168daa03f1b127c6f7140044915de1a25541819047f4444224b5408690b480f056141794b38554c736474133e0083461e12787200", | ||
"160830005e014910157d434c322f60101e5d785400550e094e7a3e668115782060225c234b7b7f5f3c2b4d345c554568416b4d732a2b4461155c3c4a8d05433b" | ||
] |
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.
Those looks surprisingly long. They are 128-char long 🤔 ?
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.
hm - that looks strange because its generated with arbitrary 32 bytes/chars so that should give 64 chars string: https://github.com/input-output-hk/cardano-wallet/blob/dfa7167225ff44477c25333e1613f86e46286f15/test/unit/Cardano/Wallet/Api/TypesSpec.hs#L455 .
> hash <- generate (arbitrary :: Gen (Hash "Tx"))
> hash
Hash {getHash = "\NAKtc@\249X\DELd\DC3(5W\NUL\\]J('\DC2,_@?s\SO<\vq\RS,M\164"}
> encode $ ApiT hash
"\"15746340f9587f6413283557005c5d4a2827122c5f403f730e3c0b711e2c4da4\""
> length "15746340f9587f6413283557005c5d4a2827122c5f403f730e3c0b711e2c4da4"
64
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.
Aha, I see you have fixed it. Sorry forgot to push regenerated golden tests
6b2d8b3
to
dfa7167
Compare
Issue Number
#93
Overview
Comments
Real diff of this PR is ~250L , rest is mostly golden files produced by our test spec so don't be intemidated. Golden files might be too big: #111 (comment) ?