Skip to content

Commit

Permalink
Actual no_std support
Browse files Browse the repository at this point in the history
  • Loading branch information
devrandom committed Aug 1, 2021
1 parent bee9a1e commit 305f723
Show file tree
Hide file tree
Showing 22 changed files with 256 additions and 151 deletions.
14 changes: 10 additions & 4 deletions lightning/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,25 +26,31 @@ max_level_debug = []
unsafe_revoked_tx_signing = []
unstable = []

no_std = ["hashbrown", "bitcoin/no-std"]
std = ["bitcoin/std"]
no_std = ["hashbrown", "bitcoin/no-std", "core2/alloc", "bitcoin/no-std"]
std = ["bitcoin/std", "bitcoin/std"]

default = ["std"]

[dependencies]
bitcoin = "0.27"
bitcoin = { version = "0.27", default-features = false, features = ["secp-recovery"] }
# TODO maybe bitcoin no-std should pull in this feature?
secp256k1 = { version = "0.20.2", default-features = false, features = ["alloc"] }

hashbrown = { version = "0.11", optional = true }
hex = { version = "0.3", optional = true }
regex = { version = "0.1.80", optional = true }

core2 = { version = "0.3.0", optional = true, default-features = false }

[dev-dependencies]
hex = "0.3"
regex = "0.1.80"
secp256k1 = { version = "0.20.2", default-features = false, features = ["alloc"] }

[dev-dependencies.bitcoin]
version = "0.27"
features = ["bitcoinconsensus"]
default-features = false
features = ["bitcoinconsensus", "secp-recovery"]

[package.metadata.docs.rs]
features = ["allow_wallclock_use"] # When https://github.com/rust-lang/rust/issues/43781 complies with our MSVR, we can add nice banners in the docs for the methods behind this feature-gate.
12 changes: 6 additions & 6 deletions lightning/src/chain/channelmonitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ use util::events::Event;

use prelude::*;
use core::{cmp, mem};
use std::io::Error;
use io::{self, Error};
use core::ops::Deref;
use sync::Mutex;

