Files
khadhroony-bot3/kb-lib/src/materializer/fees/core.rs

447 lines
18 KiB
Rust

// file: kb-lib/src/materializer/fees/core.rs
// version: 3
//! Stable fee projections derived from exact committed Token-2022 observations.
const ACCEPTED_FAMILIES: &[crate::MdEventFamily] = &[crate::MdEventFamily::Fee];
const SPL_TOKEN2022_SURFACE: &str = "spl_token2022";
const TOKEN2022_FEE_ENTRIES: &[&str] = &[
"initialize_transfer_fee_config",
"set_transfer_fee",
"withdraw_withheld_tokens_from_mint",
"withdraw_withheld_tokens_from_accounts",
"harvest_withheld_tokens_to_mint",
"transfer_checked_with_fee",
"initialize_confidential_transfer_fee_config",
"withdraw_confidential_withheld_tokens_from_mint",
"withdraw_confidential_withheld_tokens_from_accounts",
"harvest_confidential_withheld_tokens_to_mint",
"enable_confidential_harvest_to_mint",
"disable_confidential_harvest_to_mint",
"transfer_confidential_tokens_with_fee",
];
/// Fee materializer for committed Token-2022 fee instructions.
#[derive(Clone, Debug, Default)]
pub struct MtFeesMaterializer;
impl crate::MtMaterializer for crate::MtFeesMaterializer {
fn materializer_name(&self) -> &'static str {
return "kb_materializer_fees";
}
fn materializer_version(&self) -> &'static str {
return env!("CARGO_PKG_VERSION");
}
fn accepts_event(&self, event: &crate::MdDecodedProtocolEvent) -> bool {
return accepts_event(event);
}
fn materialize_event(
&self,
_event: &crate::MdDecodedProtocolEvent,
) -> kb_core::Result<std::vec::Vec<crate::MdMaterializedEvent>> {
return std::result::Result::Ok(std::vec::Vec::new());
}
}
impl crate::MtApiEventMaterializer for crate::MtFeesMaterializer {
fn identity(&self) -> crate::MtApiMaterializerIdentity {
return crate::MtApiMaterializerIdentity {
name: "fees".to_string(),
version: env!("CARGO_PKG_VERSION").to_string(),
};
}
fn accepted_families(&self) -> &'static [crate::MdEventFamily] {
return ACCEPTED_FAMILIES;
}
fn accepts_observation(&self, observation: &crate::DcApiDecodedObservation) -> bool {
return accepts_event(&observation.event);
}
fn transaction_policy(
&self,
_family: crate::MdEventFamily,
) -> crate::MtApiMaterializationTransactionPolicy {
return crate::MtApiMaterializationTransactionPolicy::SuccessfulCommittedOnly;
}
fn materialize(
&self,
observation: &crate::DcApiDecodedObservation,
) -> crate::MtApiMaterializerExecutionResult {
if !accepts_event(&observation.event) {
return crate::MtApiMaterializerExecutionResult::ignored();
}
if observation.transaction_failed || !observation.observation_committed {
return crate::MtApiMaterializerExecutionResult::refused(
"failed_transaction_fee_refused",
"failed or uncommitted Token-2022 observations cannot create fee outputs",
);
}
let operation = observation.event.event_name.0.clone();
let accounts = observation
.payload_json
.get("accounts")
.cloned()
.unwrap_or(serde_json::Value::Null);
let parameters = observation
.payload_json
.get("parameters")
.cloned()
.unwrap_or_else(|| return observation.payload_json.clone());
let output = crate::MtApiMaterializedOutput {
output_key: format!("token2022_fee:{operation}:0"),
family: crate::MdMaterializedEventFamily::Fee,
payload_json: serde_json::json!({
"projectionVersion": 1,
"projectionSemantics": "committed_instruction_fee_event",
"domain": fee_domain(observation.event.event_name.0.as_str()),
"operation": operation,
"programId": observation.event.program_id.0.clone(),
"signature": observation.event.signature.0.clone(),
"slot": observation.event.slot.0,
"instructionPath": observation.event.instruction_path.0.clone(),
"transactionSucceeded": true,
"accounts": accounts,
"parameters": parameters,
"stateReadRequired": state_read_required(
observation.event.event_name.0.as_str(),
),
"confidentialValuesDecrypted": false,
}),
};
return crate::MtApiMaterializerExecutionResult {
status: crate::MtApiMaterializerOutcomeStatus::Inserted,
outputs: std::vec![output],
diagnostics: std::vec::Vec::new(),
};
}
}
fn accepts_event(event: &crate::MdDecodedProtocolEvent) -> bool {
return event.event_family == crate::MdEventFamily::Fee
&& event.surface_code.0 == SPL_TOKEN2022_SURFACE
&& event.program_id.0 == kb_program_ids::SPL_TOKEN2022_PROGRAM_ID
&& contains(TOKEN2022_FEE_ENTRIES, event.event_name.0.as_str());
}
fn fee_domain(operation: &str) -> &'static str {
if operation.contains("confidential") {
return "token2022_confidential_transfer_fee";
}
return "token2022_transfer_fee";
}
fn state_read_required(operation: &str) -> bool {
return matches!(
operation,
"initialize_transfer_fee_config"
| "set_transfer_fee"
| "withdraw_withheld_tokens_from_mint"
| "withdraw_withheld_tokens_from_accounts"
| "harvest_withheld_tokens_to_mint"
| "initialize_confidential_transfer_fee_config"
| "withdraw_confidential_withheld_tokens_from_mint"
| "withdraw_confidential_withheld_tokens_from_accounts"
| "harvest_confidential_withheld_tokens_to_mint"
| "enable_confidential_harvest_to_mint"
| "disable_confidential_harvest_to_mint"
);
}
fn contains(entries: &[&str], entry_code: &str) -> bool {
return entries.iter().any(|entry| return *entry == entry_code);
}
/// Materialize authoritative Token-2022 fee extension snapshots without decrypting confidential values.
pub fn materializer_fees_materialize_token2022_state_snapshots(
account_key: &str,
slot: u64,
state: &crate::DcToken2022State,
) -> std::result::Result<std::vec::Vec<crate::MtApiMaterializedOutput>, String> {
if account_key.is_empty() {
return std::result::Result::Err(
"Token-2022 fee state snapshot requires a non-empty account key".to_string(),
);
}
let state_kind = match state.kind {
crate::DcToken2022StateKind::Mint => "mint",
crate::DcToken2022StateKind::Account => "account",
crate::DcToken2022StateKind::Multisig => {
return std::result::Result::Err(
"Token-2022 multisig state cannot contain fee extensions".to_string(),
);
},
};
let mut outputs = std::vec::Vec::new();
for entry in &state.extensions {
let confidential = match entry.extension_name {
"transfer_fee_config" | "transfer_fee_amount" => false,
"confidential_transfer_fee_config" | "confidential_transfer_fee_amount" => true,
_ => continue,
};
let expected_kind = match entry.extension_name {
"transfer_fee_config" | "confidential_transfer_fee_config" => "mint",
"transfer_fee_amount" | "confidential_transfer_fee_amount" => "account",
_ => continue,
};
if state_kind != expected_kind {
return std::result::Result::Err(format!(
"Token-2022 {} extension requires {expected_kind} state, got {state_kind}",
entry.extension_name
));
}
outputs.push(crate::MtApiMaterializedOutput {
output_key: format!(
"token2022_fee_state:{}:{account_key}:{slot}",
entry.extension_name
),
family: crate::MdMaterializedEventFamily::Fee,
payload_json: serde_json::json!({
"projectionVersion": 1,
"projectionSemantics": "authoritative_bounded_fee_state_snapshot",
"domain": if confidential {
"token2022_confidential_transfer_fee_state"
} else {
"token2022_transfer_fee_state"
},
"idempotenceKey": format!(
"token2022_fee_state:{}:{account_key}:{slot}",
entry.extension_name
),
"accountKey": account_key,
"slot": slot,
"programId": kb_program_ids::SPL_TOKEN2022_PROGRAM_ID,
"stateKind": state_kind,
"extensionType": entry.extension_type,
"extensionName": entry.extension_name,
"valueHex": entry.value_hex,
"valueFields": entry.value_fields,
"containsConfidentialState": confidential,
"confidentialValuesDecrypted": false,
"finalAccountStateCaptured": true,
"provenance": {
"processorName": "fees",
"processorVersion": env!("CARGO_PKG_VERSION"),
"source": "bounded_token2022_state_parser"
}
}),
});
}
return std::result::Result::Ok(outputs);
}
#[cfg(test)]
mod tests {
fn observation(
surface_code: &str,
program_id: &str,
entry_code: &str,
transaction_failed: bool,
) -> crate::DcApiDecodedObservation {
return crate::DcApiDecodedObservation {
event_key: format!("{entry_code}:0"),
event: crate::MdDecodedProtocolEvent {
signature: crate::MdSignature("signature".to_string()),
slot: crate::MdSlot(42),
instruction_path: crate::MdInstructionPath("0".to_string()),
program_id: crate::MdProgramId(program_id.to_string()),
protocol_code: crate::MdProtocolCode("spl_token2022".to_string()),
surface_code: crate::MdSurfaceCode(surface_code.to_string()),
event_code: crate::MdEventCode(format!("{surface_code}.{entry_code}")),
event_name: crate::MdEventName(entry_code.to_string()),
event_family: crate::MdEventFamily::Fee,
source_kind: crate::MdEventSourceKind::Instruction,
confidence: crate::MdDecoderConfidence::ManualExact,
},
payload_json: serde_json::json!({
"accounts": [{"position": 0, "role": "mint", "accountKey": "mint111"}],
"parameters": {"extension": "transfer_fee", "basisPoints": 25},
}),
transaction_failed,
transaction_error: if transaction_failed {
std::option::Option::Some(serde_json::json!({"InstructionError": [0, "Custom"]}))
} else {
std::option::Option::None
},
observation_committed: !transaction_failed,
proof: crate::DcApiDecoderProof {
kind: crate::DcApiDecoderProofKind::Manual,
confidence: crate::MdDecoderConfidence::ManualExact,
evidence: std::vec!["fixture".to_string()],
},
};
}
#[test]
fn committed_token2022_fee_instruction_creates_one_stable_output() {
let observation = observation(
super::SPL_TOKEN2022_SURFACE,
kb_program_ids::SPL_TOKEN2022_PROGRAM_ID,
"set_transfer_fee",
false,
);
let result =
crate::MtApiEventMaterializer::materialize(&crate::MtFeesMaterializer, &observation);
assert_eq!(result.status, crate::MtApiMaterializerOutcomeStatus::Inserted);
assert_eq!(result.outputs.len(), 1);
assert_eq!(result.outputs[0].family, crate::MdMaterializedEventFamily::Fee);
assert_eq!(result.outputs[0].output_key, "token2022_fee:set_transfer_fee:0");
assert_eq!(result.outputs[0].payload_json["stateReadRequired"], true);
}
#[test]
fn failed_token2022_fee_instruction_is_refused() {
let observation = observation(
super::SPL_TOKEN2022_SURFACE,
kb_program_ids::SPL_TOKEN2022_PROGRAM_ID,
"harvest_withheld_tokens_to_mint",
true,
);
let result =
crate::MtApiEventMaterializer::materialize(&crate::MtFeesMaterializer, &observation);
assert_eq!(result.status, crate::MtApiMaterializerOutcomeStatus::Refused);
assert!(result.outputs.is_empty());
}
#[test]
fn classic_token_and_program_surface_mismatches_are_ignored() {
let classic = observation(
"spl_token",
kb_program_ids::SPL_TOKEN_PROGRAM_ID,
"set_transfer_fee",
false,
);
let wrong_program = observation(
super::SPL_TOKEN2022_SURFACE,
kb_program_ids::SPL_TOKEN_PROGRAM_ID,
"set_transfer_fee",
false,
);
assert!(!crate::MtApiEventMaterializer::accepts_observation(
&crate::MtFeesMaterializer,
&classic,
));
assert!(!crate::MtApiEventMaterializer::accepts_observation(
&crate::MtFeesMaterializer,
&wrong_program,
));
}
#[test]
fn transfer_checked_with_fee_is_self_contained_but_state_mutations_are_not() {
assert!(!super::state_read_required("transfer_checked_with_fee"));
assert!(super::state_read_required("withdraw_withheld_tokens_from_accounts"));
}
#[test]
fn committed_confidential_fee_instruction_is_projected_without_decryption() {
let observation = observation(
super::SPL_TOKEN2022_SURFACE,
kb_program_ids::SPL_TOKEN2022_PROGRAM_ID,
"initialize_confidential_transfer_fee_config",
false,
);
let result =
crate::MtApiEventMaterializer::materialize(&crate::MtFeesMaterializer, &observation);
assert_eq!(result.status, crate::MtApiMaterializerOutcomeStatus::Inserted);
assert_eq!(result.outputs.len(), 1);
assert_eq!(result.outputs[0].payload_json["domain"], "token2022_confidential_transfer_fee");
assert_eq!(result.outputs[0].payload_json["stateReadRequired"], true);
assert_eq!(result.outputs[0].payload_json["confidentialValuesDecrypted"], false);
}
#[test]
fn confidential_transfer_with_fee_is_instructionally_self_contained() {
assert!(!super::state_read_required("transfer_confidential_tokens_with_fee",));
assert_eq!(
super::fee_domain("transfer_confidential_tokens_with_fee"),
"token2022_confidential_transfer_fee"
);
}
#[test]
fn public_fee_state_snapshots_are_owned_once_and_idempotent() {
let mint = crate::DcToken2022State {
kind: crate::DcToken2022StateKind::Mint,
base_fields: serde_json::json!({}),
base_hex: "00".to_string(),
account_type: std::option::Option::Some(1),
extensions: std::vec![crate::DcToken2022TlvEntry {
extension_type: 1,
extension_name: "transfer_fee_config",
value_hex: "01".to_string(),
value_fields: serde_json::json!({"withheldAmount":"7"}),
}],
};
let first =
crate::materializer_fees_materialize_token2022_state_snapshots("mint111", 42, &mint);
let second =
crate::materializer_fees_materialize_token2022_state_snapshots("mint111", 42, &mint);
assert!(first.is_ok());
assert_eq!(first, second);
let outputs = match first {
std::result::Result::Ok(outputs) => outputs,
std::result::Result::Err(error) => panic!("unexpected error: {error}"),
};
assert_eq!(outputs.len(), 1);
assert_eq!(outputs[0].payload_json["stateKind"], "mint");
assert_eq!(outputs[0].payload_json["valueFields"]["withheldAmount"], "7");
assert_eq!(outputs[0].payload_json["confidentialValuesDecrypted"], false);
}
#[test]
fn confidential_fee_amount_preserves_ciphertext_without_decryption_claim() {
let account = crate::DcToken2022State {
kind: crate::DcToken2022StateKind::Account,
base_fields: serde_json::json!({}),
base_hex: "00".to_string(),
account_type: std::option::Option::Some(2),
extensions: std::vec![crate::DcToken2022TlvEntry {
extension_type: 17,
extension_name: "confidential_transfer_fee_amount",
value_hex: "02".to_string(),
value_fields: serde_json::json!({"withheldAmount":"ciphertext"}),
}],
};
let result = crate::materializer_fees_materialize_token2022_state_snapshots(
"account111",
43,
&account,
);
assert!(result.is_ok());
let outputs = match result {
std::result::Result::Ok(outputs) => outputs,
std::result::Result::Err(error) => panic!("unexpected error: {error}"),
};
assert_eq!(outputs[0].payload_json["containsConfidentialState"], true);
assert_eq!(outputs[0].payload_json["confidentialValuesDecrypted"], false);
assert_eq!(outputs[0].payload_json["valueFields"]["withheldAmount"], "ciphertext");
}
#[test]
fn fee_state_snapshot_rejects_wrong_state_kind_and_empty_identity() {
let wrong = crate::DcToken2022State {
kind: crate::DcToken2022StateKind::Account,
base_fields: serde_json::json!({}),
base_hex: "00".to_string(),
account_type: std::option::Option::Some(2),
extensions: std::vec![crate::DcToken2022TlvEntry {
extension_type: 1,
extension_name: "transfer_fee_config",
value_hex: "01".to_string(),
value_fields: serde_json::json!({}),
}],
};
assert!(
crate::materializer_fees_materialize_token2022_state_snapshots(
"account111",
44,
&wrong,
)
.is_err()
);
assert!(
crate::materializer_fees_materialize_token2022_state_snapshots("", 44, &wrong,)
.is_err()
);
}
}