Skip to content

Commit 5ecfebf

Browse files
committed
add models for entry and tx
1 parent 7247d89 commit 5ecfebf

File tree

4 files changed

+287
-0
lines changed

4 files changed

+287
-0
lines changed

ex/native/rdb/src/model.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
pub mod _codec;
22
pub mod attestation;
3+
pub mod entry;
4+
pub mod tx;

ex/native/rdb/src/model/_codec.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ pub fn pl_get_varint(pairs: &[(Term, Term)], key: &[u8]) -> i128 {
3535
}
3636
}
3737

38+
#[inline]
39+
pub fn pl_get_varint_opt(pairs: &[(Term, Term)], key: &[u8]) -> Option<i128> {
40+
match pl_find_opt(pairs, key) {
41+
Some(Term::VarInt(x)) => Some(*x),
42+
_ => None,
43+
}
44+
}
45+
3846
#[inline]
3947
pub fn pl_get_u64(pairs: &[(Term, Term)], key: &[u8]) -> u64 {
4048
pl_get_varint(pairs, key) as u64
@@ -54,3 +62,18 @@ pub fn pl_get_list<'a>(pairs: &'a [(Term, Term)], key: &[u8]) -> &'a [Term] {
5462
_ => unreachable!(),
5563
}
5664
}
65+
66+
#[inline]
67+
pub fn pl_find_opt<'a>(pairs: &'a [(Term, Term)], key: &[u8]) -> Option<&'a Term> {
68+
pairs.iter()
69+
.find(|(k, _)| matches!(k, Term::Binary(b) if b.as_slice() == key))
70+
.map(|(_, v)| v)
71+
}
72+
73+
#[inline]
74+
pub fn pl_get_bytes_opt<'a>(pairs: &'a [(Term, Term)], key: &[u8]) -> Option<&'a [u8]> {
75+
match pl_find_opt(pairs, key) {
76+
Some(Term::Binary(v)) => Some(v.as_slice()),
77+
_ => None,
78+
}
79+
}

