@@ -3,6 +3,7 @@ use ntt_messages::chain_id::ChainId;
3
3
4
4
use crate :: {
5
5
config:: Config ,
6
+ error:: NTTError ,
6
7
peer:: NttManagerPeer ,
7
8
queue:: { inbox:: InboxRateLimit , outbox:: OutboxRateLimit , rate_limit:: RateLimitState } ,
8
9
registered_transceiver:: RegisteredTransceiver ,
@@ -76,7 +77,7 @@ pub fn set_peer(ctx: Context<SetPeer>, args: SetPeerArgs) -> Result<()> {
76
77
Ok ( ( ) )
77
78
}
78
79
79
- // * Register transceivers
80
+ // * Transceiver registration
80
81
81
82
#[ derive( Accounts ) ]
82
83
pub struct RegisterTransceiver < ' info > {
@@ -91,13 +92,16 @@ pub struct RegisterTransceiver<'info> {
91
92
#[ account( mut ) ]
92
93
pub payer : Signer < ' info > ,
93
94
94
- #[ account( executable) ]
95
+ #[ account(
96
+ executable,
97
+ constraint = transceiver. key( ) != Pubkey :: default ( ) @ NTTError :: InvalidTransceiverProgram
98
+ ) ]
95
99
/// CHECK: transceiver is meant to be a transceiver program. Arguably a `Program` constraint could be
96
100
/// used here that wraps the Transceiver account type.
97
101
pub transceiver : UncheckedAccount < ' info > ,
98
102
99
103
#[ account(
100
- init ,
104
+ init_if_needed ,
101
105
space = 8 + RegisteredTransceiver :: INIT_SPACE ,
102
106
payer = payer,
103
107
seeds = [ RegisteredTransceiver :: SEED_PREFIX , transceiver. key( ) . as_ref( ) ] ,
@@ -109,17 +113,62 @@ pub struct RegisterTransceiver<'info> {
109
113
}
110
114
111
115
pub fn register_transceiver ( ctx : Context < RegisterTransceiver > ) -> Result < ( ) > {
112
- let id = ctx. accounts . config . next_transceiver_id ;
113
- ctx. accounts . config . next_transceiver_id += 1 ;
116
+ // initialize registered transceiver with new id on init
117
+ if ctx. accounts . registered_transceiver . transceiver_address == Pubkey :: default ( ) {
118
+ let id = ctx. accounts . config . next_transceiver_id ;
119
+ ctx. accounts . config . next_transceiver_id += 1 ;
120
+ ctx. accounts
121
+ . registered_transceiver
122
+ . set_inner ( RegisteredTransceiver {
123
+ bump : ctx. bumps . registered_transceiver ,
124
+ id,
125
+ transceiver_address : ctx. accounts . transceiver . key ( ) ,
126
+ } ) ;
127
+ }
128
+
114
129
ctx. accounts
115
- . registered_transceiver
116
- . set_inner ( RegisteredTransceiver {
117
- bump : ctx. bumps . registered_transceiver ,
118
- id,
119
- transceiver_address : ctx. accounts . transceiver . key ( ) ,
120
- } ) ;
121
-
122
- ctx. accounts . config . enabled_transceivers . set ( id, true ) ?;
130
+ . config
131
+ . enabled_transceivers
132
+ . set ( ctx. accounts . registered_transceiver . id , true ) ?;
133
+ Ok ( ( ) )
134
+ }
135
+
136
+ #[ derive( Accounts ) ]
137
+ pub struct DeregisterTransceiver < ' info > {
138
+ #[ account(
139
+ mut ,
140
+ has_one = owner,
141
+ ) ]
142
+ pub config : Account < ' info , Config > ,
143
+
144
+ #[ account( mut ) ]
145
+ pub owner : Signer < ' info > ,
146
+
147
+ #[ account( executable) ]
148
+ /// CHECK: transceiver is meant to be a transceiver program. Arguably a `Program` constraint could be
149
+ /// used here that wraps the Transceiver account type.
150
+ pub transceiver : UncheckedAccount < ' info > ,
151
+
152
+ #[ account(
153
+ seeds = [ RegisteredTransceiver :: SEED_PREFIX , transceiver. key( ) . as_ref( ) ] ,
154
+ bump,
155
+ constraint = config. enabled_transceivers. get( registered_transceiver. id) ? @ NTTError :: DisabledTransceiver ,
156
+ ) ]
157
+ pub registered_transceiver : Account < ' info , RegisteredTransceiver > ,
158
+ }
159
+
160
+ pub fn deregister_transceiver ( ctx : Context < DeregisterTransceiver > ) -> Result < ( ) > {
161
+ ctx. accounts
162
+ . config
163
+ . enabled_transceivers
164
+ . set ( ctx. accounts . registered_transceiver . id , false ) ?;
165
+
166
+ // decrement threshold if too high
167
+ let num_enabled_transceivers = ctx. accounts . config . enabled_transceivers . len ( ) ;
168
+ if num_enabled_transceivers < ctx. accounts . config . threshold {
169
+ // threshold should be at least 1
170
+ ctx. accounts . config . threshold = num_enabled_transceivers. max ( 1 ) ;
171
+ }
123
172
Ok ( ( ) )
124
173
}
125
174
@@ -200,3 +249,26 @@ pub fn set_paused(ctx: Context<SetPaused>, paused: bool) -> Result<()> {
200
249
ctx. accounts . config . paused = paused;
201
250
Ok ( ( ) )
202
251
}
252
+
253
+ // * Set Threshold
254
+
255
+ #[ derive( Accounts ) ]
256
+ #[ instruction( threshold: u8 ) ]
257
+ pub struct SetThreshold < ' info > {
258
+ pub owner : Signer < ' info > ,
259
+
260
+ #[ account(
261
+ mut ,
262
+ has_one = owner,
263
+ constraint = threshold <= config. enabled_transceivers. len( ) @ NTTError :: ThresholdTooHigh
264
+ ) ]
265
+ pub config : Account < ' info , Config > ,
266
+ }
267
+
268
+ pub fn set_threshold ( ctx : Context < SetThreshold > , threshold : u8 ) -> Result < ( ) > {
269
+ if threshold == 0 {
270
+ return Err ( NTTError :: ZeroThreshold . into ( ) ) ;
271
+ }
272
+ ctx. accounts . config . threshold = threshold;
273
+ Ok ( ( ) )
274
+ }
0 commit comments