Line data Source code
1 : #include "fd_types_custom.h"
2 : #include "fd_bincode.h"
3 : #include "fd_types.h"
4 : #ifndef SOURCE_fd_src_flamenco_types_fd_types_c
5 : #error "fd_types_custom.c is part of the fd_types.c compile uint"
6 : #endif /* !SOURCE_fd_src_flamenco_types_fd_types_c */
7 :
8 : #include <stdio.h>
9 :
10 : int
11 3 : fd_flamenco_txn_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) {
12 3 : *total_sz += sizeof(fd_flamenco_txn_t);
13 3 : void const * start_data = ctx->data;
14 3 : int err = fd_flamenco_txn_decode_footprint_inner( ctx, total_sz );
15 3 : ctx->data = start_data;
16 3 : return err;
17 3 : }
18 :
19 : int
20 9 : fd_flamenco_txn_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) {
21 9 : if( FD_UNLIKELY( ctx->data>=ctx->dataend ) ) { return FD_BINCODE_ERR_OVERFLOW; }
22 9 : ulong bufsz = (ulong)ctx->dataend - (ulong)ctx->data;
23 9 : fd_flamenco_txn_t self;
24 9 : ulong sz = 0UL;
25 9 : ulong res = fd_txn_parse_core( ctx->data,
26 9 : bufsz,
27 9 : self.txn,
28 9 : NULL,
29 9 : &sz );
30 9 : if( FD_UNLIKELY( !res ) ) {
31 0 : return -1000001;
32 0 : }
33 9 : ctx->data = (void *)( (ulong)ctx->data + sz );
34 9 : *total_sz += sz;
35 9 : return 0;
36 9 : }
37 :
38 : void *
39 3 : fd_flamenco_txn_decode( void * mem, fd_bincode_decode_ctx_t * ctx ) {
40 3 : fd_flamenco_txn_t * self = (fd_flamenco_txn_t *)mem;
41 3 : fd_flamenco_txn_new( self );
42 3 : void * alloc_region = (uchar *)mem + sizeof(fd_flamenco_txn_t);
43 3 : void * * alloc_mem = &alloc_region;
44 3 : fd_flamenco_txn_decode_inner( mem, alloc_mem, ctx );
45 3 : return self;
46 3 : }
47 :
48 : void
49 9 : fd_flamenco_txn_decode_inner( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) {
50 9 : fd_flamenco_txn_t * self = (fd_flamenco_txn_t *)struct_mem;
51 9 : static FD_TL fd_txn_parse_counters_t counters[1];
52 9 : ulong bufsz = (ulong)ctx->dataend - (ulong)ctx->data;
53 9 : ulong sz = 0UL;
54 9 : ulong res = fd_txn_parse_core( ctx->data,
55 9 : bufsz,
56 9 : self->txn,
57 9 : counters,
58 9 : &sz );
59 9 : if( FD_UNLIKELY( !res ) ) {
60 0 : FD_LOG_ERR(( "Failed to decode txn (fd_txn.c:%lu)",
61 0 : counters->failure_ring[ counters->failure_cnt % FD_TXN_PARSE_COUNTERS_RING_SZ ] ));
62 0 : return;
63 0 : }
64 9 : fd_memcpy( self->raw, ctx->data, sz );
65 9 : self->raw_sz = sz;
66 9 : ctx->data = (void *)( (ulong)ctx->data + sz );
67 9 : }
68 :
69 : void *
70 0 : fd_flamenco_txn_decode_global( void * mem, fd_bincode_decode_ctx_t * ctx ) {
71 0 : fd_flamenco_txn_t * self = (fd_flamenco_txn_t *)mem;
72 0 : fd_flamenco_txn_new( self );
73 0 : void * alloc_region = (uchar *)mem + sizeof(fd_flamenco_txn_t);
74 0 : void * * alloc_mem = &alloc_region;
75 0 : fd_flamenco_txn_decode_inner_global( mem, alloc_mem, ctx );
76 0 : return self;
77 0 : }
78 :
79 : int
80 0 : fd_flamenco_txn_convert_global_to_local( void const * global_self, fd_flamenco_txn_t * self, fd_bincode_decode_ctx_t * ctx ) {
81 0 : FD_LOG_ERR(("TODO: Implement"));
82 0 : }
83 :
84 : void
85 0 : fd_flamenco_txn_decode_inner_global( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) {
86 0 : FD_LOG_ERR(("TODO: Implement"));
87 0 : }
88 :
89 :
90 : void
91 : fd_gossip_ip4_addr_walk( void * w,
92 : fd_gossip_ip4_addr_t const * self,
93 : fd_types_walk_fn_t fun,
94 : char const * name,
95 93 : uint level ) {
96 :
97 93 : char buf[ 16 ];
98 93 : sprintf( buf, FD_IP4_ADDR_FMT, FD_IP4_ADDR_FMT_ARGS( *self ) );
99 93 : fun( w, buf, name, FD_FLAMENCO_TYPE_CSTR, "ip4_addr", level );
100 93 : }
101 :
102 : void
103 : fd_gossip_ip6_addr_walk( void * w,
104 : fd_gossip_ip6_addr_t const * self,
105 : fd_types_walk_fn_t fun,
106 : char const * name,
107 0 : uint level ) {
108 :
109 0 : char buf[ 40 ];
110 0 : sprintf( buf,
111 0 : "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
112 0 : FD_LOG_HEX16_FMT_ARGS( self->us ) );
113 0 : fun( w, buf, name, FD_FLAMENCO_TYPE_CSTR, "ip6_addr", level );
114 0 : }
115 :
116 0 : int fd_tower_sync_encode( fd_tower_sync_t const * self, fd_bincode_encode_ctx_t * ctx ) {
117 0 : FD_LOG_ERR(( "todo"));
118 0 : }
119 :
120 0 : int fd_tower_sync_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) {
121 0 : *total_sz += sizeof(fd_tower_sync_t);
122 0 : void const * start_data = ctx->data;
123 0 : int err = fd_tower_sync_decode_footprint_inner( ctx, total_sz );
124 0 : ctx->data = start_data;
125 0 : return err;
126 0 : }
127 :
128 0 : int fd_tower_sync_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) {
129 : /* This is a modified version of fd_compact_tower_sync_decode_footprint_inner() */
130 0 : int err = 0;
131 0 : if( FD_UNLIKELY( ctx->data>ctx->dataend ) ) { return FD_BINCODE_ERR_OVERFLOW; }
132 0 : err = fd_bincode_uint64_decode_footprint( ctx );
133 :
134 : /* The first modification is that we want to grab the value fo the root. */
135 0 : ulong root = 0UL;
136 0 : fd_bincode_decode_ctx_t root_ctx = { .data = (uchar*)ctx->data - sizeof(ulong), .dataend = ctx->data };
137 0 : if( FD_UNLIKELY( ((ulong)ctx->data)+sizeof(ulong)>(ulong)ctx->dataend ) ) { return FD_BINCODE_ERR_OVERFLOW; }
138 0 : fd_bincode_uint64_decode_unsafe( &root, &root_ctx );
139 0 : root = root != ULONG_MAX ? root : 0UL;
140 : /* Done with first modification */
141 :
142 0 : if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err;
143 0 : ushort lockout_offsets_len;
144 0 : if( FD_UNLIKELY( ctx->data>=ctx->dataend ) ) { return FD_BINCODE_ERR_OVERFLOW; }
145 0 : err = fd_bincode_compact_u16_decode( &lockout_offsets_len, ctx );
146 :
147 0 : if( FD_UNLIKELY( err ) ) return err;
148 0 : ulong lockout_offsets_max = fd_ulong_max( lockout_offsets_len, 32 );
149 0 : *total_sz += deq_fd_lockout_offset_t_align() + deq_fd_lockout_offset_t_footprint( lockout_offsets_max );
150 :
151 0 : for( ulong i = 0; i < lockout_offsets_len; ++i ) {
152 :
153 0 : uchar const * start_data = ctx->data;
154 0 : if( FD_UNLIKELY( ctx->data>=ctx->dataend ) ) { return FD_BINCODE_ERR_OVERFLOW; }
155 0 : err = fd_lockout_offset_decode_footprint_inner( ctx, total_sz );
156 0 : if( FD_UNLIKELY( err ) ) {
157 0 : return err;
158 0 : }
159 :
160 : /* The second modification is that we want to grab the lockout offset from
161 : the deque to make sure that we can do a checked add successfully. */
162 0 : fd_lockout_offset_t lockout_offset = {0};
163 0 : fd_bincode_decode_ctx_t lockout_ctx = { .data = start_data, .dataend = start_data+sizeof(fd_lockout_offset_t) };
164 0 : if( FD_UNLIKELY( ctx->data>=ctx->dataend ) ) { return FD_BINCODE_ERR_OVERFLOW; }
165 0 : fd_lockout_offset_decode_inner( &lockout_offset, NULL, &lockout_ctx );
166 0 : err = __builtin_uaddl_overflow( root, lockout_offset.offset, &root );
167 0 : if( FD_UNLIKELY( err ) ) {
168 0 : return err;
169 0 : }
170 : /* Done with second modification. */
171 0 : }
172 :
173 0 : if( FD_UNLIKELY( ctx->data>=ctx->dataend ) ) { return FD_BINCODE_ERR_OVERFLOW; }
174 0 : err = fd_hash_decode_footprint_inner( ctx, total_sz );
175 0 : if( FD_UNLIKELY( err ) ) return err;
176 0 : {
177 0 : uchar o;
178 0 : if( FD_UNLIKELY( ctx->data>=ctx->dataend ) ) { return FD_BINCODE_ERR_OVERFLOW; }
179 0 : err = fd_bincode_bool_decode( &o, ctx );
180 0 : if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err;
181 0 : if( o ) {
182 0 : if( FD_UNLIKELY( ctx->data>=ctx->dataend ) ) { return FD_BINCODE_ERR_OVERFLOW; }
183 0 : err = fd_bincode_int64_decode_footprint( ctx );
184 0 : if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err;
185 0 : }
186 0 : }
187 0 : if( FD_UNLIKELY( ctx->data>=ctx->dataend ) ) { return FD_BINCODE_ERR_OVERFLOW; }
188 0 : err = fd_hash_decode_footprint_inner( ctx, total_sz );
189 0 : if( FD_UNLIKELY( err ) ) return err;
190 0 : return 0;
191 0 : }
192 :
193 0 : void * fd_tower_sync_decode( void * mem, fd_bincode_decode_ctx_t * ctx ) {
194 0 : fd_tower_sync_t * self = (fd_tower_sync_t *)mem;
195 0 : fd_tower_sync_new( self );
196 0 : void * alloc_region = (uchar *)mem + sizeof(fd_tower_sync_t);
197 0 : void * * alloc_mem = &alloc_region;
198 0 : fd_tower_sync_decode_inner( mem, alloc_mem, ctx );
199 0 : return self;
200 0 : }
201 :
202 0 : void fd_tower_sync_decode_inner( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) {
203 0 : fd_tower_sync_t * self = (fd_tower_sync_t *)struct_mem;
204 0 : self->has_root = 1;
205 0 : fd_bincode_uint64_decode_unsafe( &self->root, ctx );
206 0 : self->has_root = self->root != ULONG_MAX;
207 :
208 0 : ushort lockout_offsets_len;
209 0 : fd_bincode_compact_u16_decode_unsafe( &lockout_offsets_len, ctx );
210 0 : ulong lockout_offsets_max = fd_ulong_max( lockout_offsets_len, 32 );
211 0 : self->lockouts = deq_fd_vote_lockout_t_join_new( alloc_mem, lockout_offsets_max );
212 :
213 : /* NOTE: Agave does a a checked add on the sum of the root with all of the
214 : lockout offsets in their custom deserializer for tower sync votes. If the
215 : checked add is violated (this should never happen), the deocder will
216 : return NULL. */
217 :
218 : // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/state/mod.rs#L1062-L1077
219 0 : ulong last_slot = ((self->root == ULONG_MAX) ? 0 : self->root);
220 0 : for( ulong i=0; i < lockout_offsets_len; i++ ) {
221 0 : fd_vote_lockout_t * elem = deq_fd_vote_lockout_t_push_tail_nocopy( self->lockouts );
222 :
223 0 : fd_lockout_offset_t o;
224 0 : fd_lockout_offset_decode_inner( &o, alloc_mem, ctx );
225 :
226 0 : elem->slot = last_slot + o.offset;
227 0 : elem->confirmation_count = o.confirmation_count;
228 0 : last_slot = elem->slot;
229 0 : }
230 :
231 0 : fd_hash_decode_inner( &self->hash, alloc_mem, ctx );
232 0 : {
233 0 : uchar o;
234 0 : fd_bincode_bool_decode_unsafe( &o, ctx );
235 0 : self->has_timestamp = !!o;
236 0 : if( o ) {
237 0 : fd_bincode_int64_decode_unsafe( &self->timestamp, ctx );
238 0 : }
239 0 : }
240 0 : fd_hash_decode_inner( &self->block_id, alloc_mem, ctx );
241 0 : }
242 :
243 0 : void fd_tower_sync_decode_inner_global( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) {
244 0 : FD_LOG_ERR(("TODO: Implement"));
245 0 : }
246 :
247 0 : #define REDBLK_T fd_vote_reward_t_mapnode_t
248 : #define REDBLK_NAME fd_vote_reward_t_map
249 : #define REDBLK_IMPL_STYLE 2
250 : #include "../../util/tmpl/fd_redblack.c"
251 :
252 0 : long fd_vote_reward_t_map_compare( fd_vote_reward_t_mapnode_t * left, fd_vote_reward_t_mapnode_t * right ) {
253 0 : return memcmp( left->elem.pubkey.uc, right->elem.pubkey.uc, sizeof(right->elem.pubkey) );
254 0 : }
|