Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add subscriptions support #225

Merged
merged 122 commits into from
May 23, 2020
Merged
Show file tree
Hide file tree
Changes from 53 commits
Commits
Show all changes
122 commits
Select commit Hold shift + click to select a range
bd3430e
initial new commit struct
Shivani912 Feb 25, 2020
d129ad2
update functions
Shivani912 Mar 10, 2020
b64840b
fixed deserialization for new commit struct
Shivani912 Mar 12, 2020
b893a25
updated links to generator + val_set_test file
Shivani912 Mar 12, 2020
17c3c02
Ismail/commit struct followup (#182)
liamsi Mar 17, 2020
525b419
fix error
Shivani912 Mar 17, 2020
ae3ee39
more json bisection tests
Shivani912 Mar 17, 2020
0e6a073
abci_info struct app_version implemented
greg-szabo Mar 19, 2020
1a9a96e
Fixed fmt
greg-szabo Mar 19, 2020
a3367f3
Updated integration tests to tendermint v0.33 node
greg-szabo Mar 20, 2020
d0b9039
update block result response
Shivani912 Mar 20, 2020
accb997
changes to abci_info and block_results
Shivani912 Mar 24, 2020
e4918c8
Removed CircleCI reference and added codecov reference to Cargo
greg-szabo Mar 24, 2020
e0bce41
removing unwanted Option from DeliverTx struct fields
Shivani912 Mar 25, 2020
06d91d4
last_block_app_hash is now Option<Vec<u8>>
Shivani912 Mar 25, 2020
af430df
AbciInfo.last_block_app_hash is base64 encoded instead of hex
Shivani912 Mar 25, 2020
0ad0537
last_block_app_hash changed to Vec<u8>
Shivani912 Mar 25, 2020
ddbc113
Cherry-pick from 87e888b8a1278297ddeedb3f1823e6cc6f0d4ad7 (Liamsi)
liamsi Dec 12, 2019
323b44a
[88] Fix JSON ID
greg-szabo Mar 29, 2020
95902c6
[192] Fix abci_info compatibility for v0.33
greg-szabo Mar 29, 2020
c0c3ed7
[4] block_results test fix
greg-szabo Mar 29, 2020
3659a30
[184][120] Tendermint v0.33 compatibility fixes + integration tests f…
greg-szabo Mar 29, 2020
6c589c9
Added one abci_query test
greg-szabo Mar 29, 2020
2bf6125
FMT + get rid of warnings
greg-szabo Mar 29, 2020
5e9b62a
Relaxed genesis struct AppHash requirements from strict hex to anything
greg-szabo Mar 29, 2020
0d4952d
Removed unused Protocol struct
greg-szabo Mar 29, 2020
58411ac
Removed unused Protocol struct
greg-szabo Mar 29, 2020
2743f8b
Merge branch 'tendermint/v0.33' of github.com:informalsystems/tenderm…
greg-szabo Mar 29, 2020
7649289
IdType removed and JSON ID made as enum
greg-szabo Mar 29, 2020
f0048c5
Duration looks better now
Shivani912 Mar 30, 2020
a2ae776
fix fmt
Shivani912 Mar 30, 2020
5801875
Update tendermint/src/lite_impl/signed_header.rs
greg-szabo Mar 31, 2020
bceaf4f
Update tendermint/src/lite_impl/signed_header.rs
greg-szabo Mar 31, 2020
624ecae
Removed AsRef from JSON ID
greg-szabo Mar 31, 2020
4e2f2a9
Merge branch 'tendermint/v0.33' of github.com:informalsystems/tenderm…
greg-szabo Mar 31, 2020
ccb7b78
Merge remote-tracking branch 'remotes/origin/master' into tendermint/…
liamsi Apr 8, 2020
51934ba
Update Proof and ProofOp (#206)
liamsi Apr 8, 2020
2993d23
Add missing serializer for TrustThresholdFraction fields (#210)
romac Apr 10, 2020
0eae723
commit followup (#199)
liamsi Apr 10, 2020
39ba45f
Initial support for websocket subscriptions
zmanian Apr 17, 2020
ee80538
Websocker error
zmanian Apr 17, 2020
810a351
Fix formatting
zmanian Apr 17, 2020
719235d
Intitial integration test
zmanian Apr 18, 2020
0cd2972
Fmt
zmanian Apr 18, 2020
89ed138
Missed adding file
zmanian Apr 18, 2020
f0e18a9
Fix url scheme
zmanian Apr 18, 2020
f3b1414
fix url scheme
zmanian Apr 18, 2020
7e05068
Format
zmanian Apr 18, 2020
ab8e799
Debugged event subscription with unit tests
zmanian Apr 19, 2020
a87d02d
Fix clippy lint
zmanian Apr 19, 2020
f17a2e5
Add back in the integration test ignore
zmanian Apr 19, 2020
1412206
Refactor the websocket listener into a seperate struct from the RPC c…
zmanian Apr 21, 2020
eed55a7
Cargo fmt
zmanian Apr 21, 2020
b7ae18c
Merge branch 'master' of https://github.com/informalsystems/tendermin…
zmanian Apr 21, 2020
1bede88
Cargo fmt
zmanian Apr 21, 2020
ceffc44
Fix integration tests
zmanian Apr 21, 2020
7331520
Remove the Box<Errors>
zmanian Apr 21, 2020
4b6961a
Update tendermint/src/rpc/endpoint/subscribe.rs
zmanian Apr 21, 2020
49674ea
Fix the doc comment for subscribe
zmanian Apr 21, 2020
e7cb621
Merge branch 'zaki-event-subscribe' of github.com:iqlusioninc/tenderm…
zmanian Apr 21, 2020
02b7f1f
Moved a TODO comment to correct place
zmanian Apr 21, 2020
4a843f8
Create a more specific type for JSON RPC TX Result responses
zmanian Apr 24, 2020
3248c23
Add a convinience function for extracting the event hashmap
zmanian Apr 24, 2020
2b75213
add an an additional query for helping type the event responses
zmanian Apr 25, 2020
facfaef
switch to borrowed types
zmanian Apr 26, 2020
66cdd43
Remove extra borrow
zmanian Apr 26, 2020
7a44a6b
Remove borrow
zmanian Apr 26, 2020
ebf8cbc
Fmt and fix clippy issues
zmanian Apr 26, 2020
b8b00d7
Improve the extract events function so that we treat any matching que…
zmanian Apr 28, 2020
68f5d72
Derive Clone for the Event type
zmanian Apr 28, 2020
ffb954c
Prevent panics in extract events
zmanian Apr 30, 2020
766a86d
Fix module query
zmanian Apr 30, 2020
97f5c9b
Type events only on message.action
zmanian May 1, 2020
644bbd1
Ensures all that events end up in the hashmap. A little unclear if th…
zmanian May 5, 2020
fef6738
Revert "Type events only on message.action"
zmanian May 5, 2020
81e2bc5
Revert "Type events only on message.action"
zmanian May 5, 2020
85ab966
accept periods in the chain-id
zmanian May 22, 2020
c3044f9
Fmt and clippy
zmanian May 22, 2020
884ed90
Merge branch 'master' of https://github.com/informalsystems/tendermin…
zmanian May 22, 2020
73fe138
review comments
ancazamfir May 22, 2020
b16e1f5
fix build: dbg! macro and catch up with renaming
liamsi May 22, 2020
1ad3f70
simplify match in integration test
liamsi May 22, 2020
1842f71
Fix typo in doc comment
liamsi May 22, 2020
7af4caa
Make queries an enum
zmanian May 23, 2020
4ab7c52
Merge branch 'zaki-event-subscribe' of github.com:iqlusioninc/tenderm…
zmanian May 23, 2020
eb58620
Refactor Enum to remove data field
zmanian May 23, 2020
c611c09
Update tendermint/src/rpc/event_listener.rs
zmanian May 23, 2020
c593880
Explain why we throw away subscription responses
zmanian May 23, 2020
b18e98e
Merge branch 'zaki-event-subscribe' of github.com:iqlusioninc/tenderm…
zmanian May 23, 2020
e1549e8
DRY the top level JSON response type
zmanian May 23, 2020
f2c42a0
Update tendermint/src/rpc/endpoint/subscribe.rs
zmanian May 23, 2020
b99b0d6
DRY some of the Block types
zmanian May 23, 2020
6b1b106
Merge branch 'zaki-event-subscribe' of github.com:iqlusioninc/tenderm…
zmanian May 23, 2020
a3a8e65
Fmt
zmanian May 23, 2020
d342d37
Merge branch 'zaki-event-subscribe' of https://github.com/iqlusioninc…
liamsi May 23, 2020
668696d
return `Box<dyn stdError>` instead of `&'static str`
liamsi May 23, 2020
c884f3b
Fix clippy warnings and errs
liamsi May 23, 2020
6231dcc
Fix typo
liamsi May 23, 2020
3269d58
DRY Block, BlockData, Evidence, Parts
liamsi May 23, 2020
f2da1e1
Remove raw json responses from the public API
zmanian May 23, 2020
395bb93
Merge branch 'zaki-event-subscribe' of github.com:iqlusioninc/tenderm…
zmanian May 23, 2020
9910c3f
Please clippy
zmanian May 23, 2020
09db6a8
Box large variant
zmanian May 23, 2020
9c2fcb0
Box the other variant
zmanian May 23, 2020
aa60b6a
Update the RPCTxResult to the new api
zmanian May 23, 2020
5cb2030
clarify some local var names
liamsi May 23, 2020
b11ea9a
use rpc::response::Response and improve err handling
liamsi May 23, 2020
f9b8899
Fix hyperlink in doc comment
liamsi May 23, 2020
4a4d9cb
Update link on error codes
liamsi May 23, 2020
6dbe426
Make error codes symmetric
liamsi May 23, 2020
42b5cfc
Fix panic string
liamsi May 23, 2020
3193c73
Add some debug output
liamsi May 23, 2020
81748e7
Add some more debug output
liamsi May 23, 2020
fc8fc43
Type alias instead of wrapping the wrapper
liamsi May 23, 2020
0cb9ea3
Revert "DRY Block, BlockData, Evidence, Parts"
liamsi May 23, 2020
fdf8873
DRY Block, BlockData, Evidence, Parts
liamsi May 23, 2020
31e48a8
Let's try an Option
liamsi May 23, 2020
86e3f6a
Another Option?
liamsi May 23, 2020
c2711e8
These events are actually optional
liamsi May 23, 2020
0efbcb8
typo
liamsi May 23, 2020
04053f5
Let it be
liamsi May 23, 2020
9b77399
Fix match arm
liamsi May 23, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ jobs:
runs-on: ubuntu-latest
services:
tendermint:
image: interchainio/tendermint
image: tendermint/tendermint
ports:
- 26656:26656
- 26657:26657
Expand Down
2 changes: 1 addition & 1 deletion light-node/src/commands/start.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ impl config::Override<LightNodeConfig> for StartCmd {
* trusted state and store it in the store ...
* TODO: this should take traits ... but how to deal with the State ?
* TODO: better name ?
*/
*/
async fn subjective_init(
height: Height,
vals_hash: Hash,
Expand Down
6 changes: 4 additions & 2 deletions tendermint/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ authors = [
all-features = true

[badges]
circle-ci = { repository = "interchainio/tendermint-rs" }
codecov = { repository = "..."}

[dependencies]
anomaly = "0.2"
Expand All @@ -44,6 +44,7 @@ prost-amino = "0.5"
prost-amino-derive = "0.5"
serde = { version = "1", features = ["derive"] }
serde_json = { version = "1" }
serde_bytes = "0.11"
sha2 = { version = "0.8", default-features = false }
signatory = { version = "0.18", features = ["ed25519", "ecdsa"] }
signatory-dalek = "0.18"
Expand All @@ -55,7 +56,8 @@ thiserror = "1"
toml = { version = "0.5" }
uuid = { version = "0.8", default-features = false }
zeroize = { version = "1.1", features = ["zeroize_derive"] }
async-tungstenite = {version="0.4", features = ["tokio-runtime"]}
tokio = { version = "0.2", features = ["macros"] }

[dev-dependencies]
serde_json = "1"
tokio = { version = "0.2", features = ["macros"] }
13 changes: 10 additions & 3 deletions tendermint/src/abci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,18 @@ mod info;
mod log;
mod path;
mod proof;
mod responses;
pub mod responses;
pub mod tag;
pub mod transaction;

pub use self::{
code::Code, data::Data, gas::Gas, info::Info, log::Log, path::Path, proof::Proof,
responses::Responses, transaction::Transaction,
code::Code,
data::Data,
gas::Gas,
info::Info,
log::Log,
path::Path,
proof::Proof,
responses::{DeliverTx, Event, Responses},
transaction::Transaction,
};
96 changes: 53 additions & 43 deletions tendermint/src/abci/proof.rs
Original file line number Diff line number Diff line change
@@ -1,51 +1,61 @@
//! ABCI Merkle proofs

use crate::error::Error;
use serde::{de::Error as _, Deserialize, Deserializer, Serialize, Serializer};
use std::{
fmt::{self, Display},
str::FromStr,
};
use subtle_encoding::{Encoding, Hex};

/// ABCI Merkle proofs
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct Proof(Vec<u8>);

impl AsRef<[u8]> for Proof {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}

impl Display for Proof {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}",
&Hex::upper_case().encode_to_string(&self.0).unwrap()
)
}
use crate::serializers;
use serde::{Deserialize, Serialize};

/// Proof is Merkle proof defined by the list of ProofOps
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct Proof {
/// The list of ProofOps
pub ops: Vec<ProofOp>,
}

impl FromStr for Proof {
type Err = Error;

fn from_str(s: &str) -> Result<Self, Error> {
let bytes = Hex::upper_case().decode(s)?;
Ok(Proof(bytes))
}
}

impl<'de> Deserialize<'de> for Proof {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let hex = String::deserialize(deserializer)?;
Ok(Self::from_str(&hex).map_err(|e| D::Error::custom(format!("{}", e)))?)
}
/// ProofOp defines an operation used for calculating Merkle root
/// The data could be arbitrary format, providing necessary data
/// for example neighbouring node hash
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct ProofOp {
/// Type of the ProofOp
#[serde(alias = "type")]
pub field_type: String,
/// Key of the ProofOp
#[serde(
default,
serialize_with = "serializers::serialize_base64",
deserialize_with = "serializers::parse_base64"
)]
pub key: Vec<u8>,
/// Actual data
#[serde(
default,
serialize_with = "serializers::serialize_base64",
deserialize_with = "serializers::parse_base64"
)]
pub data: Vec<u8>,
}

impl Serialize for Proof {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.to_string().serialize(serializer)
#[cfg(test)]
mod test {
use super::Proof;
use crate::test::test_serialization_roundtrip;

#[test]
fn serialization_roundtrip() {
let payload = r#"
{
"ops": [
{
"type": "iavl:v",
"key": "Y29uc2Vuc3VzU3RhdGUvaWJjb25lY2xpZW50LzIy",
"data": "8QEK7gEKKAgIEAwYHCIgG9RAkJgHlxNjmyzOW6bUAidhiRSja0x6+GXCVENPG1oKKAgGEAUYFyIgwRns+dJvjf1Zk2BaFrXz8inPbvYHB7xx2HCy9ima5f8KKAgEEAMYFyogOr8EGajEV6fG5fzJ2fAAvVMgRLhdMJTzCPlogl9rxlIKKAgCEAIYFyIgcjzX/a+2bFbnNldpawQqZ+kYhIwz5r4wCUzuu1IFW04aRAoeY29uc2Vuc3VzU3RhdGUvaWJjb25lY2xpZW50LzIyEiAZ1uuG60K4NHJZZMuS9QX6o4eEhica5jIHYwflRiYkDBgX"
},
{
"type": "multistore",
"key": "aWJj",
"data": "CvEECjAKBGJhbmsSKAomCIjYAxIg2MEyyonbZButYnvSRkf2bPQg+nqA+Am1MeDxG6F4p1UKLwoDYWNjEigKJgiI2AMSIN2YHczeuXNvyetrSFQpkCcJzfB6PXVCw0i/XShMgPnIChEKB3VwZ3JhZGUSBgoECIjYAwovCgNnb3YSKAomCIjYAxIgYM0TfBli7KxhY4nWgDSDPykhUJwtKFql9RU5l86WinQKLwoDaWJjEigKJgiI2AMSIFp6aJASeInQKF8y824zjmgcFORN6M+ECbgFfJkobKs8CjAKBG1haW4SKAomCIjYAxIgsZzwmLQ7PH1UeZ/vCUSqlQmfgt3CGfoMgJLkUqKCv0EKMwoHc3Rha2luZxIoCiYIiNgDEiCiBZoBLyDGj5euy3n33ik+SpqYK9eB5xbI+iY8ycYVbwo0CghzbGFzaGluZxIoCiYIiNgDEiAJz3gEYuIhdensHU3b5qH5ons2quepd6EaRgCHXab6PQoyCgZzdXBwbHkSKAomCIjYAxIglWLA5/THPTiTxAlaLHOBYFIzEJTmKPznItUwAc8zD+AKEgoIZXZpZGVuY2USBgoECIjYAwowCgRtaW50EigKJgiI2AMSIMS8dZ1j8F6JVVv+hB1rHBZC+gIFJxHan2hM8qDC64n/CjIKBnBhcmFtcxIoCiYIiNgDEiB8VIzExUHX+SvHZFz/P9NM9THnw/gTDDLVReuZX8htLgo4CgxkaXN0cmlidXRpb24SKAomCIjYAxIg3u/Nd4L+8LT8OXJCh14o8PHIJ/GLQwsmE7KYIl1GdSYKEgoIdHJhbnNmZXISBgoECIjYAw=="
}
]
}"#;
test_serialization_roundtrip::<Proof>(payload);
}
}
32 changes: 20 additions & 12 deletions tendermint/src/abci/responses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,36 +42,44 @@ where
///
/// This type corresponds to the `ResponseDeliverTx` proto from:
///
/// <https://github.com/tendermint/tendermint/blob/develop/abci/types/types.proto>
/// <https://github.com/tendermint/tendermint/blob/master/abci/types/types.proto>
// TODO(tarcieri): generate this automatically from the proto
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct DeliverTx {
/// ABCI application response code
pub code: Option<Code>,
pub code: Code,

/// ABCI application data
pub data: Option<Data>,
pub data: Data,

/// ABCI log data (nondeterministic)
pub log: Option<Log>,
pub log: Log,

/// ABCI info (nondeterministic)
pub info: Option<Info>,
pub info: Info,

/// Amount of gas wanted
#[serde(default, rename = "gasWanted")]
pub gas_wanted: Gas,

/// Amount of gas used
#[serde(default, rename = "gasUsed")]
pub gas_used: Gas,

/// Tags
#[serde(default)]
pub tags: Vec<Tag>,
/// Events
pub events: Vec<Event>,

/// Codespace
pub codespace: Option<Codespace>,
pub codespace: Codespace,
}

/// Event
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Event {
/// Event type
#[serde(rename = "type")]
pub type_str: String,

/// Attributes
pub attributes: Vec<Tag>,
}

/// Begin block response.
Expand Down Expand Up @@ -108,7 +116,7 @@ pub struct EndBlock {
}

/// Return an empty vec in the event `validator_updates` is `null`
fn deserialize_validator_updates<'de, D>(
pub fn deserialize_validator_updates<'de, D>(
deserializer: D,
) -> Result<Vec<validator::Update>, D::Error>
where
Expand Down
2 changes: 1 addition & 1 deletion tendermint/src/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use subtle::{self, ConstantTimeEq};
use subtle_encoding::hex;

/// Size of an account ID in bytes
const LENGTH: usize = 20;
pub const LENGTH: usize = 20;

/// Account IDs
#[derive(Copy, Clone, Eq, Hash, PartialEq, PartialOrd, Ord)]
Expand Down
18 changes: 14 additions & 4 deletions tendermint/src/block.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Blocks within the chains of a Tendermint network

mod commit;
pub mod commit_sig;
pub mod header;
mod height;
mod id;
Expand All @@ -11,6 +12,7 @@ mod size;

pub use self::{
commit::*,
commit_sig::*,
header::Header,
height::*,
id::{Id, ParseId},
Expand Down Expand Up @@ -46,18 +48,26 @@ where
{
#[derive(Deserialize)]
struct TmpCommit {
pub height: Height,
#[serde(
serialize_with = "serializers::serialize_u64",
deserialize_with = "serializers::parse_u64"
)]
pub round: u64,
#[serde(deserialize_with = "serializers::parse_non_empty_block_id")]
block_id: Option<Id>,
precommits: Option<Precommits>,
pub block_id: Option<Id>,
pub signatures: Option<CommitSigs>,
}

let commit = TmpCommit::deserialize(deserializer)?;
if commit.block_id.is_none() || commit.precommits.is_none() {
if commit.block_id.is_none() || commit.signatures.is_none() {
Ok(None)
} else {
Ok(Some(Commit {
height: commit.height,
round: commit.round,
block_id: commit.block_id.unwrap(),
precommits: commit.precommits.unwrap(),
signatures: commit.signatures.unwrap(),
}))
}
}
58 changes: 35 additions & 23 deletions tendermint/src/block/commit.rs
Original file line number Diff line number Diff line change
@@ -1,62 +1,74 @@
//! Commits to a Tendermint blockchain

use crate::{block, Vote};
use crate::block::commit_sig::CommitSig;
use crate::block::{Height, Id};
use crate::serializers;
use serde::{Deserialize, Serialize};
use std::{ops::Deref, slice};

/// Commit contains the justification (ie. a set of signatures) that a block was committed by a set
/// of validators.
///
/// TODO: Update links below!
/// <https://github.com/tendermint/tendermint/blob/51dc810d041eaac78320adc6d53ad8b160b06601/types/block.go#L486-L502>
/// <https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/blockchain.md#lastcommit>
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
pub struct Commit {
/// Block ID of the last commit
pub block_id: block::Id,
/// Block height
pub height: Height,

/// Precommits
pub precommits: Precommits,
/// Round
#[serde(
serialize_with = "serializers::serialize_u64",
deserialize_with = "serializers::parse_u64"
)]
pub round: u64,

