Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
206 changes: 163 additions & 43 deletions src/flamenco/gossip/fd_gossip_msg_parse.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
#include "fd_gossip_private.h"
#include "../../ballet/txn/fd_compact_u16.h"

/* https://github.com/anza-xyz/agave/blob/bff4df9cf6f41520a26c9838ee3d4d8c024a96a1/gossip/src/crds_data.rs#L22-L23 */
#define WALLCLOCK_MAX_MILLIS (1000000000000000UL)
#define MAX_SLOT (1000000000000000UL)

/* https://github.com/anza-xyz/agave/blob/master/gossip/src/epoch_slots.rs#L15 */
#define MAX_SLOTS_PER_EPOCH_SLOT (2048UL*8UL)

struct __attribute__((packed)) slot_hash_pair {
ulong slot;
uchar hash[ 32UL ];
};

typedef struct slot_hash_pair slot_hash_pair_t;

/* Adapted from fd_txn_parse.c */
#define CHECK_INIT( payload, payload_sz, offset ) \
uchar const * _payload = (payload); \
Expand Down Expand Up @@ -39,6 +53,15 @@
#define BYTES_CONSUMED (_i-_offset)
#define BYTES_REMAINING (_payload_sz-_i)

#define CHECKED_WALLCLOCK_LOAD( var_name ) do { \
CHECK_LEFT( 8U ); \
ulong _wallclock_ms = FD_LOAD( ulong, CURSOR ); \
/* https://github.com/anza-xyz/agave/blob/bff4df9cf6f41520a26c9838ee3d4d8c024a96a1/gossip/src/crds_data.rs#L490-L497 */ \
CHECK( _wallclock_ms<WALLCLOCK_MAX_MILLIS ); \
(var_name) = FD_MILLI_TO_NANOSEC( _wallclock_ms ); \
INC( 8U ); \
} while( 0 )

