avalanche_rs/pvm/parser/
input_parser.rs1use tracing::{instrument, trace};
2
3use std::borrow::Borrow;
4
5use std::error::Error;
6
7use crate::avm::parser::Context;
8use crate::pvm::parser::output_parser::StakeableLockedInput;
9use crate::utils::conversion::{pop_i32, pop_i64};
10
11#[derive(Serialize, Deserialize, Debug)]
12pub struct Input {
13 pub type_id: i32,
14 pub stakeable_locked_input: Option<StakeableLockedInput>,
15 pub secp256k_transfer_input: Option<SECP256KTransferInput>,
16}
17
18#[derive(Serialize, Deserialize, Debug)]
19pub struct SECP256KTransferInput {
20 pub type_id: i32,
21 pub amount: i64,
22 pub address_indices: Vec<i32>,
23}
24
25#[instrument(skip(_raw_msg), fields(tx_id = % _context.tx_id))]
26pub fn input_parser<'a>(
27 _raw_msg: &'a [u8],
28 _context: &mut Context,
29) -> Result<Input, Box<dyn Error>> {
30 let type_id = pop_i32(_raw_msg[*_context.offset..=(*_context.offset + 3)].borrow());
32 trace!("Type Id -- {}", type_id);
33 *_context.offset += 4;
34
35 let mut secp256k_transfer_input = None;
37 let mut stakeable_locked_input = None;
38 match type_id {
39 5 => secp256k_transfer_input = Some(secp256k1_transfer_input_parser(_raw_msg, _context)?),
40 21 => stakeable_locked_input = Some(stackeable_lockin_parser(_raw_msg, _context)?),
41 _ => {
42 panic!(
43 "This input type is incorrect or not yet supported {}",
44 type_id
45 )
46 }
47 }
48
49 Ok(Input {
50 type_id,
51 stakeable_locked_input,
52 secp256k_transfer_input,
53 })
54}
55
56#[instrument(skip(_raw_msg), fields(tx_id = % _context.tx_id))]
57pub fn secp256k1_transfer_input_parser<'a>(
58 _raw_msg: &'a [u8],
59 _context: &mut Context,
60) -> Result<SECP256KTransferInput, Box<dyn Error>> {
61 let amount = pop_i64(_raw_msg[*_context.offset..=(*_context.offset + 7)].borrow());
63 trace!("Amount : {:?}", amount);
64 *_context.offset += 8;
65
66 let number_of_address = pop_i32(_raw_msg[*_context.offset..=(*_context.offset + 3)].borrow());
68 trace!("Number of addresses : {:?}", number_of_address);
69 *_context.offset += 4;
70
71 let mut index = 0;
73 let mut address_indices = Vec::new();
74
75 while index < number_of_address {
76 let address_indice = pop_i32(_raw_msg[*_context.offset..=(*_context.offset + 3)].borrow());
77 trace!("Addresses number {} {:?}", index, address_indice);
78 address_indices.push(address_indice);
79 *_context.offset += 4;
80 index += 1;
81 }
82
83 Ok(SECP256KTransferInput {
84 type_id: 5,
85 amount,
86 address_indices,
87 })
88}
89
90pub fn stackeable_lockin_parser<'a>(
91 _raw_msg: &'a [u8],
92 _context: &mut Context,
93) -> Result<StakeableLockedInput, Box<dyn Error>> {
94 let locktime = pop_i64(_raw_msg[*_context.offset..=(*_context.offset + 7)].borrow());
96 trace!("Stack Locktime : {:?}", locktime);
97 *_context.offset += 8;
98
99 let type_id = pop_i32(_raw_msg[*_context.offset..=(*_context.offset + 3)].borrow());
100 trace!("Type Id : {:?}", type_id);
101 *_context.offset += 4;
102
103 let input;
104
105 match type_id {
106 5 => input = secp256k1_transfer_input_parser(_raw_msg, _context)?,
107 _ => panic!(
108 "This input type is incorrect or not yet supported {}",
109 type_id
110 ),
111 }
112
113 Ok(StakeableLockedInput {
114 locktime,
115 asset_id: "".to_string(),
116 input,
117 })
118}