/// Block ID
pub block_id: Id,

/// Signatures
pub signatures: CommitSigs,
}

/// Precommits which certify that a block is valid
/// CommitSigs which certify that a block is valid
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
pub struct Precommits(Vec<Option<Vote>>);
pub struct CommitSigs(Vec<CommitSig>);

impl Precommits {
/// Create a new precommit collection
pub fn new<I>(into_precommits: I) -> Self
impl CommitSigs {
/// Create a new CommitSig collection
pub fn new<I>(into_commit_sigs: I) -> Self
where
I: Into<Vec<Option<Vote>>>,
I: Into<Vec<CommitSig>>,
{
Self(into_precommits.into())
Self(into_commit_sigs.into())
}

/// Convert this collection of precommits into a vector
pub fn into_vec(self) -> Vec<Option<Vote>> {
/// Convert this collection of CommitSigs into a vector
pub fn into_vec(self) -> Vec<CommitSig> {
self.0
}

/// Iterate over the precommits in the collection
pub fn iter(&self) -> slice::Iter<'_, Option<Vote>> {
/// Iterate over the CommitSigs in the collection
pub fn iter(&self) -> slice::Iter<'_, CommitSig> {
self.0.iter()
}
}

impl AsRef<[Option<Vote>]> for Precommits {
fn as_ref(&self) -> &[Option<Vote>] {
impl AsRef<[CommitSig]> for CommitSigs {
fn as_ref(&self) -> &[CommitSig] {
self.0.as_slice()
}
}

impl Deref for Precommits {
type Target = [Option<Vote>];
impl Deref for CommitSigs {
type Target = [CommitSig];

fn deref(&self) -> &[Option<Vote>] {
fn deref(&self) -> &[CommitSig] {
self.as_ref()
}
}

impl PartialEq for Precommits {
impl PartialEq for CommitSigs {
fn eq(&self, other: &Self) -> bool {
// Note: this is used for asserts in tests:
self.0.clone().into_iter().eq(other.0.clone().into_iter())
Expand Down
Loading