Skip to content

Commit

Permalink
Merge pull request #2349 from AleoHQ/feat/cleanup-map
Browse files Browse the repository at this point in the history
Clean up `ConfirmedTransactionsMap`
  • Loading branch information
howardwu authored Feb 12, 2024
2 parents e0add02 + 26bd4df commit d1f4e17
Show file tree
Hide file tree
Showing 11 changed files with 430 additions and 108 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions ledger/store/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ optional = true
[dependencies.serde]
version = "1.0"

[dependencies.serde_json]
version = "1.0"
features = [ "preserve_order" ]

[dependencies.tracing]
version = "0.1"
optional = true
Expand Down
82 changes: 82 additions & 0 deletions ledger/store/src/block/confirmed_tx_type/bytes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright (C) 2019-2023 Aleo Systems Inc.
// This file is part of the snarkVM library.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use super::*;

impl<N: Network> FromBytes for ConfirmedTxType<N> {
/// Reads the confirmed transaction type from the buffer.
fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
// Read the variant.
let variant = u8::read_le(&mut reader)?;
// Match the variant.
match variant {
0 => Ok(Self::AcceptedDeploy(u32::read_le(&mut reader)?)),
1 => Ok(Self::AcceptedExecute(u32::read_le(&mut reader)?)),
2 => Ok(Self::RejectedDeploy(u32::read_le(&mut reader)?, Rejected::read_le(&mut reader)?)),
3 => Ok(Self::RejectedExecute(u32::read_le(&mut reader)?, Rejected::read_le(&mut reader)?)),
4.. => Err(error("Invalid confirmed transaction type variant")),
}
}
}

impl<N: Network> ToBytes for ConfirmedTxType<N> {
/// Writes the confirmed transaction type to the buffer.
fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
// Write the confirmed transaction type.
match self {
Self::AcceptedDeploy(index) => {
// Write the variant.
0u8.write_le(&mut writer)?;
// Write the index.
index.write_le(&mut writer)
}
Self::AcceptedExecute(index) => {
// Write the variant.
1u8.write_le(&mut writer)?;
// Write the index.
index.write_le(&mut writer)
}
Self::RejectedDeploy(index, rejected) => {
// Write the variant.
2u8.write_le(&mut writer)?;
// Write the index.
index.write_le(&mut writer)?;
// Write the rejected transaction.
rejected.write_le(&mut writer)
}
Self::RejectedExecute(index, rejected) => {
// Write the variant.
3u8.write_le(&mut writer)?;
// Write the index.
index.write_le(&mut writer)?;
// Write the rejected transaction.
rejected.write_le(&mut writer)
}
}
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_bytes() {
for expected in crate::confirmed_tx_type::test_helpers::sample_confirmed_tx_types() {
// Check the byte representation.
let expected_bytes = expected.to_bytes_le().unwrap();
assert_eq!(expected, ConfirmedTxType::read_le(&expected_bytes[..]).unwrap());
}
}
}
79 changes: 79 additions & 0 deletions ledger/store/src/block/confirmed_tx_type/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright (C) 2019-2023 Aleo Systems Inc.
// This file is part of the snarkVM library.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

mod bytes;
mod serialize;
mod string;

use super::*;

#[derive(Clone, PartialEq, Eq)]
pub enum ConfirmedTxType<N: Network> {
/// A deploy transaction that was accepted.
AcceptedDeploy(u32),
/// An execute transaction that was accepted.
AcceptedExecute(u32),
/// A deploy transaction that was rejected.
RejectedDeploy(u32, Rejected<N>),
/// An execute transaction that was rejected.
RejectedExecute(u32, Rejected<N>),
}

