v0.1.0-pre.008
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// file: kb-lib/src/decoder.rs
|
||||
// version: 4
|
||||
// version: 5
|
||||
|
||||
//! Consolidated decoder modules.
|
||||
|
||||
@@ -33,6 +33,8 @@ pub mod vesting;
|
||||
pub mod wallet;
|
||||
pub mod weighted;
|
||||
|
||||
/// One parsed SPL ElGamal registry instruction.
|
||||
pub(crate) use self::spl::ParsedRegistryInstruction;
|
||||
/// Current stable Associated Token Account decoded event contract version.
|
||||
pub(crate) use self::spl::SPL_ASSOCIATED_TOKEN_ACCOUNT_EVENT_VERSION;
|
||||
/// Exact Associated Token Account instructions published by the official interface.
|
||||
@@ -51,6 +53,14 @@ pub(crate) use self::spl::SPL_ASSOCIATED_TOKEN_ACCOUNT_MAX_TRANSACTION_KEYS;
|
||||
pub(crate) use self::spl::SPL_ASSOCIATED_TOKEN_ACCOUNT_SURFACE_CODE;
|
||||
/// Canonical tracing target for the Associated Token Account decoder.
|
||||
pub(crate) use self::spl::SPL_ASSOCIATED_TOKEN_ACCOUNT_TRACING_TARGET;
|
||||
/// Current stable SPL ElGamal registry event contract version.
|
||||
pub(crate) use self::spl::SPL_ELGAMAL_REGISTRY_EVENT_VERSION;
|
||||
/// Maximum retained SPL ElGamal registry instruction payload size.
|
||||
pub(crate) use self::spl::SPL_ELGAMAL_REGISTRY_MAX_INSTRUCTION_BYTES;
|
||||
/// Stable SPL ElGamal registry surface code.
|
||||
pub(crate) use self::spl::SPL_ELGAMAL_REGISTRY_SURFACE_CODE;
|
||||
/// Canonical tracing target for the SPL ElGamal registry decoder.
|
||||
pub(crate) use self::spl::SPL_ELGAMAL_REGISTRY_TRACING_TARGET;
|
||||
/// Maximum payload prefix retained for bounded diagnostics.
|
||||
pub(crate) use self::spl::SPL_MEMO_DIAGNOSTIC_PREFIX_BYTES;
|
||||
/// Current stable Memo decoded event contract version.
|
||||
@@ -67,6 +77,24 @@ pub(crate) use self::spl::SPL_MEMO_V1_SURFACE_CODE;
|
||||
pub(crate) use self::spl::SPL_MEMO_V3_SURFACE_CODE;
|
||||
/// Stable Memo v4 surface code.
|
||||
pub(crate) use self::spl::SPL_MEMO_V4_SURFACE_CODE;
|
||||
/// Maximum prefix retained in bounded Token-2022 diagnostics.
|
||||
pub(crate) use self::spl::SPL_TOKEN_2022_DIAGNOSTIC_PREFIX_BYTES;
|
||||
/// Current stable Token-2022 decoded event contract version.
|
||||
pub(crate) use self::spl::SPL_TOKEN_2022_EVENT_VERSION;
|
||||
/// Exact top-level instruction inventory published by the resolved Token-2022 interface.
|
||||
pub(crate) use self::spl::SPL_TOKEN_2022_INSTRUCTION_ENTRIES;
|
||||
/// Maximum total account metas consumed by one Token-2022 batch.
|
||||
pub(crate) use self::spl::SPL_TOKEN_2022_MAX_BATCH_ACCOUNTS;
|
||||
/// Maximum decoded sub-instructions in one Token-2022 batch.
|
||||
pub(crate) use self::spl::SPL_TOKEN_2022_MAX_BATCH_INSTRUCTIONS;
|
||||
/// Maximum retained Token-2022 instruction payload size.
|
||||
pub(crate) use self::spl::SPL_TOKEN_2022_MAX_INSTRUCTION_BYTES;
|
||||
/// Maximum retained UTF-8 string size for embedded Token Metadata instructions.
|
||||
pub(crate) use self::spl::SPL_TOKEN_2022_MAX_METADATA_STRING_BYTES;
|
||||
/// Stable Token-2022 surface code.
|
||||
pub(crate) use self::spl::SPL_TOKEN_2022_SURFACE_CODE;
|
||||
/// Canonical tracing target for the Token-2022 decoder.
|
||||
pub(crate) use self::spl::SPL_TOKEN_2022_TRACING_TARGET;
|
||||
/// Maximum prefix retained in bounded classic SPL Token diagnostics.
|
||||
pub(crate) use self::spl::SPL_TOKEN_DIAGNOSTIC_PREFIX_BYTES;
|
||||
/// Current stable classic SPL Token decoded event contract version.
|
||||
@@ -89,8 +117,20 @@ pub(crate) use self::spl::spl_associated_token_account_decode;
|
||||
pub(crate) use self::spl::spl_associated_token_account_entry;
|
||||
/// Reads one bounded Associated Token Account payload.
|
||||
pub(crate) use self::spl::spl_associated_token_account_payload;
|
||||
/// Decodes one bounded SPL ElGamal registry instruction.
|
||||
pub(crate) use self::spl::spl_elgamal_registry_decode;
|
||||
/// Decodes one bounded SPL ElGamal registry instruction payload.
|
||||
pub(crate) use self::spl::spl_elgamal_registry_decode_payload;
|
||||
/// Parses one exact SPL ElGamal registry instruction.
|
||||
pub(crate) use self::spl::spl_elgamal_registry_parse;
|
||||
/// Decodes one bounded SPL Memo instruction.
|
||||
pub(crate) use self::spl::spl_memo_decode;
|
||||
/// Decodes one bounded Token-2022 instruction.
|
||||
pub(crate) use self::spl::spl_token_2022_decode;
|
||||
/// Returns the exact entry matching one Token-2022 tag.
|
||||
pub(crate) use self::spl::spl_token_2022_entry_for_tag;
|
||||
/// Returns the first byte of one retained Token-2022 payload.
|
||||
pub(crate) use self::spl::spl_token_2022_payload_tag;
|
||||
/// Decodes one bounded classic SPL Token instruction.
|
||||
pub(crate) use self::spl::spl_token_decode;
|
||||
/// Returns the published entry matching one classic SPL Token tag.
|
||||
@@ -98,9 +138,27 @@ pub(crate) use self::spl::spl_token_entry_for_tag;
|
||||
/// Returns the first byte of one retained classic SPL Token payload.
|
||||
pub(crate) use self::spl::spl_token_payload_tag;
|
||||
|
||||
/// Exact byte length of one SPL ElGamal registry account.
|
||||
pub use self::spl::ELGAMAL_REGISTRY_ACCOUNT_LEN;
|
||||
/// Parsed SPL ElGamal public-key registry account.
|
||||
pub use self::spl::ElGamalRegistryState;
|
||||
/// Exact decoder for the SPL Associated Token Account program.
|
||||
pub use self::spl::SplAssociatedTokenAccountDecoder;
|
||||
/// Exact decoder for the SPL ElGamal registry program.
|
||||
pub use self::spl::SplElgamalRegistryDecoder;
|
||||
/// Exact decoder for the three registered SPL Memo generations.
|
||||
pub use self::spl::SplMemoDecoder;
|
||||
/// Exact decoder for the Token-2022 program.
|
||||
pub use self::spl::SplToken2022Decoder;
|
||||
/// Exact decoder for the classic SPL Token program.
|
||||
pub use self::spl::SplTokenDecoder;
|
||||
/// Parsed Token-2022 Mint, Account, or Multisig state.
|
||||
pub use self::spl::Token2022State;
|
||||
/// Exact Token-2022 base account state kind.
|
||||
pub use self::spl::Token2022StateKind;
|
||||
/// One exact Token-2022 TLV entry.
|
||||
pub use self::spl::Token2022TlvEntry;
|
||||
/// Parses one exact SPL ElGamal registry account.
|
||||
pub use self::spl::parse_elgamal_registry_state;
|
||||
/// Parses one Token-2022 Mint, Account, or Multisig state.
|
||||
pub use self::spl::parse_token_2022_state;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: kb-lib/src/decoder/spl.rs
|
||||
// version: 4
|
||||
// version: 5
|
||||
|
||||
//! `spl` decoder family.
|
||||
|
||||
@@ -37,6 +37,22 @@ pub(crate) use self::associated_token_account::spl_associated_token_account_deco
|
||||
pub(crate) use self::associated_token_account::spl_associated_token_account_entry;
|
||||
/// Reads one bounded Associated Token Account payload.
|
||||
pub(crate) use self::associated_token_account::spl_associated_token_account_payload;
|
||||
/// One parsed SPL ElGamal registry instruction.
|
||||
pub(crate) use self::elgamal_registry::ParsedRegistryInstruction;
|
||||
/// Current stable SPL ElGamal registry event contract version.
|
||||
pub(crate) use self::elgamal_registry::SPL_ELGAMAL_REGISTRY_EVENT_VERSION;
|
||||
/// Maximum retained SPL ElGamal registry instruction payload size.
|
||||
pub(crate) use self::elgamal_registry::SPL_ELGAMAL_REGISTRY_MAX_INSTRUCTION_BYTES;
|
||||
/// Stable SPL ElGamal registry surface code.
|
||||
pub(crate) use self::elgamal_registry::SPL_ELGAMAL_REGISTRY_SURFACE_CODE;
|
||||
/// Canonical tracing target for the SPL ElGamal registry decoder.
|
||||
pub(crate) use self::elgamal_registry::SPL_ELGAMAL_REGISTRY_TRACING_TARGET;
|
||||
/// Decodes one bounded SPL ElGamal registry instruction.
|
||||
pub(crate) use self::elgamal_registry::spl_elgamal_registry_decode;
|
||||
/// Decodes one bounded SPL ElGamal registry instruction payload.
|
||||
pub(crate) use self::elgamal_registry::spl_elgamal_registry_decode_payload;
|
||||
/// Parses one exact SPL ElGamal registry instruction.
|
||||
pub(crate) use self::elgamal_registry::spl_elgamal_registry_parse;
|
||||
/// Maximum payload prefix retained for bounded diagnostics.
|
||||
pub(crate) use self::memo::SPL_MEMO_DIAGNOSTIC_PREFIX_BYTES;
|
||||
/// Current stable Memo decoded event contract version.
|
||||
@@ -77,10 +93,52 @@ pub(crate) use self::token::spl_token_decode;
|
||||
pub(crate) use self::token::spl_token_entry_for_tag;
|
||||
/// Returns the first byte of one retained classic SPL Token payload.
|
||||
pub(crate) use self::token::spl_token_payload_tag;
|
||||
/// Maximum prefix retained in bounded Token-2022 diagnostics.
|
||||
pub(crate) use self::token_2022::SPL_TOKEN_2022_DIAGNOSTIC_PREFIX_BYTES;
|
||||
/// Current stable Token-2022 decoded event contract version.
|
||||
pub(crate) use self::token_2022::SPL_TOKEN_2022_EVENT_VERSION;
|
||||
/// Exact top-level instruction inventory published by the resolved Token-2022 interface.
|
||||
pub(crate) use self::token_2022::SPL_TOKEN_2022_INSTRUCTION_ENTRIES;
|
||||
/// Maximum total account metas consumed by one Token-2022 batch.
|
||||
pub(crate) use self::token_2022::SPL_TOKEN_2022_MAX_BATCH_ACCOUNTS;
|
||||
/// Maximum decoded sub-instructions in one Token-2022 batch.
|
||||
pub(crate) use self::token_2022::SPL_TOKEN_2022_MAX_BATCH_INSTRUCTIONS;
|
||||
/// Maximum retained Token-2022 instruction payload size.
|
||||
pub(crate) use self::token_2022::SPL_TOKEN_2022_MAX_INSTRUCTION_BYTES;
|
||||
/// Maximum retained UTF-8 string size for embedded Token Metadata instructions.
|
||||
pub(crate) use self::token_2022::SPL_TOKEN_2022_MAX_METADATA_STRING_BYTES;
|
||||
/// Stable Token-2022 surface code.
|
||||
pub(crate) use self::token_2022::SPL_TOKEN_2022_SURFACE_CODE;
|
||||
/// Canonical tracing target for the Token-2022 decoder.
|
||||
pub(crate) use self::token_2022::SPL_TOKEN_2022_TRACING_TARGET;
|
||||
/// Decodes one bounded Token-2022 instruction.
|
||||
pub(crate) use self::token_2022::spl_token_2022_decode;
|
||||
/// Returns the exact entry matching one Token-2022 tag.
|
||||
pub(crate) use self::token_2022::spl_token_2022_entry_for_tag;
|
||||
/// Returns the first byte of one retained Token-2022 payload.
|
||||
pub(crate) use self::token_2022::spl_token_2022_payload_tag;
|
||||
|
||||
/// Exact decoder for the SPL Associated Token Account program.
|
||||
pub use self::associated_token_account::SplAssociatedTokenAccountDecoder;
|
||||
/// Exact byte length of one SPL ElGamal registry account.
|
||||
pub use self::elgamal_registry::ELGAMAL_REGISTRY_ACCOUNT_LEN;
|
||||
/// Parsed SPL ElGamal public-key registry account.
|
||||
pub use self::elgamal_registry::ElGamalRegistryState;
|
||||
/// Exact decoder for the SPL ElGamal registry program.
|
||||
pub use self::elgamal_registry::SplElgamalRegistryDecoder;
|
||||
/// Parses one exact SPL ElGamal registry account.
|
||||
pub use self::elgamal_registry::parse_elgamal_registry_state;
|
||||
/// Exact decoder for the three registered SPL Memo generations.
|
||||
pub use self::memo::SplMemoDecoder;
|
||||
/// Exact decoder for the classic SPL Token program.
|
||||
pub use self::token::SplTokenDecoder;
|
||||
/// Exact decoder for the Token-2022 program.
|
||||
pub use self::token_2022::SplToken2022Decoder;
|
||||
/// Parsed Token-2022 Mint, Account, or Multisig state.
|
||||
pub use self::token_2022::Token2022State;
|
||||
/// Exact Token-2022 base account state kind.
|
||||
pub use self::token_2022::Token2022StateKind;
|
||||
/// One exact Token-2022 TLV entry.
|
||||
pub use self::token_2022::Token2022TlvEntry;
|
||||
/// Parses one Token-2022 Mint, Account, or Multisig state.
|
||||
pub use self::token_2022::parse_token_2022_state;
|
||||
|
||||
@@ -1,10 +1,35 @@
|
||||
// file: kb-lib/src/decoder/spl/elgamal_registry.rs
|
||||
// version: 1
|
||||
// version: 2
|
||||
|
||||
//! Migration boundary for legacy crate `kb_decoder_spl_elgamal_registry`.
|
||||
//! Exact SPL Token-2022 ElGamal public-key registry decoder component.
|
||||
|
||||
/// Legacy crate name retained for migration and compatibility tracking.
|
||||
pub const LEGACY_CRATE: &str = "kb_decoder_spl_elgamal_registry";
|
||||
mod constants;
|
||||
mod decoder;
|
||||
mod state;
|
||||
mod wire;
|
||||
|
||||
/// Current porting status.
|
||||
pub const MIGRATION_STATUS: &str = "source-preserved-pending-port";
|
||||
/// Current stable SPL ElGamal registry event contract version.
|
||||
pub(crate) use self::constants::SPL_ELGAMAL_REGISTRY_EVENT_VERSION;
|
||||
/// Maximum retained SPL ElGamal registry instruction payload size.
|
||||
pub(crate) use self::constants::SPL_ELGAMAL_REGISTRY_MAX_INSTRUCTION_BYTES;
|
||||
/// Stable SPL ElGamal registry surface code.
|
||||
pub(crate) use self::constants::SPL_ELGAMAL_REGISTRY_SURFACE_CODE;
|
||||
/// Canonical tracing target for the SPL ElGamal registry decoder.
|
||||
pub(crate) use self::constants::SPL_ELGAMAL_REGISTRY_TRACING_TARGET;
|
||||
/// One parsed SPL ElGamal registry instruction.
|
||||
pub(crate) use self::wire::ParsedRegistryInstruction;
|
||||
/// Decodes one bounded SPL ElGamal registry instruction.
|
||||
pub(crate) use self::wire::spl_elgamal_registry_decode;
|
||||
/// Decodes one bounded SPL ElGamal registry instruction payload.
|
||||
pub(crate) use self::wire::spl_elgamal_registry_decode_payload;
|
||||
/// Parses one exact SPL ElGamal registry instruction.
|
||||
pub(crate) use self::wire::spl_elgamal_registry_parse;
|
||||
|
||||
/// Exact decoder for the SPL ElGamal registry program.
|
||||
pub use self::decoder::SplElgamalRegistryDecoder;
|
||||
/// Exact byte length of one SPL ElGamal registry account.
|
||||
pub use self::state::ELGAMAL_REGISTRY_ACCOUNT_LEN;
|
||||
/// Parsed SPL ElGamal public-key registry account.
|
||||
pub use self::state::ElGamalRegistryState;
|
||||
/// Parses one exact SPL ElGamal registry account.
|
||||
pub use self::state::parse_elgamal_registry_state;
|
||||
|
||||
11
kb-lib/src/decoder/spl/elgamal_registry/constants.rs
Normal file
11
kb-lib/src/decoder/spl/elgamal_registry/constants.rs
Normal file
@@ -0,0 +1,11 @@
|
||||
// file: kb-lib/src/decoder/spl/elgamal_registry/constants.rs
|
||||
// version: 1
|
||||
|
||||
//! Constants for the SPL ElGamal registry decoder.
|
||||
|
||||
pub(crate) const SPL_ELGAMAL_REGISTRY_SURFACE_CODE: &str = "spl_elgamal_registry";
|
||||
pub(crate) const SPL_ELGAMAL_REGISTRY_EVENT_VERSION: u32 = 1;
|
||||
pub(crate) const SPL_ELGAMAL_REGISTRY_MAX_INSTRUCTION_BYTES: usize = 16;
|
||||
|
||||
/// Canonical tracing target for this crate.
|
||||
pub(crate) const SPL_ELGAMAL_REGISTRY_TRACING_TARGET: &str = "kb-lib.decoder.spl.elgamal_registry";
|
||||
246
kb-lib/src/decoder/spl/elgamal_registry/decoder.rs
Normal file
246
kb-lib/src/decoder/spl/elgamal_registry/decoder.rs
Normal file
@@ -0,0 +1,246 @@
|
||||
// file: kb-lib/src/decoder/spl/elgamal_registry/decoder.rs
|
||||
// version: 1
|
||||
|
||||
//! Exact dispatch for the SPL ElGamal registry program.
|
||||
|
||||
const SURFACES: &[crate::DecoderSurface] = &[crate::DecoderSurface {
|
||||
program_id: kb_program_ids::SPL_TOKEN_2022_ELGAMAL_REGISTRY_PROGRAM_ID,
|
||||
surface_code: crate::SPL_ELGAMAL_REGISTRY_SURFACE_CODE,
|
||||
priority: 100,
|
||||
}];
|
||||
|
||||
const PROGRAM_IDS: &[&str] = &[kb_program_ids::SPL_TOKEN_2022_ELGAMAL_REGISTRY_PROGRAM_ID];
|
||||
|
||||
/// Decoder for the dedicated Token-2022 ElGamal public-key registry program.
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct SplElgamalRegistryDecoder;
|
||||
|
||||
impl crate::ProtocolDecoder for crate::SplElgamalRegistryDecoder {
|
||||
fn decoder_name(&self) -> &'static str {
|
||||
return "kb_decoder_spl_elgamal_registry";
|
||||
}
|
||||
|
||||
fn decoder_version(&self) -> &'static str {
|
||||
return env!("CARGO_PKG_VERSION");
|
||||
}
|
||||
|
||||
fn program_ids(&self) -> &'static [&'static str] {
|
||||
return PROGRAM_IDS;
|
||||
}
|
||||
|
||||
fn supports_observation(
|
||||
&self,
|
||||
observation: &crate::ProgramObservation,
|
||||
) -> crate::DecoderSupport {
|
||||
return if crate::ProtocolDecoder::handles_program_id(self, &observation.program_id) {
|
||||
crate::DecoderSupport::Yes
|
||||
} else {
|
||||
crate::DecoderSupport::No
|
||||
};
|
||||
}
|
||||
|
||||
fn decode_observation(
|
||||
&self,
|
||||
_observation: &crate::ProgramObservation,
|
||||
) -> kb_core::Result<std::vec::Vec<crate::DecodedProtocolEvent>> {
|
||||
return std::result::Result::Ok(std::vec::Vec::new());
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::InstructionDecoder for crate::SplElgamalRegistryDecoder {
|
||||
fn identity(&self) -> crate::DecoderIdentity {
|
||||
return crate::DecoderIdentity {
|
||||
name: "spl_elgamal_registry".to_string(),
|
||||
version: env!("CARGO_PKG_VERSION").to_string(),
|
||||
};
|
||||
}
|
||||
|
||||
fn surfaces(&self) -> &'static [crate::DecoderSurface] {
|
||||
return SURFACES;
|
||||
}
|
||||
|
||||
fn coverage(&self) -> std::vec::Vec<crate::DecoderCoverageDeclaration> {
|
||||
return [(0_u8, "create_registry"), (1_u8, "update_registry")]
|
||||
.into_iter()
|
||||
.map(|(tag, code)| {
|
||||
return crate::DecoderCoverageDeclaration {
|
||||
program_id: kb_program_ids::SPL_TOKEN_2022_ELGAMAL_REGISTRY_PROGRAM_ID
|
||||
.to_string(),
|
||||
surface_code: std::option::Option::Some(
|
||||
crate::SPL_ELGAMAL_REGISTRY_SURFACE_CODE.to_string(),
|
||||
),
|
||||
entry_kind: crate::DecoderCoverageEntryKind::Instruction,
|
||||
entry_code: code.to_string(),
|
||||
discriminator_hex: std::option::Option::Some(format!("{tag:02x}")),
|
||||
historical: false,
|
||||
};
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
|
||||
fn recognize(&self, input: &crate::CoreInstructionReplayInput) -> crate::DecoderRecognition {
|
||||
if input.program_id != kb_program_ids::SPL_TOKEN_2022_ELGAMAL_REGISTRY_PROGRAM_ID {
|
||||
return crate::DecoderRecognition::incompatible();
|
||||
}
|
||||
let entry = input
|
||||
.instruction_payload_json
|
||||
.as_ref()
|
||||
.and_then(|payload| return payload.get("dataBase64"))
|
||||
.and_then(serde_json::Value::as_str)
|
||||
.and_then(|encoded| {
|
||||
use base64::Engine; // rust-rules: trait-import
|
||||
return base64::engine::general_purpose::STANDARD.decode(encoded.as_bytes()).ok();
|
||||
})
|
||||
.and_then(|bytes| return bytes.first().copied())
|
||||
.and_then(|tag| {
|
||||
return match tag {
|
||||
0 => std::option::Option::Some("create_registry".to_string()),
|
||||
1 => std::option::Option::Some("update_registry".to_string()),
|
||||
_ => std::option::Option::None,
|
||||
};
|
||||
});
|
||||
return crate::DecoderRecognition::compatible(
|
||||
entry.is_some(),
|
||||
100,
|
||||
std::option::Option::Some(crate::SPL_ELGAMAL_REGISTRY_SURFACE_CODE.to_string()),
|
||||
entry,
|
||||
std::option::Option::None,
|
||||
);
|
||||
}
|
||||
|
||||
fn decode(&self, input: &crate::CoreInstructionReplayInput) -> crate::DecoderExecutionResult {
|
||||
if input.program_id != kb_program_ids::SPL_TOKEN_2022_ELGAMAL_REGISTRY_PROGRAM_ID {
|
||||
return crate::DecoderExecutionResult::unsupported(std::option::Option::None);
|
||||
}
|
||||
let result = crate::spl_elgamal_registry_decode(input);
|
||||
if matches!(
|
||||
result.status,
|
||||
crate::DecoderOutcomeStatus::Failed | crate::DecoderOutcomeStatus::Unsupported
|
||||
) {
|
||||
tracing::error!(
|
||||
target: crate::SPL_ELGAMAL_REGISTRY_TRACING_TARGET,
|
||||
action = "decode_failure",
|
||||
signature = %input.signature,
|
||||
slot = input.slot,
|
||||
instruction_path = %input.instruction_path,
|
||||
program_id = %input.program_id,
|
||||
processor_name = "spl_elgamal_registry",
|
||||
processor_version = env!("CARGO_PKG_VERSION"),
|
||||
input_key = %input.replay_input_key,
|
||||
payload_hash = ?input.instruction_payload_hash,
|
||||
transaction_failed = input.transaction_failed,
|
||||
result_status = ?result.status,
|
||||
diagnostics = ?result.diagnostics,
|
||||
"SPL ElGamal registry instruction was not decoded successfully"
|
||||
);
|
||||
}
|
||||
tracing::debug!(
|
||||
target: crate::SPL_ELGAMAL_REGISTRY_TRACING_TARGET,
|
||||
action = "decode",
|
||||
signature = %input.signature,
|
||||
instruction_path = %input.instruction_path,
|
||||
program_id = %input.program_id,
|
||||
transaction_failed = input.transaction_failed,
|
||||
result_status = ?result.status,
|
||||
observation_count = result.observations.len(),
|
||||
"SPL ElGamal registry instruction decode completed"
|
||||
);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use base64::Engine; // rust-rules: trait-import
|
||||
|
||||
fn input(
|
||||
program_id: &str,
|
||||
payload: &[u8],
|
||||
failed: bool,
|
||||
path: &str,
|
||||
) -> crate::CoreInstructionReplayInput {
|
||||
let result = crate::CoreInstructionReplayInput::new(
|
||||
format!("signature:{path}"),
|
||||
"signature",
|
||||
42,
|
||||
path,
|
||||
program_id,
|
||||
failed,
|
||||
if failed {
|
||||
std::option::Option::Some(serde_json::json!({"InstructionError":[0,"Custom"]}))
|
||||
} else {
|
||||
std::option::Option::None
|
||||
},
|
||||
serde_json::json!([]),
|
||||
serde_json::json!([]),
|
||||
std::option::Option::Some(serde_json::json!({
|
||||
"dataBase64": base64::engine::general_purpose::STANDARD.encode(payload)
|
||||
})),
|
||||
std::option::Option::None,
|
||||
serde_json::json!([]),
|
||||
serde_json::json!([]),
|
||||
serde_json::json!([]),
|
||||
serde_json::json!([]),
|
||||
);
|
||||
return match result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => panic!("registry replay input failed: {error}"),
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exact_program_boundary_and_interface_id_are_preserved() {
|
||||
assert_eq!(
|
||||
spl_elgamal_registry_interface::id().to_string(),
|
||||
kb_program_ids::SPL_TOKEN_2022_ELGAMAL_REGISTRY_PROGRAM_ID
|
||||
);
|
||||
let decoder = crate::SplElgamalRegistryDecoder;
|
||||
assert_eq!(crate::InstructionDecoder::coverage(&decoder).len(), 2);
|
||||
let foreign = input(kb_program_ids::SPL_TOKEN_2022_PROGRAM_ID, &[0, 1], false, "0");
|
||||
assert_eq!(
|
||||
crate::InstructionDecoder::decode(&decoder, &foreign).status,
|
||||
crate::DecoderOutcomeStatus::Unsupported
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_and_update_decode_exact_offsets_and_commit_state() {
|
||||
for (tag, code, offset, failed, path) in [
|
||||
(0_u8, "create_registry", 1_i8, false, "0"),
|
||||
(1_u8, "update_registry", -1_i8, true, "1/0"),
|
||||
(1_u8, "update_registry", 0_i8, false, "2"),
|
||||
] {
|
||||
let input = input(
|
||||
kb_program_ids::SPL_TOKEN_2022_ELGAMAL_REGISTRY_PROGRAM_ID,
|
||||
&[tag, offset as u8],
|
||||
failed,
|
||||
path,
|
||||
);
|
||||
let result =
|
||||
crate::InstructionDecoder::decode(&crate::SplElgamalRegistryDecoder, &input);
|
||||
assert_eq!(result.status, crate::DecoderOutcomeStatus::Decoded);
|
||||
assert_eq!(result.recognized_entry_code.as_deref(), std::option::Option::Some(code));
|
||||
assert_eq!(
|
||||
result.observations[0].payload_json["proofInstructionOffset"],
|
||||
serde_json::json!(offset)
|
||||
);
|
||||
assert_eq!(result.observations[0].observation_committed, !failed);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn malformed_unknown_and_suffixed_wire_fail_closed() {
|
||||
for payload in [std::vec::Vec::new(), vec![0], vec![2, 0], vec![0, 1, 2]] {
|
||||
let input = input(
|
||||
kb_program_ids::SPL_TOKEN_2022_ELGAMAL_REGISTRY_PROGRAM_ID,
|
||||
payload.as_slice(),
|
||||
false,
|
||||
"0",
|
||||
);
|
||||
let result =
|
||||
crate::InstructionDecoder::decode(&crate::SplElgamalRegistryDecoder, &input);
|
||||
assert_eq!(result.status, crate::DecoderOutcomeStatus::Failed);
|
||||
assert!(result.observations.is_empty());
|
||||
}
|
||||
}
|
||||
}
|
||||
76
kb-lib/src/decoder/spl/elgamal_registry/state.rs
Normal file
76
kb-lib/src/decoder/spl/elgamal_registry/state.rs
Normal file
@@ -0,0 +1,76 @@
|
||||
// file: kb-lib/src/decoder/spl/elgamal_registry/state.rs
|
||||
// version: 1
|
||||
|
||||
//! Strict SPL ElGamal registry account-state parsing.
|
||||
|
||||
use base64::Engine; // rust-rules: trait-import
|
||||
|
||||
/// Exact byte length of one SPL ElGamal registry account.
|
||||
pub const ELGAMAL_REGISTRY_ACCOUNT_LEN: usize = 64;
|
||||
|
||||
/// Public state retained by one SPL ElGamal registry account.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct ElGamalRegistryState {
|
||||
/// Wallet address associated with this registry.
|
||||
pub owner: String,
|
||||
/// Exact 32-byte ElGamal public key encoded as standard base64.
|
||||
pub elgamal_pubkey_base64: String,
|
||||
/// Exact account bytes encoded as lowercase hexadecimal.
|
||||
pub wire_hex: String,
|
||||
}
|
||||
|
||||
/// Parse one exact SPL ElGamal registry account.
|
||||
pub fn parse_elgamal_registry_state(
|
||||
data: &[u8],
|
||||
) -> std::result::Result<ElGamalRegistryState, std::string::String> {
|
||||
if data.len() != ELGAMAL_REGISTRY_ACCOUNT_LEN {
|
||||
return std::result::Result::Err(format!(
|
||||
"SPL ElGamal registry account requires exactly {ELGAMAL_REGISTRY_ACCOUNT_LEN} bytes; received {}",
|
||||
data.len()
|
||||
));
|
||||
}
|
||||
return std::result::Result::Ok(ElGamalRegistryState {
|
||||
owner: bs58::encode(&data[..32]).into_string(),
|
||||
elgamal_pubkey_base64: base64::engine::general_purpose::STANDARD.encode(&data[32..64]),
|
||||
wire_hex: lower_hex(data),
|
||||
});
|
||||
}
|
||||
|
||||
fn lower_hex(bytes: &[u8]) -> String {
|
||||
let mut output = String::with_capacity(bytes.len() * 2);
|
||||
for byte in bytes {
|
||||
output.push_str(&format!("{byte:02x}"));
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use base64::Engine; // rust-rules: trait-import
|
||||
|
||||
#[test]
|
||||
fn exact_registry_state_preserves_owner_key_and_wire() {
|
||||
let mut data = [0u8; crate::ELGAMAL_REGISTRY_ACCOUNT_LEN];
|
||||
data[..32].fill(7);
|
||||
data[32..].fill(9);
|
||||
let parsed = crate::parse_elgamal_registry_state(&data);
|
||||
assert_eq!(
|
||||
parsed.as_ref().map(|state| return state.owner.clone()),
|
||||
std::result::Result::Ok(bs58::encode([7u8; 32]).into_string())
|
||||
);
|
||||
assert_eq!(
|
||||
parsed.as_ref().map(|state| return state.elgamal_pubkey_base64.clone()),
|
||||
std::result::Result::Ok(base64::engine::general_purpose::STANDARD.encode([9u8; 32]))
|
||||
);
|
||||
assert_eq!(
|
||||
parsed.as_ref().map(|state| return state.wire_hex.len()),
|
||||
std::result::Result::Ok(128)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn registry_state_rejects_every_non_exact_length() {
|
||||
assert!(crate::parse_elgamal_registry_state(&[0; 63]).is_err());
|
||||
assert!(crate::parse_elgamal_registry_state(&[0; 65]).is_err());
|
||||
}
|
||||
}
|
||||
195
kb-lib/src/decoder/spl/elgamal_registry/wire.rs
Normal file
195
kb-lib/src/decoder/spl/elgamal_registry/wire.rs
Normal file
@@ -0,0 +1,195 @@
|
||||
// file: kb-lib/src/decoder/spl/elgamal_registry/wire.rs
|
||||
// version: 1
|
||||
|
||||
//! Exact two-byte SPL ElGamal registry instruction decoding.
|
||||
|
||||
use base64::Engine; // rust-rules: trait-import
|
||||
use sha2::Digest; // rust-rules: trait-import
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct ParsedRegistryInstruction {
|
||||
pub(crate) code: &'static str,
|
||||
pub(crate) tag: u8,
|
||||
pub(crate) proof_instruction_offset: i8,
|
||||
}
|
||||
|
||||
pub(crate) fn spl_elgamal_registry_decode_payload(
|
||||
input: &crate::CoreInstructionReplayInput,
|
||||
) -> std::result::Result<std::vec::Vec<u8>, std::string::String> {
|
||||
let payload = match input.instruction_payload_json.as_ref() {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => {
|
||||
return std::result::Result::Err(
|
||||
"ElGamal registry instruction payload is not retained".to_string(),
|
||||
);
|
||||
},
|
||||
};
|
||||
let encoded = match payload.get("dataBase64").and_then(serde_json::Value::as_str) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => {
|
||||
return std::result::Result::Err(
|
||||
"ElGamal registry payload does not contain dataBase64".to_string(),
|
||||
);
|
||||
},
|
||||
};
|
||||
if encoded.len() > 32 {
|
||||
return std::result::Result::Err(
|
||||
"ElGamal registry base64 payload is too large".to_string(),
|
||||
);
|
||||
}
|
||||
let bytes = match base64::engine::general_purpose::STANDARD.decode(encoded.as_bytes()) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => {
|
||||
return std::result::Result::Err(format!(
|
||||
"ElGamal registry payload is not valid base64: {error}"
|
||||
));
|
||||
},
|
||||
};
|
||||
if bytes.len() > crate::SPL_ELGAMAL_REGISTRY_MAX_INSTRUCTION_BYTES {
|
||||
return std::result::Result::Err(format!(
|
||||
"ElGamal registry payload exceeds {} bytes",
|
||||
crate::SPL_ELGAMAL_REGISTRY_MAX_INSTRUCTION_BYTES
|
||||
));
|
||||
}
|
||||
return std::result::Result::Ok(bytes);
|
||||
}
|
||||
|
||||
pub(crate) fn spl_elgamal_registry_parse(
|
||||
bytes: &[u8],
|
||||
) -> std::result::Result<crate::ParsedRegistryInstruction, std::string::String> {
|
||||
if bytes.len() != 2 {
|
||||
return std::result::Result::Err(format!(
|
||||
"ElGamal registry instruction requires exactly 2 bytes; received {}",
|
||||
bytes.len()
|
||||
));
|
||||
}
|
||||
let code = match bytes[0] {
|
||||
0 => "create_registry",
|
||||
1 => "update_registry",
|
||||
tag => return std::result::Result::Err(format!("unknown ElGamal registry tag {tag}")),
|
||||
};
|
||||
return std::result::Result::Ok(crate::ParsedRegistryInstruction {
|
||||
code,
|
||||
tag: bytes[0],
|
||||
proof_instruction_offset: bytes[1] as i8,
|
||||
});
|
||||
}
|
||||
|
||||
pub(crate) fn spl_elgamal_registry_decode(
|
||||
input: &crate::CoreInstructionReplayInput,
|
||||
) -> crate::DecoderExecutionResult {
|
||||
let bytes = match crate::spl_elgamal_registry_decode_payload(input) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(message) => {
|
||||
return crate::DecoderExecutionResult {
|
||||
status: crate::DecoderOutcomeStatus::Failed,
|
||||
recognized_entry_code: std::option::Option::None,
|
||||
observations: std::vec::Vec::new(),
|
||||
diagnostics: std::vec![crate::DecoderDiagnostic {
|
||||
code: "elgamal_registry_payload_invalid".to_string(),
|
||||
message,
|
||||
retriable: false,
|
||||
}],
|
||||
};
|
||||
},
|
||||
};
|
||||
let parsed = match crate::spl_elgamal_registry_parse(bytes.as_slice()) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(message) => {
|
||||
return crate::DecoderExecutionResult {
|
||||
status: crate::DecoderOutcomeStatus::Failed,
|
||||
recognized_entry_code: bytes.first().and_then(|tag| {
|
||||
return match tag {
|
||||
0 => std::option::Option::Some("create_registry".to_string()),
|
||||
1 => std::option::Option::Some("update_registry".to_string()),
|
||||
_ => std::option::Option::None,
|
||||
};
|
||||
}),
|
||||
observations: std::vec::Vec::new(),
|
||||
diagnostics: std::vec![crate::DecoderDiagnostic {
|
||||
code: "elgamal_registry_wire_invalid".to_string(),
|
||||
message,
|
||||
retriable: false,
|
||||
}],
|
||||
};
|
||||
},
|
||||
};
|
||||
let committed = !input.transaction_failed;
|
||||
let wire_hash = hash(bytes.as_slice());
|
||||
let event = crate::DecodedProtocolEvent {
|
||||
signature: crate::Signature(input.signature.clone()),
|
||||
slot: crate::Slot(input.slot),
|
||||
instruction_path: crate::InstructionPath(input.instruction_path.clone()),
|
||||
program_id: crate::ProgramId(input.program_id.clone()),
|
||||
protocol_code: crate::ProtocolCode(crate::SPL_ELGAMAL_REGISTRY_SURFACE_CODE.to_string()),
|
||||
surface_code: crate::SurfaceCode(crate::SPL_ELGAMAL_REGISTRY_SURFACE_CODE.to_string()),
|
||||
event_code: crate::EventCode(format!(
|
||||
"{}.{}",
|
||||
crate::SPL_ELGAMAL_REGISTRY_SURFACE_CODE,
|
||||
parsed.code
|
||||
)),
|
||||
event_name: crate::EventName(parsed.code.to_string()),
|
||||
event_family: crate::EventFamily::Admin,
|
||||
source_kind: if input.instruction_path.contains('/') {
|
||||
crate::EventSourceKind::InnerInstruction
|
||||
} else {
|
||||
crate::EventSourceKind::Instruction
|
||||
},
|
||||
confidence: crate::DecoderConfidence::ManualExact,
|
||||
};
|
||||
let observation = crate::DecodedObservation {
|
||||
event_key: format!("elgamal_registry:{}:0", parsed.code),
|
||||
event,
|
||||
payload_json: serde_json::json!({
|
||||
"eventVersion": crate::SPL_ELGAMAL_REGISTRY_EVENT_VERSION,
|
||||
"instruction": parsed.code,
|
||||
"wireTag": parsed.tag,
|
||||
"proofInstructionOffset": parsed.proof_instruction_offset,
|
||||
"proofLocationKind": if parsed.proof_instruction_offset == 0 { "context_state_account" } else { "relative_instruction_offset" },
|
||||
"instructionPath": input.instruction_path,
|
||||
"instructionLocation": if input.instruction_path.contains('/') { "inner" } else { "outer" },
|
||||
"transactionSucceeded": !input.transaction_failed,
|
||||
"committed": committed,
|
||||
"accounts": input.instruction_accounts_json,
|
||||
"wire": {
|
||||
"lengthBytes": bytes.len(),
|
||||
"sha256": wire_hash,
|
||||
"prefixHex": hex(bytes.as_slice()),
|
||||
"complete": true,
|
||||
},
|
||||
"programBoundary": {
|
||||
"registryProgramId": kb_program_ids::SPL_TOKEN_2022_ELGAMAL_REGISTRY_PROGRAM_ID,
|
||||
"token2022ProgramId": kb_program_ids::SPL_TOKEN_2022_PROGRAM_ID,
|
||||
"zkProofProgramId": kb_program_ids::ZK_ELGAMAL_PROOF_PROGRAM_ID,
|
||||
"proofDecodedHere": false,
|
||||
}
|
||||
}),
|
||||
transaction_failed: input.transaction_failed,
|
||||
transaction_error: input.transaction_err_json.clone(),
|
||||
observation_committed: committed,
|
||||
proof: crate::DecoderProof {
|
||||
kind: crate::DecoderProofKind::Manual,
|
||||
confidence: crate::DecoderConfidence::ManualExact,
|
||||
evidence: std::vec![
|
||||
"spl_elgamal_registry_interface_0_2_1_registry_instruction_unpack".to_string(),
|
||||
format!("wire_tag:{}", parsed.tag),
|
||||
format!("wire_sha256:{wire_hash}"),
|
||||
],
|
||||
},
|
||||
};
|
||||
return crate::DecoderExecutionResult {
|
||||
status: crate::DecoderOutcomeStatus::Decoded,
|
||||
recognized_entry_code: std::option::Option::Some(parsed.code.to_string()),
|
||||
observations: std::vec![observation],
|
||||
diagnostics: std::vec::Vec::new(),
|
||||
};
|
||||
}
|
||||
|
||||
fn hash(bytes: &[u8]) -> std::string::String {
|
||||
let digest = sha2::Sha256::digest(bytes);
|
||||
return digest.iter().map(|byte| return format!("{byte:02x}")).collect();
|
||||
}
|
||||
|
||||
fn hex(bytes: &[u8]) -> std::string::String {
|
||||
return bytes.iter().map(|byte| return format!("{byte:02x}")).collect();
|
||||
}
|
||||
@@ -1,10 +1,45 @@
|
||||
// file: kb-lib/src/decoder/spl/token_2022.rs
|
||||
// version: 1
|
||||
// version: 2
|
||||
|
||||
//! Migration boundary for legacy crate `kb_decoder_spl_token_2022`.
|
||||
//! Exact Token-2022 instruction and state decoder component.
|
||||
|
||||
/// Legacy crate name retained for migration and compatibility tracking.
|
||||
pub const LEGACY_CRATE: &str = "kb_decoder_spl_token_2022";
|
||||
mod constants;
|
||||
mod decoder;
|
||||
mod state;
|
||||
mod wire;
|
||||
|
||||
/// Current porting status.
|
||||
pub const MIGRATION_STATUS: &str = "source-preserved-pending-port";
|
||||
/// Maximum prefix retained in bounded Token-2022 diagnostics.
|
||||
pub(crate) use self::constants::SPL_TOKEN_2022_DIAGNOSTIC_PREFIX_BYTES;
|
||||
/// Current stable Token-2022 decoded event contract version.
|
||||
pub(crate) use self::constants::SPL_TOKEN_2022_EVENT_VERSION;
|
||||
/// Exact top-level instruction inventory published by the resolved Token-2022 interface.
|
||||
pub(crate) use self::constants::SPL_TOKEN_2022_INSTRUCTION_ENTRIES;
|
||||
/// Maximum total account metas consumed by one Token-2022 batch.
|
||||
pub(crate) use self::constants::SPL_TOKEN_2022_MAX_BATCH_ACCOUNTS;
|
||||
/// Maximum decoded sub-instructions in one Token-2022 batch.
|
||||
pub(crate) use self::constants::SPL_TOKEN_2022_MAX_BATCH_INSTRUCTIONS;
|
||||
/// Maximum retained Token-2022 instruction payload size.
|
||||
pub(crate) use self::constants::SPL_TOKEN_2022_MAX_INSTRUCTION_BYTES;
|
||||
/// Maximum retained UTF-8 string size for embedded Token Metadata instructions.
|
||||
pub(crate) use self::constants::SPL_TOKEN_2022_MAX_METADATA_STRING_BYTES;
|
||||
/// Stable Token-2022 surface code.
|
||||
pub(crate) use self::constants::SPL_TOKEN_2022_SURFACE_CODE;
|
||||
/// Canonical tracing target for the Token-2022 decoder.
|
||||
pub(crate) use self::constants::SPL_TOKEN_2022_TRACING_TARGET;
|
||||
/// Decodes one bounded Token-2022 instruction.
|
||||
pub(crate) use self::wire::spl_token_2022_decode;
|
||||
/// Returns the exact entry matching one Token-2022 tag.
|
||||
pub(crate) use self::wire::spl_token_2022_entry_for_tag;
|
||||
/// Returns the first byte of one retained Token-2022 payload.
|
||||
pub(crate) use self::wire::spl_token_2022_payload_tag;
|
||||
|
||||
/// Exact decoder for the Token-2022 program.
|
||||
pub use self::decoder::SplToken2022Decoder;
|
||||
/// Parsed Token-2022 Mint, Account, or Multisig state.
|
||||
pub use self::state::Token2022State;
|
||||
/// Exact Token-2022 base account state kind.
|
||||
pub use self::state::Token2022StateKind;
|
||||
/// One exact Token-2022 TLV entry.
|
||||
pub use self::state::Token2022TlvEntry;
|
||||
/// Parses one Token-2022 Mint, Account, or Multisig state.
|
||||
pub use self::state::parse_token_2022_state;
|
||||
|
||||
72
kb-lib/src/decoder/spl/token_2022/constants.rs
Normal file
72
kb-lib/src/decoder/spl/token_2022/constants.rs
Normal file
@@ -0,0 +1,72 @@
|
||||
// file: kb-lib/src/decoder/spl/token_2022/constants.rs
|
||||
// version: 1
|
||||
|
||||
//! Local constants for the exact Token-2022 decoder. Program identifiers live in `kb_program_ids`.
|
||||
|
||||
/// Stable Token-2022 surface code.
|
||||
pub(crate) const SPL_TOKEN_2022_SURFACE_CODE: &str = "spl_token_2022";
|
||||
/// Current decoded event contract version.
|
||||
pub(crate) const SPL_TOKEN_2022_EVENT_VERSION: u32 = 1;
|
||||
/// Maximum retained instruction payload size.
|
||||
pub(crate) const SPL_TOKEN_2022_MAX_INSTRUCTION_BYTES: usize = 16_384;
|
||||
/// Maximum retained UTF-8 string size for embedded Token Metadata instructions.
|
||||
pub(crate) const SPL_TOKEN_2022_MAX_METADATA_STRING_BYTES: usize = 4_096;
|
||||
/// Maximum prefix retained in diagnostics.
|
||||
pub(crate) const SPL_TOKEN_2022_DIAGNOSTIC_PREFIX_BYTES: usize = 32;
|
||||
/// Maximum decoded sub-instructions in one batch.
|
||||
pub(crate) const SPL_TOKEN_2022_MAX_BATCH_INSTRUCTIONS: usize = 64;
|
||||
/// Maximum total account metas consumed by one batch.
|
||||
pub(crate) const SPL_TOKEN_2022_MAX_BATCH_ACCOUNTS: usize = 512;
|
||||
/// Exact top-level instruction inventory published by the resolved Token-2022 interface.
|
||||
pub(crate) const SPL_TOKEN_2022_INSTRUCTION_ENTRIES: &[(u8, &str, bool)] = &[
|
||||
(0, "initialize_mint", false),
|
||||
(1, "initialize_account", false),
|
||||
(2, "initialize_multisig", false),
|
||||
(3, "transfer", false),
|
||||
(4, "approve", false),
|
||||
(5, "revoke", false),
|
||||
(6, "set_authority", false),
|
||||
(7, "mint_to", false),
|
||||
(8, "burn", false),
|
||||
(9, "close_account", false),
|
||||
(10, "freeze_account", false),
|
||||
(11, "thaw_account", false),
|
||||
(12, "transfer_checked", false),
|
||||
(13, "approve_checked", false),
|
||||
(14, "mint_to_checked", false),
|
||||
(15, "burn_checked", false),
|
||||
(16, "initialize_account2", false),
|
||||
(17, "sync_native", false),
|
||||
(18, "initialize_account3", false),
|
||||
(19, "initialize_multisig2", false),
|
||||
(20, "initialize_mint2", false),
|
||||
(21, "get_account_data_size", false),
|
||||
(22, "initialize_immutable_owner", false),
|
||||
(23, "amount_to_ui_amount", false),
|
||||
(24, "ui_amount_to_amount", false),
|
||||
(25, "initialize_mint_close_authority", false),
|
||||
(26, "transfer_fee_extension", false),
|
||||
(27, "confidential_transfer_extension", false),
|
||||
(28, "default_account_state_extension", false),
|
||||
(29, "reallocate", false),
|
||||
(30, "memo_transfer_extension", false),
|
||||
(31, "create_native_mint", false),
|
||||
(32, "initialize_non_transferable_mint", false),
|
||||
(33, "interest_bearing_mint_extension", false),
|
||||
(34, "cpi_guard_extension", false),
|
||||
(35, "initialize_permanent_delegate", false),
|
||||
(36, "transfer_hook_extension", false),
|
||||
(37, "confidential_transfer_fee_extension", false),
|
||||
(38, "withdraw_excess_lamports", false),
|
||||
(39, "metadata_pointer_extension", false),
|
||||
(40, "group_pointer_extension", false),
|
||||
(41, "group_member_pointer_extension", false),
|
||||
(42, "confidential_mint_burn_extension", false),
|
||||
(43, "scaled_ui_amount_extension", false),
|
||||
(44, "pausable_extension", false),
|
||||
(45, "unwrap_lamports", false),
|
||||
(46, "permissioned_burn_extension", false),
|
||||
(255, "batch", false),
|
||||
];
|
||||
/// Canonical tracing target for this crate.
|
||||
pub(crate) const SPL_TOKEN_2022_TRACING_TARGET: &str = "kb-lib.decoder.spl.token_2022";
|
||||
1238
kb-lib/src/decoder/spl/token_2022/decoder.rs
Normal file
1238
kb-lib/src/decoder/spl/token_2022/decoder.rs
Normal file
File diff suppressed because it is too large
Load Diff
1647
kb-lib/src/decoder/spl/token_2022/state.rs
Normal file
1647
kb-lib/src/decoder/spl/token_2022/state.rs
Normal file
File diff suppressed because it is too large
Load Diff
2603
kb-lib/src/decoder/spl/token_2022/wire.rs
Normal file
2603
kb-lib/src/decoder/spl/token_2022/wire.rs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
// file: kb-lib/src/lib.rs
|
||||
// version: 9
|
||||
// version: 10
|
||||
|
||||
//! Consolidated decoder, executor, materializer and shared model library.
|
||||
#![warn(missing_docs)]
|
||||
@@ -11,6 +11,8 @@ pub mod executor;
|
||||
pub mod materializer;
|
||||
pub mod model;
|
||||
|
||||
/// One parsed SPL ElGamal registry instruction.
|
||||
pub(crate) use crate::decoder::ParsedRegistryInstruction;
|
||||
/// Current stable Associated Token Account decoded event contract version.
|
||||
pub(crate) use crate::decoder::SPL_ASSOCIATED_TOKEN_ACCOUNT_EVENT_VERSION;
|
||||
/// Exact Associated Token Account instructions published by the official interface.
|
||||
@@ -29,6 +31,14 @@ pub(crate) use crate::decoder::SPL_ASSOCIATED_TOKEN_ACCOUNT_MAX_TRANSACTION_KEYS
|
||||
pub(crate) use crate::decoder::SPL_ASSOCIATED_TOKEN_ACCOUNT_SURFACE_CODE;
|
||||
/// Canonical tracing target for the Associated Token Account decoder.
|
||||
pub(crate) use crate::decoder::SPL_ASSOCIATED_TOKEN_ACCOUNT_TRACING_TARGET;
|
||||
/// Current stable SPL ElGamal registry event contract version.
|
||||
pub(crate) use crate::decoder::SPL_ELGAMAL_REGISTRY_EVENT_VERSION;
|
||||
/// Maximum retained SPL ElGamal registry instruction payload size.
|
||||
pub(crate) use crate::decoder::SPL_ELGAMAL_REGISTRY_MAX_INSTRUCTION_BYTES;
|
||||
/// Stable SPL ElGamal registry surface code.
|
||||
pub(crate) use crate::decoder::SPL_ELGAMAL_REGISTRY_SURFACE_CODE;
|
||||
/// Canonical tracing target for the SPL ElGamal registry decoder.
|
||||
pub(crate) use crate::decoder::SPL_ELGAMAL_REGISTRY_TRACING_TARGET;
|
||||
/// Maximum payload prefix retained for bounded Memo diagnostics.
|
||||
pub(crate) use crate::decoder::SPL_MEMO_DIAGNOSTIC_PREFIX_BYTES;
|
||||
/// Current stable Memo decoded event contract version.
|
||||
@@ -45,6 +55,24 @@ pub(crate) use crate::decoder::SPL_MEMO_V1_SURFACE_CODE;
|
||||
pub(crate) use crate::decoder::SPL_MEMO_V3_SURFACE_CODE;
|
||||
/// Stable Memo v4 surface code.
|
||||
pub(crate) use crate::decoder::SPL_MEMO_V4_SURFACE_CODE;
|
||||
/// Maximum prefix retained in bounded Token-2022 diagnostics.
|
||||
pub(crate) use crate::decoder::SPL_TOKEN_2022_DIAGNOSTIC_PREFIX_BYTES;
|
||||
/// Current stable Token-2022 decoded event contract version.
|
||||
pub(crate) use crate::decoder::SPL_TOKEN_2022_EVENT_VERSION;
|
||||
/// Exact top-level instruction inventory published by the resolved Token-2022 interface.
|
||||
pub(crate) use crate::decoder::SPL_TOKEN_2022_INSTRUCTION_ENTRIES;
|
||||
/// Maximum total account metas consumed by one Token-2022 batch.
|
||||
pub(crate) use crate::decoder::SPL_TOKEN_2022_MAX_BATCH_ACCOUNTS;
|
||||
/// Maximum decoded sub-instructions in one Token-2022 batch.
|
||||
pub(crate) use crate::decoder::SPL_TOKEN_2022_MAX_BATCH_INSTRUCTIONS;
|
||||
/// Maximum retained Token-2022 instruction payload size.
|
||||
pub(crate) use crate::decoder::SPL_TOKEN_2022_MAX_INSTRUCTION_BYTES;
|
||||
/// Maximum retained UTF-8 string size for embedded Token Metadata instructions.
|
||||
pub(crate) use crate::decoder::SPL_TOKEN_2022_MAX_METADATA_STRING_BYTES;
|
||||
/// Stable Token-2022 surface code.
|
||||
pub(crate) use crate::decoder::SPL_TOKEN_2022_SURFACE_CODE;
|
||||
/// Canonical tracing target for the Token-2022 decoder.
|
||||
pub(crate) use crate::decoder::SPL_TOKEN_2022_TRACING_TARGET;
|
||||
/// Maximum prefix retained in bounded classic SPL Token diagnostics.
|
||||
pub(crate) use crate::decoder::SPL_TOKEN_DIAGNOSTIC_PREFIX_BYTES;
|
||||
/// Current stable classic SPL Token decoded event contract version.
|
||||
@@ -89,43 +117,6 @@ pub(crate) use crate::decoder::solana::SOLANA_CORE_NATIVE_EVENT_VERSION;
|
||||
pub(crate) use crate::decoder::solana::SOLANA_CORE_NATIVE_LOADER_SURFACE_CODE;
|
||||
/// Maximum number of component bytes retained as a hexadecimal event prefix.
|
||||
pub(crate) use crate::decoder::solana::SOLANA_CORE_PRECOMPILE_COMPONENT_PREFIX_BYTES;
|
||||
/// Expected role and privileges for one positional instruction account.
|
||||
pub(crate) use crate::decoder::solana::SolanaCoreAccountRole;
|
||||
/// Returns declared Address Lookup Table instruction coverage.
|
||||
pub(crate) use crate::decoder::solana::solana_core_address_lookup_table_coverage;
|
||||
/// Decodes one Address Lookup Table instruction.
|
||||
pub(crate) use crate::decoder::solana::solana_core_address_lookup_table_decode;
|
||||
/// Recognizes one Address Lookup Table instruction without producing an event.
|
||||
pub(crate) use crate::decoder::solana::solana_core_address_lookup_table_recognize;
|
||||
/// Returns declared Compute Budget instruction coverage.
|
||||
pub(crate) use crate::decoder::solana::solana_core_compute_budget_coverage;
|
||||
/// Decodes one Compute Budget instruction.
|
||||
pub(crate) use crate::decoder::solana::solana_core_compute_budget_decode;
|
||||
/// Recognizes one Compute Budget instruction without producing an event.
|
||||
pub(crate) use crate::decoder::solana::solana_core_compute_budget_recognize;
|
||||
/// Returns declared Config Program instruction coverage.
|
||||
pub(crate) use crate::decoder::solana::solana_core_config_coverage;
|
||||
/// Decodes one generic Config Program store instruction.
|
||||
pub(crate) use crate::decoder::solana::solana_core_config_decode;
|
||||
/// Recognizes one generic Config Program store instruction.
|
||||
pub(crate) use crate::decoder::solana::solana_core_config_recognize;
|
||||
/// Resolves positional instruction accounts and validates their core indexes.
|
||||
pub(crate) use crate::decoder::solana::solana_core_resolve_accounts;
|
||||
/// Decodes one bounded Associated Token Account instruction.
|
||||
pub(crate) use crate::decoder::spl_associated_token_account_decode;
|
||||
/// Returns the exact entry matching an Associated Token Account wire.
|
||||
pub(crate) use crate::decoder::spl_associated_token_account_entry;
|
||||
/// Reads one bounded Associated Token Account payload.
|
||||
pub(crate) use crate::decoder::spl_associated_token_account_payload;
|
||||
/// Decodes one bounded SPL Memo instruction.
|
||||
pub(crate) use crate::decoder::spl_memo_decode;
|
||||
/// Decodes one bounded classic SPL Token instruction.
|
||||
pub(crate) use crate::decoder::spl_token_decode;
|
||||
/// Returns the published entry matching one classic SPL Token tag.
|
||||
pub(crate) use crate::decoder::spl_token_entry_for_tag;
|
||||
/// Returns the first byte of one retained classic SPL Token payload.
|
||||
pub(crate) use crate::decoder::spl_token_payload_tag;
|
||||
|
||||
/// Stable protocol code shared by native Solana events.
|
||||
pub(crate) use crate::decoder::solana::SOLANA_CORE_PROTOCOL_CODE;
|
||||
/// Byte length of a secp256k1 Ethereum address.
|
||||
@@ -158,12 +149,32 @@ pub(crate) use crate::decoder::solana::SOLANA_CORE_VOTE_SURFACE_CODE;
|
||||
pub(crate) use crate::decoder::solana::SOLANA_CORE_ZK_ELGAMAL_PROOF_SURFACE_CODE;
|
||||
/// Stable historical ZK Token Proof surface code.
|
||||
pub(crate) use crate::decoder::solana::SOLANA_CORE_ZK_TOKEN_PROOF_SURFACE_CODE;
|
||||
/// Expected role and privileges for one positional instruction account.
|
||||
pub(crate) use crate::decoder::solana::SolanaCoreAccountRole;
|
||||
/// One resolved outer instruction payload and its provenance relative to the target instruction.
|
||||
pub(crate) use crate::decoder::solana::SolanaCoreResolvedInstructionPayload;
|
||||
/// Returns declared Address Lookup Table instruction coverage.
|
||||
pub(crate) use crate::decoder::solana::solana_core_address_lookup_table_coverage;
|
||||
/// Decodes one Address Lookup Table instruction.
|
||||
pub(crate) use crate::decoder::solana::solana_core_address_lookup_table_decode;
|
||||
/// Recognizes one Address Lookup Table instruction without producing an event.
|
||||
pub(crate) use crate::decoder::solana::solana_core_address_lookup_table_recognize;
|
||||
/// Returns a hexadecimal prefix no longer than the available byte slice.
|
||||
pub(crate) use crate::decoder::solana::solana_core_bounded_hexadecimal_prefix;
|
||||
/// Extracts one exact bounded byte slice with checked arithmetic.
|
||||
pub(crate) use crate::decoder::solana::solana_core_bounded_slice;
|
||||
/// Returns declared Compute Budget instruction coverage.
|
||||
pub(crate) use crate::decoder::solana::solana_core_compute_budget_coverage;
|
||||
/// Decodes one Compute Budget instruction.
|
||||
pub(crate) use crate::decoder::solana::solana_core_compute_budget_decode;
|
||||
/// Recognizes one Compute Budget instruction without producing an event.
|
||||
pub(crate) use crate::decoder::solana::solana_core_compute_budget_recognize;
|
||||
/// Returns declared Config Program instruction coverage.
|
||||
pub(crate) use crate::decoder::solana::solana_core_config_coverage;
|
||||
/// Decodes one generic Config Program store instruction.
|
||||
pub(crate) use crate::decoder::solana::solana_core_config_decode;
|
||||
/// Recognizes one generic Config Program store instruction.
|
||||
pub(crate) use crate::decoder::solana::solana_core_config_recognize;
|
||||
/// Decodes one retained base64 instruction payload with an explicit byte limit.
|
||||
pub(crate) use crate::decoder::solana::solana_core_decode_instruction_data;
|
||||
/// Returns the decoded target payload length when retained and valid.
|
||||
@@ -202,6 +213,8 @@ pub(crate) use crate::decoder::solana::solana_core_precompiles_recognize;
|
||||
pub(crate) use crate::decoder::solana::solana_core_read_u32_le;
|
||||
/// Reads one little-endian `u64` from an exact byte range.
|
||||
pub(crate) use crate::decoder::solana::solana_core_read_u64_le;
|
||||
/// Resolves positional instruction accounts and validates their core indexes.
|
||||
pub(crate) use crate::decoder::solana::solana_core_resolve_accounts;
|
||||
/// Resolves a secp256k1 instruction reference. The runtime format has no current-instruction
|
||||
/// sentinel: every `u8` value is an explicit outer instruction index.
|
||||
pub(crate) use crate::decoder::solana::solana_core_resolve_u8_instruction_payload;
|
||||
@@ -247,13 +260,53 @@ pub(crate) use crate::decoder::solana::solana_core_zk_token_proof_coverage;
|
||||
pub(crate) use crate::decoder::solana::solana_core_zk_token_proof_decode;
|
||||
/// Recognizes one historical ZK Token Proof layout or the current no-op runtime fallback.
|
||||
pub(crate) use crate::decoder::solana::solana_core_zk_token_proof_recognize;
|
||||
/// Decodes one bounded Associated Token Account instruction.
|
||||
pub(crate) use crate::decoder::spl_associated_token_account_decode;
|
||||
/// Returns the exact entry matching an Associated Token Account wire.
|
||||
pub(crate) use crate::decoder::spl_associated_token_account_entry;
|
||||
/// Reads one bounded Associated Token Account payload.
|
||||
pub(crate) use crate::decoder::spl_associated_token_account_payload;
|
||||
/// Decodes one bounded SPL ElGamal registry instruction.
|
||||
pub(crate) use crate::decoder::spl_elgamal_registry_decode;
|
||||
/// Decodes one bounded SPL ElGamal registry instruction payload.
|
||||
pub(crate) use crate::decoder::spl_elgamal_registry_decode_payload;
|
||||
/// Parses one exact SPL ElGamal registry instruction.
|
||||
pub(crate) use crate::decoder::spl_elgamal_registry_parse;
|
||||
/// Decodes one bounded SPL Memo instruction.
|
||||
pub(crate) use crate::decoder::spl_memo_decode;
|
||||
/// Decodes one bounded Token-2022 instruction.
|
||||
pub(crate) use crate::decoder::spl_token_2022_decode;
|
||||
/// Returns the exact entry matching one Token-2022 tag.
|
||||
pub(crate) use crate::decoder::spl_token_2022_entry_for_tag;
|
||||
/// Returns the first byte of one retained Token-2022 payload.
|
||||
pub(crate) use crate::decoder::spl_token_2022_payload_tag;
|
||||
/// Decodes one bounded classic SPL Token instruction.
|
||||
pub(crate) use crate::decoder::spl_token_decode;
|
||||
/// Returns the published entry matching one classic SPL Token tag.
|
||||
pub(crate) use crate::decoder::spl_token_entry_for_tag;
|
||||
/// Returns the first byte of one retained classic SPL Token payload.
|
||||
pub(crate) use crate::decoder::spl_token_payload_tag;
|
||||
|
||||
/// Exact byte length of one SPL ElGamal registry account.
|
||||
pub use crate::decoder::ELGAMAL_REGISTRY_ACCOUNT_LEN;
|
||||
/// Parsed SPL ElGamal public-key registry account.
|
||||
pub use crate::decoder::ElGamalRegistryState;
|
||||
/// Exact decoder for the SPL Associated Token Account program.
|
||||
pub use crate::decoder::SplAssociatedTokenAccountDecoder;
|
||||
/// Exact decoder for the SPL ElGamal registry program.
|
||||
pub use crate::decoder::SplElgamalRegistryDecoder;
|
||||
/// Exact decoder for the three registered SPL Memo generations.
|
||||
pub use crate::decoder::SplMemoDecoder;
|
||||
/// Exact decoder for the Token-2022 program.
|
||||
pub use crate::decoder::SplToken2022Decoder;
|
||||
/// Exact decoder for the classic SPL Token program.
|
||||
pub use crate::decoder::SplTokenDecoder;
|
||||
/// Parsed Token-2022 Mint, Account, or Multisig state.
|
||||
pub use crate::decoder::Token2022State;
|
||||
/// Exact Token-2022 base account state kind.
|
||||
pub use crate::decoder::Token2022StateKind;
|
||||
/// One exact Token-2022 TLV entry.
|
||||
pub use crate::decoder::Token2022TlvEntry;
|
||||
/// Current contextual core instruction input contract version.
|
||||
pub use crate::decoder::api::contracts::CORE_INSTRUCTION_INPUT_CONTRACT_VERSION;
|
||||
/// Stable contextual decoded observation.
|
||||
@@ -294,6 +347,10 @@ pub use crate::decoder::api::decoder::DecoderSupport;
|
||||
pub use crate::decoder::api::decoder::InitialDecoder;
|
||||
/// Exposes the common protocol decoder trait.
|
||||
pub use crate::decoder::api::decoder::ProtocolDecoder;
|
||||
/// Parses one exact SPL ElGamal registry account.
|
||||
pub use crate::decoder::parse_elgamal_registry_state;
|
||||
/// Parses one Token-2022 Mint, Account, or Multisig state.
|
||||
pub use crate::decoder::parse_token_2022_state;
|
||||
/// Runtime-native Solana decoder with maximal native instruction coverage.
|
||||
pub use crate::decoder::solana::SolanaCoreDecoder;
|
||||
/// Exposes the blockhash policy kind.
|
||||
|
||||
Reference in New Issue
Block a user