Expand Down Expand Up @@ -88,7 +88,7 @@ pub struct ChannelMonitorUpdate {
pub const CLOSED_CHANNEL_UPDATE_ID: u64 = core::u64::MAX;

impl Writeable for ChannelMonitorUpdate {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
write_ver_prefix!(w, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);
self.update_id.write(w)?;
(self.updates.len() as u64).write(w)?;
Expand All @@ -100,7 +100,7 @@ impl Writeable for ChannelMonitorUpdate {
}
}
impl Readable for ChannelMonitorUpdate {
fn read<R: ::std::io::Read>(r: &mut R) -> Result<Self, DecodeError> {
fn read<R: io::Read>(r: &mut R) -> Result<Self, DecodeError> {
let _ver = read_ver_prefix!(r, SERIALIZATION_VERSION);
let update_id: u64 = Readable::read(r)?;
let len: u64 = Readable::read(r)?;
Expand Down Expand Up @@ -293,7 +293,7 @@ struct CounterpartyCommitmentTransaction {
}

impl Writeable for CounterpartyCommitmentTransaction {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
w.write_all(&byte_utils::be64_to_array(self.per_htlc.len() as u64))?;
for (ref txid, ref htlcs) in self.per_htlc.iter() {
w.write_all(&txid[..])?;
Expand All @@ -311,7 +311,7 @@ impl Writeable for CounterpartyCommitmentTransaction {
}
}
impl Readable for CounterpartyCommitmentTransaction {
fn read<R: ::std::io::Read>(r: &mut R) -> Result<Self, DecodeError> {
fn read<R: io::Read>(r: &mut R) -> Result<Self, DecodeError> {
let counterparty_commitment_transaction = {
let per_htlc_len: u64 = Readable::read(r)?;
let mut per_htlc = HashMap::with_capacity(cmp::min(per_htlc_len as usize, MAX_ALLOC_SIZE / 64));
Expand Down Expand Up @@ -2581,7 +2581,7 @@ const MAX_ALLOC_SIZE: usize = 64*1024;

impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
for (BlockHash, ChannelMonitor<Signer>) {
fn read<R: ::std::io::Read>(reader: &mut R, keys_manager: &'a K) -> Result<Self, DecodeError> {
fn read<R: io::Read>(reader: &mut R, keys_manager: &'a K) -> Result<Self, DecodeError> {
macro_rules! unwrap_obj {
($key: expr) => {
match $key {
Expand Down
6 changes: 3 additions & 3 deletions lightning/src/chain/keysinterface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ use ln::msgs::UnsignedChannelAnnouncement;

use prelude::*;
use core::sync::atomic::{AtomicUsize, Ordering};
use std::io::Error;
use io::{self, Error};
use ln::msgs::{DecodeError, MAX_VALUE_MSAT};

/// Information about a spendable output to a P2WSH script. See
Expand Down Expand Up @@ -699,7 +699,7 @@ impl Writeable for InMemorySigner {
}

impl Readable for InMemorySigner {
fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
let _ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);

let funding_key = Readable::read(reader)?;
Expand Down Expand Up @@ -1039,7 +1039,7 @@ impl KeysInterface for KeysManager {
}

fn read_chan_signer(&self, reader: &[u8]) -> Result<Self::Signer, DecodeError> {
InMemorySigner::read(&mut std::io::Cursor::new(reader))
InMemorySigner::read(&mut io::Cursor::new(reader))
}

fn sign_invoice(&self, invoice_preimage: Vec<u8>) -> Result<RecoverableSignature, ()> {
Expand Down
11 changes: 6 additions & 5 deletions lightning/src/chain/onchaintx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use util::logger::Logger;
use util::ser::{Readable, ReadableArgs, Writer, Writeable, VecWriter};
use util::byte_utils;

use io;
use prelude::*;
use alloc::collections::BTreeMap;
use core::cmp;
Expand Down Expand Up @@ -94,7 +95,7 @@ impl_writeable_tlv_based_enum!(OnchainEvent,
;);

impl Readable for Option<Vec<Option<(usize, Signature)>>> {
fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
match Readable::read(reader)? {
0u8 => Ok(None),
1u8 => {
Expand All @@ -115,7 +116,7 @@ impl Readable for Option<Vec<Option<(usize, Signature)>>> {
}

impl Writeable for Option<Vec<Option<(usize, Signature)>>> {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
match self {
&Some(ref vec) => {
1u8.write(writer)?;
Expand Down Expand Up @@ -191,7 +192,7 @@ const SERIALIZATION_VERSION: u8 = 1;
const MIN_SERIALIZATION_VERSION: u8 = 1;

impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
pub(crate) fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
pub(crate) fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);

self.destination_script.write(writer)?;
Expand Down Expand Up @@ -242,7 +243,7 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
}

impl<'a, K: KeysInterface> ReadableArgs<&'a K> for OnchainTxHandler<K::Signer> {
fn read<R: ::std::io::Read>(reader: &mut R, keys_manager: &'a K) -> Result<Self, DecodeError> {
fn read<R: io::Read>(reader: &mut R, keys_manager: &'a K) -> Result<Self, DecodeError> {
let _ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);

let destination_script = Readable::read(reader)?;
Expand Down Expand Up @@ -285,7 +286,7 @@ impl<'a, K: KeysInterface> ReadableArgs<&'a K> for OnchainTxHandler<K::Signer> {
for _ in 0..locktimed_packages_len {
let locktime = Readable::read(reader)?;
let packages_len: u64 = Readable::read(reader)?;
let mut packages = Vec::with_capacity(cmp::min(packages_len as usize, MAX_ALLOC_SIZE / std::mem::size_of::<PackageTemplate>()));
let mut packages = Vec::with_capacity(cmp::min(packages_len as usize, MAX_ALLOC_SIZE / core::mem::size_of::<PackageTemplate>()));
for _ in 0..packages_len {
packages.push(Readable::read(reader)?);
}
Expand Down
10 changes: 6 additions & 4 deletions lightning/src/chain/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ use util::byte_utils;
use util::logger::Logger;
use util::ser::{Readable, Writer, Writeable};

use io;
use prelude::*;
use core::cmp;
use core::mem;
use core::ops::Deref;
Expand Down Expand Up @@ -395,8 +397,8 @@ impl PackageSolvingData {
PackageSolvingData::RevokedOutput(_) => output_conf_height + 1,
PackageSolvingData::RevokedHTLCOutput(_) => output_conf_height + 1,
PackageSolvingData::CounterpartyOfferedHTLCOutput(_) => output_conf_height + 1,
PackageSolvingData::CounterpartyReceivedHTLCOutput(ref outp) => std::cmp::max(outp.htlc.cltv_expiry, output_conf_height + 1),
PackageSolvingData::HolderHTLCOutput(ref outp) => std::cmp::max(outp.cltv_expiry, output_conf_height + 1),
PackageSolvingData::CounterpartyReceivedHTLCOutput(ref outp) => cmp::max(outp.htlc.cltv_expiry, output_conf_height + 1),
PackageSolvingData::HolderHTLCOutput(ref outp) => cmp::max(outp.cltv_expiry, output_conf_height + 1),
PackageSolvingData::HolderFundingOutput(_) => output_conf_height + 1,
};
absolute_timelock
Expand Down Expand Up @@ -682,7 +684,7 @@ impl PackageTemplate {
}

impl Writeable for PackageTemplate {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
writer.write_all(&byte_utils::be64_to_array(self.inputs.len() as u64))?;
for (ref outpoint, ref rev_outp) in self.inputs.iter() {
outpoint.write(writer)?;
Expand All @@ -699,7 +701,7 @@ impl Writeable for PackageTemplate {
}

impl Readable for PackageTemplate {
fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
let inputs_count = <u64 as Readable>::read(reader)?;
let mut inputs: Vec<(BitcoinOutPoint, PackageSolvingData)> = Vec::with_capacity(cmp::min(inputs_count as usize, MAX_ALLOC_SIZE / 128));
for _ in 0..inputs_count {
Expand Down
76 changes: 75 additions & 1 deletion lightning/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,31 +28,105 @@
#![allow(bare_trait_objects)]
#![allow(ellipsis_inclusive_range_patterns)]

#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]

#![cfg_attr(all(any(test, feature = "_test_utils"), feature = "unstable"), feature(test))]
#[cfg(all(any(test, feature = "_test_utils"), feature = "unstable"))] extern crate test;

#[macro_use]
extern crate alloc;
extern crate bitcoin;
#[cfg(any(test, feature = "std"))]
extern crate core;

#[cfg(any(test, feature = "_test_utils"))] extern crate hex;
#[cfg(any(test, feature = "fuzztarget", feature = "_test_utils"))] extern crate regex;

#[cfg(feature = "no_std")] extern crate core2;


#[macro_use]
pub mod util;
pub mod chain;
pub mod ln;
pub mod routing;

#[cfg(feature = "std")]
use std::io;
#[cfg(not(feature = "std"))]
use core2::io;

#[cfg(not(feature = "std"))]
mod io_extras {
use core2::io::{self, Read, Write};

/// A writer which will move data into the void.
pub struct Sink {
_priv: (),
}

/// Creates an instance of a writer which will successfully consume all data.
pub const fn sink() -> Sink {
Sink { _priv: () }
}

impl core2::io::Write for Sink {
#[inline]
fn write(&mut self, buf: &[u8]) -> core2::io::Result<usize> {
Ok(buf.len())
}

#[inline]
fn flush(&mut self) -> core2::io::Result<()> {
Ok(())
}
}

pub fn copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> Result<u64, io::Error>
where
R: Read,
W: Write,
{
let mut count = 0;
let mut buf = [0u8; 64];

loop {
match reader.read(&mut buf) {
Ok(0) => break,
Ok(n) => { writer.write_all(&buf[0..n])?; count += n as u64; },
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {},
Err(e) => return Err(e.into()),
};
}
Ok(count)
}
}


mod prelude {
#[cfg(feature = "hashbrown")]
extern crate hashbrown;

pub use alloc::{vec, vec::Vec, string::String, collections::VecDeque};
pub use alloc::{vec, vec::Vec, string::String, collections::VecDeque, boxed::Box};
#[cfg(not(feature = "hashbrown"))]
pub use std::collections::{HashMap, HashSet, hash_map};
#[cfg(feature = "hashbrown")]
pub use self::hashbrown::{HashMap, HashSet, hash_map};

#[cfg(feature = "std")]
pub use std::io::sink;

#[cfg(not(feature = "std"))]
pub use io_extras::sink;

#[cfg(feature = "std")]
pub use std::io::copy;

#[cfg(not(feature = "std"))]
pub use io_extras::copy;

pub use alloc::borrow::ToOwned;
pub use alloc::string::ToString;
}

#[cfg(feature = "std")]
Expand Down
5 changes: 3 additions & 2 deletions lightning/src/ln/chan_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use bitcoin::secp256k1::{Secp256k1, Signature, Message};
use bitcoin::secp256k1::Error as SecpError;
use bitcoin::secp256k1;

use io;
use prelude::*;
use core::cmp;
use ln::chan_utils;
Expand Down Expand Up @@ -167,7 +168,7 @@ impl CounterpartyCommitmentSecrets {
}

impl Writeable for CounterpartyCommitmentSecrets {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
for &(ref secret, ref idx) in self.old_secrets.iter() {
writer.write_all(secret)?;
writer.write_all(&byte_utils::be64_to_array(*idx))?;
Expand All @@ -177,7 +178,7 @@ impl Writeable for CounterpartyCommitmentSecrets {
}
}
impl Readable for CounterpartyCommitmentSecrets {
fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
let mut old_secrets = [([0; 32], 1 << 48); 49];
for &mut (ref mut secret, ref mut idx) in old_secrets.iter_mut() {
*secret = Readable::read(reader)?;
Expand Down
9 changes: 5 additions & 4 deletions lightning/src/ln/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ use util::errors::APIError;
use util::config::{UserConfig,ChannelConfig};
use util::scid_utils::scid_from_parts;

use io;
use prelude::*;
use core::{cmp,mem,fmt};
use core::ops::Deref;
Expand Down Expand Up @@ -4512,7 +4513,7 @@ impl_writeable_tlv_based_enum!(InboundHTLCRemovalReason,;
);

impl Writeable for ChannelUpdateStatus {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
// We only care about writing out the current state as it was announced, ie only either
// Enabled or Disabled. In the case of DisabledStaged, we most recently announced the
// channel as enabled, so we write 0. For EnabledStaged, we similarly write a 1.
Expand All @@ -4527,7 +4528,7 @@ impl Writeable for ChannelUpdateStatus {
}

impl Readable for ChannelUpdateStatus {
fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
Ok(match <u8 as Readable>::read(reader)? {
0 => ChannelUpdateStatus::Enabled,
1 => ChannelUpdateStatus::Disabled,
Expand All @@ -4537,7 +4538,7 @@ impl Readable for ChannelUpdateStatus {
}

impl<Signer: Sign> Writeable for Channel<Signer> {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
// Note that we write out as if remove_uncommitted_htlcs_and_mark_paused had just been
// called.

Expand Down Expand Up @@ -4770,7 +4771,7 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
const MAX_ALLOC_SIZE: usize = 64*1024;
impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
where K::Target: KeysInterface<Signer = Signer> {
fn read<R : ::std::io::Read>(reader: &mut R, keys_source: &'a K) -> Result<Self, DecodeError> {
fn read<R : io::Read>(reader: &mut R, keys_source: &'a K) -> Result<Self, DecodeError> {
let ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);

let user_id = Readable::read(reader)?;
Expand Down
Loading

0 comments on commit 305f723

Please sign in to comment.