Skip to content

Commit 050a341

Browse files
committed
refactor(target_chains/starknet): move ByteArray to a separate module
1 parent cf90bff commit 050a341

File tree

6 files changed

+73
-67
lines changed

6 files changed

+73
-67
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
use core::fmt::{Debug, Formatter};
2+
3+
/// A byte array with storage format similar to `core::ByteArray`, but
4+
/// suitable for reading data from it.
5+
#[derive(Drop, Clone, Serde)]
6+
pub struct ByteArray {
7+
// Number of bytes stored in the last item of `self.data` (or 0 if it's empty).
8+
num_last_bytes: u8,
9+
// Bytes in big endian. Each item except the last one stores 31 bytes.
10+
// If `num_last_bytes < 31`, unused most significant bytes of the last item will be unused.
11+
data: Array<bytes31>,
12+
}
13+
14+
impl DebugByteArray of Debug<ByteArray> {
15+
fn fmt(self: @ByteArray, ref f: Formatter) -> Result<(), core::fmt::Error> {
16+
write!(f, "ByteArray {{ num_last_bytes: {}, data: [", self.num_last_bytes)?;
17+
let mut data = self.data.clone();
18+
loop {
19+
match data.pop_front() {
20+
Option::Some(v) => {
21+
let v: u256 = v.into();
22+
write!(f, "{:?}, ", v).unwrap();
23+
},
24+
Option::None => { break; },
25+
}
26+
};
27+
write!(f, "]}}")
28+
}
29+
}
30+
31+
#[generate_trait]
32+
pub impl ByteArrayImpl of ByteArrayTrait {
33+
/// Creates a byte array with the data.
34+
fn new(data: Array<bytes31>, num_last_bytes: u8) -> ByteArray {
35+
if data.len() == 0 {
36+
assert!(num_last_bytes == 0);
37+
} else {
38+
assert!(num_last_bytes <= 31);
39+
// TODO: check that unused bytes are zeroed.
40+
}
41+
ByteArray { num_last_bytes, data }
42+
}
43+
44+
/// Removes 31 or less bytes from the start of the array.
45+
/// Returns the value and the number of bytes.
46+
fn pop_front(ref self: ByteArray) -> Option<(bytes31, u8)> {
47+
let item = self.data.pop_front()?;
48+
if self.data.is_empty() {
49+
let num_bytes = self.num_last_bytes;
50+
self.num_last_bytes = 0;
51+
Option::Some((item, num_bytes))
52+
} else {
53+
Option::Some((item, 31))
54+
}
55+
}
56+
57+
fn len(self: @ByteArray) -> usize {
58+
if self.data.is_empty() {
59+
0
60+
} else {
61+
(self.data.len() - 1) * 31 + (*self.num_last_bytes).into()
62+
}
63+
}
64+
}

target_chains/starknet/contracts/src/lib.cairo

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
pub mod pyth;
22
pub mod wormhole;
3+
pub mod byte_array;
34
pub mod reader;
45
pub mod hash;
56
pub mod util;

target_chains/starknet/contracts/src/merkle_tree.cairo

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::hash::{Hasher, HasherImpl};
2-
use super::reader::{Reader, ReaderImpl, ByteArray};
2+
use super::reader::{Reader, ReaderImpl};
3+
use super::byte_array::ByteArray;
34
use super::util::ONE_SHIFT_96;
45
use core::cmp::{min, max};
56

target_chains/starknet/contracts/src/reader.cairo

Lines changed: 1 addition & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use core::keccak::cairo_keccak;
44
use core::integer::u128_byte_reverse;
55
use core::fmt::{Debug, Formatter};
66
use pyth::util::{UNEXPECTED_OVERFLOW, UNEXPECTED_ZERO, one_shift_left_bytes_u128};
7+
use super::byte_array::{ByteArray, ByteArrayImpl};
78

89
#[derive(Copy, Drop, Debug, Serde, PartialEq)]
910
pub enum Error {
@@ -18,69 +19,6 @@ impl ErrorIntoFelt252 of Into<Error, felt252> {
1819
}
1920
}
2021

