1+ mod canonical;
2+
13use anyhow:: anyhow;
24use lightning_signer:: bitcoin:: secp256k1:: PublicKey ;
35use lightning_signer:: chain:: tracker:: ChainTracker ;
@@ -19,6 +21,8 @@ use std::str::FromStr;
1921use std:: sync:: Arc ;
2022use std:: sync:: Mutex ;
2123
24+ use self :: canonical:: { canonical_json_bytes, CanonicalJsonValue } ;
25+
2226const NODE_PREFIX : & str = "nodes" ;
2327const NODE_STATE_PREFIX : & str = "nodestates" ;
2428const CHANNEL_PREFIX : & str = "channels" ;
@@ -41,6 +45,10 @@ impl StateEntry {
4145 signature : vec ! [ ] ,
4246 }
4347 }
48+
49+ fn canonical_value_bytes ( & self ) -> anyhow:: Result < Vec < u8 > > {
50+ canonical_json_bytes ( & self . value )
51+ }
4452}
4553
4654impl Serialize for StateEntry {
@@ -55,7 +63,7 @@ impl Serialize for StateEntry {
5563 } ;
5664
5765 seq. serialize_element ( & self . version ) ?;
58- seq. serialize_element ( & self . value ) ?;
66+ seq. serialize_element ( & CanonicalJsonValue ( & self . value ) ) ?;
5967 if !self . signature . is_empty ( ) {
6068 seq. serialize_element ( & self . signature ) ?;
6169 }
@@ -500,8 +508,7 @@ impl State {
500508 if !entry. signature . is_empty ( ) {
501509 continue ;
502510 }
503- let value = serde_json:: to_vec ( & entry. value )
504- . map_err ( |e| anyhow ! ( "failed to serialize state value for key {key}: {e}" ) ) ?;
511+ let value = entry. canonical_value_bytes ( ) ?;
505512 let signature = signer ( key, entry. version , & value) ?;
506513 entry. signature = signature;
507514 changed += 1 ;
@@ -589,7 +596,9 @@ impl Into<Vec<crate::pb::SignerStateEntry>> for State {
589596 . iter ( )
590597 . map ( |( k, v) | crate :: pb:: SignerStateEntry {
591598 key : k. to_owned ( ) ,
592- value : serde_json:: to_vec ( & v. value ) . unwrap ( ) ,
599+ value : v
600+ . canonical_value_bytes ( )
601+ . expect ( "canonical signer state value" ) ,
593602 version : v. version ,
594603 signature : v. signature . clone ( ) ,
595604 } )
@@ -1047,6 +1056,18 @@ mod tests {
10471056 assert_eq ! ( tuple[ 2 ] , json!( [ 7 , 8 , 9 ] ) ) ;
10481057 }
10491058
1059+ #[ test]
1060+ fn state_entry_canonical_value_bytes_sorts_nested_object_keys ( ) {
1061+ let entry = StateEntry :: new ( 0 , json ! ( {
1062+ "z" : { "b" : 1 , "a" : 2 } ,
1063+ "a" : [ { "d" : 4 , "c" : 3 } ]
1064+ } ) ) ;
1065+
1066+ let bytes = entry. canonical_value_bytes ( ) . unwrap ( ) ;
1067+
1068+ assert_eq ! ( bytes, br#"{"a":[{"c":3,"d":4}],"z":{"a":2,"b":1}}"# ) ;
1069+ }
1070+
10501071 #[ test]
10511072 fn signer_state_entry_conversions_preserve_signature ( ) {
10521073 let entries = vec ! [ SignerStateEntry {
@@ -1066,6 +1087,22 @@ mod tests {
10661087 assert_eq ! ( roundtrip, entries) ;
10671088 }
10681089
1090+ #[ test]
1091+ fn signer_state_entry_conversions_emit_canonical_value_bytes ( ) {
1092+ let entries = vec ! [ SignerStateEntry {
1093+ version: 6 ,
1094+ key: "k" . to_string( ) ,
1095+ value: br#"{ "b": 1, "a": 2 }"# . to_vec( ) ,
1096+ signature: vec![ 11 , 12 ] ,
1097+ } ] ;
1098+
1099+ let state: State = entries. into ( ) ;
1100+ let roundtrip: Vec < SignerStateEntry > = state. into ( ) ;
1101+ assert_eq ! ( roundtrip. len( ) , 1 ) ;
1102+ assert_eq ! ( roundtrip[ 0 ] . value, br#"{"a":2,"b":1}"# ) ;
1103+ assert_eq ! ( roundtrip[ 0 ] . signature, vec![ 11 , 12 ] ) ;
1104+ }
1105+
10691106 #[ test]
10701107 fn merge_newer_entry_propagates_signature ( ) {
10711108 let mut base = mk_state ( vec ! [ ( "k" , 1 , json!( { "v" : 1 } ) ) ] ) ;
0 commit comments