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-compatible signer.exe #5863

Merged
merged 17 commits into from
Sep 5, 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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ build_archive: git_hooks reformat-diff

build_rosetta:
$(info Starting Build)
ulimit -s 65532 && (ulimit -n 10240 || true) && dune build src/app/rosetta/rosetta.exe --profile=$(DUNE_PROFILE)
ulimit -s 65532 && (ulimit -n 10240 || true) && dune build src/app/archive/archive.exe src/app/rosetta/rosetta.exe src/app/rosetta/ocaml-signer/signer.exe --profile=$(DUNE_PROFILE)
$(info Build complete)

client_sdk :
Expand Down
9 changes: 8 additions & 1 deletion buildkite/scripts/docker-artifact.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ scripts/release-docker.sh --service "${CODA_SERVICE}" --version "${CODA_VERSION}

if [[ -n $CODA_BUILD_ROSETTA ]]; then
echo "--- Build/Release coda-rosetta to docker hub"
docker pull gcr.io/o1labs-192920/coda-rosetta-build-deps:develop
# Could also cache-from opam-deps but we would need to get that automatically building nightly or at least when src/opam.export changes
# build-deps is updated by manually running scripts/build-rosetta-stages.sh which always builds + pushes each stage
scripts/release-docker.sh --service "coda-rosetta" --version "dev-${CODA_VERSION}"\
--extra-args "--build-arg DUNE_PROFILE=dev --build-arg CODA_BRANCH=${CODA_GIT_BRANCH} --cache-from gcr.io/o1labs-192920/coda-rosetta-build-deps:develop"
# Also build with the standard DUNE_PROFILE, and use the dev profile as a cache.
# This means it will use the opam-deps stage from the previous step, but make a new builder stage because the DUNE_PROFILE arg changed
scripts/release-docker.sh --service "coda-rosetta" --version "${CODA_VERSION}"\
--extra-args "--build-arg DUNE_PROFILE=dev --build-arg CODA_BRANCH=${CODA_GIT_BRANCH}"
--extra-args "--build-arg --build-arg CODA_BRANCH=${CODA_GIT_BRANCH} --cache-from codaprotocol/coda-rosetta:dev-${CODA_VERSION}"
fi
1 change: 1 addition & 0 deletions dockerfiles/Dockerfile-rosetta
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ RUN eval $(opam config env) \
src/app/runtime_genesis_ledger/runtime_genesis_ledger.exe \
src/app/generate_keypair/generate_keypair.exe \
src/app/rosetta/test-agent/agent.exe \
src/app/rosetta/ocaml-signer/signer.exe \
&& _build/default/src/app/runtime_genesis_ledger/runtime_genesis_ledger.exe \
--config-file src/app/rosetta/demo-config.json \
--genesis-dir ${HOME}/demo-genesis \
Expand Down
2 changes: 1 addition & 1 deletion scripts/release-docker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ coda-demo)
;;
coda-rosetta)
DOCKERFILE_PATH="dockerfiles/Dockerfile-rosetta"
mkdir some_empty_dir
mkdir -p some_empty_dir
DOCKER_CONTEXT="./some_empty_dir"
;;
leaderboard)
Expand Down
2 changes: 1 addition & 1 deletion src/app/rosetta/lib/construction.ml
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ module Payloads = struct
in
pk)
; hex_bytes= pk
; signature_type= Some "schnorr" } ] }
; signature_type= Some "schnorr_poseidon" } ] }
end

