Skip to content

Commit 6368c13

Browse files
authored
programs: backward compatible instruction args deserialization (#1949)
## Summary of Changes - Add a [new crate](https://github.com/malbeclabs/borsh-incremental-rs) providing the `BorshDeserializeIncremental` derive macro for incremental deserialization of structs with per-field defaults. - Enables decoding to succeed when new fields are added, allowing backward-compatible evolution of instruction argument types and onchain state layouts, without breaking interaction of existing clients and components. - Generalizes the manual partial-decode pattern used for [state objects](https://github.com/malbeclabs/doublezero/blob/main/smartcontract/programs/doublezero-serviceability/src/state/accesspass.rs#L184-L199), so we no longer have to hand-write incremental deserialization for each type. - Update serviceability and telemetry program instruction args to use the derive. - Resolves #1950 ## Testing Verification - Added test coverage for the new derive macro, including default fallbacks and partial input handling.
1 parent 4a85933 commit 6368c13

File tree

97 files changed

+460
-303
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+460
-303
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file.
1010

1111
- Onchain programs
1212
- serviceability: add auto-assignment and validation for exchange.bgp_community
13+
- Update serviceability and telemetry program instruction args to use the `BorshDeserializeIncremental` derive macro incremental, backward-compatible, deserialization of structs.
1314
- CLI
1415
- Removed `--bgp-community` option from `doublezero exchange create` since these values are now assigned automatically
1516
- Add `--next-bgp-community` option to `doublezero global-config set` so authorized users can control which bgp_community will be assigned next

Cargo.lock

Lines changed: 22 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ base64 = "0.22.1"
3434
bincode = { version = "2", features = ["serde"] }
3535
bitvec = "1"
3636
borsh = "1"
37+
borsh-incremental = { version = "0" }
3738
bytemuck = { version = "1", features = ["derive"] }
3839
byteorder = "1"
3940
chrono = "0"

activator/src/process/device.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ mod tests {
189189
.times(1)
190190
.in_sequence(&mut seq)
191191
.with(
192-
predicate::eq(DoubleZeroInstruction::ActivateDevice(DeviceActivateArgs)),
192+
predicate::eq(DoubleZeroInstruction::ActivateDevice(DeviceActivateArgs {})),
193193
predicate::always(),
194194
)
195195
.returning(|_, _| Ok(Signature::new_unique()));

smartcontract/programs/doublezero-serviceability/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ crate-type = ["cdylib", "lib"]
1717

1818
[dependencies]
1919
borsh.workspace = true
20+
borsh-incremental.workspace = true
2021
doublezero-program-common.workspace = true
2122
ipnetwork.workspace = true
2223
serde = { workspace = true, optional = true }

smartcontract/programs/doublezero-serviceability/src/instructions.rs

Lines changed: 99 additions & 99 deletions
Large diffs are not rendered by default.

smartcontract/programs/doublezero-serviceability/src/processors/accesspass/check_status.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ use crate::{
33
globalstate::globalstate_get,
44
state::{accesspass::AccessPass, accounttype::AccountTypeInfo},
55
};
6-
use borsh::{BorshDeserialize, BorshSerialize};
6+
use borsh::BorshSerialize;
7+
use borsh_incremental::BorshDeserializeIncremental;
78
use core::fmt;
89
use doublezero_program_common::resize_account::resize_account_if_needed;
910
use solana_program::{
@@ -13,7 +14,7 @@ use solana_program::{
1314
pubkey::Pubkey,
1415
};
1516

16-
#[derive(BorshSerialize, BorshDeserialize, PartialEq, Clone, Default)]
17+
#[derive(BorshSerialize, BorshDeserializeIncremental, PartialEq, Clone, Default)]
1718
pub struct CheckStatusAccessPassArgs {}
1819

1920
impl fmt::Debug for CheckStatusAccessPassArgs {

smartcontract/programs/doublezero-serviceability/src/processors/accesspass/close.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ use crate::{
22
error::DoubleZeroError, globalstate::globalstate_get, helper::account_close,
33
state::accounttype::AccountType,
44
};
5-
use borsh::{BorshDeserialize, BorshSerialize};
5+
use borsh::BorshSerialize;
6+
use borsh_incremental::BorshDeserializeIncremental;
67
use core::fmt;
78
use solana_program::{
89
account_info::{next_account_info, AccountInfo},
@@ -11,7 +12,7 @@ use solana_program::{
1112
pubkey::Pubkey,
1213
};
1314

14-
#[derive(BorshSerialize, BorshDeserialize, PartialEq, Clone, Default)]
15+
#[derive(BorshSerialize, BorshDeserializeIncremental, PartialEq, Clone, Default)]
1516
pub struct CloseAccessPassArgs {}
1617

1718
impl fmt::Debug for CloseAccessPassArgs {

smartcontract/programs/doublezero-serviceability/src/processors/accesspass/set.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ use crate::{
1111
accounttype::{AccountType, AccountTypeInfo},
1212
},
1313
};
14-
use borsh::{BorshDeserialize, BorshSerialize};
14+
use borsh::BorshSerialize;
15+
use borsh_incremental::BorshDeserializeIncremental;
1516
use doublezero_program_common::{resize_account::resize_account_if_needed, try_create_account};
1617
use solana_program::{
1718
account_info::{next_account_info, AccountInfo},
@@ -29,10 +30,11 @@ use solana_program::{
2930
// `User` account size assumes a single publisher and subscriber pubkey registered
3031
const AIRDROP_USER_RENT_LAMPORTS_BYTES: usize = 236 * 3; // 236 bytes per User account x 3 accounts = 708 bytes
3132

32-
#[derive(BorshSerialize, BorshDeserialize, PartialEq, Clone)]
33+
#[derive(BorshSerialize, BorshDeserializeIncremental, PartialEq, Clone)]
3334
pub struct SetAccessPassArgs {
3435
pub accesspass_type: AccessPassType, // 1 or 33
35-
pub client_ip: Ipv4Addr, // 4
36+
#[incremental(default = Ipv4Addr::UNSPECIFIED)]
37+
pub client_ip: Ipv4Addr, // 4
3638
pub last_access_epoch: u64, // 8
3739
pub allow_multiple_ip: bool, // 1
3840
}

smartcontract/programs/doublezero-serviceability/src/processors/allowlist/device/add.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ use crate::{
55
globalstate::{globalstate_get, globalstate_write_with_realloc},
66
pda::*,
77
};
8-
use borsh::{BorshDeserialize, BorshSerialize};
8+
use borsh::BorshSerialize;
9+
use borsh_incremental::BorshDeserializeIncremental;
910
#[cfg(test)]
1011
use solana_program::msg;
1112
use solana_program::{
@@ -15,7 +16,7 @@ use solana_program::{
1516
pubkey::Pubkey,
1617
};
1718

18-
#[derive(BorshSerialize, BorshDeserialize, PartialEq, Clone, Default)]
19+
#[derive(BorshSerialize, BorshDeserializeIncremental, PartialEq, Clone, Default)]
1920
pub struct AddDeviceAllowlistArgs {
2021
pub pubkey: Pubkey,
2122
}

0 commit comments

Comments
 (0)