Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
34ed2b1
mina-verify-packaged-fork-config checks the hashes against a block fr…
emberian Mar 27, 2024
e1d3aea
runtime_genesis_ledger: output an 'oldhash' for input ledgers
emberian Mar 28, 2024
8bb1efc
verify-packaged-fork-config: use the new oldhash
emberian Mar 28, 2024
16fec5b
ensure packages have required $PATH constituents
emberian Mar 28, 2024
00a025c
gotta do the cooking by the book
emberian Mar 28, 2024
1f1a2b3
whoops
emberian Mar 28, 2024
7914260
Use ledger_depth=20 for old hash
georgeee Apr 1, 2024
cd20af0
Support v1 format for ledger hash generation
georgeee Apr 1, 2024
0664830
Revert "Support v1 format for ledger hash generation"
georgeee Apr 1, 2024
65823f8
Revert "Use ledger_depth=20 for old hash"
georgeee Apr 1, 2024
b2687fb
Revert changes to runtime_genesis_ledger
georgeee Apr 1, 2024
17e02fb
Update script with use of mina-create-legacy-genesis
georgeee Apr 1, 2024
2b7fabe
try this approach
emberian Apr 2, 2024
be5079c
Merge branch 'berkeley' into feat/verify-epoch-ledgers-too
georgeee Apr 2, 2024
e88c7e4
install mina-create-legacy-ledger from #15433
emberian Apr 2, 2024
377f5a7
cleanup extra stuff that happened differently already upstream
emberian Apr 2, 2024
84cf8b1
these are probably aesthetically unnecessary despite helping >1 person
emberian Apr 2, 2024
6441ccb
ok, mina-docker gets that one
emberian Apr 2, 2024
875c00c
typo
emberian Apr 2, 2024
1235243
use correct name in mina-create-legacy-genesis
dkijania Apr 3, 2024
263c7b6
Merge branch 'berkeley' into feat/verify-epoch-ledgers-too
dkijania Apr 3, 2024
2972ab4
Merge branch 'berkeley' into feat/verify-epoch-ledgers-too
georgeee Apr 3, 2024
e344310
Merge remote-tracking branch 'origin/compatible' into feat/verify-epo…
georgeee Apr 3, 2024
3d48ddd
Fix a typo
georgeee Apr 3, 2024
c1f7046
brace expansion only happens outside double quotes
emberian Apr 3, 2024
abc8253
Nits
georgeee Apr 4, 2024
84d4804
Split the jq-based check to two separate checks
georgeee Apr 4, 2024
4622105
Fix expression extracting info from precomputed block
georgeee Apr 4, 2024
45d56b0
Fix for "Assert corrupted packaged artifacts are unverifiable"
georgeee Apr 4, 2024
b733cf9
Silence noise in re-attempting to export staged ledger
georgeee Apr 4, 2024
34064ef
Merge branch 'berkeley' into feat/verify-epoch-ledgers-too
georgeee Apr 4, 2024
5ee02fa
Patch against a bug in 1.4 which is fixed by PR #15462
georgeee Apr 4, 2024
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 buildkite/src/Command/MinaArtifact.dhall
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ let hardforkPipeline : DebianVersions.DebVersion -> Pipeline.Config.Type =
Cmd.runInDocker Cmd.Docker::{
image = "gcr.io/o1labs-192920/mina-daemon:\${BUILDKITE_COMMIT:0:7}-${DebianVersions.lowerName debVersion}-${network}"
, extraEnv = [ "CONFIG_JSON_GZ_URL=\$CONFIG_JSON_GZ_URL", "NETWORK_NAME=\$NETWORK_NAME" ]
} "curl \$CONFIG_JSON_GZ_URL > config.json.gz && gunzip config.json.gz && mina-verify-packaged-fork-config config.json /workdir/verification"
} "curl \$CONFIG_JSON_GZ_URL > config.json.gz && gunzip config.json.gz && mina-verify-packaged-fork-config \$NETWORK_NAME config.json /workdir/verification"
]
, label = "Verify packaged artifacts"
, key = "verify-packaged-artifacts"
Expand Down
2 changes: 1 addition & 1 deletion docs/upgrading-to-berkeley.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ done
A script is installed (from `./scripts/mina-verify-packaged-fork-config`) that automates this process. If you want to verify that an installed Mina package was generated from the same configuration as the one exported earlier, it is as easy as:

```
mina-verify-packaged-fork-config fork_config.json /tmp/mina-verification
mina-verify-packaged-fork-config (mainnet|devnet) fork_config.json /tmp/mina-verification
```

