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

Rosetta update for v1.4.4 of spec #5901

Merged
merged 3 commits into from
Sep 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
40 changes: 25 additions & 15 deletions src/app/rosetta/lib/construction.ml
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,12 @@ module Derive = struct
end

module Impl (M : Monad_fail.S) = struct
(* TODO: Don't assume req.metadata is a token_id without checking *)
module Token_id_decode = Amount_of.Token_id.T (M)

let handle ~(env : Env.T(M).t) (req : Construction_derive_request.t) =
let open M.Let_syntax in
(* TODO: Verify curve-type is tweedle *)
let%map pk =
let%bind pk =
let pk_or_error =
try Ok (Rosetta_coding.Coding.to_public_key req.public_key.hex_bytes)
with exn -> Error (Core_kernel.Error.of_exn exn)
Expand All @@ -188,9 +189,14 @@ module Derive = struct
~f:(fun _ -> Errors.create `Malformed_public_key)
pk_or_error
in
{ Construction_derive_response.address=
Public_key.(compress pk |> Compressed.to_base58_check)
; metadata= req.metadata }
let%map token_id = Token_id_decode.decode req.metadata in
{ Construction_derive_response.address= None
; account_identifier=
Some
(User_command_info.account_id
(`Pk Public_key.(compress pk |> Compressed.to_base58_check))
(Option.value ~default:Amount_of.Token_id.default token_id))
; metadata= None }
end

module Real = Impl (Deferred.Result)
Expand Down Expand Up @@ -317,7 +323,8 @@ module Preprocess = struct
(Options.to_json
{ Options.sender= pk
; token_id= partial_user_command.User_command_info.Partial.token
}) }
})
; required_public_keys= [] }
end