21-
/// A byte array with storage format similar to `core::ByteArray`, but
22-
/// suitable for reading data from it.
23-
#[derive(Drop, Clone, Serde)]
24-
pub struct ByteArray {
25-
// Number of bytes stored in the last item of `self.data` (or 0 if it's empty).
26-
num_last_bytes: u8,
27-
// Bytes in big endian. Each item except the last one stores 31 bytes.
28-
// If `num_last_bytes < 31`, unused most significant bytes of the last item will be unused.
29-
data: Array<bytes31>,
30-
}
31-
32-
impl DebugByteArray of Debug<ByteArray> {
33-
fn fmt(self: @ByteArray, ref f: Formatter) -> Result<(), core::fmt::Error> {
34-
write!(f, "ByteArray {{ num_last_bytes: {}, data: [", self.num_last_bytes)?;
35-
let mut data = self.data.clone();
36-
loop {
37-
match data.pop_front() {
38-
Option::Some(v) => {
39-
let v: u256 = v.into();
40-
write!(f, "{:?}, ", v).unwrap();
41-
},
42-
Option::None => { break; },
43-
}
44-
};
45-
write!(f, "]}}")
46-
}
47-
}
48-
49-
#[generate_trait]
50-
pub impl ByteArrayImpl of ByteArrayTrait {
51-
/// Creates a byte array with the data.
52-
fn new(data: Array<bytes31>, num_last_bytes: u8) -> ByteArray {
53-
if data.len() == 0 {
54-
assert!(num_last_bytes == 0);
55-
} else {
56-
assert!(num_last_bytes <= 31);
57-
// TODO: check that unused bytes are zeroed.
58-
}
59-
ByteArray { num_last_bytes, data }
60-
}
61-
62-
/// Removes 31 or less bytes from the start of the array.
63-
/// Returns the value and the number of bytes.
64-
fn pop_front(ref self: ByteArray) -> Option<(bytes31, u8)> {
65-
let item = self.data.pop_front()?;
66-
if self.data.is_empty() {
67-
let num_bytes = self.num_last_bytes;
68-
self.num_last_bytes = 0;
69-
Option::Some((item, num_bytes))
70-
} else {
71-
Option::Some((item, 31))
72-
}
73-
}
74-
75-
fn len(self: @ByteArray) -> usize {
76-
if self.data.is_empty() {
77-
0
78-
} else {
79-
(self.data.len() - 1) * 31 + (*self.num_last_bytes).into()
80-
}
81-
}
82-
}
83-
8422
/// Allows to read data from a byte array as big endian integers.
8523
/// All methods return `EOF` error if attempted to
8624
/// read more bytes than is available.

target_chains/starknet/contracts/src/wormhole.cairo

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use pyth::reader::ByteArray;
1+
use super::byte_array::ByteArray;
22
use core::starknet::secp256_trait::Signature;
33
use pyth::util::UnwrapWithFelt252;
44

@@ -114,7 +114,8 @@ mod wormhole {
114114
use super::{
115115
VM, IWormhole, GuardianSignature, quorum, ParseAndVerifyVmError, SubmitNewGuardianSetError
116116
};
117-
use pyth::reader::{Reader, ReaderImpl, ByteArray};
117+
use pyth::reader::{Reader, ReaderImpl};
118+
use pyth::byte_array::ByteArray;
118119
use core::starknet::secp256_trait::{Signature, recover_public_key, Secp256PointTrait};
119120
use core::starknet::secp256k1::Secp256k1Point;
120121
use core::starknet::{

target_chains/starknet/contracts/tests/wormhole.cairo

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use snforge_std::{declare, ContractClassTrait, start_prank, stop_prank, CheatTarget};
22
use pyth::wormhole::{IWormholeDispatcher, IWormholeDispatcherTrait, ParseAndVerifyVmError};
3-
use pyth::reader::{ByteArray, ByteArrayImpl, ReaderImpl};
3+
use pyth::reader::ReaderImpl;
4+
use pyth::byte_array::{ByteArray, ByteArrayImpl};
45
use pyth::util::{UnwrapWithFelt252, array_felt252_to_bytes31};
56
use core::starknet::ContractAddress;
67
use core::panic_with_felt252;

0 commit comments

Comments
 (0)