Line data Source code
1 : #include "fd_failover_proto.h"
2 :
3 : #include "../../ballet/ed25519/fd_ed25519.h"
4 : #include "../../ballet/sha256/fd_sha256.h"
5 : #include "../../disco/keyguard/fd_keyguard.h"
6 :
7 : FD_STATIC_ASSERT( sizeof(FD_KEYGUARD_FAILOVER_CLIENT_DOMAIN)-1UL==FD_KEYGUARD_FAILOVER_DOMAIN_SZ, client_proof_domain );
8 : FD_STATIC_ASSERT( sizeof(FD_KEYGUARD_FAILOVER_SERVER_DOMAIN)-1UL==FD_KEYGUARD_FAILOVER_DOMAIN_SZ, server_proof_domain );
9 :
10 : int
11 : fd_failover_hello_check( fd_failover_hello_t const * self,
12 0 : fd_failover_hello_t const * peer ) {
13 0 : if( FD_UNLIKELY( self->version!=peer->version ) ) return FD_FAILOVER_HELLO_ERR_VERSION;
14 0 : if( FD_UNLIKELY( self->holds>1 || peer->holds>1 ) ) return FD_FAILOVER_HELLO_ERR_HOLDS;
15 0 : if( FD_UNLIKELY( self->mode!=FD_FAILOVER_MODE_ALPENGLOW ||
16 0 : self->mode!=peer->mode ) ) return FD_FAILOVER_HELLO_ERR_MODE;
17 0 : if( FD_UNLIKELY( !self->boot_id || !peer->boot_id ) ) return FD_FAILOVER_HELLO_ERR_BOOT_ID;
18 0 : if( FD_UNLIKELY( !fd_memeq( self->staked_pubkey, peer->staked_pubkey, 32UL ) ) ) return FD_FAILOVER_HELLO_ERR_STAKED;
19 0 : if( FD_UNLIKELY( self->boot_id==peer->boot_id ) ) return FD_FAILOVER_HELLO_ERR_SELF;
20 0 : if( FD_UNLIKELY( self->holds && peer->holds ) ) return FD_FAILOVER_HELLO_ERR_BOTH_HOLD;
21 0 : return FD_FAILOVER_HELLO_OK;
22 0 : }
23 :
24 : void
25 : fd_failover_admission_hash( fd_failover_admission_start_t const * start,
26 : uchar const * client_hello,
27 : fd_failover_admission_challenge_t const * challenge,
28 0 : uchar out[ 32 ] ) {
29 0 : fd_sha256_t sha[1];
30 0 : fd_sha256_init( sha );
31 0 : fd_sha256_append( sha, start, sizeof(*start) );
32 0 : fd_sha256_append( sha, client_hello, start->client_hello_sz );
33 0 : fd_sha256_append( sha, challenge, sizeof(*challenge) );
34 0 : fd_sha256_fini( sha, out );
35 0 : }
36 :
37 : void
38 : fd_failover_response_hash( uchar const transcript[ 32 ],
39 : uchar const client_proof[ 64 ],
40 : uchar const * server_flight,
41 : ushort server_flight_sz,
42 0 : uchar out[ 32 ] ) {
43 0 : fd_sha256_t sha[1];
44 0 : fd_sha256_init( sha );
45 0 : fd_sha256_append( sha, transcript, 32UL );
46 0 : fd_sha256_append( sha, client_proof, 64UL );
47 0 : fd_sha256_append( sha, &server_flight_sz, sizeof(server_flight_sz) );
48 0 : fd_sha256_append( sha, server_flight, server_flight_sz );
49 0 : fd_sha256_fini( sha, out );
50 0 : }
51 :
52 : void
53 : fd_failover_proof_msg( uchar out[ FD_KEYGUARD_FAILOVER_PROOF_SZ ],
54 : int server,
55 0 : uchar const transcript[ 32 ] ) {
56 0 : fd_memcpy( out, server ? FD_KEYGUARD_FAILOVER_SERVER_DOMAIN : FD_KEYGUARD_FAILOVER_CLIENT_DOMAIN,
57 0 : FD_KEYGUARD_FAILOVER_DOMAIN_SZ );
58 0 : fd_memcpy( out+FD_KEYGUARD_FAILOVER_DOMAIN_SZ, transcript, 32UL );
59 0 : }
60 :
61 : int
62 : fd_failover_handoff_request_decode( fd_failover_handoff_request_t * out,
63 : uchar const * payload,
64 0 : ulong payload_sz ) {
65 0 : if( FD_UNLIKELY( payload_sz!=sizeof(fd_failover_handoff_request_t) ) ) return 0;
66 0 : fd_failover_handoff_request_t request;
67 0 : fd_memcpy( &request, payload, sizeof(request) );
68 0 : if( FD_UNLIKELY( !request.handoff_id || !request.target_boot_id ) ) return 0;
69 0 : *out = request;
70 0 : return 1;
71 0 : }
72 :
73 : int
74 : fd_failover_handoff_result_decode( fd_failover_handoff_result_t * out,
75 : uchar const * payload,
76 0 : ulong payload_sz ) {
77 0 : if( FD_UNLIKELY( payload_sz!=sizeof(fd_failover_handoff_result_t) ) ) return 0;
78 0 : fd_failover_handoff_result_t result;
79 0 : fd_memcpy( &result, payload, sizeof(result) );
80 0 : if( FD_UNLIKELY( !result.handoff_id ) ) return 0;
81 0 : *out = result;
82 0 : return 1;
83 0 : }
84 :
85 : ulong
86 : fd_failover_demoted_encode( uchar * out,
87 : ulong handoff_id,
88 : ulong target_boot_id,
89 : ulong last_vote_slot,
90 : uchar const * state,
91 0 : ulong state_sz ) {
92 0 : if( FD_UNLIKELY( !state_sz || state_sz>FD_FAILOVER_ALPENGLOW_STATE_MAX ) ) return 0UL;
93 :
94 0 : fd_failover_demoted_t demoted = {
95 0 : .handoff_id = handoff_id,
96 0 : .target_boot_id = target_boot_id,
97 0 : .last_vote_slot = last_vote_slot,
98 0 : .mode = (uchar)FD_FAILOVER_MODE_ALPENGLOW,
99 0 : .state_len = (ushort)state_sz,
100 0 : };
101 0 : fd_memcpy( out, &demoted, sizeof(demoted) );
102 0 : fd_memcpy( out+sizeof(demoted), state, state_sz );
103 0 : return sizeof(demoted)+state_sz;
104 0 : }
105 :
106 : int
107 : fd_failover_demoted_decode( fd_failover_demoted_t * out,
108 : uchar const * payload,
109 0 : ulong payload_sz ) {
110 0 : if( FD_UNLIKELY( payload_sz<sizeof(fd_failover_demoted_t) ||
111 0 : payload_sz>FD_FAILOVER_DEMOTED_PAYLOAD_MAX ) ) return 0;
112 :
113 0 : fd_failover_demoted_t demoted;
114 0 : fd_memcpy( &demoted, payload, sizeof(demoted) );
115 :
116 0 : ulong state_sz = payload_sz-sizeof(fd_failover_demoted_t);
117 0 : if( FD_UNLIKELY( (ulong)demoted.state_len!=state_sz ||
118 0 : !state_sz || state_sz>FD_FAILOVER_ALPENGLOW_STATE_MAX ||
119 0 : demoted.mode!=(uchar)FD_FAILOVER_MODE_ALPENGLOW ||
120 0 : demoted.last_vote_slot==FD_FAILOVER_SLOT_NULL ) ) return 0;
121 :
122 0 : *out = demoted;
123 0 : return 1;
124 0 : }
125 :
126 : ulong
127 : fd_failover_promote_ack_encode( uchar * out,
128 0 : ulong handoff_id ) {
129 0 : fd_failover_promote_ack_t ack = { .handoff_id=handoff_id };
130 0 : fd_memcpy( out, &ack, sizeof(ack) );
131 0 : return sizeof(ack);
132 0 : }
133 :
134 : ulong
135 : fd_failover_promote_rejected_encode( uchar * out,
136 : ulong handoff_id,
137 0 : uchar reason ) {
138 0 : if( FD_UNLIKELY( reason==(uchar)FD_FAILOVER_REJECT_NONE || reason>=(uchar)FD_FAILOVER_REJECT_CNT ) ) return 0UL;
139 0 : fd_failover_promote_rejected_t rej = { .handoff_id=handoff_id, .reason=reason };
140 0 : fd_memcpy( out, &rej, sizeof(rej) );
141 0 : return sizeof(rej);
142 0 : }
143 :
144 : int
145 : fd_failover_promote_ack_decode( fd_failover_promote_ack_t * out,
146 : uchar const * payload,
147 0 : ulong payload_sz ) {
148 0 : if( FD_UNLIKELY( payload_sz!=sizeof(fd_failover_promote_ack_t) ) ) return 0;
149 0 : fd_memcpy( out, payload, sizeof(fd_failover_promote_ack_t) );
150 0 : return 1;
151 0 : }
152 :
153 : int
154 : fd_failover_promote_rejected_decode( fd_failover_promote_rejected_t * out,
155 : uchar const * payload,
156 0 : ulong payload_sz ) {
157 0 : if( FD_UNLIKELY( payload_sz!=sizeof(fd_failover_promote_rejected_t) ) ) return 0;
158 0 : fd_failover_promote_rejected_t rej;
159 0 : fd_memcpy( &rej, payload, sizeof(rej) );
160 0 : if( FD_UNLIKELY( rej.reason==(uchar)FD_FAILOVER_REJECT_NONE || rej.reason>=(uchar)FD_FAILOVER_REJECT_CNT ) ) return 0;
161 0 : *out = rej;
162 0 : return 1;
163 0 : }
|