Many of the script inputs are environment variables that default to the locations used by the debs. If you are building from source, inspect the script, determine what you need to change, and then run it.
10 changes: 5 additions & 5 deletions scripts/deb-builder-helpers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,26 @@ source "${SCRIPTPATH}/../buildkite/scripts/export-git-env-vars.sh"
cd "${SCRIPTPATH}/../_build"

# Set dependencies based on debian release
SHARED_DEPS="libssl1.1, libgmp10, libgomp1, tzdata, rocksdb-tools"
SHARED_DEPS="libssl1.1, libgmp10, libgomp1, tzdata, jq, wget, rocksdb-tools"

TEST_EXECUTIVE_DEPS=", mina-logproc, python3, nodejs, yarn, google-cloud-sdk, kubectl, google-cloud-sdk-gke-gcloud-auth-plugin, terraform, helm"

case "${MINA_DEB_CODENAME}" in
bookworm|jammy)
DAEMON_DEPS=", libffi8, libjemalloc2, libpq-dev, libprocps8, mina-logproc"
ARCHIVE_DEPS="libssl1.1, libgomp1, libpq-dev, libjemalloc2"
ARCHIVE_DEPS="libssl1.1, libgomp1, libpq-dev, google-cloud-sdk, libjemalloc2"
;;
bullseye|focal)
DAEMON_DEPS=", libffi7, libjemalloc2, libpq-dev, libprocps8, mina-logproc"
ARCHIVE_DEPS="libssl1.1, libgomp1, libpq-dev, libjemalloc2"
ARCHIVE_DEPS="libssl1.1, libgomp1, libpq-dev, google-cloud-sdk, libjemalloc2"
;;
buster)
DAEMON_DEPS=", libffi6, libjemalloc2, libpq-dev, libprocps7, mina-logproc"
ARCHIVE_DEPS="libssl1.1, libgomp1, libpq-dev, libjemalloc2"
ARCHIVE_DEPS="libssl1.1, libgomp1, libpq-dev, google-cloud-sdk, libjemalloc2"
;;
stretch|bionic)
DAEMON_DEPS=", libffi6, libjemalloc1, libpq-dev, libprocps6, mina-logproc"
ARCHIVE_DEPS="libssl1.1, libgomp1, libpq-dev, libjemalloc1"
ARCHIVE_DEPS="libssl1.1, libgomp1, libpq-dev, google-cloud-sdk, libjemalloc1"
;;
*)
echo "Unknown Debian codename provided: ${MINA_DEB_CODENAME}"; exit 1
Expand Down
39 changes: 33 additions & 6 deletions scripts/mina-verify-packaged-fork-config
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
set -eo pipefail

