2
2
//! # Impl function of tendermint ABCI
3
3
//!
4
4
5
- use globutils:: wallet;
6
- use ledger:: {
7
- data_model:: ASSET_TYPE_FRA ,
8
- staking:: { FF_ADDR_EXTRA_120_0000 , FF_ADDR_LIST } ,
9
- } ;
10
- use zei:: noah_api:: xfr:: asset_record:: AssetRecordType ;
11
-
12
5
mod utils;
13
6
14
7
use {
@@ -32,11 +25,15 @@ use {
32
25
STATE_UPDATE_LIST , TXS , WEB3_SERVICE_START_HEIGHT ,
33
26
} ,
34
27
fp_storage:: hash:: { Sha256 , StorageHasher } ,
28
+ globutils:: wallet,
35
29
lazy_static:: lazy_static,
36
30
ledger:: {
37
31
converter:: is_convert_account,
38
- data_model:: Operation ,
39
- staking:: { evm:: EVM_STAKING , KEEP_HIST , VALIDATOR_UPDATE_BLOCK_ITV } ,
32
+ data_model:: { Operation , Transaction , ASSET_TYPE_FRA } ,
33
+ staking:: {
34
+ evm:: EVM_STAKING , FF_ADDR_EXTRA_120_0000 , FF_ADDR_LIST , KEEP_HIST ,
35
+ VALIDATOR_UPDATE_BLOCK_ITV ,
36
+ } ,
40
37
store:: {
41
38
api_cache,
42
39
fbnc:: { new_mapx, Mapx } ,
56
53
} ,
57
54
} ,
58
55
tracing:: { error, info} ,
56
+ zei:: noah_api:: xfr:: asset_record:: AssetRecordType ,
59
57
} ;
60
58
61
59
pub ( crate ) static TENDERMINT_BLOCK_HEIGHT : AtomicI64 = AtomicI64 :: new ( 0 ) ;
@@ -100,9 +98,15 @@ pub fn info(s: &mut ABCISubmissionServer, req: &RequestInfo) -> ResponseInfo {
100
98
&& h < CFG . checkpoint . enable_frc20_height
101
99
{
102
100
resp. set_last_block_app_hash ( la_hash) ;
103
- } else {
101
+ } else if h < CFG . checkpoint . enable_ed25519_triple_masking_height {
104
102
let cs_hash = s. account_base_app . write ( ) . info ( req) . last_block_app_hash ;
105
103
resp. set_last_block_app_hash ( app_hash ( "info" , h, la_hash, cs_hash) ) ;
104
+ } else {
105
+ let cs_hash = s. account_base_app . write ( ) . info ( req) . last_block_app_hash ;
106
+ let tm_hash = state. get_anon_state_commitment ( ) . 0 ;
107
+ resp. set_last_block_app_hash ( app_hash_v2 (
108
+ "info" , h, la_hash, cs_hash, tm_hash,
109
+ ) ) ;
106
110
}
107
111
}
108
112
@@ -140,6 +144,18 @@ pub fn check_tx(s: &mut ABCISubmissionServer, req: &RequestCheckTx) -> ResponseC
140
144
TxCatalog :: FindoraTx => {
141
145
if matches ! ( req. field_type, CheckTxType :: New ) {
142
146
if let Ok ( tx) = convert_tx ( req. get_tx ( ) ) {
147
+ for op in tx. body . operations . iter ( ) {
148
+ if let Operation :: TransferAnonAsset ( op) = op {
149
+ let mut inputs = op. note . body . inputs . clone ( ) ;
150
+ inputs. sort ( ) ;
151
+ inputs. dedup ( ) ;
152
+ if inputs. len ( ) != op. note . body . inputs . len ( ) {
153
+ resp. log = "anon Transfer input error" . to_owned ( ) ;
154
+ resp. code = 1 ;
155
+ return resp;
156
+ }
157
+ }
158
+ }
143
159
if td_height > CFG . checkpoint . check_signatures_num {
144
160
for op in tx. body . operations . iter ( ) {
145
161
if let Operation :: TransferAsset ( op) = op {
@@ -171,6 +187,12 @@ pub fn check_tx(s: &mut ABCISubmissionServer, req: &RequestCheckTx) -> ResponseC
171
187
} else if TX_HISTORY . read ( ) . contains_key ( & tx. hash_tm_rawbytes ( ) ) {
172
188
resp. log = "Historical transaction" . to_owned ( ) ;
173
189
resp. code = 1 ;
190
+ } else if is_tm_transaction ( & tx)
191
+ && td_height
192
+ < CFG . checkpoint . enable_ed25519_triple_masking_height
193
+ {
194
+ resp. code = 1 ;
195
+ resp. log = "Triple Masking is disabled" . to_owned ( ) ;
174
196
}
175
197
} else {
176
198
resp. log = "Invalid format" . to_owned ( ) ;
@@ -272,6 +294,18 @@ pub fn deliver_tx(
272
294
match tx_catalog {
273
295
TxCatalog :: FindoraTx => {
274
296
if let Ok ( tx) = convert_tx ( req. get_tx ( ) ) {
297
+ for op in tx. body . operations . iter ( ) {
298
+ if let Operation :: TransferAnonAsset ( op) = op {
299
+ let mut inputs = op. note . body . inputs . clone ( ) ;
300
+ inputs. sort ( ) ;
301
+ inputs. dedup ( ) ;
302
+ if inputs. len ( ) != op. note . body . inputs . len ( ) {
303
+ resp. log = "anon Transfer input error" . to_owned ( ) ;
304
+ resp. code = 1 ;
305
+ return resp;
306
+ }
307
+ }
308
+ }
275
309
if td_height > CFG . checkpoint . check_signatures_num {
276
310
for op in tx. body . operations . iter ( ) {
277
311
if let Operation :: TransferAsset ( op) = op {
@@ -336,7 +370,7 @@ pub fn deliver_tx(
336
370
if let Err ( err) =
337
371
s. account_base_app . write ( ) . deliver_findora_tx ( & tx, & hash. 0 )
338
372
{
339
- info ! ( target: "abciapp" , "deliver convert account tx failed: {err:?}" ) ;
373
+ error ! ( target: "abciapp" , "deliver convert account tx failed: {err:?}" ) ;
340
374
341
375
resp. code = 1 ;
342
376
resp. log =
@@ -375,6 +409,17 @@ pub fn deliver_tx(
375
409
. db
376
410
. write ( )
377
411
. discard_session ( ) ;
412
+ } else if is_tm_transaction ( & tx)
413
+ && td_height
414
+ < CFG . checkpoint . enable_ed25519_triple_masking_height
415
+ {
416
+ info ! ( target: "abciapp" ,
417
+ "Triple Masking transaction(FindoraTx) detected at early height {}: {:?}" ,
418
+ td_height, tx
419
+ ) ;
420
+ resp. code = 2 ;
421
+ resp. log = "Triple Masking is disabled" . to_owned ( ) ;
422
+ return resp;
378
423
} else if CFG . checkpoint . utxo_checktx_height < td_height {
379
424
match tx. check_tx ( ) {
380
425
Ok ( _) => {
@@ -597,8 +642,11 @@ pub fn commit(s: &mut ABCISubmissionServer, req: &RequestCommit) -> ResponseComm
597
642
&& td_height < CFG . checkpoint . enable_frc20_height
598
643
{
599
644
r. set_data ( la_hash) ;
600
- } else {
645
+ } else if td_height < CFG . checkpoint . enable_ed25519_triple_masking_height {
601
646
r. set_data ( app_hash ( "commit" , td_height, la_hash, cs_hash) ) ;
647
+ } else {
648
+ let tm_hash = state. get_anon_state_commitment ( ) . 0 ;
649
+ r. set_data ( app_hash_v2 ( "commit" , td_height, la_hash, cs_hash, tm_hash) ) ;
602
650
}
603
651
604
652
IN_SAFE_ITV . store ( false , Ordering :: Release ) ;
@@ -728,3 +776,45 @@ fn app_hash(
728
776
la_hash
729
777
}
730
778
}
779
+
780
+ /// Combines ledger state hash and EVM chain state hash
781
+ /// and print app hashes for debugging
782
+ fn app_hash_v2 (
783
+ when : & str ,
784
+ height : i64 ,
785
+ mut la_hash : Vec < u8 > ,
786
+ mut cs_hash : Vec < u8 > ,
787
+ mut tm_hash : Vec < u8 > ,
788
+ ) -> Vec < u8 > {
789
+ info ! ( target: "abciapp" ,
790
+ "app_hash_{}: {}_{}_{}, height: {}" ,
791
+ when,
792
+ hex:: encode( la_hash. clone( ) ) ,
793
+ hex:: encode( cs_hash. clone( ) ) ,
794
+ hex:: encode( tm_hash. clone( ) ) ,
795
+ height
796
+ ) ;
797
+
798
+ // append ONLY non-empty EVM chain state hash
799
+ if !tm_hash. is_empty ( ) || !cs_hash. is_empty ( ) {
800
+ la_hash. append ( & mut cs_hash) ;
801
+ la_hash. append ( & mut tm_hash) ;
802
+
803
+ Sha256 :: hash ( la_hash. as_slice ( ) ) . to_vec ( )
804
+ } else {
805
+ la_hash
806
+ }
807
+ }
808
+
809
+ fn is_tm_transaction ( tx : & Transaction ) -> bool {
810
+ tx. body
811
+ . operations
812
+ . iter ( )
813
+ . try_for_each ( |op| match op {
814
+ Operation :: BarToAbar ( _a) => None ,
815
+ Operation :: AbarToBar ( _a) => None ,
816
+ Operation :: TransferAnonAsset ( _a) => None ,
817
+ _ => Some ( ( ) ) ,
818
+ } )
819
+ . is_none ( )
820
+ }
0 commit comments