axiom_codec/decoder/
native.rs1use std::io::{self, Read, Result};
2
3use axiom_eth::halo2curves::bn256::G1Affine;
4use byteorder::{BigEndian, ReadBytesExt};
5use ethers_core::types::Bytes;
6
7use crate::{
8 constants::MAX_SOLIDITY_MAPPING_KEYS,
9 types::native::{
10 AccountSubquery, AnySubquery, AxiomV2ComputeSnark, HeaderSubquery, ReceiptSubquery,
11 SolidityNestedMappingSubquery, StorageSubquery, Subquery, SubqueryType, TxSubquery,
12 },
13 utils::reader::{read_address, read_curve_compressed, read_h256, read_u256},
14};
15
16impl TryFrom<Subquery> for AnySubquery {
17 type Error = io::Error;
18
19 fn try_from(subquery: Subquery) -> Result<Self> {
20 let mut reader = &subquery.encoded_subquery_data[..];
21 let subquery_type = subquery.subquery_type;
22 Ok(match subquery_type {
23 SubqueryType::Null => AnySubquery::Null,
24 SubqueryType::Header => AnySubquery::Header(decode_header_subquery(&mut reader)?),
25 SubqueryType::Account => AnySubquery::Account(decode_account_subquery(&mut reader)?),
26 SubqueryType::Storage => AnySubquery::Storage(decode_storage_subquery(&mut reader)?),
27 SubqueryType::Transaction => AnySubquery::Transaction(decode_tx_subquery(&mut reader)?),
28 SubqueryType::Receipt => AnySubquery::Receipt(decode_receipt_subquery(&mut reader)?),
29 SubqueryType::SolidityNestedMapping => AnySubquery::SolidityNestedMapping(
30 decode_solidity_nested_mapping_subquery(&mut reader)?,
31 ),
32 })
33 }
34}
35
36impl TryFrom<u16> for SubqueryType {
37 type Error = io::Error;
38 fn try_from(value: u16) -> Result<Self> {
39 match value {
40 0 => Ok(Self::Null),
41 1 => Ok(Self::Header),
42 2 => Ok(Self::Account),
43 3 => Ok(Self::Storage),
44 4 => Ok(Self::Transaction),
45 5 => Ok(Self::Receipt),
46 6 => Ok(Self::SolidityNestedMapping),
47 _ => Err(io::Error::new(io::ErrorKind::InvalidData, "Invalid SubqueryType")),
49 }
50 }
51}
52
53pub fn decode_compute_snark(
56 mut reader: impl Read,
57 result_len: u16,
58 is_aggregation: bool,
59) -> Result<AxiomV2ComputeSnark> {
60 let kzg_accumulator = if is_aggregation {
61 let lhs = read_curve_compressed::<G1Affine>(&mut reader)?;
62 let rhs = read_curve_compressed::<G1Affine>(&mut reader)?;
63 Some((lhs, rhs))
64 } else {
65 read_h256(&mut reader)?;
66 read_h256(&mut reader)?;
67 None
68 };
69 let mut compute_results = Vec::with_capacity(result_len as usize);
70 for _ in 0..result_len {
71 compute_results.push(read_h256(&mut reader)?);
72 }
73 let mut proof_transcript = vec![];
74 reader.read_to_end(&mut proof_transcript)?;
75 Ok(AxiomV2ComputeSnark { kzg_accumulator, compute_results, proof_transcript })
76}
77
78pub fn decode_subquery(mut reader: impl Read) -> Result<AnySubquery> {
79 let subquery_type = reader.read_u16::<BigEndian>()?;
80 let subquery_type = subquery_type.try_into()?;
81 let mut buf = vec![];
82 reader.read_to_end(&mut buf)?;
83 let encoded_subquery_data = Bytes::from(buf);
84 let subquery = Subquery { subquery_type, encoded_subquery_data };
85 subquery.try_into()
86}
87
88pub fn decode_header_subquery(mut reader: impl Read) -> Result<HeaderSubquery> {
89 let block_number = reader.read_u32::<BigEndian>()?;
90 let field_idx = reader.read_u32::<BigEndian>()?;
91 Ok(HeaderSubquery { block_number, field_idx })
92}
93
94pub fn decode_account_subquery(mut reader: impl Read) -> Result<AccountSubquery> {
95 let block_number = reader.read_u32::<BigEndian>()?;
96 let addr = read_address(&mut reader)?;
97 let field_idx = reader.read_u32::<BigEndian>()?;
98 Ok(AccountSubquery { block_number, addr, field_idx })
99}
100
101pub fn decode_storage_subquery(mut reader: impl Read) -> Result<StorageSubquery> {
102 let block_number = reader.read_u32::<BigEndian>()?;
103 let addr = read_address(&mut reader)?;
104 let slot = read_u256(&mut reader)?;
105 Ok(StorageSubquery { block_number, addr, slot })
106}
107
108pub fn decode_tx_subquery(mut reader: impl Read) -> Result<TxSubquery> {
109 let block_number = reader.read_u32::<BigEndian>()?;
110 let tx_idx = reader.read_u16::<BigEndian>()?;
111 let field_or_calldata_idx = reader.read_u32::<BigEndian>()?;
112 Ok(TxSubquery { block_number, tx_idx, field_or_calldata_idx })
113}
114
115pub fn decode_receipt_subquery(mut reader: impl Read) -> Result<ReceiptSubquery> {
116 let block_number = reader.read_u32::<BigEndian>()?;
117 let tx_idx = reader.read_u16::<BigEndian>()?;
118 let field_or_log_idx = reader.read_u32::<BigEndian>()?;
119 let topic_or_data_or_address_idx = reader.read_u32::<BigEndian>()?;
120 let event_schema = read_h256(&mut reader)?;
121 Ok(ReceiptSubquery {
122 block_number,
123 tx_idx,
124 field_or_log_idx,
125 topic_or_data_or_address_idx,
126 event_schema,
127 })
128}
129
130pub fn decode_solidity_nested_mapping_subquery(
131 mut reader: impl Read,
132) -> Result<SolidityNestedMappingSubquery> {
133 let block_number = reader.read_u32::<BigEndian>()?;
134 let addr = read_address(&mut reader)?;
135 let mapping_slot = read_u256(&mut reader)?;
136 let mapping_depth = reader.read_u8()?;
137 if mapping_depth as usize > MAX_SOLIDITY_MAPPING_KEYS {
138 return Err(io::Error::new(
139 io::ErrorKind::InvalidData,
140 format!(
141 "SolidityNestedMappingSubquery mapping_depth {} exceeds MAX_SOLIDITY_MAPPING_KEYS {}",
142 mapping_depth, MAX_SOLIDITY_MAPPING_KEYS
143 ),
144 ));
145 }
146 let mut keys = Vec::with_capacity(mapping_depth as usize);
147 for _ in 0..mapping_depth {
148 keys.push(read_h256(&mut reader)?);
149 }
150 Ok(SolidityNestedMappingSubquery { block_number, addr, mapping_slot, mapping_depth, keys })
151}