module Real = Impl (Deferred.Result)
Expand Down Expand Up @@ -392,11 +399,12 @@ module Payloads = struct
{ Construction_payloads_response.unsigned_transaction=
unsigned_transaction_string
; payloads=
[ { Signing_payload.address=
(let (`Pk pk) =
partial_user_command.User_command_info.Partial.source
in
pk)
[ { Signing_payload.address= None
; account_identifier=
Some
(User_command_info.account_id
partial_user_command.User_command_info.Partial.source
partial_user_command.User_command_info.Partial.token)
; hex_bytes= pk
; signature_type= Some "schnorr_poseidon" } ] }
end
Expand Down Expand Up @@ -479,7 +487,7 @@ module Parse = struct
try M.return (Yojson.Safe.from_string req.transaction)
with _ -> M.fail (Errors.create (`Json_parse None))
in
let%map operations, `Pk signer_pk =
let%map operations, account_identifier_signers =
match req.signed with
| true ->
let%map signed_transaction =
Expand All @@ -491,7 +499,8 @@ module Parse = struct
in
( User_command_info.to_operations ~failure_status:None
signed_transaction.command
, signed_transaction.command.source )
, [ User_command_info.account_id signed_transaction.command.source
signed_transaction.command.token ] )
| false ->
let%map unsigned_transaction =
Transaction.Unsigned.Rendered.of_yojson json
Expand All @@ -502,10 +511,11 @@ module Parse = struct
in
( User_command_info.to_operations ~failure_status:None
unsigned_transaction.command
, unsigned_transaction.command.source )
, [] )
in
{ Construction_parse_response.operations
; signers= [signer_pk]
; signers= []
; account_identifier_signers
; metadata= None }
end

Expand Down
4 changes: 2 additions & 2 deletions src/app/rosetta/lib/network.ml
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ module Options = struct
~network_identifier:network.network_identifier
in
{ Network_options_response.version=
Version.create "1.4.2" (Option.value ~default:"unknown" res#version)
Version.create "1.4.4" (Option.value ~default:"unknown" res#version)
; allow=
{ Allow.operation_statuses= Lazy.force Operation_statuses.all
; operation_types= Lazy.force Operation_types.all
Expand Down Expand Up @@ -468,7 +468,7 @@ module Options = struct
~actual:(Mock.handle ~env dummy_network_request)
~expected:
( Result.return
@@ { Network_options_response.version= Version.create "1.4.2" "v1.0"
@@ { Network_options_response.version= Version.create "1.4.4" "v1.0"
; allow=
{ Allow.operation_statuses= Lazy.force Operation_statuses.all
; operation_types= Lazy.force Operation_types.all
Expand Down
28 changes: 15 additions & 13 deletions src/app/rosetta/test-agent/agent.ml
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,9 @@ let construction_api_transaction_through_mempool ~logger ~rosetta_uri
Offline.Derive.req ~logger ~rosetta_uri ~network_response
~public_key_hex_bytes:keys.public_key_hex_bytes
in
let operations = operations derive_res.address in
let operations =
operations (Option.value_exn derive_res.account_identifier)
in
let%bind preprocess_res =
Offline.Preprocess.req ~logger ~rosetta_uri ~network_response
~max_fee:(Unsigned.UInt64.of_int 100_000_000_000)
Expand Down Expand Up @@ -357,7 +359,7 @@ let construction_api_transaction_through_mempool ~logger ~rosetta_uri
Offline.Combine.req ~logger ~rosetta_uri ~network_response ~signature
~unsigned_transaction:payloads_res.unsigned_transaction
~public_key_hex_bytes:keys.public_key_hex_bytes
~address:derive_res.address
~account_id:(Option.value_exn derive_res.account_identifier)
in
let%bind combine_parse_res =
Offline.Parse.req ~logger ~rosetta_uri ~network_response
Expand Down Expand Up @@ -403,8 +405,8 @@ let construction_api_transaction_through_mempool ~logger ~rosetta_uri

let construction_api_payment_through_mempool =
construction_api_transaction_through_mempool
~operations:(fun address ->
Poke.SendTransaction.payment_operations ~from:address
~operations:(fun account_id ->
Poke.SendTransaction.payment_operations ~from:account_id.address
~fee:(Unsigned.UInt64.of_int 3_000_000_000)
~amount:(Unsigned.UInt64.of_int 10_000_000_000)
~to_:other_pk )
Expand All @@ -431,8 +433,8 @@ let construction_api_payment_through_mempool =

let construction_api_delegation_through_mempool =
construction_api_transaction_through_mempool
~operations:(fun address ->
Poke.SendTransaction.delegation_operations ~from:address
~operations:(fun account_id ->
Poke.SendTransaction.delegation_operations ~from:account_id.address
~fee:(Unsigned.UInt64.of_int 5_000_000_000)
~to_:other_pk )
~operation_expectations:
Expand All @@ -452,8 +454,8 @@ let construction_api_delegation_through_mempool =

let construction_api_create_token_through_mempool =
construction_api_transaction_through_mempool
~operations:(fun address ->
Poke.SendTransaction.create_token_operations ~sender:address
~operations:(fun account_id ->
Poke.SendTransaction.create_token_operations ~sender:account_id.address
~fee:(Unsigned.UInt64.of_int 5_000_000_000) )
~operation_expectations:
Operation_expectation.
Expand All @@ -471,8 +473,8 @@ let construction_api_create_token_through_mempool =

let construction_api_create_token_account_through_mempool =
construction_api_transaction_through_mempool
~operations:(fun address ->
Poke.SendTransaction.create_token_operations ~sender:address
~operations:(fun account_id ->
Poke.SendTransaction.create_token_operations ~sender:account_id.address
~fee:(Unsigned.UInt64.of_int 5_000_000_000) )
~operation_expectations:
Operation_expectation.
Expand All @@ -485,9 +487,9 @@ let construction_api_create_token_account_through_mempool =

let construction_api_mint_tokens_through_mempool =
construction_api_transaction_through_mempool
~operations:(fun address ->
Poke.SendTransaction.mint_tokens_operations ~sender:address
~receiver:address
~operations:(fun account_id ->
Poke.SendTransaction.mint_tokens_operations ~sender:account_id.address
~receiver:account_id.address
~amount:(Unsigned.UInt64.of_int 1_000_000_000)
~fee:(Unsigned.UInt64.of_int 3_000_000_000) )
~operation_expectations:
Expand Down
8 changes: 5 additions & 3 deletions src/app/rosetta/test-agent/offline.ml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ module Payloads = struct
Construction_payloads_request.(
{ network_identifier= net_id network_response
; operations
; metadata= Some metadata }
; metadata= Some metadata
; public_keys= [] }
|> to_yojson)
~path:"construction/payloads"
in
Expand Down Expand Up @@ -83,7 +84,7 @@ module Parse = struct
end

module Combine = struct
let req ~rosetta_uri ~logger ~unsigned_transaction ~signature ~address
let req ~rosetta_uri ~logger ~unsigned_transaction ~signature ~account_id
~public_key_hex_bytes ~network_response =
let%bind r =
post ~rosetta_uri ~logger
Expand All @@ -94,7 +95,8 @@ module Combine = struct
; signatures=
[ (* TODO: How important is it to fill in all these details properly? *)
{ Signature.signing_payload=
{ Signing_payload.address
{ Signing_payload.account_identifier= Some account_id
; address= None
; hex_bytes= "TODO"
; signature_type= None }
; public_key=
Expand Down
5 changes: 4 additions & 1 deletion src/app/rosetta/test-agent/peek.ml
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,10 @@ module Construction = struct
post ~rosetta_uri ~logger
~body:
Construction_metadata_request.(
{network_identifier= net_id network_response; options} |> to_yojson)
{ network_identifier= net_id network_response
; options
; public_keys= [] }
|> to_yojson)
~path:"construction/metadata"
in
Lift.res ~logger res ~of_yojson:Construction_metadata_response.of_yojson
Expand Down
7 changes: 4 additions & 3 deletions src/lib/rosetta_models/construction_derive_response.ml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@
*)

type t =
{ (* Address in network-specific format. *)
address: string
{ (* [DEPRECATED by `account_identifier` in `v1.4.4`] Address in network-specific format. *)
address: string option [@default None]
; account_identifier: Account_identifier.t option [@default None]
; metadata: Yojson.Safe.t option [@default None] }
[@@deriving yojson {strict= false}, show]

(** ConstructionDeriveResponse is returned by the `/construction/derive` endpoint. *)
let create (address : string) : t = {address; metadata= None}
let create () : t = {address= None; account_identifier= None; metadata= None}
9 changes: 5 additions & 4 deletions src/lib/rosetta_models/construction_metadata_request.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@
*
* Generated by: https://openapi-generator.tech
*
* Schema Construction_metadata_request.t : A ConstructionMetadataRequest is utilized to get information required to construct a transaction. The Options object used to specify which metadata to return is left purposely unstructured to allow flexibility for implementers.
* Schema Construction_metadata_request.t : A ConstructionMetadataRequest is utilized to get information required to construct a transaction. The Options object used to specify which metadata to return is left purposely unstructured to allow flexibility for implementers. Optionally, the request can also include an array of PublicKeys associated with the AccountIdentifiers returned in ConstructionPreprocessResponse.
*)

type t =
{ network_identifier: Network_identifier.t
; (* Some blockchains require different metadata for different types of transaction construction (ex: delegation versus a transfer). Instead of requiring a blockchain node to return all possible types of metadata for construction (which may require multiple node fetches), the client can populate an options object to limit the metadata returned to only the subset required. *)
options: Yojson.Safe.t }
options: Yojson.Safe.t
; public_keys: Public_key.t list }
[@@deriving yojson {strict= false}, show]

(** A ConstructionMetadataRequest is utilized to get information required to construct a transaction. The Options object used to specify which metadata to return is left purposely unstructured to allow flexibility for implementers. *)
(** A ConstructionMetadataRequest is utilized to get information required to construct a transaction. The Options object used to specify which metadata to return is left purposely unstructured to allow flexibility for implementers. Optionally, the request can also include an array of PublicKeys associated with the AccountIdentifiers returned in ConstructionPreprocessResponse. *)
let create (network_identifier : Network_identifier.t)
(options : Yojson.Safe.t) : t =
{network_identifier; options}
{network_identifier; options; public_keys= []}
7 changes: 4 additions & 3 deletions src/lib/rosetta_models/construction_parse_response.ml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@

type t =
{ operations: Operation.t list
; (* All signers of a particular transaction. If the transaction is unsigned, it should be empty. *)
; (* [DEPRECATED by `account_identifier_signers` in `v1.4.4`] All signers (addresses) of a particular transaction. If the transaction is unsigned, it should be empty. *)
signers: string list
; account_identifier_signers: Account_identifier.t list
; metadata: Yojson.Safe.t option [@default None] }
[@@deriving yojson {strict= false}, show]

(** ConstructionParseResponse contains an array of operations that occur in a transaction blob. This should match the array of operations provided to `/construction/preprocess` and `/construction/payloads`. *)
let create (operations : Operation.t list) (signers : string list) : t =
{operations; signers; metadata= None}
let create (operations : Operation.t list) : t =
{operations; signers= []; account_identifier_signers= []; metadata= None}
9 changes: 5 additions & 4 deletions src/lib/rosetta_models/construction_payloads_request.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@
*
* Generated by: https://openapi-generator.tech
*
* Schema Construction_payloads_request.t : ConstructionPayloadsRequest is the request to `/construction/payloads`. It contains the network, a slice of operations, and arbitrary metadata that was returned by the call to `/construction/metadata`.
* Schema Construction_payloads_request.t : ConstructionPayloadsRequest is the request to `/construction/payloads`. It contains the network, a slice of operations, and arbitrary metadata that was returned by the call to `/construction/metadata`. Optionally, the request can also include an array of PublicKeys associated with the AccountIdentifiers returned in ConstructionPreprocessResponse.
*)

type t =
{ network_identifier: Network_identifier.t
; operations: Operation.t list
; metadata: Yojson.Safe.t option [@default None] }
; metadata: Yojson.Safe.t option [@default None]
; public_keys: Public_key.t list }
[@@deriving yojson {strict= false}, show]

(** ConstructionPayloadsRequest is the request to `/construction/payloads`. It contains the network, a slice of operations, and arbitrary metadata that was returned by the call to `/construction/metadata`. *)
(** ConstructionPayloadsRequest is the request to `/construction/payloads`. It contains the network, a slice of operations, and arbitrary metadata that was returned by the call to `/construction/metadata`. Optionally, the request can also include an array of PublicKeys associated with the AccountIdentifiers returned in ConstructionPreprocessResponse. *)
let create (network_identifier : Network_identifier.t)
(operations : Operation.t list) : t =
{network_identifier; operations; metadata= None}
{network_identifier; operations; metadata= None; public_keys= []}
9 changes: 5 additions & 4 deletions src/lib/rosetta_models/construction_preprocess_response.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
*
* Generated by: https://openapi-generator.tech
*
* Schema Construction_preprocess_response.t : ConstructionPreprocessResponse contains the request that will be sent directly to `/construction/metadata`. If it is not necessary to make a request to `/construction/metadata`, options should be null.
* Schema Construction_preprocess_response.t : ConstructionPreprocessResponse contains `options` that will be sent unmodified to `/construction/metadata`. If it is not necessary to make a request to `/construction/metadata`, `options` should be omitted. Some blockchains require the PublicKey of particular AccountIdentifiers to construct a valid transaction. To fetch these PublicKeys, populate `required_public_keys` with the AccountIdentifiers associated with the desired PublicKeys. If it is not necessary to retrieve any PublicKeys for construction, `required_public_keys` should be omitted.
*)

type t =
{ (* The options that will be sent directly to `/construction/metadata` by the caller. *)
options: Yojson.Safe.t option [@default None] }
options: Yojson.Safe.t option [@default None]
; required_public_keys: Account_identifier.t list }
[@@deriving yojson {strict= false}, show]

(** ConstructionPreprocessResponse contains the request that will be sent directly to `/construction/metadata`. If it is not necessary to make a request to `/construction/metadata`, options should be null. *)
let create () : t = {options= None}
(** ConstructionPreprocessResponse contains `options` that will be sent unmodified to `/construction/metadata`. If it is not necessary to make a request to `/construction/metadata`, `options` should be omitted. Some blockchains require the PublicKey of particular AccountIdentifiers to construct a valid transaction. To fetch these PublicKeys, populate `required_public_keys` with the AccountIdentifiers associated with the desired PublicKeys. If it is not necessary to retrieve any PublicKeys for construction, `required_public_keys` should be omitted. *)
let create () : t = {options= None; required_public_keys= []}
13 changes: 7 additions & 6 deletions src/lib/rosetta_models/signing_payload.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@
*
* Generated by: https://openapi-generator.tech
*
* Schema Signing_payload.t : SigningPayload is signed by the client with the keypair associated with an address using the specified SignatureType. SignatureType can be optionally populated if there is a restriction on the signature scheme that can be used to sign the payload.
* Schema Signing_payload.t : SigningPayload is signed by the client with the keypair associated with an AccountIdentifier using the specified SignatureType. SignatureType can be optionally populated if there is a restriction on the signature scheme that can be used to sign the payload.
*)

type t =
{ (* The network-specific address of the account that should sign the payload. *)
address: string
{ (* [DEPRECATED by `account_identifier` in `v1.4.4`] The network-specific address of the account that should sign the payload. *)
address: string option [@default None]
; account_identifier: Account_identifier.t option [@default None]
; hex_bytes: string
; signature_type: Enums.signaturetype option [@default None] }
[@@deriving yojson {strict= false}, show]

(** SigningPayload is signed by the client with the keypair associated with an address using the specified SignatureType. SignatureType can be optionally populated if there is a restriction on the signature scheme that can be used to sign the payload. *)
let create (address : string) (hex_bytes : string) : t =
{address; hex_bytes; signature_type= None}
(** SigningPayload is signed by the client with the keypair associated with an AccountIdentifier using the specified SignatureType. SignatureType can be optionally populated if there is a restriction on the signature scheme that can be used to sign the payload. *)
let create (hex_bytes : string) : t =
{address= None; account_identifier= None; hex_bytes; signature_type= None}