module Real = Impl (Deferred.Result)
Expand Down
1 change: 1 addition & 0 deletions src/app/rosetta/lib/dune
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
yojson
archive_lib
signature_lib
secrets
unsigned_extended
)
(preprocess (pps
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ module Keys = struct
type t = {keypair: Keypair.t; public_key_hex_bytes: string}

let of_keypair keypair =
{ keypair
; public_key_hex_bytes=
Rosetta_coding.Coding.of_public_key keypair.public_key }
{keypair; public_key_hex_bytes= Coding.of_public_key keypair.public_key}

let to_private_key_bytes t = Coding.of_scalar t.keypair.private_key

let of_private_key_bytes s =
Coding.to_scalar s |> Keypair.of_private_key_exn |> of_keypair

let of_private_key_box secret_box_string =
let json = Yojson.Safe.from_string secret_box_string in
Expand All @@ -26,6 +29,7 @@ module Keys = struct
|> Result.ok |> Option.value_exn
in
let sk = output |> Bigstring.of_bytes |> Private_key.of_bigstring_exn in
(*printf !"Secret key hex bytes is: %s\n" (Coding.of_scalar sk) ;*)
of_keypair (Keypair.of_private_key_exn sk)
end

Expand All @@ -43,8 +47,8 @@ let sign ~(keys : Keys.t) ~unsigned_transaction_string =
in
let user_command_payload =
User_command_info.Partial.to_user_command_payload
~nonce:unsigned_transaction.nonce
unsigned_transaction.Transaction.Unsigned.command
~nonce:unsigned_transaction.Transaction.Unsigned.nonce
unsigned_transaction.command
|> Result.ok |> Option.value_exn
in
let signature =
Expand Down
25 changes: 25 additions & 0 deletions src/app/rosetta/ocaml-signer/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
(executable
(package signer)
(name signer)
(public_name signer)
(modes native)
(libraries
async
async_ssl
core_kernel
logger
rosetta_models
lib
ppx_deriving_yojson.runtime
yojson
)
(preprocess (pps
graphql_ppx
ppx_coda
ppx_deriving.show
ppx_deriving_yojson
ppx_jane
ppx_version
ppx_deriving.eq
))
)
90 changes: 90 additions & 0 deletions src/app/rosetta/ocaml-signer/signer.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
(** An agent that pokes at Coda and peeks at Rosetta to see if things look alright *)

open Core_kernel
open Async
open Rosetta_lib
open Signature_lib
open Lib

let sign_command =
let open Command.Let_syntax in
let%map_open unsigned_transaction =
flag "unsigned-transaction"
~doc:"Unsigned transaction string returned from Rosetta"
(required string)
and private_key =
flag "private-key" ~doc:"Private key hex bytes" (required string)
in
let open Deferred.Let_syntax in
fun () ->
let keys = Signer.Keys.of_private_key_bytes private_key in
match
Signer.sign ~keys ~unsigned_transaction_string:unsigned_transaction
with
| Ok signature ->
printf "%s\n" signature ; return ()
| Error e ->
eprintf "Failed to sign transaction %s" (Errors.show e) ;
exit 1

let verify_command =
let open Command.Let_syntax in
let%map_open signed_transaction =
flag "signed-transaction"
~doc:"Signed transaction string returned from Rosetta" (required string)
and public_key =
flag "public-key" ~doc:"Public key hex bytes" (required string)
in
let open Deferred.Let_syntax in
fun () ->
match
Signer.verify ~public_key_hex_bytes:public_key
~signed_transaction_string:signed_transaction
with
| Ok b when b ->
return ()
| Ok _b (* when not _b *) ->
eprintf "Signature does not verify against this public key" ;
exit 1
| Error e ->
eprintf "Failed to verify signature %s" (Errors.show e) ;
exit 1

let derive_command =
let open Command.Let_syntax in
let%map_open private_key =
flag "private-key" ~doc:"Private key hex bytes" (required string)
in
let open Deferred.Let_syntax in
fun () ->
printf "%s\n"
Signer.Keys.(of_private_key_bytes private_key).public_key_hex_bytes ;
return ()

let generate_command =
let open Deferred.Let_syntax in
Command.Param.return
@@ fun () ->
let keypair = Keypair.create () in
printf "%s\n" Signer.Keys.(of_keypair keypair |> to_private_key_bytes) ;
return ()

let () =
Copy link
Member

Choose a reason for hiding this comment

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

Think you could get away with Core_kernel, rather than Async here; see dump_dhall_types.ml. That one uses Core, because it does things like chdir, but I believe it could otherwise use Core_kernel.

No need to change this PR. I'm standing atop my "minimal dependencies" soapbox, is all.

Command.run
(Command.group
~summary:"OCaml reference signer implementation for Rosetta."
[ ( "sign"
, Command.async ~summary:"Sign an unsigned transaction" sign_command
)
; ( "verify"
, Command.async
~summary:
"Verify the signature of a signed transaction. Exits 0 if the \
signature verifies."
verify_command )
; ( "derive-public-key"
, Command.async ~summary:"Import a private key, returns a public-key"
derive_command )
; ( "generate-private-key"
, Command.async ~summary:"Generate a new private key" generate_command
) ])
5 changes: 5 additions & 0 deletions src/app/rosetta/signer.opam
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
opam-version: "1.2"
version: "0.1"
build: [
["dune" "build" "--only" "src" "--root" "." "-j" jobs "@install"]
]
2 changes: 1 addition & 1 deletion src/app/rosetta/start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ PG_CONN=postgres://$USER:$USER@localhost:5432/archiver

# rebuild
pushd ../../../
PATH=/usr/local/bin:$PATH dune b src/app/runtime_genesis_ledger/runtime_genesis_ledger.exe src/app/cli/src/coda.exe src/app/archive/archive.exe src/app/rosetta/rosetta.exe src/app/rosetta/test-agent/agent.exe
PATH=/usr/local/bin:$PATH dune b src/app/runtime_genesis_ledger/runtime_genesis_ledger.exe src/app/cli/src/coda.exe src/app/archive/archive.exe src/app/rosetta/rosetta.exe src/app/rosetta/test-agent/agent.exe src/app/rosetta/ocaml-signer/signer.exe
popd

# make genesis (synchronously)
Expand Down
1 change: 0 additions & 1 deletion src/app/rosetta/test-agent/dune
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
lib
ppx_deriving_yojson.runtime
yojson
secrets
)
(preprocess (pps
graphql_ppx
Expand Down
2 changes: 1 addition & 1 deletion src/app/rosetta/test-agent/offline.ml
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ module Combine = struct
; public_key=
{ Public_key.hex_bytes= public_key_hex_bytes
; curve_type= "tweedle" }
; signature_type= "schnorr"
; signature_type= "schnorr_poseidon"
; hex_bytes= signature } ] }
|> to_yojson)
~path:"construction/combine"
Expand Down
2 changes: 1 addition & 1 deletion src/lib/rosetta_models/enums.ml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
type curvetype = (* tweedle *) string [@@deriving yojson, show]

type signaturetype = (* schnorr *) string [@@deriving yojson, show]
type signaturetype = (* schnorr_poseidon *) string [@@deriving yojson, show]

type coinaction = () [@@deriving yojson, show, eq]