From 62e5ace442eec55c23d877b9f6a465c56e9d6cf6 Mon Sep 17 00:00:00 2001 From: David Burkett Date: Wed, 10 Jun 2026 12:02:01 -0400 Subject: [PATCH 1/4] pibd: bound segment decoding allocations (#3850) --- chain/src/txhashset/bitmap_accumulator.rs | 149 +++++++++++++++++----- chain/tests/bitmap_segment.rs | 63 ++++++++- core/src/core/pmmr/segment.rs | 79 ++++++------ core/tests/segment.rs | 32 +++++ p2p/src/protocol.rs | 2 +- 5 files changed, 250 insertions(+), 75 deletions(-) diff --git a/chain/src/txhashset/bitmap_accumulator.rs b/chain/src/txhashset/bitmap_accumulator.rs index cae45f7d..6d6b388d 100644 --- a/chain/src/txhashset/bitmap_accumulator.rs +++ b/chain/src/txhashset/bitmap_accumulator.rs @@ -280,6 +280,102 @@ pub struct BitmapSegment { proof: SegmentProof, } +impl BitmapSegment { + // Matches the upper end of the currently served PIBD bitmap segment range. + const MAX_SEGMENT_HEIGHT: u8 = 13; + + fn max_chunks(identifier: &SegmentIdentifier) -> Result { + if identifier.height > Self::MAX_SEGMENT_HEIGHT { + return Err(ser::Error::TooLargeReadErr); + } + 1usize + .checked_shl(identifier.height as u32) + .ok_or(ser::Error::TooLargeReadErr) + } + + fn leaf_offset(identifier: &SegmentIdentifier) -> Result { + let segment_capacity = 1u64 + .checked_shl(identifier.height as u32) + .ok_or(ser::Error::TooLargeReadErr)?; + segment_capacity + .checked_mul(identifier.idx) + .ok_or(ser::Error::TooLargeReadErr) + } + + fn n_chunks(blocks: &[BitmapBlock]) -> Result { + let (last, full_blocks) = blocks.split_last().ok_or(ser::Error::CorruptedData)?; + for block in full_blocks { + if block.try_n_chunks()? != BitmapBlock::NCHUNKS { + return Err(ser::Error::CorruptedData); + } + } + let last_chunks = last.try_n_chunks()?; + if last_chunks == 0 { + return Err(ser::Error::CorruptedData); + } + full_blocks + .len() + .checked_mul(BitmapBlock::NCHUNKS) + .and_then(|n| n.checked_add(last_chunks)) + .ok_or(ser::Error::TooLargeReadErr) + } + + fn validate_blocks( + identifier: &SegmentIdentifier, + blocks: &[BitmapBlock], + ) -> Result { + let offset = Self::leaf_offset(identifier)?; + let n_chunks = Self::n_chunks(blocks)?; + if n_chunks > Self::max_chunks(identifier)? { + return Err(ser::Error::TooLargeReadErr); + } + offset + .checked_add((n_chunks - 1) as u64) + .ok_or(ser::Error::TooLargeReadErr)?; + Ok(n_chunks) + } + + /// Convert this bitmap segment into a PMMR segment, validating its encoded shape. + pub fn into_segment(self) -> Result, ser::Error> { + let BitmapSegment { + identifier, + blocks, + proof, + } = self; + + let n_chunks = Self::validate_blocks(&identifier, &blocks)?; + let mut leaf_pos = Vec::with_capacity(n_chunks); + let mut chunks = Vec::with_capacity(n_chunks); + let offset = Self::leaf_offset(&identifier)?; + for i in 0..(n_chunks as u64) { + let insertion_idx = offset.checked_add(i).ok_or(ser::Error::TooLargeReadErr)?; + leaf_pos.push(pmmr::insertion_to_pmmr_index(insertion_idx)); + chunks.push(BitmapChunk::new()); + } + + for (block_idx, block) in blocks.into_iter().enumerate() { + block.try_n_chunks()?; + let offset = block_idx * BitmapBlock::NCHUNKS; + for (i, _) in block.inner.iter().enumerate().filter(|&(_, v)| v) { + chunks + .get_mut(offset + i / BitmapChunk::LEN_BITS) + .ok_or(ser::Error::CorruptedData)? + .0 + .set(i % BitmapChunk::LEN_BITS, true); + } + } + + Ok(Segment::from_parts( + identifier, + Vec::new(), + Vec::new(), + leaf_pos, + chunks, + proof, + )) + } +} + impl Writeable for BitmapSegment { fn write(&self, writer: &mut W) -> Result<(), ser::Error> { Writeable::write(&self.identifier, writer)?; @@ -297,10 +393,20 @@ impl Readable for BitmapSegment { let identifier: SegmentIdentifier = Readable::read(reader)?; let n_blocks = reader.read_u16()? as usize; + if n_blocks == 0 { + return Err(ser::Error::CorruptedData); + } + let max_blocks = (BitmapSegment::max_chunks(&identifier)? + BitmapBlock::NCHUNKS - 1) + / BitmapBlock::NCHUNKS; + if n_blocks > max_blocks { + return Err(ser::Error::TooLargeReadErr); + } + BitmapSegment::leaf_offset(&identifier)?; let mut blocks = Vec::::with_capacity(n_blocks); for _ in 0..n_blocks { blocks.push(Readable::read(reader)?); } + BitmapSegment::validate_blocks(&identifier, &blocks)?; let proof = Readable::read(reader)?; Ok(Self { @@ -348,36 +454,7 @@ impl From> for BitmapSegment { // TODO: this can be sped up with some `unsafe` code impl From for Segment { fn from(segment: BitmapSegment) -> Self { - let BitmapSegment { - identifier, - blocks, - proof, - } = segment; - - // Count the number of chunks taking into account that the final block might be smaller - let n_chunks = (blocks.len() - 1) * BitmapBlock::NCHUNKS - + blocks.last().map(|b| b.n_chunks()).unwrap_or(0); - let mut leaf_pos = Vec::with_capacity(n_chunks); - let mut chunks = Vec::with_capacity(n_chunks); - let offset = (1 << identifier.height) * identifier.idx; - for i in 0..(n_chunks as u64) { - leaf_pos.push(pmmr::insertion_to_pmmr_index(offset + i)); - chunks.push(BitmapChunk::new()); - } - - for (block_idx, block) in blocks.into_iter().enumerate() { - assert!(block.inner.len() <= BitmapBlock::NBITS as usize); - let offset = block_idx * BitmapBlock::NCHUNKS; - for (i, _) in block.inner.iter().enumerate().filter(|&(_, v)| v) { - chunks - .get_mut(offset + i / BitmapChunk::LEN_BITS) - .unwrap() - .0 - .set(i % BitmapChunk::LEN_BITS, true); - } - } - - Segment::from_parts(identifier, Vec::new(), Vec::new(), leaf_pos, chunks, proof) + segment.into_segment().expect("valid bitmap segment") } } @@ -401,12 +478,16 @@ impl BitmapBlock { } } - fn n_chunks(&self) -> usize { + fn try_n_chunks(&self) -> Result { let length = self.inner.len(); - assert_eq!(length % BitmapChunk::LEN_BITS, 0); + if length % BitmapChunk::LEN_BITS != 0 { + return Err(ser::Error::CorruptedData); + } let n_chunks = length / BitmapChunk::LEN_BITS; - assert!(n_chunks <= BitmapBlock::NCHUNKS); - n_chunks + if n_chunks > BitmapBlock::NCHUNKS { + return Err(ser::Error::TooLargeReadErr); + } + Ok(n_chunks) } } diff --git a/chain/tests/bitmap_segment.rs b/chain/tests/bitmap_segment.rs index 960625ba..39092b8e 100644 --- a/chain/tests/bitmap_segment.rs +++ b/chain/tests/bitmap_segment.rs @@ -1,7 +1,7 @@ use self::chain::txhashset::{BitmapAccumulator, BitmapSegment}; use self::core::core::pmmr::segment::{Segment, SegmentIdentifier}; use self::core::ser::{ - BinReader, BinWriter, DeserializationMode, ProtocolVersion, Readable, Writeable, + self, BinReader, BinWriter, DeserializationMode, ProtocolVersion, Readable, Writeable, }; use croaring::Bitmap; use grin_chain as chain; @@ -10,6 +10,29 @@ use grin_util::secp::rand::Rng; use rand::thread_rng; use std::io::Cursor; +fn push_u16(bytes: &mut Vec, n: u16) { + bytes.extend_from_slice(&n.to_be_bytes()); +} + +fn push_u64(bytes: &mut Vec, n: u64) { + bytes.extend_from_slice(&n.to_be_bytes()); +} + +fn bitmap_segment_header(height: u8, idx: u64, n_blocks: u16) -> Vec { + let mut bytes = vec![height]; + push_u64(&mut bytes, idx); + push_u16(&mut bytes, n_blocks); + bytes +} + +fn read_bitmap_segment(bytes: &[u8]) -> Result { + ser::deserialize( + &mut &bytes[..], + ProtocolVersion(1), + DeserializationMode::default(), + ) +} + fn test_roundtrip(entries: usize) { let mut rng = thread_rng(); @@ -63,7 +86,7 @@ fn test_roundtrip(entries: usize) { assert_eq!(bms, bms2); // Convert back to `Segment` - let segment2 = Segment::from(bms2); + let segment2 = bms2.into_segment().unwrap(); assert_eq!(segment, segment2); } @@ -83,3 +106,39 @@ fn abundant_segment_ser_roundtrip() { let max = 1 << 16; test_roundtrip(thread_rng().gen_range(max - 4096, max - 1024)); } + +#[test] +fn bitmap_segment_read_rejects_empty_blocks() { + let bytes = bitmap_segment_header(9, 0, 0); + assert_eq!( + read_bitmap_segment(&bytes).err(), + Some(ser::Error::CorruptedData) + ); +} + +#[test] +fn bitmap_segment_read_rejects_too_many_blocks() { + let bytes = bitmap_segment_header(9, 0, 9); + assert_eq!( + read_bitmap_segment(&bytes).err(), + Some(ser::Error::TooLargeReadErr) + ); +} + +#[test] +fn bitmap_segment_read_rejects_too_large_height() { + let bytes = bitmap_segment_header(14, 0, 1); + assert_eq!( + read_bitmap_segment(&bytes).err(), + Some(ser::Error::TooLargeReadErr) + ); +} + +#[test] +fn bitmap_segment_read_rejects_offset_overflow() { + let bytes = bitmap_segment_header(13, u64::MAX, 1); + assert_eq!( + read_bitmap_segment(&bytes).err(), + Some(ser::Error::TooLargeReadErr) + ); +} diff --git a/core/src/core/pmmr/segment.rs b/core/src/core/pmmr/segment.rs index 8df8b8f9..f9f555bd 100644 --- a/core/src/core/pmmr/segment.rs +++ b/core/src/core/pmmr/segment.rs @@ -21,6 +21,39 @@ use croaring::Bitmap; use std::cmp::min; use std::fmt::Debug; +const MAX_SEGMENT_READ_ITEMS: u64 = 1_000_000; +const SEGMENT_READ_PREALLOC_ITEMS: u64 = 1024; + +fn read_segment_item_count(reader: &mut R) -> Result { + let count = reader.read_u64()?; + if count > MAX_SEGMENT_READ_ITEMS { + return Err(Error::TooLargeReadErr); + } + Ok(count) +} + +fn read_segment_positions(reader: &mut R, count: u64) -> Result, Error> { + let mut positions = Vec::with_capacity(min(count, SEGMENT_READ_PREALLOC_ITEMS) as usize); + let mut last_pos = 0; + for _ in 0..count { + let pos = reader.read_u64()?; + if pos <= last_pos { + return Err(Error::SortError); + } + last_pos = pos; + positions.push(pos - 1); + } + Ok(positions) +} + +fn read_segment_items(reader: &mut R, count: u64) -> Result, Error> { + let mut items = Vec::with_capacity(min(count, SEGMENT_READ_PREALLOC_ITEMS) as usize); + for _ in 0..count { + items.push(T::read(reader)?); + } + Ok(items) +} + #[derive(Clone, Debug, Eq, PartialEq)] /// Possible segment types, according to this desegmenter pub enum SegmentType { @@ -568,39 +601,13 @@ impl Readable for Segment { fn read(reader: &mut R) -> Result { let identifier = Readable::read(reader)?; - let n_hashes = reader.read_u64()? as usize; - let mut hash_pos = Vec::with_capacity(n_hashes); - let mut last_pos = 0; - for _ in 0..n_hashes { - let pos = reader.read_u64()?; - if pos <= last_pos { - return Err(Error::SortError); - } - last_pos = pos; - hash_pos.push(pos - 1); - } + let n_hashes = read_segment_item_count(reader)?; + let hash_pos = read_segment_positions(reader, n_hashes)?; + let hashes = read_segment_items(reader, n_hashes)?; - let mut hashes = Vec::::with_capacity(n_hashes); - for _ in 0..n_hashes { - hashes.push(Readable::read(reader)?); - } - - let n_leaves = reader.read_u64()? as usize; - let mut leaf_pos = Vec::with_capacity(n_leaves); - last_pos = 0; - for _ in 0..n_leaves { - let pos = reader.read_u64()?; - if pos <= last_pos { - return Err(Error::SortError); - } - last_pos = pos; - leaf_pos.push(pos - 1); - } - - let mut leaf_data = Vec::::with_capacity(n_leaves); - for _ in 0..n_leaves { - leaf_data.push(Readable::read(reader)?); - } + let n_leaves = read_segment_item_count(reader)?; + let leaf_pos = read_segment_positions(reader, n_leaves)?; + let leaf_data = read_segment_items(reader, n_leaves)?; let proof = Readable::read(reader)?; @@ -823,12 +830,8 @@ impl SegmentProof { impl Readable for SegmentProof { fn read(reader: &mut R) -> Result { - let n_hashes = reader.read_u64()? as usize; - let mut hashes = Vec::with_capacity(n_hashes); - for _ in 0..n_hashes { - let hash: Hash = Readable::read(reader)?; - hashes.push(hash); - } + let n_hashes = read_segment_item_count(reader)?; + let hashes = read_segment_items(reader, n_hashes)?; Ok(Self { hashes }) } } diff --git a/core/tests/segment.rs b/core/tests/segment.rs index cb81402f..3ab04f7a 100644 --- a/core/tests/segment.rs +++ b/core/tests/segment.rs @@ -16,10 +16,15 @@ mod common; use self::core::core::pmmr; use self::core::core::{Segment, SegmentIdentifier}; +use self::core::ser::{self, DeserializationMode, ProtocolVersion}; use common::TestElem; use grin_core as core; use grin_core::core::pmmr::ReadablePMMR; +fn push_u64(bytes: &mut Vec, n: u64) { + bytes.extend_from_slice(&n.to_be_bytes()); +} + fn test_unprunable_size(height: u8, n_leaves: u32) { let size = 1u64 << height; let n_segments = (n_leaves as u64 + size - 1) / size; @@ -59,3 +64,30 @@ fn unprunable_mmr() { test_unprunable_size(3, i); } } + +#[test] +fn segment_read_rejects_large_hash_count() { + let mut bytes = vec![1]; + push_u64(&mut bytes, 0); + push_u64(&mut bytes, 1_000_001); + + let res: Result, _> = ser::deserialize( + &mut &bytes[..], + ProtocolVersion(1), + DeserializationMode::default(), + ); + assert_eq!(res.err(), Some(ser::Error::TooLargeReadErr)); +} + +#[test] +fn segment_proof_read_rejects_large_hash_count() { + let mut bytes = vec![]; + push_u64(&mut bytes, 1_000_001); + + let res: Result = ser::deserialize( + &mut &bytes[..], + ProtocolVersion(1), + DeserializationMode::default(), + ); + assert_eq!(res.err(), Some(ser::Error::TooLargeReadErr)); +} diff --git a/p2p/src/protocol.rs b/p2p/src/protocol.rs index 31e06932..2699b304 100644 --- a/p2p/src/protocol.rs +++ b/p2p/src/protocol.rs @@ -382,7 +382,7 @@ impl MessageHandler for Protocol { block_hash, output_root ); - adapter.receive_bitmap_segment(block_hash, output_root, segment.into())?; + adapter.receive_bitmap_segment(block_hash, output_root, segment.into_segment()?)?; Consumed::None } Message::OutputSegment(req) => { From 68053a203e0bcf7899bba29d608b48f6123a4bbd Mon Sep 17 00:00:00 2001 From: David Burkett Date: Wed, 10 Jun 2026 20:27:40 -0400 Subject: [PATCH 2/4] Add fountainoffairfortune seeds --- servers/src/grin/seed.rs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/servers/src/grin/seed.rs b/servers/src/grin/seed.rs index 3d5fe8d8..aa1e8d44 100644 --- a/servers/src/grin/seed.rs +++ b/servers/src/grin/seed.rs @@ -35,18 +35,20 @@ use crate::util::StopState; /// DNS Seeds with contacts associated - Mainnet pub const MAINNET_DNS_SEEDS: &[&str] = &[ - "mainnet-seed.grinnode.live", // info@grinnode.live - "grincoin.org", // xmpp:aglkm@conversations.im - "main.gri.mw", // admin@gri.mw - "mainnet.grinffindor.org", // support@grinffindor.org - "main-seed.grin.money", // support@grinily.com + "mainnet-seed.grinnode.live", // info@grinnode.live + "grincoin.org", // xmpp:aglkm@conversations.im + "main.gri.mw", // admin@gri.mw + "mainnet.grinffindor.org", // support@grinffindor.org + "main-seed.grin.money", // support@grinily.com + "mainnet.fountainoffairfortune.it", // support@fountainoffairfortune.it ]; /// DNS Seeds with contacts associated - Testnet pub const TESTNET_DNS_SEEDS: &[&str] = &[ - "testnet.grincoin.org", // xmpp:aglkm@conversations.im - "test.gri.mw", // admin@gri.mw - "testnet.grinffindor.org", // support@grinffindor.org - "test-seed.grin.money", // support@grinily.com + "testnet.grincoin.org", // xmpp:aglkm@conversations.im + "test.gri.mw", // admin@gri.mw + "testnet.grinffindor.org", // support@grinffindor.org + "test-seed.grin.money", // support@grinily.com + "testnet.fountainoffairfortune.it", // support@fountainoffairfortune.it ]; pub fn connect_and_monitor( From ee4390e4376d4832267078cd8803615cdcb24019 Mon Sep 17 00:00:00 2001 From: wiesche <120273695+wiesche89@users.noreply.github.com> Date: Tue, 26 May 2026 13:01:02 +0200 Subject: [PATCH 3/4] Clarifies the blinding factor range proof explanation and includes the remaining typo fixes (#3840) --- api/src/foreign.rs | 2 +- api/src/owner.rs | 2 +- doc/intro.md | 4 +++- doc/pow/pow.md | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/api/src/foreign.rs b/api/src/foreign.rs index cddfe783..f1f83c00 100644 --- a/api/src/foreign.rs +++ b/api/src/foreign.rs @@ -32,7 +32,7 @@ use crate::{rest::*, BlockListing}; use std::sync::Weak; /// Main interface into all node API functions. -/// Node APIs are split into two seperate blocks of functionality +/// Node APIs are split into two separate blocks of functionality /// called the ['Owner'](struct.Owner.html) and ['Foreign'](struct.Foreign.html) APIs /// /// Methods in this API are intended to be 'single use'. diff --git a/api/src/owner.rs b/api/src/owner.rs index b63609c2..2ec02c12 100644 --- a/api/src/owner.rs +++ b/api/src/owner.rs @@ -27,7 +27,7 @@ use std::net::SocketAddr; use std::sync::Weak; /// Main interface into all node API functions. -/// Node APIs are split into two seperate blocks of functionality +/// Node APIs are split into two separate blocks of functionality /// called the ['Owner'](struct.Owner.html) and ['Foreign'](struct.Foreign.html) APIs /// /// Methods in this API are intended to be 'single use'. diff --git a/doc/intro.md b/doc/intro.md index 9a05f9cb..a57763a7 100644 --- a/doc/intro.md +++ b/doc/intro.md @@ -252,7 +252,9 @@ which can be signed by the attacker because Carol's blinding factor cancels out This output (`(113 + 99)*G + 2*H`) requires that both the numbers 113 and 99 are known in order to be spent; the attacker would thus have successfully locked Carol's UTXO. The requirement for a range proof for the blinding factor prevents this -because the attacker doesn't know the number 113 and thus neither (113 + 99). A more detailed description of range proofs is further detailed in the [range proof paper](https://eprint.iacr.org/2017/1066.pdf). +because the attacker doesn't know the number 113 and thus neither (113 + 99). In other words, without knowing the private +key (blinding factor), the attacker would not know the value in the output and would not be able to produce a valid range proof for it. +A more detailed description of range proofs is further detailed in the [range proof paper](https://eprint.iacr.org/2017/1066.pdf). #### Putting It All Together diff --git a/doc/pow/pow.md b/doc/pow/pow.md index 52ef3607..3de4728d 100644 --- a/doc/pow/pow.md +++ b/doc/pow/pow.md @@ -113,10 +113,10 @@ Now, (hopefully) armed with a basic understanding of what the Cuckoo Cycle algor ## Mining in Grin -The Cuckoo Cycle outlined above forms the basis of Grin's mining process, however Grin uses two variantion of Cuckoo Cycle in tandem with several other systems to create a Proof-of-Work. +The Cuckoo Cycle outlined above forms the basis of Grin's mining process, however Grin uses two variations of Cuckoo Cycle in tandem with several other systems to create a Proof-of-Work. 1. for GPUs: Cuckaroo on 2^29 edges - * Tweaked every 6 months to maitain ASIC resistance. + * Tweaked every 6 months to maintain ASIC resistance. * 90% of rewards at launch, linearly decreasing to 0% in 2 years. * Variant of Cuckoo that enforces so-called ``mean'' mining. * Takes 5.5GB of memory (perhaps 4GB with slowdown). From a25fde96744a18e1d12f753177242963de82a642 Mon Sep 17 00:00:00 2001 From: David Burkett Date: Wed, 10 Jun 2026 20:50:21 -0400 Subject: [PATCH 4/4] Bump version to v5.4.1 --- Cargo.lock | 22 +++++++++++----------- Cargo.toml | 24 ++++++++++++------------ api/Cargo.toml | 14 +++++++------- chain/Cargo.toml | 10 +++++----- config/Cargo.toml | 10 +++++----- core/Cargo.toml | 6 +++--- keychain/Cargo.toml | 4 ++-- p2p/Cargo.toml | 12 ++++++------ pool/Cargo.toml | 10 +++++----- servers/Cargo.toml | 18 +++++++++--------- store/Cargo.toml | 6 +++--- util/Cargo.toml | 2 +- 12 files changed, 69 insertions(+), 69 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 429a99f9..4788f9ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -932,7 +932,7 @@ dependencies = [ [[package]] name = "grin" -version = "5.4.0" +version = "5.4.1" dependencies = [ "blake2-rfc", "built", @@ -962,7 +962,7 @@ dependencies = [ [[package]] name = "grin_api" -version = "5.4.0" +version = "5.4.1" dependencies = [ "async-stream", "bytes 1.7.1", @@ -995,7 +995,7 @@ dependencies = [ [[package]] name = "grin_chain" -version = "5.4.0" +version = "5.4.1" dependencies = [ "bit-vec", "bitflags 1.3.2", @@ -1019,7 +1019,7 @@ dependencies = [ [[package]] name = "grin_config" -version = "5.4.0" +version = "5.4.1" dependencies = [ "dirs", "grin_core", @@ -1035,7 +1035,7 @@ dependencies = [ [[package]] name = "grin_core" -version = "5.4.0" +version = "5.4.1" dependencies = [ "blake2-rfc", "byteorder", @@ -1061,7 +1061,7 @@ dependencies = [ [[package]] name = "grin_keychain" -version = "5.4.0" +version = "5.4.1" dependencies = [ "blake2-rfc", "byteorder", @@ -1082,7 +1082,7 @@ dependencies = [ [[package]] name = "grin_p2p" -version = "5.4.0" +version = "5.4.1" dependencies = [ "bitflags 1.3.2", "bytes 0.5.6", @@ -1104,7 +1104,7 @@ dependencies = [ [[package]] name = "grin_pool" -version = "5.4.0" +version = "5.4.1" dependencies = [ "blake2-rfc", "chrono", @@ -1136,7 +1136,7 @@ dependencies = [ [[package]] name = "grin_servers" -version = "5.4.0" +version = "5.4.1" dependencies = [ "async-stream", "chrono", @@ -1167,7 +1167,7 @@ dependencies = [ [[package]] name = "grin_store" -version = "5.4.0" +version = "5.4.1" dependencies = [ "byteorder", "chrono", @@ -1189,7 +1189,7 @@ dependencies = [ [[package]] name = "grin_util" -version = "5.4.0" +version = "5.4.1" dependencies = [ "anyhow", "backtrace", diff --git a/Cargo.toml b/Cargo.toml index b4b26e16..0e13bddf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "grin" -version = "5.4.0" +version = "5.4.1" authors = ["Grin Developers "] description = "Simple, private and scalable cryptocurrency implementation based on the Mimblewimble chain format." license = "Apache-2.0" @@ -34,15 +34,15 @@ serde_json = "1" log = "0.4" term = "0.6" -grin_api = { path = "./api", version = "5.4.0" } -grin_config = { path = "./config", version = "5.4.0" } -grin_chain = { path = "./chain", version = "5.4.0" } -grin_core = { path = "./core", version = "5.4.0" } -grin_keychain = { path = "./keychain", version = "5.4.0" } -grin_p2p = { path = "./p2p", version = "5.4.0" } -grin_servers = { path = "./servers", version = "5.4.0" } -grin_util = { path = "./util", version = "5.4.0" } -grin_store = { path = "./store", version = "5.4.0" } +grin_api = { path = "./api", version = "5.4.1" } +grin_config = { path = "./config", version = "5.4.1" } +grin_chain = { path = "./chain", version = "5.4.1" } +grin_core = { path = "./core", version = "5.4.1" } +grin_keychain = { path = "./keychain", version = "5.4.1" } +grin_p2p = { path = "./p2p", version = "5.4.1" } +grin_servers = { path = "./servers", version = "5.4.1" } +grin_util = { path = "./util", version = "5.4.1" } +grin_store = { path = "./store", version = "5.4.1" } [dependencies.cursive] version = "0.21" @@ -53,5 +53,5 @@ features = ["pancurses-backend"] built = { version = "0.8.0", features = ["git2"]} [dev-dependencies] -grin_chain = { path = "./chain", version = "5.4.0" } -grin_store = { path = "./store", version = "5.4.0" } +grin_chain = { path = "./chain", version = "5.4.1" } +grin_store = { path = "./store", version = "5.4.1" } diff --git a/api/Cargo.toml b/api/Cargo.toml index 88af1575..ecccd74f 100644 --- a/api/Cargo.toml +++ b/api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "grin_api" -version = "5.4.0" +version = "5.4.1" authors = ["Grin Developers "] description = "APIs for grin, a simple, private and scalable cryptocurrency implementation based on the Mimblewimble chain format." license = "Apache-2.0" @@ -32,9 +32,9 @@ async-stream = "0.3" url = "2.1" bytes = "1" -grin_core = { path = "../core", version = "5.4.0" } -grin_chain = { path = "../chain", version = "5.4.0" } -grin_p2p = { path = "../p2p", version = "5.4.0" } -grin_pool = { path = "../pool", version = "5.4.0" } -grin_store = { path = "../store", version = "5.4.0" } -grin_util = { path = "../util", version = "5.4.0" } +grin_core = { path = "../core", version = "5.4.1" } +grin_chain = { path = "../chain", version = "5.4.1" } +grin_p2p = { path = "../p2p", version = "5.4.1" } +grin_pool = { path = "../pool", version = "5.4.1" } +grin_store = { path = "../store", version = "5.4.1" } +grin_util = { path = "../util", version = "5.4.1" } diff --git a/chain/Cargo.toml b/chain/Cargo.toml index c9fab243..927a6741 100644 --- a/chain/Cargo.toml +++ b/chain/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "grin_chain" -version = "5.4.0" +version = "5.4.1" authors = ["Grin Developers "] description = "Chain implementation for grin, a simple, private and scalable cryptocurrency implementation based on the Mimblewimble chain format." license = "Apache-2.0" @@ -23,10 +23,10 @@ chrono = "0.4.11" lru-cache = "0.1" lazy_static = "1" -grin_core = { path = "../core", version = "5.4.0" } -grin_keychain = { path = "../keychain", version = "5.4.0" } -grin_store = { path = "../store", version = "5.4.0" } -grin_util = { path = "../util", version = "5.4.0" } +grin_core = { path = "../core", version = "5.4.1" } +grin_keychain = { path = "../keychain", version = "5.4.1" } +grin_store = { path = "../store", version = "5.4.1" } +grin_util = { path = "../util", version = "5.4.1" } [dev-dependencies] env_logger = "0.7" diff --git a/config/Cargo.toml b/config/Cargo.toml index 5700ea18..51511493 100644 --- a/config/Cargo.toml +++ b/config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "grin_config" -version = "5.4.0" +version = "5.4.1" authors = ["Grin Developers "] description = "Configuration for grin, a simple, private and scalable cryptocurrency implementation based on the Mimblewimble chain format." license = "Apache-2.0" @@ -16,10 +16,10 @@ serde_derive = "1" toml = "0.5" dirs = "2.0" -grin_core = { path = "../core", version = "5.4.0" } -grin_servers = { path = "../servers", version = "5.4.0" } -grin_p2p = { path = "../p2p", version = "5.4.0" } -grin_util = { path = "../util", version = "5.4.0" } +grin_core = { path = "../core", version = "5.4.1" } +grin_servers = { path = "../servers", version = "5.4.1" } +grin_p2p = { path = "../p2p", version = "5.4.1" } +grin_util = { path = "../util", version = "5.4.1" } [dev-dependencies] pretty_assertions = "0.6.1" diff --git a/core/Cargo.toml b/core/Cargo.toml index e9229e2f..ffe0249f 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "grin_core" -version = "5.4.0" +version = "5.4.1" authors = ["Grin Developers "] description = "Chain implementation for grin, a simple, private and scalable cryptocurrency implementation based on the Mimblewimble chain format." license = "Apache-2.0" @@ -28,8 +28,8 @@ chrono = { version = "0.4.11", features = ["serde"] } zeroize = { version = "1.1", features =["zeroize_derive"] } bytes = "0.5" -keychain = { package = "grin_keychain", path = "../keychain", version = "5.4.0" } -util = { package = "grin_util", path = "../util", version = "5.4.0" } +keychain = { package = "grin_keychain", path = "../keychain", version = "5.4.1" } +util = { package = "grin_util", path = "../util", version = "5.4.1" } [dev-dependencies] serde_json = "1" diff --git a/keychain/Cargo.toml b/keychain/Cargo.toml index 2d46b63d..5afd5a0b 100644 --- a/keychain/Cargo.toml +++ b/keychain/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "grin_keychain" -version = "5.4.0" +version = "5.4.1" authors = ["Grin Developers "] description = "Chain implementation for grin, a simple, private and scalable cryptocurrency implementation based on the Mimblewimble chain format." license = "Apache-2.0" @@ -26,4 +26,4 @@ ripemd160 = "0.9" sha2 = "0.9" pbkdf2 = "0.8" -grin_util = { path = "../util", version = "5.4.0" } +grin_util = { path = "../util", version = "5.4.1" } diff --git a/p2p/Cargo.toml b/p2p/Cargo.toml index 274a07d4..96adcaeb 100644 --- a/p2p/Cargo.toml +++ b/p2p/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "grin_p2p" -version = "5.4.0" +version = "5.4.1" authors = ["Grin Developers "] description = "Chain implementation for grin, a simple, private and scalable cryptocurrency implementation based on the Mimblewimble chain format." license = "Apache-2.0" @@ -22,10 +22,10 @@ log = "0.4" chrono = { version = "0.4.11", features = ["serde"] } bytes = "0.5" -grin_core = { path = "../core", version = "5.4.0" } -grin_store = { path = "../store", version = "5.4.0" } -grin_util = { path = "../util", version = "5.4.0" } -grin_chain = { path = "../chain", version = "5.4.0" } +grin_core = { path = "../core", version = "5.4.1" } +grin_store = { path = "../store", version = "5.4.1" } +grin_util = { path = "../util", version = "5.4.1" } +grin_chain = { path = "../chain", version = "5.4.1" } [dev-dependencies] -grin_pool = { path = "../pool", version = "5.4.0" } +grin_pool = { path = "../pool", version = "5.4.1" } diff --git a/pool/Cargo.toml b/pool/Cargo.toml index 3b0f77ad..e8697a49 100644 --- a/pool/Cargo.toml +++ b/pool/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "grin_pool" -version = "5.4.0" +version = "5.4.1" authors = ["Grin Developers "] description = "Chain implementation for grin, a simple, private and scalable cryptocurrency implementation based on the Mimblewimble chain format." license = "Apache-2.0" @@ -18,9 +18,9 @@ thiserror = "1" log = "0.4" chrono = "0.4.11" -grin_core = { path = "../core", version = "5.4.0" } -grin_keychain = { path = "../keychain", version = "5.4.0" } -grin_util = { path = "../util", version = "5.4.0" } +grin_core = { path = "../core", version = "5.4.1" } +grin_keychain = { path = "../keychain", version = "5.4.1" } +grin_util = { path = "../util", version = "5.4.1" } [dev-dependencies] -grin_chain = { path = "../chain", version = "5.4.0" } +grin_chain = { path = "../chain", version = "5.4.1" } diff --git a/servers/Cargo.toml b/servers/Cargo.toml index cb162771..206eea0c 100644 --- a/servers/Cargo.toml +++ b/servers/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "grin_servers" -version = "5.4.0" +version = "5.4.1" authors = ["Grin Developers "] description = "Simple, private and scalable cryptocurrency implementation based on the Mimblewimble chain format." license = "Apache-2.0" @@ -28,11 +28,11 @@ async-stream = "0.3" rustls = "0.20" walkdir = "2.3.1" -grin_api = { path = "../api", version = "5.4.0" } -grin_chain = { path = "../chain", version = "5.4.0" } -grin_core = { path = "../core", version = "5.4.0" } -grin_keychain = { path = "../keychain", version = "5.4.0" } -grin_p2p = { path = "../p2p", version = "5.4.0" } -grin_pool = { path = "../pool", version = "5.4.0" } -grin_store = { path = "../store", version = "5.4.0" } -grin_util = { path = "../util", version = "5.4.0" } +grin_api = { path = "../api", version = "5.4.1" } +grin_chain = { path = "../chain", version = "5.4.1" } +grin_core = { path = "../core", version = "5.4.1" } +grin_keychain = { path = "../keychain", version = "5.4.1" } +grin_p2p = { path = "../p2p", version = "5.4.1" } +grin_pool = { path = "../pool", version = "5.4.1" } +grin_store = { path = "../store", version = "5.4.1" } +grin_util = { path = "../util", version = "5.4.1" } diff --git a/store/Cargo.toml b/store/Cargo.toml index 72f30ca8..9bb92c07 100644 --- a/store/Cargo.toml +++ b/store/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "grin_store" -version = "5.4.0" +version = "5.4.1" authors = ["Grin Developers "] description = "Simple, private and scalable cryptocurrency implementation based on the Mimblewimble chain format." license = "Apache-2.0" @@ -21,8 +21,8 @@ serde_derive = "1" thiserror = "1" log = "0.4" -grin_core = { path = "../core", version = "5.4.0" } -grin_util = { path = "../util", version = "5.4.0" } +grin_core = { path = "../core", version = "5.4.1" } +grin_util = { path = "../util", version = "5.4.1" } [dev-dependencies] chrono = "0.4.11" diff --git a/util/Cargo.toml b/util/Cargo.toml index 978b5568..eef7f626 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "grin_util" -version = "5.4.0" +version = "5.4.1" authors = ["Grin Developers "] description = "Simple, private and scalable cryptocurrency implementation based on the Mimblewimble chain format." license = "Apache-2.0"