ex/native/rdb/src/model/entry.rs

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
use crate::model::_codec as codec;
2+
use crate::model::_codec::{EncodeToTerm, DecodeFromTerm};
3+
use crate::model::tx::{TXU};
4+
use vecpak::{Term};
5+
6+
#[derive(Debug, Clone)]
7+
pub struct Header {
8+
pub prev_hash: Vec<u8>,
9+
pub height: i128,
10+
pub slot: i128,
11+
pub prev_slot: i128,
12+
pub signer: Vec<u8>,
13+
pub dr: Vec<u8>,
14+
pub vr: Vec<u8>,
15+
pub root_tx: Vec<u8>,
16+
pub root_validator: Vec<u8>,
17+
}
18+
19+
#[derive(Debug, Clone)]
20+
pub struct Entry {
21+
pub hash: Vec<u8>,
22+
pub signature: Vec<u8>,
23+
pub header: Header,
24+
pub txs: Vec<TXU>,
25+
pub mask: Option<Vec<u8>>,
26+
pub mask_size: Option<i128>,
27+
pub mask_set_size: Option<i128>,
28+
}
29+
30+
impl EncodeToTerm for Header {
31+
fn to_term(&self) -> Result<Term, &'static str> {
32+
Ok(Term::PropList(vec![
33+
(Term::Binary(b"prev_hash".to_vec()), Term::Binary(self.prev_hash.clone())),
34+
(Term::Binary(b"height".to_vec()), Term::VarInt(self.height)),
35+
(Term::Binary(b"slot".to_vec()), Term::VarInt(self.slot)),
36+
(Term::Binary(b"prev_slot".to_vec()), Term::VarInt(self.prev_slot)),
37+
(Term::Binary(b"signer".to_vec()), Term::Binary(self.signer.clone())),
38+
(Term::Binary(b"dr".to_vec()), Term::Binary(self.dr.clone())),
39+
(Term::Binary(b"vr".to_vec()), Term::Binary(self.vr.clone())),
40+
(Term::Binary(b"root_tx".to_vec()), Term::Binary(self.root_tx.clone())),
41+
(Term::Binary(b"root_validator".to_vec()), Term::Binary(self.root_validator.clone())),
42+
]))
43+
}
44+
}
45+
46+
impl DecodeFromTerm for Header {
47+
fn from_term(t: &Term) -> Self {
48+
let Term::PropList(pairs) = t else { unreachable!("Expected PropList for Header") };
49+
50+
Header {
51+
prev_hash: codec::pl_get_bytes(pairs, b"prev_hash").to_vec(),
52+
height: codec::pl_get_varint(pairs, b"height"),
53+
slot: codec::pl_get_varint(pairs, b"slot"),
54+
prev_slot: codec::pl_get_varint(pairs, b"prev_slot"),
55+
signer: codec::pl_get_bytes(pairs, b"signer").to_vec(),
56+
dr: codec::pl_get_bytes(pairs, b"dr").to_vec(),
57+
vr: codec::pl_get_bytes(pairs, b"vr").to_vec(),
58+
root_tx: codec::pl_get_bytes(pairs, b"root_tx").to_vec(),
59+
root_validator: codec::pl_get_bytes(pairs, b"root_validator").to_vec(),
60+
}
61+
}
62+
}
63+
64+
impl EncodeToTerm for Entry {
65+
fn to_term(&self) -> Result<Term, &'static str> {
66+
let mut txs_list = Vec::with_capacity(self.txs.len());
67+
for tx in &self.txs {
68+
txs_list.push(tx.to_term()?);
69+
}
70+
71+
let mut pairs = vec![
72+
(Term::Binary(b"hash".to_vec()), Term::Binary(self.hash.clone())),
73+
(Term::Binary(b"signature".to_vec()), Term::Binary(self.signature.clone())),
74+
(Term::Binary(b"header".to_vec()), self.header.to_term()?),
75+
(Term::Binary(b"txs".to_vec()), Term::List(txs_list)),
76+
];
77+
78+
if let Some(ref m) = self.mask {
79+
pairs.push((Term::Binary(b"mask".to_vec()), Term::Binary(m.clone())));
80+
}
81+
if let Some(ms) = self.mask_size {
82+
pairs.push((Term::Binary(b"mask_size".to_vec()), Term::VarInt(ms)));
83+
}
84+
if let Some(mss) = self.mask_set_size {
85+
pairs.push((Term::Binary(b"mask_set_size".to_vec()), Term::VarInt(mss)));
86+
}
87+
88+
Ok(Term::PropList(pairs))
89+
}
90+
}
91+
92+
impl DecodeFromTerm for Entry {
93+
fn from_term(t: &Term) -> Self {
94+
let Term::PropList(pairs) = t else { unreachable!("Expected PropList for Entry") };
95+
96+
let hash = codec::pl_get_bytes(pairs, b"hash").to_vec();
97+
let signature = codec::pl_get_bytes(pairs, b"signature").to_vec();
98+
99+
let header_term = codec::pl_find(pairs, b"header");
100+
let header = Header::from_term(header_term);
101+
102+
let txs_term_list = codec::pl_get_list(pairs, b"txs");
103+
let txs = txs_term_list.iter()
104+
.map(|t| TXU::from_term(t))
105+
.collect();
106+
107+
let mask = codec::pl_get_bytes_opt(pairs, b"mask").map(|b| b.to_vec());
108+
109+
let mask_size = codec::pl_get_varint_opt(pairs, b"mask_size");
110+
let mask_set_size = codec::pl_get_varint_opt(pairs, b"mask_set_size");
111+
112+
Entry {
113+
hash,
114+
signature,
115+
header,
116+
txs,
117+
mask,
118+
mask_size,
119+
mask_set_size,
120+
}
121+
}
122+
}
123+
124+
pub fn from_bytes(data: &[u8]) -> Result<Entry, &'static str> {
125+
let term = vecpak::decode(data)?;
126+
Ok(Entry::from_term(&term))
127+
}

