Line data Source code
1 : #ifndef HEADER_fd_src_app_fdctl_run_tiles_verify_h 2 : #define HEADER_fd_src_app_fdctl_run_tiles_verify_h 3 : 4 : #include "../../../../disco/tiles.h" 5 : 6 15 : #define FD_TXN_VERIFY_SUCCESS 0 7 12 : #define FD_TXN_VERIFY_FAILED -1 8 15 : #define FD_TXN_VERIFY_DEDUP -2 9 : 10 : /* fd_verify_in_ctx_t is a context object for each in (producer) mcache 11 : connected to the verify tile. */ 12 : 13 : typedef struct { 14 : fd_wksp_t * mem; 15 : ulong chunk0; 16 : ulong wmark; 17 : } fd_verify_in_ctx_t; 18 : 19 : typedef struct { 20 : /* TODO switch to fd_sha512_batch_t? */ 21 : fd_sha512_t * sha[ FD_TXN_ACTUAL_SIG_MAX ]; 22 : 23 : int bundle_failed; 24 : ulong bundle_id; 25 : 26 : ulong round_robin_idx; 27 : ulong round_robin_cnt; 28 : 29 : ulong tcache_depth; 30 : ulong tcache_map_cnt; 31 : ulong * tcache_sync; 32 : ulong * tcache_ring; 33 : ulong * tcache_map; 34 : 35 : ulong in_kind[ 32 ]; 36 : fd_verify_in_ctx_t in[ 32 ]; 37 : 38 : fd_wksp_t * out_mem; 39 : ulong out_chunk0; 40 : ulong out_wmark; 41 : ulong out_chunk; 42 : 43 : ulong hashmap_seed; 44 : 45 : struct { 46 : ulong parse_fail_cnt; 47 : ulong verify_fail_cnt; 48 : ulong dedup_fail_cnt; 49 : ulong bundle_peer_fail_cnt; 50 : } metrics; 51 : } fd_verify_ctx_t; 52 : 53 : static inline int 54 : fd_txn_verify( fd_verify_ctx_t * ctx, 55 : uchar const * udp_payload, 56 : ushort const payload_sz, 57 : fd_txn_t const * txn, 58 42 : ulong * opt_sig ) { 59 : 60 : /* We do not want to deref any non-data field from the txn struct more than once */ 61 42 : uchar signature_cnt = txn->signature_cnt; 62 42 : ushort signature_off = txn->signature_off; 63 42 : ushort acct_addr_off = txn->acct_addr_off; 64 42 : ushort message_off = txn->message_off; 65 : 66 42 : uchar const * signatures = udp_payload + signature_off; 67 42 : uchar const * pubkeys = udp_payload + acct_addr_off; 68 42 : uchar const * msg = udp_payload + message_off; 69 42 : ulong msg_sz = (ulong)payload_sz - message_off; 70 : 71 : /* The first signature is the transaction id, i.e. a unique identifier. 72 : So use this to do a quick dedup of ha traffic. */ 73 : 74 42 : ulong ha_dedup_tag = fd_hash( ctx->hashmap_seed, signatures, 64UL ); 75 42 : int ha_dup; 76 42 : FD_FN_UNUSED ulong tcache_map_idx = 0; /* ignored */ 77 42 : FD_TCACHE_QUERY( ha_dup, tcache_map_idx, ctx->tcache_map, ctx->tcache_map_cnt, ha_dedup_tag ); 78 42 : if( FD_UNLIKELY( ha_dup ) ) { 79 15 : return FD_TXN_VERIFY_DEDUP; 80 15 : } 81 : 82 : /* Verify signatures */ 83 27 : int res = fd_ed25519_verify_batch_single_msg( msg, msg_sz, signatures, pubkeys, ctx->sha, signature_cnt ); 84 27 : if( FD_UNLIKELY( res != FD_ED25519_SUCCESS ) ) { 85 12 : return FD_TXN_VERIFY_FAILED; 86 12 : } 87 : 88 : /* Insert into the tcache to dedup ha traffic. 89 : The dedup check is repeated to guard against duped txs verifying signatures at the same time */ 90 15 : FD_TCACHE_INSERT( ha_dup, *ctx->tcache_sync, ctx->tcache_ring, ctx->tcache_depth, ctx->tcache_map, ctx->tcache_map_cnt, ha_dedup_tag ); 91 15 : if( FD_UNLIKELY( ha_dup ) ) { 92 0 : return FD_TXN_VERIFY_DEDUP; 93 0 : } 94 : 95 15 : *opt_sig = ha_dedup_tag; 96 15 : return FD_TXN_VERIFY_SUCCESS; 97 15 : } 98 : 99 : #endif /* HEADER_fd_src_app_fdctl_run_tiles_verify_h */