static ulong
decode_u64_varint( uchar const * payload,
ulong payload_sz,
Expand All @@ -58,6 +81,64 @@ decode_u64_varint( uchar const * payload,
return BYTES_CONSUMED;
}

/* Returns bytes_consumed for valid bitvec, 0 otherwise (should be dropped) */
static inline ulong
decode_bitvec_impl( uchar const * payload,
ulong payload_sz,
ulong start_offset,
ulong * out_bits_offset,
ulong * out_bits_len,
ulong * out_bits_cnt,
ulong bits_per_element ) {
CHECK_INIT( payload, payload_sz, start_offset );

uchar has_bits = 0;
CHECK_LEFT( 1U ); has_bits = FD_LOAD( uchar, CURSOR ) ; INC( 1U );
if( FD_UNLIKELY( !has_bits ) ) {
*out_bits_offset = 0UL;
*out_bits_len = 0UL;
*out_bits_cnt = 0UL;
return BYTES_CONSUMED;
}

ulong elem_sz = bits_per_element/8U;

CHECK_LEFT( 8U ); ulong bits_len = FD_LOAD( ulong, CURSOR ); INC( 8U );
/* elem_sz*bits_len doesn't overflow */
CHECK( bits_len<=(ULONG_MAX-(elem_sz-1U))/elem_sz );

CHECK_LEFT( bits_len*elem_sz ); ulong bits_offset = CUR_OFFSET ; INC( bits_len*elem_sz );
CHECK_LEFT( 8U ); ulong bits_cnt = FD_LOAD( ulong, CURSOR ); INC( 8U );

/* https://github.com/tov/bv-rs/blob/de155853ff8b69d7e9e7f7dcfdf4061242f6eaff/src/bit_vec/mod.rs#L86-L88 */
CHECK( bits_cnt<=bits_len*bits_per_element );

*out_bits_offset = bits_offset;
*out_bits_len = bits_len;
*out_bits_cnt = bits_cnt;
return BYTES_CONSUMED;
}

static inline ulong
decode_bitvec_u64( uchar const * payload,
ulong payload_sz,
ulong start_offset,
ulong * out_bits_offset,
ulong * out_bits_len,
ulong * out_bits_cnt ) {
return decode_bitvec_impl( payload, payload_sz, start_offset, out_bits_offset, out_bits_len, out_bits_cnt, 64U );
}

static inline ulong
decode_bitvec_u8( uchar const * payload,
ulong payload_sz,
ulong start_offset,
ulong * out_bits_offset,
ulong * out_bits_len,
ulong * out_bits_cnt ) {
return decode_bitvec_impl( payload, payload_sz, start_offset, out_bits_offset, out_bits_len, out_bits_cnt, 8U );
}

static ulong
fd_gossip_msg_crds_legacy_contact_info_parse( fd_gossip_view_crds_value_t * crds_val,
uchar const * payload,
Expand All @@ -74,7 +155,7 @@ fd_gossip_msg_crds_legacy_contact_info_parse( fd_gossip_view_crds_value_t * crds
CHECKED_INC( 16U+2U+4U+4U ); /* ip6 + port + flowinfo + scope_id */
}
}
CHECK_LEFT( 8U ); crds_val->wallclock_nanos = FD_MILLI_TO_NANOSEC( FD_LOAD( ulong, CURSOR ) ); INC( 8U );
CHECKED_WALLCLOCK_LOAD( crds_val->wallclock_nanos );
CHECKED_INC( 2U ); /* shred_version */
return BYTES_CONSUMED;
}
Expand All @@ -86,13 +167,15 @@ fd_gossip_msg_crds_vote_parse( fd_gossip_view_crds_value_t * crds_val,
ulong start_offset ) {
CHECK_INIT( payload, payload_sz, start_offset );
CHECK_LEFT( 1U ); crds_val->vote->index = FD_LOAD( uchar, CURSOR ) ; INC( 1U );
/* https://github.com/anza-xyz/agave/blob/bff4df9cf6f41520a26c9838ee3d4d8c024a96a1/gossip/src/crds_data.rs#L67-L107 */
CHECK( crds_val->vote->index<FD_GOSSIP_VOTE_IDX_MAX );
CHECK_LEFT( 32U ); crds_val->pubkey_off = CUR_OFFSET ; INC( 32U );
ulong transaction_sz;
CHECK( fd_txn_parse_core( CURSOR, BYTES_REMAINING, NULL, NULL, &transaction_sz )!=0UL );
crds_val->vote->txn_off = CUR_OFFSET;
crds_val->vote->txn_sz = transaction_sz;
INC( transaction_sz );
CHECK_LEFT( 8U ); crds_val->wallclock_nanos = FD_MILLI_TO_NANOSEC( FD_LOAD( ulong, CURSOR ) ); INC( 8U );
CHECKED_WALLCLOCK_LOAD( crds_val->wallclock_nanos );
return BYTES_CONSUMED;
}

