Signer: better high watermarking
This commit is contained in:
parent
3f04501c0d
commit
89372a8e28
@ -40,11 +40,12 @@ module High_watermark = struct
|
|||||||
(List.map (fun (pkh, mark) -> Signature.Public_key_hash.to_b58check pkh, mark))
|
(List.map (fun (pkh, mark) -> Signature.Public_key_hash.to_b58check pkh, mark))
|
||||||
(List.map (fun (pkh, mark) -> Signature.Public_key_hash.of_b58check_exn pkh, mark)) @@
|
(List.map (fun (pkh, mark) -> Signature.Public_key_hash.of_b58check_exn pkh, mark)) @@
|
||||||
assoc @@
|
assoc @@
|
||||||
obj2
|
obj3
|
||||||
(req "level" int32)
|
(req "level" int32)
|
||||||
(req "hash" raw_hash)
|
(req "hash" raw_hash)
|
||||||
|
(opt "signature" Signature.encoding)
|
||||||
|
|
||||||
let mark_if_block_or_endorsement (cctxt : #Client_context.wallet) pkh bytes =
|
let mark_if_block_or_endorsement (cctxt : #Client_context.wallet) pkh bytes sign =
|
||||||
let mark art name get_level =
|
let mark art name get_level =
|
||||||
let file = name ^ "_high_watermark" in
|
let file = name ^ "_high_watermark" in
|
||||||
cctxt#with_lock @@ fun () ->
|
cctxt#with_lock @@ fun () ->
|
||||||
@ -56,32 +57,41 @@ module High_watermark = struct
|
|||||||
let chain_id = Chain_id.of_bytes_exn (MBytes.sub bytes 1 4) in
|
let chain_id = Chain_id.of_bytes_exn (MBytes.sub bytes 1 4) in
|
||||||
let level = get_level () in
|
let level = get_level () in
|
||||||
begin match List.assoc_opt chain_id all with
|
begin match List.assoc_opt chain_id all with
|
||||||
| None -> return ()
|
| None -> return None
|
||||||
| Some marks ->
|
| Some marks ->
|
||||||
match List.assoc_opt pkh marks with
|
match List.assoc_opt pkh marks with
|
||||||
| None -> return ()
|
| None -> return None
|
||||||
| Some (previous_level, previous_hash) ->
|
| Some (previous_level, _, None) ->
|
||||||
|
if previous_level >= level then
|
||||||
|
failwith "%s level %ld not above high watermark %ld" name level previous_level
|
||||||
|
else
|
||||||
|
return None
|
||||||
|
| Some (previous_level, previous_hash, Some signature) ->
|
||||||
if previous_level > level then
|
if previous_level > level then
|
||||||
failwith "%s level %ld below high watermark %ld" name level previous_level
|
failwith "%s level %ld below high watermark %ld" name level previous_level
|
||||||
else if previous_level = level && previous_hash <> hash then
|
else if previous_level = level && previous_hash <> hash then
|
||||||
failwith "%s level %ld already signed with a different header" name level
|
failwith "%s level %ld already signed with different data" name level
|
||||||
else
|
else
|
||||||
return ()
|
return (Some signature)
|
||||||
end >>=? fun () ->
|
end >>=? function
|
||||||
|
| Some signature -> return signature
|
||||||
|
| None ->
|
||||||
|
sign bytes >>=? fun signature ->
|
||||||
let rec update = function
|
let rec update = function
|
||||||
| [] -> [ chain_id, [ pkh, (level, hash) ] ]
|
| [] -> [ chain_id, [ pkh, (level, hash, Some signature) ] ]
|
||||||
| (e_chain_id, marks) :: rest ->
|
| (e_chain_id, marks) :: rest ->
|
||||||
if chain_id = e_chain_id then
|
if chain_id = e_chain_id then
|
||||||
let marks = (pkh, (level, hash)) :: List.filter (fun (pkh', _) -> pkh <> pkh') marks in
|
let marks = (pkh, (level, hash, Some signature)) :: List.filter (fun (pkh', _) -> pkh <> pkh') marks in
|
||||||
(e_chain_id, marks) :: rest
|
(e_chain_id, marks) :: rest
|
||||||
else
|
else
|
||||||
(e_chain_id, marks) :: update rest in
|
(e_chain_id, marks) :: update rest in
|
||||||
cctxt#write file (update all) encoding in
|
cctxt#write file (update all) encoding >>=? fun () ->
|
||||||
|
return signature in
|
||||||
if MBytes.length bytes > 0 && MBytes.get_uint8 bytes 0 = 0x01 then
|
if MBytes.length bytes > 0 && MBytes.get_uint8 bytes 0 = 0x01 then
|
||||||
mark "a" "block" (fun () -> MBytes.get_int32 bytes 5)
|
mark "a" "block" (fun () -> MBytes.get_int32 bytes 5)
|
||||||
else if MBytes.length bytes > 0 && MBytes.get_uint8 bytes 0 = 0x02 then
|
else if MBytes.length bytes > 0 && MBytes.get_uint8 bytes 0 = 0x02 then
|
||||||
mark "an" "endorsement" (fun () -> MBytes.get_int32 bytes (MBytes.length bytes - 4))
|
mark "an" "endorsement" (fun () -> MBytes.get_int32 bytes (MBytes.length bytes - 4))
|
||||||
else return ()
|
else sign bytes
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -134,12 +144,11 @@ let sign
|
|||||||
f "Signing data for key %s"
|
f "Signing data for key %s"
|
||||||
-% t event "signing_data"
|
-% t event "signing_data"
|
||||||
-% s Client_keys.Logging.tag name) >>= fun () ->
|
-% s Client_keys.Logging.tag name) >>= fun () ->
|
||||||
begin if check_high_watermark then
|
let sign = Client_keys.sign cctxt sk_uri in
|
||||||
High_watermark.mark_if_block_or_endorsement cctxt pkh data
|
if check_high_watermark then
|
||||||
else return ()
|
High_watermark.mark_if_block_or_endorsement cctxt pkh data sign
|
||||||
end >>=? fun () ->
|
else
|
||||||
Client_keys.sign cctxt sk_uri data >>=? fun signature ->
|
sign data
|
||||||
return signature
|
|
||||||
|
|
||||||
let public_key (cctxt : #Client_context.wallet) pkh =
|
let public_key (cctxt : #Client_context.wallet) pkh =
|
||||||
log Tag.DSL.(fun f ->
|
log Tag.DSL.(fun f ->
|
||||||
|
Loading…
Reference in New Issue
Block a user