if [ $# -lt 2 ]; then
echo "Usage: $0 <mainnet-fork-config.json> <working-dir>"
echo "Usage: $0 <network-name> <fork-config.json> <working-dir>"
cat <<EOF
This script is used to validate that an installed package is correct
according to an exported fork_config.json file.
Expand All @@ -21,6 +21,9 @@ Inputs:
- FORKING_FROM_CONFIG_JSON (default: /var/lib/coda/mainnet.json)
the pre-fork genesis ledger
- SECONDS_PER_SLOT (default: 180)
- PRECOMPUTED_FORK_BLOCK (default: fetches with gsutil)
- GSUTIL (default: gsutil)
the Google Cloud Storage utility if the PRECOMPUTED_FORK_BLOCK isn't a file

Ensures:
- The accounts listed in config.json are the ones in the PACKAGED_DAEMON_CONFIG
Expand Down Expand Up @@ -50,6 +53,12 @@ source_build_fallback() {
MINA_EXE=${MINA_EXE:-$(source_build_fallback "$(command -v mina)" ./_build/default/src/app/cli/src/mina.exe)}
MINA_GENESIS_EXE=${MINA_GENESIS_EXE:-$(source_build_fallback "$(command -v mina-create-genesis)" ./_build/default/src/app/runtime_genesis_ledger/runtime_genesis_ledger.exe)}
CREATE_RUNTIME_CONFIG=${CREATE_RUNTIME_CONFIG:-$(source_build_fallback "$(command -v mina-hf-create-runtime-config)" ./scripts/hardfork/create_runtime_config.sh)}
GSUTIL=${GSUTIL:-$(source_build_fallback "$(command -v gsutil)" false)}

if [[ -e "$PRECOMPUTED_FORK_BLOCK" && ! -x "$GSUTIL" ]]; then
echo "Error: gsutil is required when PRECOMPUTED_FORK_BLOCK is nonexistent path"
exit 1
fi

installed_config=$(echo /var/lib/coda/config_*.json)
PACKAGED_DAEMON_CONFIG=${PACKAGED_DAEMON_CONFIG:-$installed_config}
Expand All @@ -67,24 +76,39 @@ export FORKING_FROM_CONFIG_JSON=${FORKING_FROM_CONFIG_JSON:-$(source_build_fallb

export MINA_LIBP2P_PASS=''

workdir=$2
workdir=$3
mkdir -p "$workdir"
mkdir -p "$workdir/ledgers"
mkdir -p "$workdir/ledgers-backup"
mkdir -p "$workdir/keys"
Copy link
Member

Choose a reason for hiding this comment

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

Why not write above commands in one line?

mkdir -p "$workdir"/{ledgers,ledgers-backup,keys}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

when there was only one .... the thought had yet to occur to me that there would be three.

chmod 700 "$workdir/keys"

fork_block_state_hash=$(jq -r '.proof.fork.state_hash' "$2")
fork_block_length=$(jq -r '.proof.fork.blockchain_length' "$2")

# Put the fork block where we want it, fetch it from gcloud if necessary
if [ ! -e "$PRECOMPUTED_FORK_BLOCK" ]; then
if [ "$PRECOMPUTED_FORK_BLOCK" = "" ]; then
"$GSUTIL" cp "gs://mina_network_block_data/$1-$fork_block_length-$fork_block_state_hash.json" "$workdir/precomputed_fork_block.json"
else
"$GSUTIL" cp "$PRECOMPUTED_FORK_BLOCK" "$workdir/precomputed_fork_block.json"
fi
else
cp "$PRECOMPUTED_FORK_BLOCK" "$workdir/precomputed_fork_block.json"
fi


if [ ! -e "$workdir/keys/p2p" ]; then
"$MINA_EXE" libp2p generate-keypair --privkey-path "$workdir/keys/p2p"
fi

echo "generating genesis ledgers ... (this may take a while)" >&2

cp "$1" "$workdir/config.json"
cp "$2" "$workdir/config.json"
sed -i -e 's/"set_verification_key": "signature"/"set_verification_key": {"auth": "signature", "txn_version": "2"}/' "$workdir/config.json"
"$MINA_GENESIS_EXE" --config-file "$workdir/config.json" --genesis-dir "$workdir/ledgers" --hash-output-file "$workdir/hashes.json"

FORK_CONFIG_JSON="$1" \
FORK_CONFIG_JSON="$2" \
LEDGER_HASHES_JSON="$workdir/hashes.json" \
GENESIS_TIMESTAMP=$(jq -r '.genesis.genesis_state_timestamp' "$PACKAGED_DAEMON_CONFIG") \
"$CREATE_RUNTIME_CONFIG" > "$workdir/config-substituted.json"
Expand Down Expand Up @@ -120,10 +144,13 @@ mv -t /var/lib/coda "$workdir/ledgers-backup"/*
echo "Performing final comparisons..." >&2
error=0

result=$(jq --slurpfile a "$workdir/config-substituted.json" --slurpfile b "$PACKAGED_DAEMON_CONFIG" -n '
result=$(jq --slurpfile block "$workdir/precomputed_fork_block.json" --slurpfile hashes "$workdir/hashes.json" --slurpfile a "$workdir/config-substituted.json" --slurpfile b "$PACKAGED_DAEMON_CONFIG" -n '
($a[0].epoch_data.staking.hash == $b[0].epoch_data.staking.hash and
$a[0].epoch_data.next.hash == $b[0].epoch_data.next.hash and
$a[0].ledger.hash == $b[0].ledger.hash)')
$hashes[0].epoch_data.staking.old_hash == $block[0].protocol_state.body.consensus_state.staking_epoch_data.ledger.hash and
$hashes[0].epoch_data.next.old_hash == $block[0].protocol_state.body.consensus_state.next_epoch_data.ledger.hash and
$a[0].ledger.hash == $b[0].ledger.hash and
$hashes[0].ledger.old_hash == $block[0].protocol_state.body.consensus_state.blockchain_state.ledger_hash)')

if [ "$result" != "true" ]; then
echo "Packaged config hashes in $PACKAGED_DAEMON_CONFIG not expected compared to $workdir/config-substituted.json" >&2
Expand Down
70 changes: 48 additions & 22 deletions src/app/runtime_genesis_ledger/runtime_genesis_ledger.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,22 @@ open Core
open Async
module Ledger = Mina_ledger.Ledger

let extract_ledgers (config : Runtime_config.t) =
let ledger = Option.value_exn ~message:"No ledger provided" config.ledger in
let staking_ledger =
let%map.Option { staking; _ } = config.epoch_data in
staking.ledger
in
let next_ledger =
let%bind.Option { next; _ } = config.epoch_data in
let%map.Option { ledger; _ } = next in
ledger
in
(ledger, staking_ledger, next_ledger)

module Hashes = struct
type t = { s3_data_hash : string; hash : string } [@@deriving to_yojson]
type t = { s3_data_hash : string; hash : string; old_hash : string }
[@@deriving to_yojson]
end

module Hash_json = struct
Expand All @@ -19,44 +33,64 @@ let ledger_depth =

let logger = Logger.create ()

let hash_root ledger =
Mina_base.Ledger_hash.to_base58_check @@ Mina_ledger.Ledger.merkle_root ledger

let migrating_from_version =
Protocol_version.transaction
(Protocol_version.create ~transaction:2 ~network:0 ~patch:0)
|> Mina_numbers.Txn_version.of_int

let migrating_from_ledger_depth = 20

let load_ledger (accounts : Runtime_config.Accounts.t) =
let accounts =
List.map accounts ~f:(fun account ->
(None, Runtime_config.Accounts.Single.to_account account) )
in
let accounts_altered =
Genesis_ledger_helper.Ledger.patch_accounts' ~version:migrating_from_version
accounts
|> List.map ~f:(fun (k, acc) -> (k, acc))
in
let packed =
Genesis_ledger_helper.Ledger.packed_genesis_ledger_of_accounts
~depth:ledger_depth
(lazy accounts)
in
Lazy.force (Genesis_ledger.Packed.t packed)
let packed_patched =
Genesis_ledger_helper.Ledger.packed_genesis_ledger_of_accounts
~depth:migrating_from_ledger_depth
~omit_set_verification_key_tx_version:true
(lazy accounts_altered)
in
( Lazy.force (Genesis_ledger.Packed.t packed)
, hash_root @@ Lazy.force (Genesis_ledger.Packed.t packed_patched) )

let generate_ledger_tarball ~genesis_dir ~ledger_name_prefix ledger =
let generate_ledger_tarball ~genesis_dir ~ledger_name_prefix ~old_hash ledger =
let%bind tar_path =
Deferred.Or_error.ok_exn
@@ Genesis_ledger_helper.Ledger.generate_tar ~genesis_dir ~logger
~ledger_name_prefix ledger
in
[%log info] "Generated ledger tar at %s" tar_path ;
let hash =
Mina_base.Ledger_hash.to_base58_check
@@ Mina_ledger.Ledger.merkle_root ledger
in
let hash = hash_root ledger in
let%map s3_data_hash = Genesis_ledger_helper.sha3_hash tar_path in
{ Hashes.s3_data_hash; hash }
{ Hashes.s3_data_hash; hash; old_hash }

let generate_hash_json ~genesis_dir ledger staking_ledger next_ledger =
let generate_hash_json ~genesis_dir (ledger, old_root)
(staking_ledger, old_staking) (next_ledger, old_next) =
let%bind ledger_hashes =
generate_ledger_tarball ~ledger_name_prefix:"genesis_ledger" ~genesis_dir
ledger
~old_hash:old_root ledger
in
let%bind staking =
generate_ledger_tarball ~ledger_name_prefix:"epoch_ledger" ~genesis_dir
staking_ledger
~old_hash:old_staking staking_ledger
in
let%map next =
generate_ledger_tarball ~ledger_name_prefix:"epoch_ledger" ~genesis_dir
next_ledger
~old_hash:old_next next_ledger
in
{ Hash_json.ledger = ledger_hashes; epoch_data = { staking; next } }

Expand Down Expand Up @@ -86,6 +120,7 @@ let extract_accounts_exn = function
| { Runtime_config.Ledger.base = Accounts accounts
; balances = []
; add_genesis_winner = None
; _
} ->
accounts
| _ ->
Expand All @@ -102,21 +137,12 @@ let load_config_exn config_file =
Failure ("Could not parse configuration: " ^ err) )
|> Result.ok_exn
in
let ledger, staking_ledger, next_ledger = extract_ledgers config in
if
Option.(
is_some config.daemon || is_some config.genesis
|| Option.value_map ~default:false ~f:is_dirty_proof config.proof)
then failwith "Runtime config has unexpected fields" ;
let ledger = Option.value_exn ~message:"No ledger provided" config.ledger in
let staking_ledger =
let%map.Option { staking; _ } = config.epoch_data in
staking.ledger
in
let next_ledger =
let%bind.Option { next; _ } = config.epoch_data in
let%map.Option { ledger; _ } = next in
ledger
in
( extract_accounts_exn ledger
, Option.map ~f:extract_accounts_exn staking_ledger
, Option.map ~f:extract_accounts_exn next_ledger )
Expand Down
5 changes: 4 additions & 1 deletion src/lib/genesis_ledger/genesis_ledger.ml
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ module Make (Inputs : Intf.Ledger_input_intf) : Intf.S = struct
|> List.mapi ~f:(fun i (_, acct) ->
(Ledger.Addr.of_int_exn ~ledger_depth i, acct) )
in
Ledger.set_batch_accounts ledger addrs_and_accounts ) ;
Ledger.set_batch_accounts ~omit_set_verification_key_tx_version ledger
addrs_and_accounts ) ;
ledger

include Utils
Expand Down Expand Up @@ -274,6 +275,8 @@ module Unit_test_ledger = Make (struct
let directory = `Ephemeral

let depth = Genesis_constants.Constraint_constants.for_unit_tests.ledger_depth

let omit_set_verification_key_tx_version = false
end)

let for_unit_tests : Packed.t = (module Unit_test_ledger)
Expand Down
2 changes: 2 additions & 0 deletions src/lib/genesis_ledger/intf.ml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ module type Ledger_input_intf = sig
val directory : [ `Ephemeral | `New | `Path of string ]

val depth : int

val omit_set_verification_key_tx_version : bool
end

module type S = sig
Expand Down
53 changes: 29 additions & 24 deletions src/lib/genesis_ledger_helper/genesis_ledger_helper.ml
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@ module Ledger = struct
let directory = `Path dirname

let depth = constraint_constants.ledger_depth

let omit_set_verification_key_tx_version = false
end) )
| None ->
( module Genesis_ledger.Of_ledger (struct
Expand Down Expand Up @@ -329,30 +331,23 @@ module Ledger = struct
let%map () = Tar.create ~root:dirname ~file:tar_path ~directory:"." () in
tar_path

let patch_account ~version account =
Mina_base.Account.Poly.
{ account with
permissions =
Mina_base.Permissions.Poly.
{ account.permissions with
set_verification_key =
(fst account.permissions.set_verification_key, version)
}
}

let patch_accounts' ~version =
List.map ~f:(fun (key, account) -> (key, patch_account ~version account))

let padded_accounts_from_runtime_config_opt ~logger ~proof_level
~ledger_name_prefix ?overwrite_version (config : Runtime_config.Ledger.t)
=
let patch_accounts_version accounts_with_keys =
match overwrite_version with
| Some version ->
List.map accounts_with_keys ~f:(fun (key, account) ->
let patched_account =
Mina_base.Account.Poly.
{ account with
permissions =
Mina_base.Permissions.Poly.
{ account.permissions with
set_verification_key =
( fst account.permissions.set_verification_key
, version )
}
}
in
(key, patched_account) )
| None ->
accounts_with_keys
in

let add_genesis_winner_account accounts =
(* We allow configurations to explicitly override adding the genesis
winner, so that we can guarantee a certain ledger layout for
Expand Down Expand Up @@ -391,8 +386,14 @@ module Ledger = struct
| Accounts accounts ->
Some
( lazy
(patch_accounts_version
(add_genesis_winner_account (Accounts.to_full accounts)) ) )
(let accts =
add_genesis_winner_account (Accounts.to_full accounts)
in
match overwrite_version with
| Some version ->
patch_accounts' ~version accts
| None ->
accts ) )
| Named name -> (
match Genesis_ledger.fetch_ledger name with
| Some (module M) ->
Expand Down Expand Up @@ -422,14 +423,18 @@ module Ledger = struct
(Lazy.map
~f:(Accounts.pad_to (Option.value ~default:0 config.num_accounts)) )

let packed_genesis_ledger_of_accounts ~depth accounts :
let packed_genesis_ledger_of_accounts
?(omit_set_verification_key_tx_version = false) ~depth accounts :
Genesis_ledger.Packed.t =
( module Genesis_ledger.Make (struct
let accounts = accounts

let directory = `New

let depth = depth

let omit_set_verification_key_tx_version =
omit_set_verification_key_tx_version
end) )

let load ~proof_level ~genesis_dir ~logger ~constraint_constants
Expand Down
Loading