Expand All @@ -102,7 +185,10 @@ fd_gossip_msg_crds_lowest_slot_parse( fd_gossip_view_crds_value_t * crds_val,
ulong payload_sz,
ulong start_offset ) {
CHECK_INIT( payload, payload_sz, start_offset );
CHECKED_INC( 1U ); /* deprecated */
CHECK_LEFT( 1U ); uchar ix = FD_LOAD( uchar, CURSOR ) ; INC( 1U );
/* https://github.com/anza-xyz/agave/blob/bff4df9cf6f41520a26c9838ee3d4d8c024a96a1/gossip/src/crds_data.rs#L67-L107 */
CHECK( !ix );

CHECK_LEFT( 32U ); crds_val->pubkey_off = CUR_OFFSET ; INC( 32U );

CHECKED_INC( 8U ); /* root: deprecated */
Expand All @@ -122,7 +208,7 @@ fd_gossip_msg_crds_lowest_slot_parse( fd_gossip_view_crds_value_t * crds_val,
CHECK_LEFT( 8U ); ulong stash_len = FD_LOAD( ulong, CURSOR ) ; INC( 8U );
CHECK( stash_len==0U );

CHECK_LEFT( 8U ); crds_val->wallclock_nanos = FD_MILLI_TO_NANOSEC( FD_LOAD( ulong, CURSOR ) ); INC( 8U );
CHECKED_WALLCLOCK_LOAD( crds_val->wallclock_nanos );
return BYTES_CONSUMED;
}

Expand All @@ -134,9 +220,15 @@ fd_gossip_msg_crds_account_hashes_parse( fd_gossip_view_crds_value_t * crds_val,
CHECK_INIT( payload, payload_sz, start_offset );
CHECK_LEFT( 32U ); crds_val->pubkey_off = CUR_OFFSET ; INC( 32U );
CHECK_LEFT( 8U ); ulong hashes_len = FD_LOAD( ulong, CURSOR ) ; INC( 8U );
CHECKED_INC( hashes_len*32U ); /* overflowing this currently doesn't matter, but be careful */

CHECK_LEFT( 8U ); crds_val->wallclock_nanos = FD_MILLI_TO_NANOSEC( FD_LOAD( ulong, CURSOR ) ); INC( 8U );
slot_hash_pair_t const * hashes = (slot_hash_pair_t const *)CURSOR;
CHECK( hashes_len<(ULONG_MAX-39U)/40U ); /* to prevent overflow in next check */
CHECKED_INC( hashes_len*40U );
CHECKED_WALLCLOCK_LOAD( crds_val->wallclock_nanos );

/* https://github.com/anza-xyz/agave/blob/bff4df9cf6f41520a26c9838ee3d4d8c024a96a1/gossip/src/crds_data.rs#L226-L230 */
for( ulong i=0UL; i<hashes_len; i++ ) {
CHECK( hashes[i].slot<MAX_SLOT );
}
return BYTES_CONSUMED;
}

Expand All @@ -147,27 +239,39 @@ fd_gossip_msg_crds_epoch_slots_parse( fd_gossip_view_crds_value_t * crds_val,
ulong start_offset ) {
CHECK_INIT( payload, payload_sz, start_offset );
CHECK_LEFT( 1U ); crds_val->epoch_slots->index = FD_LOAD( uchar, CURSOR ) ; INC( 1U );
/* https://github.com/anza-xyz/agave/blob/bff4df9cf6f41520a26c9838ee3d4d8c024a96a1/gossip/src/crds_data.rs#L67-L107 */
CHECK( crds_val->epoch_slots->index<FD_GOSSIP_EPOCH_SLOTS_IDX_MAX );
CHECK_LEFT( 32U ); crds_val->pubkey_off = CUR_OFFSET ; INC( 32U );
CHECK_LEFT( 8U ); ulong slots_len = FD_LOAD( ulong, CURSOR ) ; INC( 8U );

for( ulong i=0UL; i<slots_len; i++ ) {
CHECK_LEFT( 4U ); uint is_uncompressed = FD_LOAD( uint, CURSOR ) ; INC( 4U );
if( is_uncompressed ) {
CHECKED_INC( 8U+8U ); /* first_slot + num */
uchar has_bits = 0;
CHECK_LEFT( 1U ); has_bits = FD_LOAD( uchar, CURSOR ) ; INC( 1U );
if( has_bits ) {
CHECK_LEFT( 8U ); ulong bits_len = FD_LOAD( ulong, CURSOR ) ; INC( 8U );
CHECKED_INC( bits_len ); /* bitvec<u8> */
CHECKED_INC( 8U );
}
CHECK_LEFT( 8U ); ulong first_slot = FD_LOAD( ulong, CURSOR ) ; INC( 8U );
CHECK_LEFT( 8U ); ulong num = FD_LOAD( ulong, CURSOR ) ; INC( 8U );

ulong bits_off, bits_len, bits_cnt;
ulong bytes_consumed = decode_bitvec_u8( payload, payload_sz, CUR_OFFSET, &bits_off, &bits_len, &bits_cnt );
CHECK( !!bytes_consumed );
INC( bytes_consumed );

/* https://github.com/anza-xyz/agave/blob/bff4df9cf6f41520a26c9838ee3d4d8c024a96a1/gossip/src/epoch_slots.rs#L24-L43 */
CHECK( first_slot<MAX_SLOT );
CHECK( num<=MAX_SLOTS_PER_EPOCH_SLOT );
CHECK( bits_cnt%8U==0U ); /* must be multiple of 8 */
CHECK( bits_cnt==bits_len*8U ); /* stricter than check in decode_bitvec_u8 */
} else {
CHECKED_INC( 8U+8U ); /* first_slot + num */
/* https://github.com/anza-xyz/agave/blob/bff4df9cf6f41520a26c9838ee3d4d8c024a96a1/gossip/src/epoch_slots.rs#L79-L86*/
CHECK_LEFT( 8U ); ulong first_slot = FD_LOAD( ulong, CURSOR ) ; INC( 8U );
CHECK_LEFT( 8U ); ulong num = FD_LOAD( ulong, CURSOR ) ; INC( 8U );
CHECK( first_slot<MAX_SLOT );
CHECK( num<=MAX_SLOTS_PER_EPOCH_SLOT );

CHECK_LEFT( 8U ); ulong compressed_len = FD_LOAD( ulong, CURSOR ) ; INC( 8U );
CHECKED_INC( compressed_len ); /* compressed bitvec */
}
}
CHECK_LEFT( 8U ); crds_val->wallclock_nanos = FD_MILLI_TO_NANOSEC( FD_LOAD( ulong, CURSOR ) ); INC( 8U );
CHECKED_WALLCLOCK_LOAD( crds_val->wallclock_nanos );

return BYTES_CONSUMED;
}
Expand All @@ -179,7 +283,7 @@ fd_gossip_msg_crds_legacy_version_parse( fd_gossip_view_crds_value_t * crds_val,
ulong start_offset ) {
CHECK_INIT( payload, payload_sz, start_offset );
CHECK_LEFT( 32U ); crds_val->pubkey_off = CUR_OFFSET ; INC( 32U );
CHECK_LEFT( 8U ); crds_val->wallclock_nanos = FD_MILLI_TO_NANOSEC( FD_LOAD( ulong, CURSOR ) ); INC( 8U );
CHECKED_WALLCLOCK_LOAD( crds_val->wallclock_nanos );

CHECKED_INC( 3*2U ); /* major, minor, patch (all u16s)*/
CHECK_LEFT( 1U ); uchar has_commit = FD_LOAD( uchar, CURSOR ) ; INC( 1U );
Expand Down Expand Up @@ -207,7 +311,7 @@ fd_gossip_msg_crds_node_instance_parse( fd_gossip_view_crds_value_t * crds_val,
ulong start_offset ) {
CHECK_INIT( payload, payload_sz, start_offset );
CHECK_LEFT( 32U ); crds_val->pubkey_off = CUR_OFFSET ; INC( 32U );
CHECK_LEFT( 8U ); crds_val->wallclock_nanos = FD_MILLI_TO_NANOSEC( FD_LOAD( ulong, CURSOR ) ); INC( 8U );
CHECKED_WALLCLOCK_LOAD( crds_val->wallclock_nanos );
CHECKED_INC( 8U ); /* timestamp (currently unused) */
CHECK_LEFT( 8U ); crds_val->node_instance->token = FD_LOAD( ulong, CURSOR ) ; INC( 8U );
return BYTES_CONSUMED;
Expand All @@ -223,12 +327,16 @@ fd_gossip_msg_crds_duplicate_shred_parse( fd_gossip_view_crds_value_t * crds_val
CHECK_INIT( payload, payload_sz, start_offset );

CHECK_LEFT( 2U ); ds->index = FD_LOAD( ushort, CURSOR ) ; INC( 2U );
/* https://github.com/anza-xyz/agave/blob/bff4df9cf6f41520a26c9838ee3d4d8c024a96a1/gossip/src/crds_data.rs#L67-L107 */
CHECK( ds->index<FD_GOSSIP_DUPLICATE_SHRED_IDX_MAX );
CHECK_LEFT( 32U ); crds_val->pubkey_off = CUR_OFFSET ; INC( 32U );
CHECK_LEFT( 8U ); crds_val->wallclock_nanos = FD_MILLI_TO_NANOSEC( FD_LOAD( ulong, CURSOR ) ); INC( 8U );
CHECKED_WALLCLOCK_LOAD( crds_val->wallclock_nanos );
CHECK_LEFT( 8U ); ds->slot = FD_LOAD( ulong, CURSOR ) ; INC( 8U );
CHECKED_INC( 4U+1U ); /* (unused) + shred type (unused) */
CHECK_LEFT( 1U ); ds->num_chunks = FD_LOAD( uchar, CURSOR ) ; INC( 1U );
CHECK_LEFT( 1U ); ds->chunk_index = FD_LOAD( uchar, CURSOR ) ; INC( 1U );
/* https://github.com/anza-xyz/agave/blob/bff4df9cf6f41520a26c9838ee3d4d8c024a96a1/gossip/src/duplicate_shred.rs#L328-L336 */
CHECK( ds->chunk_index<ds->num_chunks );
CHECK_LEFT( 8U ); ds->chunk_len = FD_LOAD( ulong, CURSOR ) ; INC( 8U );
CHECK_LEFT( ds->chunk_len ); ds->chunk_off = CUR_OFFSET ; INC( ds->chunk_len );
return BYTES_CONSUMED;
Expand All @@ -243,9 +351,22 @@ fd_gossip_msg_crds_snapshot_hashes_parse( fd_gossip_view_crds_value_t * crds_val
CHECK_LEFT( 32U ); crds_val->pubkey_off = CUR_OFFSET ; INC( 32U );
CHECK_LEFT( 40U ); crds_val->snapshot_hashes->full_off = CUR_OFFSET ; INC( 40U );
CHECK_LEFT( 8U ); ulong incremental_len = FD_LOAD( ulong, CURSOR ) ; INC( 8U );
CHECK( incremental_len<(ULONG_MAX-39U)/40U ); /* to prevent overflow in next check */
CHECK_LEFT( incremental_len*40U ); crds_val->snapshot_hashes->inc_off = CUR_OFFSET ; INC( incremental_len*40U );
CHECK_LEFT( 8U ); crds_val->wallclock_nanos = FD_MILLI_TO_NANOSEC( FD_LOAD( ulong, CURSOR ) ); INC( 8U );
CHECKED_WALLCLOCK_LOAD( crds_val->wallclock_nanos );
crds_val->snapshot_hashes->inc_len = incremental_len;

/* https://github.com/anza-xyz/agave/blob/bff4df9cf6f41520a26c9838ee3d4d8c024a96a1/gossip/src/crds_data.rs#L265-L282 */
slot_hash_pair_t * full_pair = (slot_hash_pair_t *)(payload + crds_val->snapshot_hashes->full_off);
ulong full_slot = full_pair->slot;
CHECK( full_slot<MAX_SLOT );

slot_hash_pair_t * inc_pair = (slot_hash_pair_t *)(payload + crds_val->snapshot_hashes->inc_off);
for( ulong i=0UL; i<incremental_len; i++ ) {
CHECK( inc_pair[i].slot>full_slot );
CHECK( inc_pair[i].slot<MAX_SLOT );
}

return BYTES_CONSUMED;
}

Expand Down Expand Up @@ -320,7 +441,10 @@ fd_gossip_msg_crds_contact_info_parse( fd_gossip_view_crds_value_t * crds_val,
CHECK_INIT( payload, payload_sz, start_offset );
CHECK_LEFT( 32U ); crds_val->pubkey_off = CUR_OFFSET ; INC( 32U );
ulong wallclock = 0UL;
INC( decode_u64_varint( payload, payload_sz, CUR_OFFSET, &wallclock ) );
ulong bytes_consumed = decode_u64_varint( payload, payload_sz, CUR_OFFSET, &wallclock );
CHECK( !!bytes_consumed );
INC( bytes_consumed );
CHECK( wallclock<WALLCLOCK_MAX_MILLIS );
crds_val->wallclock_nanos = FD_MILLI_TO_NANOSEC( wallclock );

fd_contact_info_t * ci = crds_val->ci_view->contact_info;
Expand Down Expand Up @@ -411,18 +535,16 @@ fd_gossip_msg_crds_last_voted_fork_slots_parse( fd_gossip_view_crds_value_t * cr
ulong start_offset ) {
CHECK_INIT( payload, payload_sz, start_offset );
CHECK_LEFT( 32U ); crds_val->pubkey_off = CUR_OFFSET ; INC( 32U );
CHECK_LEFT( 8U ); crds_val->wallclock_nanos = FD_MILLI_TO_NANOSEC( FD_LOAD( ulong, CURSOR ) ); INC( 8U );
CHECKED_WALLCLOCK_LOAD( crds_val->wallclock_nanos );
CHECK_LEFT( 4U ); uint is_rawoffsets = FD_LOAD( uint, CURSOR ) ; INC( 4U );
if( !is_rawoffsets ) {
CHECK_LEFT( 8U ); ulong slots_len = FD_LOAD( ulong, CURSOR ) ; INC( 8U );
CHECKED_INC( slots_len*4U ); /* RunLengthEncoding */
} else {
CHECK_LEFT( 1U ); uchar has_bits = FD_LOAD( uchar, CURSOR ) ; INC( 1U );
if( has_bits ) {
CHECK_LEFT( 8U ); ulong bits_len = FD_LOAD( ulong, CURSOR ) ; INC( 8U );
CHECKED_INC( bits_len ); /* bitvec<u8 > */
CHECKED_INC( 8U ); /* bits num set */
}
ulong bits_off, bits_len, bits_cnt;
ulong bytes_consumed = decode_bitvec_u8( payload, payload_sz, CUR_OFFSET, &bits_off, &bits_len, &bits_cnt );
CHECK( !!bytes_consumed );
INC( bytes_consumed );
}
CHECKED_INC( 8U+32U+2U ); /* last voted slot + last voted hash + shred version */
return BYTES_CONSUMED;
Expand All @@ -435,7 +557,7 @@ fd_gossip_msg_crds_restart_heaviest_fork_parse( fd_gossip_view_crds_value_t * cr
ulong start_offset ) {
CHECK_INIT( payload, payload_sz, start_offset );
CHECK_LEFT( 32U ); crds_val->pubkey_off = CUR_OFFSET ; INC( 32U );
CHECK_LEFT( 8U ); crds_val->wallclock_nanos = FD_MILLI_TO_NANOSEC( FD_LOAD( ulong, CURSOR ) ); INC( 8U );
CHECKED_WALLCLOCK_LOAD( crds_val->wallclock_nanos );
CHECKED_INC( 8U+32U+8U+2U ); /* last slot + last slot hash + observed stake + shred version */
return BYTES_CONSUMED;
}
Expand Down Expand Up @@ -527,19 +649,17 @@ fd_gossip_pull_req_parse( fd_gossip_view_t * view,
CHECK( pr->bloom_keys_len<=((ULONG_MAX-7U)/8U) );
CHECK_LEFT( pr->bloom_keys_len*8U ); pr->bloom_keys_offset = CUR_OFFSET ; INC( pr->bloom_keys_len*8U );

uchar has_bits = 0;
CHECK_LEFT( 1U ); has_bits = FD_LOAD( uchar, CURSOR ) ; INC( 1U );
if( has_bits ) {
CHECK_LEFT( 8U ); pr->bloom_len = FD_LOAD( ulong, CURSOR ) ; INC( 8U );
CHECK( pr->bloom_len<=((ULONG_MAX-7U)/8U) );
CHECK_LEFT( pr->bloom_len*8U ); pr->bloom_bits_offset = CUR_OFFSET ; INC( pr->bloom_len*8U );
CHECK_LEFT( 8U ); pr->bloom_bits_cnt = FD_LOAD( ulong, CURSOR ) ; INC( 8U );
} else {
pr->bloom_len = 0U;
}
CHECK_LEFT( 8U ); pr->bloom_num_bits_set = FD_LOAD( ulong, CURSOR ); INC( 8U );
CHECK_LEFT( 8U ); pr->mask = FD_LOAD( ulong, CURSOR ) ; INC( 8U );
CHECK_LEFT( 4U ); pr->mask_bits = FD_LOAD( uint, CURSOR ) ; INC( 4U );
ulong bytes_consumed = decode_bitvec_u64( payload, payload_sz, CUR_OFFSET, &pr->bloom_bits_offset, &pr->bloom_len, &pr->bloom_bits_cnt );
CHECK( !!bytes_consumed );
INC( bytes_consumed );
/* bloom filter bitvec must have at least one element to avoid
div by zero in fd_bloom
https://github.com/anza-xyz/agave/blob/bff4df9cf6f41520a26c9838ee3d4d8c024a96a1/bloom/src/bloom.rs#L58-L67 */
CHECK( pr->bloom_bits_cnt!=0UL );

CHECK_LEFT( 8U ); pr->bloom_num_bits_set = FD_LOAD( ulong, CURSOR ); INC( 8U );
CHECK_LEFT( 8U ); pr->mask = FD_LOAD( ulong, CURSOR ); INC( 8U );
CHECK_LEFT( 4U ); pr->mask_bits = FD_LOAD( uint, CURSOR ) ; INC( 4U );

INC( fd_gossip_msg_crds_vals_parse( pr->pr_ci,
1U, /* pull request holds only one contact info */
Expand Down
Loading
Loading