#[cfg(test)]
pub mod test_helpers {
use super::*;
use console::network::MainnetV0;

type CurrentNetwork = MainnetV0;

/// Samples an accepted deploy.
pub(crate) fn sample_accepted_deploy(rng: &mut TestRng) -> ConfirmedTxType<CurrentNetwork> {
// Return the accepted deploy.
ConfirmedTxType::AcceptedDeploy(rng.gen())
}

/// Samples an accepted execution.
pub(crate) fn sample_accepted_execution(rng: &mut TestRng) -> ConfirmedTxType<CurrentNetwork> {
// Return the accepted execution.
ConfirmedTxType::AcceptedExecute(rng.gen())
}

/// Samples a rejected deploy.
pub(crate) fn sample_rejected_deploy(rng: &mut TestRng) -> ConfirmedTxType<CurrentNetwork> {
// Sample the rejected deployment.
let rejected = ledger_test_helpers::sample_rejected_deployment(rng.gen(), rng);
// Return the rejected deploy.
ConfirmedTxType::RejectedDeploy(rng.gen(), rejected)
}

/// Samples a rejected execution.
pub(crate) fn sample_rejected_execute(rng: &mut TestRng) -> ConfirmedTxType<CurrentNetwork> {
// Sample the rejected execution.
let rejected = ledger_test_helpers::sample_rejected_execution(rng.gen(), rng);
// Return the rejected execution.
ConfirmedTxType::RejectedExecute(rng.gen(), rejected)
}

/// Sample a list of randomly rejected transactions.
pub(crate) fn sample_confirmed_tx_types() -> Vec<ConfirmedTxType<CurrentNetwork>> {
let rng = &mut TestRng::default();

vec![
sample_accepted_deploy(rng),
sample_accepted_execution(rng),
sample_rejected_deploy(rng),
sample_rejected_execute(rng),
]
}
}
147 changes: 147 additions & 0 deletions ledger/store/src/block/confirmed_tx_type/serialize.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
// Copyright (C) 2019-2023 Aleo Systems Inc.
// This file is part of the snarkVM library.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use super::*;

impl<N: Network> Serialize for ConfirmedTxType<N> {
#[inline]
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
match serializer.is_human_readable() {
true => match self {
Self::AcceptedDeploy(index) => {
let mut confirmed_tx_type = serializer.serialize_struct("ConfirmedTxType", 2)?;
confirmed_tx_type.serialize_field("type", "AcceptedDeploy")?;
confirmed_tx_type.serialize_field("index", index)?;
confirmed_tx_type.end()
}
Self::AcceptedExecute(index) => {
let mut confirmed_tx_type = serializer.serialize_struct("ConfirmedTxType", 2)?;
confirmed_tx_type.serialize_field("type", "AcceptedExecute")?;
confirmed_tx_type.serialize_field("index", index)?;
confirmed_tx_type.end()
}
Self::RejectedDeploy(index, rejected) => {
let mut confirmed_tx_type = serializer.serialize_struct("ConfirmedTxType", 3)?;
confirmed_tx_type.serialize_field("type", "RejectedDeploy")?;
confirmed_tx_type.serialize_field("index", index)?;
confirmed_tx_type.serialize_field("rejected", rejected)?;
confirmed_tx_type.end()
}
Self::RejectedExecute(index, rejected) => {
let mut confirmed_tx_type = serializer.serialize_struct("ConfirmedTxType", 3)?;
confirmed_tx_type.serialize_field("type", "RejectedExecute")?;
confirmed_tx_type.serialize_field("index", index)?;
confirmed_tx_type.serialize_field("rejected", rejected)?;
confirmed_tx_type.end()
}
},
false => ToBytesSerializer::serialize_with_size_encoding(self, serializer),
}
}
}

