1. 引言
前序博客有:
Mina中的user_command交易目前有:
- 1)Signed_command交易:
- 1.1)Payment交易
- 1.2)Stake_delegation交易
- 2)Parties交易
2. Parties交易结构
Parties.Stable.V1.t结构为:
type t =
{ fee_payer : Party.Fee_payer.Stable.V1.t
; other_parties :
( Party.Stable.V1.t
, Digest.Party.Stable.V1.t
, Digest.Forest.Stable.V1.t )
Call_forest.Stable.V1.t
; memo : Signed_command_memo.Stable.V1.t (* 为string *)
}
其中:
- 1)fee_payer字段,Party.Fee_payer.Stable.V1.t结构为:
type t =
{ body : Body.Fee_payer.Stable.V1.t
; authorization : Signature.Stable.V1.t (* 为Schnorr签名:Field.t * Inner_curve.Scalar.t *)
}
- 1.1)fee_payer.body字段,Body.Fee_payer.Stable.V1.t结构为:
(* 《1》 body字段,Body.Fee_payer.Stable.V1.t结构为: *)
type t =
{ public_key : Public_key.Compressed.Stable.V1.t (* 压缩公钥 *)
; update : Update.Stable.V1.t (* 包含app_state、delegate、verification_key、permissions、zkapp_uri、token_symbol、timing、voting_for这8个字段。 *)
; fee : Fee.Stable.V1.t (* 为Unsigned.UInt64.t *)
; events : Events'.Stable.V1.t (* 为Pickles.Backend.Tick.Field.Stable.V1.t array list *)
; sequence_events : Events'.Stable.V1.t (* 为Pickles.Backend.Tick.Field.Stable.V1.t array list *)
; protocol_state_precondition :
Zkapp_precondition.Protocol_state.Stable.V1.t (* 包含snarked_ledger_hash、timestamp、blockchain_length、min_window_density、last_vrf_output、total_currency、global_slot_since_hard_fork、global_slot_since_genesis、staking_epoch_data和next_epoch_data这10个字段。 *)
[@name "networkPrecondition"]
; nonce : Account_nonce.Stable.V1.t (* 为Unsigned_extended.UInt32.t *)
}
(* 《1.1》 body.update字段,Update.Stable.V1.t结构为: *)
type t =
{ app_state :
F.Stable.V1.t Set_or_keep.Stable.V1.t Zkapp_state.V.Stable.V1.t (* 为8 fields(Set或Keep类型) of 32 bytes each of arbitrary storage *)
; delegate : Public_key.Compressed.Stable.V1.t Set_or_keep.Stable.V1.t (* 为Set或Keep类型的压缩公钥 *)
; verification_key :
( Pickles.Side_loaded.Verification_key.Stable.V2.t
, F.Stable.V1.t )
With_hash.Stable.V1.t
Set_or_keep.Stable.V1.t (* 为Set或Keep类型,可包含data(包含max_width、wrap_index和wrap_vk三个字段)和hash两个字段。 *)
; permissions : Permissions.Stable.V2.t Set_or_keep.Stable.V1.t (* 为Set或Keep类型,包含edit_state、send、receive、set_delegate、set_permissions、set_verification_key、set_zkapp_uri、edit_sequence_state、set_token_symbol、increment_nonce、set_voting_for共11个字段,均为Auth_required枚举类型:None | Either | Proof | Signature | Impossible。 *)
; zkapp_uri : string Set_or_keep.Stable.V1.t (* 为Set或Keep类型,string *)
; token_symbol :
Account.Token_symbol.Stable.V1.t Set_or_keep.Stable.V1.t (* 为Set或Keep类型,string *)
; timing : Timing_info.Stable.V1.t Set_or_keep.Stable.V1.t (* 为Set或Keep类型,包含:initial_minimum_balance(为Unsigned.UInt64.t类型)、cliff_time(为global_slot,Unsigned_extended.UInt32.t类型)、cliff_amount(为Unsigned.UInt64.t类型)、vesting_period(为global_slot,Unsigned_extended.UInt32.t类型)、vesting_increment(为Unsigned.UInt64.t类型)这5个字段。
; voting_for : State_hash.Stable.V1.t Set_or_keep.Stable.V1.t (* 为Set或Keep类型,Field.t哈希值。 *)
}
(* 《1.1.1》body.update.verification_key字段,为With_hash.Stable.V1.t Set_or_keep.Stable.V1.t,其中With_hash.Stable.V1.t结构为: *)
type ('a, 'h) t = { data : 'a; hash : 'h } (* hash字段为F.t结构 *)
(* 其中data字段,为 Side_loaded_verification_key.Stable.V2.t结构为:*)
type t =
( G.Stable.V1.t (* 为曲线上的point。 *)
, unit )
Pickles_base.Side_loaded_verification_key.Poly.Stable.V2.t
type ('g, 'vk) t = (* 其中‘vk为 uint。 *)
{ max_width : Width.Stable.V1.t (* 对应为char类型 *)
; wrap_index : 'g Plonk_verification_key_evals.Stable.V2.t (* 包含sigma_comm/coefficients_comm/generic_comm/psm_comm/complete_add_comm/mul_comm/emul_comm/endomul_scalar_comm这8个字段。 *)
; wrap_vk : 'vk option (* 其中‘vk为 uint。 *)
}
(* wrap_index字段,为Plonk_verification_key_evals.Stable.V2.t结构: *)
type 'comm t = (* 'comm对应为 G.Stable.V1.t结构 *)
{ sigma_comm : 'comm Plonk_types.Permuts_vec.Stable.V1.t
; coefficients_comm : 'comm Plonk_types.Columns_vec.Stable.V1.t
; generic_comm : 'comm
; psm_comm : 'comm
; complete_add_comm : 'comm
; mul_comm : 'comm
; emul_comm : 'comm
; endomul_scalar_comm : 'comm
}
(* 《1.1.2》body.update.permissions字段,为 Permissions.Stable.V2.t Set_or_keep.Stable.V1.t结构,其中Permissions.Stable.V2.t 结构为: *)
type t = Auth_required.Stable.V2.t Poly.Stable.V2.t
type 'controller t = (* 此处 'controller 为 Auth_required为枚举类型:None | Either | Proof | Signature | Impossible *)
{ edit_state : 'controller
; send : 'controller
; receive : 'controller (* TODO: Consider having fee *)
; set_delegate : 'controller
; set_permissions : 'controller
; set_verification_key : 'controller
; set_zkapp_uri : 'controller
; edit_sequence_state : 'controller
; set_token_symbol : 'controller
; increment_nonce : 'controller
; set_voting_for : 'controller
}
(* 《1.2》 body.protocol_state_precondition,为Zkapp_precondition.Protocol_state.Stable.V1.t结构: *)
type t =
( Frozen_ledger_hash.Stable.V1.t Hash.Stable.V1.t (* 哈希值,为Check of Field 或 Ignore类型。 *)
, Block_time.Stable.V1.t Numeric.Stable.V1.t (* 为Check或Ignore类型,包含lower和upper字段,均为Unsigned.UInt64.t类型 *)
, Length.Stable.V1.t Numeric.Stable.V1.t (* 为Check或Ignore类型,包含lower和upper字段,均为Unsigned_extended.UInt32.t类型 *)
, unit (* TODO *)
, Global_slot.Stable.V1.t Numeric.Stable.V1.t (* 为Check或Ignore类型,包含lower和upper字段,均为Unsigned_extended.UInt32.t类型 *)
, Currency.Amount.Stable.V1.t Numeric.Stable.V1.t (* 为Check或Ignore类型,包含lower和upper字段,均为Unsigned.UInt64.t类型 *)
, Epoch_data.Stable.V1.t ) (* 包含ledger、seed、start_checkpoint、lock_checkpoint、epoch_length这5个字段。 *)
Poly.Stable.V1.t
type ( 'snarked_ledger_hash (* 哈希值,为Check of Field 或 Ignore类型。 *)
, 'time (* 为Check或Ignore类型,包含lower和upper字段,均为Unsigned.UInt64.t类型 *)
, 'length (* 为Check或Ignore类型,包含lower和upper字段,均为Unsigned_extended.UInt32.t类型 *)
, 'vrf_output (* 为unit *)
, 'global_slot (* 为Check或Ignore类型,包含lower和upper字段,均为Unsigned_extended.UInt32.t类型 *)
, 'amount (* 为Check或Ignore类型,包含lower和upper字段,均为Unsigned.UInt64.t类型 *)
, 'epoch_data ) (* 包含ledger、seed、start_checkpoint、lock_checkpoint、epoch_length这5个字段。 *)
t =
{ (* TODO:
We should include staged ledger hash again! It only changes once per
block. *)
snarked_ledger_hash : 'snarked_ledger_hash (* 哈希值,为Check of Field 或 Ignore类型。 *)
; timestamp : 'time (* 为Check或Ignore类型,包含lower和upper字段,均为Unsigned.UInt64.t类型 *)
; blockchain_length : 'length (* 为Check或Ignore类型,包含lower和upper字段,均为Unsigned_extended.UInt32.t类型 *)
(* TODO: This previously had epoch_count but I removed it as I believe it is redundant
with global_slot_since_hard_fork.
epoch_count in [a, b]
should be equivalent to
global_slot_since_hard_fork in [slots_per_epoch * a, slots_per_epoch * b]
*)
; min_window_density : 'length (* 为Check或Ignore类型,包含lower和upper字段,均为Unsigned_extended.UInt32.t类型 *)
; last_vrf_output : 'vrf_output [@skip] (* 为unit *)
; total_currency : 'amount (* 为Check或Ignore类型,包含lower和upper字段,均为Unsigned.UInt64.t类型 *)
; global_slot_since_hard_fork : 'global_slot (* 为Check或Ignore类型,包含lower和upper字段,均为Unsigned_extended.UInt32.t类型 *)
; global_slot_since_genesis : 'global_slot (* 为Check或Ignore类型,包含lower和upper字段,均为Unsigned_extended.UInt32.t类型 *)
; staking_epoch_data : 'epoch_data (* 包含ledger、seed、start_checkpoint、lock_checkpoint、epoch_length这5个字段。 *)
; next_epoch_data : 'epoch_data (* 包含ledger、seed、start_checkpoint、lock_checkpoint、epoch_length这5个字段。 *)
}
(* 《1.2.1》 staking_epoch_data和next_epoch_data字段,为Epoch_data.Stable.V1.t结构: *)
type t =
( ( Frozen_ledger_hash.Stable.V1.t Hash.Stable.V1.t
, Currency.Amount.Stable.V1.t Numeric.Stable.V1.t ) (* 为Check或Ignore类型,为二元结构,分别为Field.t哈希值 和 包含lower和upper字段(均为Unsigned.UInt64.t类型)的Currency.Amount *)
Epoch_ledger.Poly.Stable.V1.t (* 为Check或Ignore类型,为Snark_params.Tick.Field.t *)
, Epoch_seed.Stable.V1.t Hash.Stable.V1.t (* 为Check或Ignore类型,为Snark_params.Tick.Field.t *)
, State_hash.Stable.V1.t Hash.Stable.V1.t (* 为Check或Ignore类型,为Field.t *)
, State_hash.Stable.V1.t Hash.Stable.V1.t (* 为Check或Ignore类型,为Field.t *)
, Length.Stable.V1.t Numeric.Stable.V1.t ) (* 为Check或Ignore类型,包含lower和upper字段,均为Unsigned_extended.UInt32.t类型 *)
Poly.Stable.V1.t
type ( 'epoch_ledger (* 为Check或Ignore类型,为Snark_params.Tick.Field.t *)
, 'epoch_seed (* 为Check或Ignore类型,为Snark_params.Tick.Field.t *)
, 'start_checkpoint (* 为Check或Ignore类型,为Field.t *)
, 'lock_checkpoint (* 为Check或Ignore类型,为Field.t *)
, 'length ) (* 为Check或Ignore类型,包含lower和upper字段,均为Unsigned_extended.UInt32.t类型 *)
t =
{ ledger : 'epoch_ledger (* 为Check或Ignore类型,为Snark_params.Tick.Field.t *)
; seed : 'epoch_seed (* 为Check或Ignore类型,为Snark_params.Tick.Field.t *)
; start_checkpoint : 'start_checkpoint (* 为Check或Ignore类型,为Field.t *)
(* The lock checkpoint is the hash of the latest state in the seed update range, not including
the current state. *)
; lock_checkpoint : 'lock_checkpoint (* 为Check或Ignore类型,为Field.t *)
; epoch_length : 'length (* 为Check或Ignore类型,包含lower和upper字段,均为Unsigned_extended.UInt32.t类型 *)
}
- 2)other_parties字段,Call_forest.Stable.V1.t结构为:
other_parties :
( Party.Stable.V1.t (* 包含body和authorization两个字段 *)
, Digest.Party.Stable.V1.t (* 为Kimchi_backend.Pasta.Basic.Fp.Stable.V1.t *)
, Digest.Forest.Stable.V1.t ) (* 为Kimchi_backend.Pasta.Basic.Fp.Stable.V1.t *)
Call_forest.Stable.V1.t
其中other_parties字段为树list结构(即forest):type ('party, 'party_digest, 'digest) t =
( ('party, 'party_digest, 'digest) Tree.Stable.V1.t
, 'digest )
With_stack_hash.Stable.V1.t (* 包含elt(为树结构) 和 stack_hash(为Digest.Forest结构)*)
list
其中的 Tree.Stable.V1.t结构为: type ('party, 'party_digest, 'digest) t =
{ party : 'party
; party_digest : 'party_digest
; calls :
( ('party, 'party_digest, 'digest) t (* 包含elt(为树结构) 和 stack_hash(为Digest.Forest结构)*)
, 'digest )
With_stack_hash.Stable.V1.t
list
}
其中Party.Stable.V1.t结构为(A party to a zkApp transaction):(** A party to a zkApp transaction *)
type t = { body : Body.Stable.V1.t; authorization : Control.Stable.V2.t }
(* 《1》authorization 字段,Control.Stable.V2.t结构为: *)
type t =
| Proof of Pickles.Side_loaded.Proof.Stable.V2.t
| Signature of Signature.Stable.V1.t (* Mina的Schnorr签名 *)
| None_given
(* Proof枚举类型时,【本质为Wrap proof(Base.Wrap.t结构)】Pickles.Side_loaded.Proof.Stable.V2.t结构为: *)
type t =
(Verification_key.Max_width.n, Verification_key.Max_width.n) Proof.t
type t =
( ( Tock.Inner_curve.Affine.Stable.V1.t
, Reduced_me_only.Wrap.Challenges_vector.Stable.V2.t
Side_loaded_verification_key.Width.Max_vector.Stable.V1.t )
Types.Wrap.Proof_state.Me_only.Stable.V1.t
, ( unit
, Tock.Curve.Affine.t
Side_loaded_verification_key.Width.Max_at_most.Stable.V1.t
, Limb_vector.Constant.Hex64.Stable.V1.t Vector.Vector_2.Stable.V1.t
Scalar_challenge.Stable.V2.t
Bulletproof_challenge.Stable.V1.t
Step_bp_vec.Stable.V1.t
Side_loaded_verification_key.Width.Max_at_most.Stable.V1.t )
Base.Me_only.Step.Stable.V1.t )
Base.Wrap.Stable.V2.t
type ('dlog_me_only, 'step_me_only) t =
{ statement :
( Limb_vector.Constant.Hex64.Stable.V1.t
Vector.Vector_2.Stable.V1.t
, Limb_vector.Constant.Hex64.Stable.V1.t
Vector.Vector_2.Stable.V1.t
Scalar_challenge.Stable.V2.t
, Tick.Field.Stable.V1.t Shifted_value.Type1.Stable.V1.t
, Tock.Field.Stable.V1.t
, 'dlog_me_only
, Digest.Constant.Stable.V1.t
, 'step_me_only
, Limb_vector.Constant.Hex64.Stable.V1.t
Vector.Vector_2.Stable.V1.t
Scalar_challenge.Stable.V2.t
Bulletproof_challenge.Stable.V1.t
Step_bp_vec.Stable.V1.t
, Branch_data.Stable.V1.t )
Types.Wrap.Statement.Minimal.Stable.V1.t
; prev_evals :
( Tick.Field.Stable.V1.t
, Tick.Field.Stable.V1.t array )
Plonk_types.All_evals.Stable.V1.t
; proof : Tock.Proof.Stable.V2.t
}
(* 《2》body字段,Body.Stable.V1.t结构为: *)
type t =
{ public_key : Public_key.Compressed.Stable.V1.t (* 压缩公钥 *)
; token_id : Token_id.Stable.V1.t (* 为:Pickles.Backend.Tick.Field.Stable.V1.t结构 *)
; update : Update.Stable.V1.t (* 见上面,同fee_payer.body.update字段,包含app_state、delegate、verification_key、permissions、zkapp_uri、token_symbol、timing、voting_for这8个字段。 *)
; balance_change :
(Amount.Stable.V1.t, Sgn.Stable.V1.t) Signed_poly.Stable.V1.t (* 包含magnitude(为Unsigned.UInt64.t)和sgn(为Pos或Neg枚举类型)两个字段 *)
; increment_nonce : bool
; events : Events'.Stable.V1.t (* 为Pickles.Backend.Tick.Field.Stable.V1.t array list *)
; sequence_events : Events'.Stable.V1.t (* 为Pickles.Backend.Tick.Field.Stable.V1.t array list *)
; call_data : Pickles.Backend.Tick.Field.Stable.V1.t
; preconditions : Preconditions.Stable.V1.t (* 包含network和account这2个字段。 *)
; use_full_commitment : bool
; caller : Token_id.Stable.V1.t (* 为:Pickles.Backend.Tick.Field.Stable.V1.t结构 *)
}
(* preconditions 字段,Preconditions.Stable.V1.t结构为: *)
type t =
{ network : Zkapp_precondition.Protocol_state.Stable.V1.t (* 同fee_payer.body.protocol_state_precondition字段,包含snarked_ledger_hash、timestamp、blockchain_length、min_window_density、last_vrf_output、total_currency、global_slot_since_hard_fork、global_slot_since_genesis、staking_epoch_data和next_epoch_data这10个字段。 *)
; account : Account_precondition.Stable.V1.t (* 为Full、Nonce或Accept枚举类型 *)
}
(* account字段,Account_precondition.Stable.V1.t结构为: *)
type t =
| Full of Zkapp_precondition.Account.Stable.V2.t (* *)
| Nonce of Account.Nonce.Stable.V1.t (* 为Unsigned_extended.UInt32.t *)
| Accept
(* Full枚举类型对应的,Zkapp_precondition.Account.Stable.V2.t 结构为: *)
type t =
{ balance : Balance.Stable.V1.t Numeric.Stable.V1.t (* Ignore或Check类型,包含lower和upper字段,均为Unsigned.UInt64.t *)
; nonce : Account_nonce.Stable.V1.t Numeric.Stable.V1.t (* Ignore或Check类型,包含lower和upper字段,均为Unsigned_extended.UInt32.t *)
; receipt_chain_hash : Receipt.Chain_hash.Stable.V1.t Hash.Stable.V1.t (* Ignore或Check类型,哈希值,Field.t *)
; delegate : Public_key.Compressed.Stable.V1.t Eq_data.Stable.V1.t (* Ignore或Check类型,压缩公钥 *)
; state : F.Stable.V1.t Eq_data.Stable.V1.t Zkapp_state.V.Stable.V1.t (* Ignore或Check类型,为8 fields(Set或Keep类型) of 32 bytes each of arbitrary storage *)
; sequence_state : F.Stable.V1.t Eq_data.Stable.V1.t (* Ignore或Check类型,F.t *)
; proved_state : bool Eq_data.Stable.V1.t (* Ignore或Check类型,bool *)
}
2.1 Parties_segment.Witness.t结构
Parties_segment.Witness.t结构为:
type t =
{ global_ledger : Sparse_ledger.Stable.V2.t (* 为Account树 *)
; local_state_init :
( ( Token_id.Stable.V1.t
, unit Parties.Call_forest.With_hashes.Stable.V1.t )
Stack_frame.Stable.V1.t (* 包含caller、caller_caller、calls三个字段,其中calller和caller_caller均为token_id,calls为Parties。 *)
, ( ( ( Token_id.Stable.V1.t
, unit Parties.Call_forest.With_hashes.Stable.V1.t )
Stack_frame.Stable.V1.t
, Stack_frame.Digest.Stable.V1.t )
With_hash.t (* 包含data和hash字段。 *)
, Call_stack_digest.Stable.V1.t )
With_stack_hash.Stable.V1.t
list
, Token_id.Stable.V1.t
, (Amount.Stable.V1.t, Sgn.Stable.V1.t) Signed_poly.Stable.V1.t
, Sparse_ledger.Stable.V2.t (* 包含elt和stack_hash字段 *)
, bool
, Kimchi_backend.Pasta.Basic.Fp.Stable.V1.t
, Transaction_status.Failure.Collection.Stable.V1.t )
Mina_transaction_logic.Parties_logic.Local_state.Stable.V1.t (* 包含stack_frame/call_stack/transaction_commitment/full_transaction_commitment/token_id/excess/ledger/success/failure_status_tbl字段。 *)
; start_parties :
( Parties.Stable.V1.t
, Kimchi_backend.Pasta.Basic.Fp.Stable.V1.t )
Mina_transaction_logic.Parties_logic.Start_data.Stable.V1.t (* 包含parties和memo_hash字段。 *)
list
; state_body : Mina_state.Protocol_state.Body.Value.Stable.V2.t (包含genesis_state_hash/blockchain_state/consensus_state/constants这4个字段。)
; init_stack : Pending_coinbase.Stack_versioned.Stable.V1.t (其中data字段为Field.t,state字段(包含init/curr)也均为Field.t)
}
2.2 Parties_segment.Basic.t结构
Parties_segment.Basic.t结构为枚举类型:
type t = Opt_signed_opt_signed | Opt_signed | Proved
2.3 Zkapp_statement.t结构
Zkapp_statement.t结构为:
type t = Parties.Transaction_commitment.Stable.V1.t Poly.Stable.V1.t (* transaction和at_party字段均为F.t结构。 *)
type 'comm t = { transaction : 'comm; at_party : 'comm }
2.4 Transaction_applied.Parties_applied.t结构
Transaction_applied.Parties_applied.t结构为:
type t =
{ accounts :
(Account_id.Stable.V2.t * Account.Stable.V2.t option) list (* 由account_id和account二元结构组成的list *)
; command : Parties.Stable.V1.t With_status.Stable.V2.t (* 包含data和status字段,其中data为Parties交易结构,status表示该Parties交易的状态,为Applied | Failed of Failure.Collection.Stable.V1.t *)
; previous_empty_accounts : Account_id.Stable.V2.t list (* 为account_id list *)
}
3. Parties交易snark流程
Parties交易snark流程见src/lib/snark_worker/prod.ml中的perform_single 函数。 其中:
input 为Transaction_snark.Statement.t类型(包含source、target、supply_increase、fee_excess、sok_digest五个字段)。w 为Transaction_witness.t类型(包含transaction、ledger、protocol_state_body、init_stack和status五个字段)。
process (fun () ->
match w.transaction with
| Command (Parties parties) -> (
let%bind witnesses_specs_stmts =
Or_error.try_with (fun () ->
Transaction_snark.parties_witnesses_exn
~constraint_constants:M.constraint_constants (* 调用Transaction_snark.Make (struct。。。时指定的。 *)
~state_body:w.protocol_state_body
~fee_excess:Currency.Amount.Signed.zero
(`Sparse_ledger w.ledger)
[ ( `Pending_coinbase_init_stack w.init_stack
, `Pending_coinbase_of_statement
{ Transaction_snark
.Pending_coinbase_stack_state
.source =
input.source.pending_coinbase_stack
; target =
input.target.pending_coinbase_stack
}
, parties )
]
|> fst |> List.rev )
|> Result.map_error ~f:(fun e ->
Error.createf
!"Failed to generate inputs for parties : \
%s: %s"
( Parties.to_yojson parties
|> Yojson.Safe.to_string )
(Error.to_string_hum e) )
|> Deferred.return
in
let log_base_snark f ~statement ~spec ~all_inputs =
match%map.Deferred
Deferred.Or_error.try_with (fun () ->
f ~statement ~spec )
with
| Ok p ->
Ok p
| Error e ->
[%log fatal]
"Transaction snark failed for input $spec \
$statement. All inputs: $inputs. Error: \
$error"
~metadata:
[ ( "spec"
, Transaction_snark.Parties_segment.Basic
.to_yojson spec )
; ( "statement"
, Transaction_snark.Statement.With_sok
.to_yojson statement )
; ("error", `String (Error.to_string_hum e))
; ( "inputs"
, parties_inputs_to_yojson all_inputs )
] ;
Error e
in
let log_merge_snark ~sok_digest prev curr ~all_inputs
=
match%map.Deferred
M.merge ~sok_digest prev curr
with
| Ok p ->
Ok p
| Error e ->
[%log fatal]
"Merge snark failed for $stmt1 $stmt2. All \
inputs: $inputs. Error: $error"
~metadata:
[ ( "stmt1"
, Transaction_snark.Statement.to_yojson
(Ledger_proof.statement prev) )
; ( "stmt2"
, Transaction_snark.Statement.to_yojson
(Ledger_proof.statement curr) )
; ("error", `String (Error.to_string_hum e))
; ( "inputs"
, parties_inputs_to_yojson all_inputs )
] ;
Error e
in
match witnesses_specs_stmts with
| [] ->
Deferred.Or_error.error_string
"no witnesses generated"
| (witness, spec, stmt, snapp_statement) :: rest as
inputs ->
let%bind (p1 : Ledger_proof.t) =
log_base_snark
~statement:{ stmt with sok_digest } ~spec
~all_inputs:inputs
(M.of_parties_segment_exn ~snapp_statement
~witness )
in
let%map (p : Ledger_proof.t) =
Deferred.List.fold ~init:(Ok p1) rest
~f:(fun
acc
(witness, spec, stmt, snapp_statement)
->
let%bind (prev : Ledger_proof.t) =
Deferred.return acc
in
let%bind (curr : Ledger_proof.t) =
log_base_snark
~statement:{ stmt with sok_digest }
~spec ~all_inputs:inputs
(M.of_parties_segment_exn
~snapp_statement ~witness )
in
log_merge_snark ~sok_digest prev curr
~all_inputs:inputs )
in
if
Transaction_snark.Statement.equal
(Ledger_proof.statement p) input
then p
else (
[%log fatal]
"Parties transaction final statement \
mismatch Expected $expected Got $got. All \
inputs: $inputs"
~metadata:
[ ( "got"
, Transaction_snark.Statement.to_yojson
(Ledger_proof.statement p) )
; ( "expected"
, Transaction_snark.Statement.to_yojson
input )
; ("inputs", parties_inputs_to_yojson inputs)
] ;
failwith
"Parties transaction final statement mismatch"
) )
。。。。。
parties_witnesses_exn 函数,
(** [parties_witnesses_exn ledger partiess] generates the parties segment witnesses
and corresponding statements needed to prove the application of each
parties transaction in [partiess] on top of ledger. If multiple parties are
given, they are applied in order and grouped together to minimise the
number of transaction proofs that would be required.
There must be at least one parties transaction in [parties].
The returned value is a list of tuples, each corresponding to a single
proof for some parts of some parties transactions, comprising:
* the witness information for the segment, to be passed to the prover
* the segment kind, identifying the type of proof that will be generated
* the proof statement, describing the transition between the states before
and after the segment
* the list of calculated 'snapp statements', corresponding to the expected
public input of any snapp parties in the current segment.
WARNING: This function calls the transaction logic internally, and thus may
raise an exception if the transaction logic would also do so. This function
should only be used on parties that are already known to pass transaction
logic without an exception.
*)
val parties_witnesses_exn :
constraint_constants:Genesis_constants.Constraint_constants.t
-> state_body:Transaction_protocol_state.Block_data.t
-> fee_excess:Currency.Amount.Signed.t
-> [ `Ledger of Mina_ledger.Ledger.t
| `Sparse_ledger of Mina_ledger.Sparse_ledger.t ]
-> ( [ `Pending_coinbase_init_stack of Pending_coinbase.Stack.t ] (* 其中data字段为Field.t,state字段(包含init/curr)也均为Field.t)。 *)
* [ `Pending_coinbase_of_statement of Pending_coinbase_stack_state.t ] (* 包含source和target字段,均为Pending_coinbase.Stack.t结构。 *)
* Parties.t )
list
-> ( Parties_segment.Witness.t
* Parties_segment.Basic.t
* Statement.With_sok.t
* (int * Zkapp_statement.t) option )
list
* Mina_ledger.Sparse_ledger.t (* `parties_witnesses_exn`函数输出结果类型 *)
附录1. Mina系列博客
Mina系列博客有:
|