ex/native/rdb/src/model/tx.rs

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
use crate::model::_codec as codec;
2+
use crate::model::_codec::{EncodeToTerm, DecodeFromTerm};
3+
use vecpak::{Term};
4+
5+
#[derive(Debug, Clone)]
6+
pub struct Action {
7+
pub op: Vec<u8>,
8+
pub contract: Vec<u8>,
9+
pub function: Vec<u8>,
10+
pub args: Vec<Vec<u8>>,
11+
pub attached_symbol: Option<Vec<u8>>,
12+
pub attached_amount: Option<Vec<u8>>,
13+
}
14+
15+
#[derive(Debug, Clone)]
16+
pub struct TX {
17+
pub signer: Vec<u8>,
18+
pub nonce: i128,
19+
pub action: Action,
20+
}
21+
22+
#[derive(Debug, Clone)]
23+
pub struct TXU {
24+
pub hash: Vec<u8>,
25+
pub signature: Vec<u8>,
26+
pub tx: TX,
27+
}
28+
29+
impl EncodeToTerm for Action {
30+
fn to_term(&self) -> Result<Term, &'static str> {
31+
let args_list: Vec<Term> = self.args.iter()
32+
.map(|a| Term::Binary(a.clone()))
33+
.collect();
34+
35+
let mut pairs = vec![
36+
(Term::Binary(b"op".to_vec()), Term::Binary(self.op.clone())),
37+
(Term::Binary(b"contract".to_vec()), Term::Binary(self.contract.clone())),
38+
(Term::Binary(b"function".to_vec()), Term::Binary(self.function.clone())),
39+
(Term::Binary(b"args".to_vec()), Term::List(args_list)),
40+
];
41+
42+
if let Some(ref sym) = self.attached_symbol {
43+
pairs.push((Term::Binary(b"attached_symbol".to_vec()), Term::Binary(sym.clone())));
44+
}
45+
46+
if let Some(ref amt) = self.attached_amount {
47+
pairs.push((Term::Binary(b"attached_amount".to_vec()), Term::Binary(amt.clone())));
48+
}
49+
50+
Ok(Term::PropList(pairs))
51+
}
52+
}
53+
54+
impl DecodeFromTerm for Action {
55+
fn from_term(t: &Term) -> Self {
56+
let Term::PropList(pairs) = t else { unreachable!("Expected PropList for Action") };
57+
58+
let op = codec::pl_get_bytes(pairs, b"op").to_vec();
59+
let contract = codec::pl_get_bytes(pairs, b"contract").to_vec();
60+
let function = codec::pl_get_bytes(pairs, b"function").to_vec();
61+
62+
let args_term_list = codec::pl_get_list(pairs, b"args");
63+
let args = args_term_list.iter().map(|item| {
64+
match item {
65+
Term::Binary(b) => b.clone(),
66+
_ => Vec::new(),
67+
}
68+
}).collect();
69+
70+
let attached_symbol = codec::pl_get_bytes_opt(pairs, b"attached_symbol").map(|b| b.to_vec());
71+
let attached_amount = codec::pl_get_bytes_opt(pairs, b"attached_amount").map(|b| b.to_vec());
72+
73+
Action {
74+
op,
75+
contract,
76+
function,
77+
args,
78+
attached_symbol,
79+
attached_amount
80+
}
81+
}
82+
}
83+
84+
impl EncodeToTerm for TX {
85+
fn to_term(&self) -> Result<Term, &'static str> {
86+
Ok(Term::PropList(vec![
87+
(Term::Binary(b"signer".to_vec()), Term::Binary(self.signer.clone())),
88+
(Term::Binary(b"nonce".to_vec()), Term::VarInt(self.nonce)),
89+
(Term::Binary(b"action".to_vec()), self.action.to_term()?),
90+
]))
91+
}
92+
}
93+
94+
impl DecodeFromTerm for TX {
95+
fn from_term(t: &Term) -> Self {
96+
let Term::PropList(pairs) = t else { unreachable!("Expected PropList for TX") };
97+
98+
let signer = codec::pl_get_bytes(pairs, b"signer").to_vec();
99+
let nonce = codec::pl_get_varint(pairs, b"nonce");
100+
101+
let action_term = codec::pl_find(pairs, b"action");
102+
let action = Action::from_term(action_term);
103+
104+
TX { signer, nonce, action }
105+
}
106+
}
107+
108+
impl EncodeToTerm for TXU {
109+
fn to_term(&self) -> Result<Term, &'static str> {
110+
Ok(Term::PropList(vec![
111+
(Term::Binary(b"hash".to_vec()), Term::Binary(self.hash.clone())),
112+
(Term::Binary(b"signature".to_vec()), Term::Binary(self.signature.clone())),
113+
(Term::Binary(b"tx".to_vec()), self.tx.to_term()?),
114+
]))
115+
}
116+
}
117+
118+
impl DecodeFromTerm for TXU {
119+
fn from_term(t: &Term) -> Self {
120+
let Term::PropList(pairs) = t else { unreachable!("Expected PropList for TXU") };
121+
122+
let hash = codec::pl_get_bytes(pairs, b"hash").to_vec();
123+
let signature = codec::pl_get_bytes(pairs, b"signature").to_vec();
124+
125+
let tx_term = codec::pl_find(pairs, b"tx");
126+
let tx = TX::from_term(tx_term);
127+
128+
TXU { hash, signature, tx }
129+
}
130+
}
131+
132+
pub fn from_bytes(data: &[u8]) -> Result<TXU, &'static str> {
133+
let term = vecpak::decode(data)?;
134+
Ok(TXU::from_term(&term))
135+
}

0 commit comments

Comments
 (0)