impl<'de, N: Network> Deserialize<'de> for ConfirmedTxType<N> {
#[inline]
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
match deserializer.is_human_readable() {
true => {
let mut confirmed_tx_type = serde_json::Value::deserialize(deserializer)?;
let type_: String = DeserializeExt::take_from_value::<D>(&mut confirmed_tx_type, "type")?;

// Recover the confirmed transaction type.
match type_.as_str() {
"AcceptedDeploy" => Ok(Self::AcceptedDeploy(
DeserializeExt::take_from_value::<D>(&mut confirmed_tx_type, "index")
.map_err(de::Error::custom)?,
)),
"AcceptedExecute" => Ok(Self::AcceptedExecute(
DeserializeExt::take_from_value::<D>(&mut confirmed_tx_type, "index")
.map_err(de::Error::custom)?,
)),
"RejectedDeploy" => {
let index = DeserializeExt::take_from_value::<D>(&mut confirmed_tx_type, "index")
.map_err(de::Error::custom)?;
let rejected = DeserializeExt::take_from_value::<D>(&mut confirmed_tx_type, "rejected")
.map_err(de::Error::custom)?;
Ok(Self::RejectedDeploy(index, rejected))
}
"RejectedExecute" => {
let index = DeserializeExt::take_from_value::<D>(&mut confirmed_tx_type, "index")
.map_err(de::Error::custom)?;
let rejected = DeserializeExt::take_from_value::<D>(&mut confirmed_tx_type, "rejected")
.map_err(de::Error::custom)?;
Ok(Self::RejectedExecute(index, rejected))
}
_ => Err(error("Invalid confirmed transaction type")).map_err(de::Error::custom),
}
}
false => FromBytesDeserializer::<Self>::deserialize_with_size_encoding(
deserializer,
"confirmed transaction type",
),
}
}
}

#[cfg(test)]
mod tests {
use super::*;

fn check_serde_json<
T: Serialize + for<'a> Deserialize<'a> + Debug + Display + PartialEq + Eq + FromStr + ToBytes + FromBytes,
>(
expected: T,
) {
// Serialize
let expected_string = expected.to_string();
let candidate_string = serde_json::to_string(&expected).unwrap();
let candidate = serde_json::from_str::<T>(&candidate_string).unwrap();
assert_eq!(expected, candidate);
assert_eq!(expected_string, candidate_string);
assert_eq!(expected_string, candidate.to_string());

// Deserialize
assert_eq!(expected, T::from_str(&expected_string).unwrap_or_else(|_| panic!("FromStr: {expected_string}")));
assert_eq!(expected, serde_json::from_str(&candidate_string).unwrap());
}

fn check_bincode<
T: Serialize + for<'a> Deserialize<'a> + Debug + Display + PartialEq + Eq + FromStr + ToBytes + FromBytes,
>(
expected: T,
) {
// Serialize
let expected_bytes = expected.to_bytes_le().unwrap();
let expected_bytes_with_size_encoding = bincode::serialize(&expected).unwrap();
assert_eq!(&expected_bytes[..], &expected_bytes_with_size_encoding[8..]);

// Deserialize
assert_eq!(expected, T::read_le(&expected_bytes[..]).unwrap());
assert_eq!(expected, bincode::deserialize(&expected_bytes_with_size_encoding[..]).unwrap());
}

#[test]
fn test_serde_json() {
for rejected in crate::confirmed_tx_type::test_helpers::sample_confirmed_tx_types() {
check_serde_json(rejected);
}
}

#[test]
fn test_bincode() {
for rejected in crate::confirmed_tx_type::test_helpers::sample_confirmed_tx_types() {
check_bincode(rejected);
}
}
}
38 changes: 38 additions & 0 deletions ledger/store/src/block/confirmed_tx_type/string.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (C) 2019-2023 Aleo Systems Inc.
// This file is part of the snarkVM library.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use super::*;

impl<N: Network> FromStr for ConfirmedTxType<N> {
type Err = Error;

/// Initializes the confirmed transaction type- from a JSON-string.
fn from_str(status: &str) -> Result<Self, Self::Err> {
Ok(serde_json::from_str(status)?)
}
}

impl<N: Network> Debug for ConfirmedTxType<N> {
/// Prints the confirmed transaction type as a JSON-string.
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
Display::fmt(self, f)
}
}

impl<N: Network> Display for ConfirmedTxType<N> {
/// Displays the confirmed transaction type as a JSON-string.
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{}", serde_json::to_string(self).map_err::<fmt::Error, _>(ser::Error::custom)?)
}
}
Loading

0 comments on commit d1f4e17

Please sign in to comment.