@@ -2,17 +2,17 @@ use crate::{
22 error:: DoubleZeroError ,
33 globalstate:: globalstate_get,
44 helper:: * ,
5- state:: { contributor:: Contributor , link:: * } ,
5+ state:: { contributor:: Contributor , device :: Device , link:: * } ,
66} ;
77use borsh:: BorshSerialize ;
88use borsh_incremental:: BorshDeserializeIncremental ;
99use core:: fmt;
1010use doublezero_program_common:: validate_account_code;
11- #[ cfg( test) ]
12- use solana_program:: msg;
11+
1312use solana_program:: {
1413 account_info:: { next_account_info, AccountInfo } ,
1514 entrypoint:: ProgramResult ,
15+ msg,
1616 pubkey:: Pubkey ,
1717} ;
1818#[ derive( BorshSerialize , BorshDeserializeIncremental , PartialEq , Clone , Default ) ]
@@ -30,11 +30,35 @@ pub struct LinkUpdateArgs {
3030
3131impl fmt:: Debug for LinkUpdateArgs {
3232 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
33- write ! (
34- f,
35- "code: {:?}, tunnel_type: {:?}, bandwidth: {:?}, mtu: {:?}, delay_ns: {:?}, jitter_ns: {:?}, delay_override_ns: {:?}" ,
36- self . code, self . tunnel_type, self . bandwidth, self . mtu, self . delay_ns, self . jitter_ns, self . delay_override_ns
37- )
33+ let mut parts = Vec :: new ( ) ;
34+ if let Some ( ref code) = self . code {
35+ parts. push ( format ! ( "code: {:?}" , code) ) ;
36+ }
37+ if let Some ( ref contributor_pk) = self . contributor_pk {
38+ parts. push ( format ! ( "contributor_pk: {:?}" , contributor_pk) ) ;
39+ }
40+ if let Some ( ref tunnel_type) = self . tunnel_type {
41+ parts. push ( format ! ( "tunnel_type: {:?}" , tunnel_type) ) ;
42+ }
43+ if let Some ( bandwidth) = self . bandwidth {
44+ parts. push ( format ! ( "bandwidth: {:?}" , bandwidth) ) ;
45+ }
46+ if let Some ( mtu) = self . mtu {
47+ parts. push ( format ! ( "mtu: {:?}" , mtu) ) ;
48+ }
49+ if let Some ( delay_ns) = self . delay_ns {
50+ parts. push ( format ! ( "delay_ns: {:?}" , delay_ns) ) ;
51+ }
52+ if let Some ( jitter_ns) = self . jitter_ns {
53+ parts. push ( format ! ( "jitter_ns: {:?}" , jitter_ns) ) ;
54+ }
55+ if let Some ( ref status) = self . status {
56+ parts. push ( format ! ( "status: {:?}" , status) ) ;
57+ }
58+ if let Some ( delay_override_ns) = self . delay_override_ns {
59+ parts. push ( format ! ( "delay_override_ns: {:?}" , delay_override_ns) ) ;
60+ }
61+ write ! ( f, "{}" , parts. join( ", " ) )
3862 }
3963}
4064
@@ -47,6 +71,11 @@ pub fn process_update_link(
4771
4872 let link_account = next_account_info ( accounts_iter) ?;
4973 let contributor_account = next_account_info ( accounts_iter) ?;
74+ let side_z_account: Option < & AccountInfo > = if accounts. len ( ) > 5 {
75+ Some ( next_account_info ( accounts_iter) ?)
76+ } else {
77+ None
78+ } ;
5079 let globalstate_account = next_account_info ( accounts_iter) ?;
5180 let payer_account = next_account_info ( accounts_iter) ?;
5281 let system_program = next_account_info ( accounts_iter) ?;
@@ -55,7 +84,11 @@ pub fn process_update_link(
5584 msg ! ( "process_update_link({:?})" , value) ;
5685
5786 // Check if the payer is a signer
58- assert ! ( payer_account. is_signer, "Payer must be a signer" ) ;
87+ assert ! (
88+ payer_account. is_signer,
89+ "Payer must be a signer {:?}" ,
90+ payer_account
91+ ) ;
5992
6093 // Check the owner of the accounts
6194 assert_eq ! ( link_account. owner, program_id, "Invalid PDA Account Owner" ) ;
@@ -77,38 +110,77 @@ pub fn process_update_link(
77110 if contributor. owner != * payer_account. key
78111 && !globalstate. foundation_allowlist . contains ( payer_account. key )
79112 {
113+ msg ! ( "contributor owner: {:?}" , contributor. owner) ;
80114 return Err ( DoubleZeroError :: NotAllowed . into ( ) ) ;
81115 }
116+ if let Some ( side_z_account) = side_z_account {
117+ if side_z_account. owner != program_id {
118+ return Err ( DoubleZeroError :: InvalidAccountOwner . into ( ) ) ;
119+ }
120+ }
121+
122+ // Deserialize the optional side_z device account
123+ let side_z: Option < Device > = if let Some ( side_z_account) = side_z_account {
124+ Some ( Device :: try_from ( side_z_account) ?)
125+ } else {
126+ None
127+ } ;
82128
129+ // Deserialize the link account
83130 let mut link: Link = Link :: try_from ( link_account) ?;
84131
85- if let Some ( ref code) = value. code {
86- link. code = validate_account_code ( code) . map_err ( |_| DoubleZeroError :: InvalidAccountCode ) ?;
87- }
88- if let Some ( contributor_pk) = value. contributor_pk {
89- link. contributor_pk = contributor_pk;
90- }
91- if let Some ( tunnel_type) = value. tunnel_type {
92- link. link_type = tunnel_type;
93- }
94- if let Some ( bandwidth) = value. bandwidth {
95- link. bandwidth = bandwidth;
96- }
97- if let Some ( mtu) = value. mtu {
98- link. mtu = mtu;
99- }
100- if let Some ( delay_ns) = value. delay_ns {
101- link. delay_ns = delay_ns;
132+ if side_z. is_none ( ) {
133+ // Link should be owned by the contributor A
134+ if link. contributor_pk != * contributor_account. key {
135+ msg ! ( "link contributor_pk: {:?}" , link. contributor_pk) ;
136+ return Err ( DoubleZeroError :: NotAllowed . into ( ) ) ;
137+ }
138+ } else if let Some ( side_z) = side_z {
139+ // Link should be owned by the side_z device's contributor B
140+ if link. side_z_pk != * side_z_account. unwrap ( ) . key {
141+ return Err ( DoubleZeroError :: InvalidAccountOwner . into ( ) ) ;
142+ }
143+ if side_z. contributor_pk != * contributor_account. key {
144+ msg ! ( "side_z contributor_pk: {:?}" , side_z. contributor_pk) ;
145+ return Err ( DoubleZeroError :: NotAllowed . into ( ) ) ;
146+ }
102147 }
103- if let Some ( jitter_ns) = value. jitter_ns {
104- link. jitter_ns = jitter_ns;
148+
149+ // can be updated by either contributor A or B
150+ if link. contributor_pk == * contributor_account. key {
151+ if let Some ( ref code) = value. code {
152+ link. code =
153+ validate_account_code ( code) . map_err ( |_| DoubleZeroError :: InvalidAccountCode ) ?;
154+ }
155+ if let Some ( tunnel_type) = value. tunnel_type {
156+ link. link_type = tunnel_type;
157+ }
158+ if let Some ( bandwidth) = value. bandwidth {
159+ link. bandwidth = bandwidth;
160+ }
161+ if let Some ( mtu) = value. mtu {
162+ link. mtu = mtu;
163+ }
164+ if let Some ( delay_ns) = value. delay_ns {
165+ link. delay_ns = delay_ns;
166+ }
167+ if let Some ( jitter_ns) = value. jitter_ns {
168+ link. jitter_ns = jitter_ns;
169+ }
105170 }
171+ // Can be updated by both contributors A and B
106172 if let Some ( delay_override_ns) = value. delay_override_ns {
107173 link. delay_override_ns = delay_override_ns;
108174 }
175+
176+ // For now only allow foundation to update status
109177 if let Some ( status) = value. status {
110178 // Only allow to update the status if the payer is in the foundation allowlist
111179 if !globalstate. foundation_allowlist . contains ( payer_account. key ) {
180+ msg ! (
181+ "Payer is not in the foundation allowlist: {:?}" ,
182+ payer_account. key
183+ ) ;
112184 return Err ( DoubleZeroError :: NotAllowed . into ( ) ) ;
113185 }
114186 link. status = status;
0 commit comments