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

Initial support for no_std platforms #842

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions ci/check-compiles.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ cargo check
cargo doc
cargo doc --document-private-items
cd fuzz && cargo check --features=stdin_fuzz
cd ../lightning && cargo check --no-default-features --features=core
4 changes: 4 additions & 0 deletions lightning/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,18 @@ max_level_error = []
max_level_warn = []
max_level_info = []
max_level_debug = []
std = []
core = ["hashbrown"]
# Allow signing of local transactions that may have been revoked or will be revoked, for functional testing (e.g. justice tx handling).
# This is unsafe to use in production because it may result in the counterparty publishing taking our funds.
unsafe_revoked_tx_signing = []
unstable = []
default = ["std"]

[dependencies]
bitcoin = "0.26"

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

Expand Down
9 changes: 7 additions & 2 deletions lightning/src/chain/chainmonitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@ use util::logger::Logger;
use util::events;
use util::events::Event;

use std::collections::{HashMap, hash_map};
use alloc::vec::Vec;
use core::ops::Deref;
use crate::{HashMap, hash_map};
use std::sync::RwLock;
use std::ops::Deref;


/// An implementation of [`chain::Watch`] for monitoring channels.
///
Expand Down Expand Up @@ -324,6 +326,9 @@ mod tests {
use util::events::MessageSendEventsProvider;
use util::test_utils::{OnRegisterOutput, TxOutReference};

#[macro_use]
use alloc::vec;

/// Tests that in-block dependent transactions are processed by `block_connected` when not
/// included in `txdata` but returned by [`chain::Filter::register_output`]. For instance,
/// a (non-anchor) commitment transaction's HTLC output may be spent in the same block as the
Expand Down
16 changes: 9 additions & 7 deletions lightning/src/chain/channelmonitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,11 @@ use util::ser::{Readable, ReadableArgs, MaybeReadable, Writer, Writeable, U48};
use util::byte_utils;
use util::events::Event;

use std::collections::{HashMap, HashSet};
use std::{cmp, mem};
#[macro_use]
use alloc::{boxed::Box, vec, vec::Vec};
use crate::{HashMap, HashSet};
use core::{cmp, mem, ops::Deref};
use std::io::Error;
use std::ops::Deref;
use std::sync::Mutex;

/// An update generated by the underlying Channel itself which contains some new information the
Expand Down Expand Up @@ -85,7 +86,7 @@ pub struct ChannelMonitorUpdate {
/// then we allow the `ChannelManager` to send a `ChannelMonitorUpdate` with this update ID,
/// with the update providing said payment preimage. No other update types are allowed after
/// force-close.
pub const CLOSED_CHANNEL_UPDATE_ID: u64 = std::u64::MAX;
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> {
Expand All @@ -101,7 +102,7 @@ impl Readable for ChannelMonitorUpdate {
fn read<R: ::std::io::Read>(r: &mut R) -> Result<Self, DecodeError> {
let update_id: u64 = Readable::read(r)?;
let len: u64 = Readable::read(r)?;
let mut updates = Vec::with_capacity(cmp::min(len as usize, MAX_ALLOC_SIZE / ::std::mem::size_of::<ChannelMonitorUpdateStep>()));
let mut updates = Vec::with_capacity(cmp::min(len as usize, MAX_ALLOC_SIZE / ::core::mem::size_of::<ChannelMonitorUpdateStep>()));
for _ in 0..len {
updates.push(Readable::read(r)?);
}
Expand Down Expand Up @@ -1932,7 +1933,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {

for &(ref htlc, _, _) in holder_tx.htlc_outputs.iter() {
if let Some(transaction_output_index) = htlc.transaction_output_index {
claim_requests.push(ClaimRequest { absolute_timelock: ::std::u32::MAX, aggregable: false, outpoint: BitcoinOutPoint { txid: holder_tx.txid, vout: transaction_output_index as u32 },
claim_requests.push(ClaimRequest { absolute_timelock: ::core::u32::MAX, aggregable: false, outpoint: BitcoinOutPoint { txid: holder_tx.txid, vout: transaction_output_index as u32 },
witness_data: InputMaterial::HolderHTLC {
preimage: if !htlc.offered {
if let Some(preimage) = self.payment_preimages.get(&htlc.payment_hash) {
Expand Down Expand Up @@ -2594,7 +2595,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
fn is_paying_spendable_output<L: Deref>(&mut self, tx: &Transaction, height: u32, logger: &L) where L::Target: Logger {
let mut spendable_output = None;
for (i, outp) in tx.output.iter().enumerate() { // There is max one spendable output for any channel tx, including ones generated by us
if i > ::std::u16::MAX as usize {
if i > ::core::u16::MAX as usize {
// While it is possible that an output exists on chain which is greater than the
// 2^16th output in a given transaction, this is only possible if the output is not
// in a lightning transaction and was instead placed there by some third party who
Expand Down Expand Up @@ -3060,6 +3061,7 @@ mod tests {
use bitcoin::secp256k1::Secp256k1;
use std::sync::{Arc, Mutex};
use chain::keysinterface::InMemorySigner;
use alloc::vec::Vec;

#[test]
fn test_prune_preimages() {
Expand Down
10 changes: 6 additions & 4 deletions lightning/src/chain/keysinterface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ use ln::chan_utils;
use ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, HolderCommitmentTransaction, ChannelTransactionParameters, CommitmentTransaction};
use ln::msgs::UnsignedChannelAnnouncement;

use std::collections::HashSet;
use std::sync::atomic::{AtomicUsize, Ordering};
#[macro_use]
use alloc::{vec, vec::Vec};
use core::sync::atomic::{AtomicUsize, Ordering};
use crate::HashSet;
use std::io::Error;
use ln::msgs::{DecodeError, MAX_VALUE_MSAT};

Expand Down Expand Up @@ -850,7 +852,7 @@ impl KeysManager {
/// onchain output detection for which a corresponding delayed_payment_key must be derived.
pub fn derive_channel_keys(&self, channel_value_satoshis: u64, params: &[u8; 32]) -> InMemorySigner {
let chan_id = byte_utils::slice_to_be64(&params[0..8]);
assert!(chan_id <= std::u32::MAX as u64); // Otherwise the params field wasn't created by us
assert!(chan_id <= core::u32::MAX as u64); // Otherwise the params field wasn't created by us
let mut unique_start = Sha256::engine();
unique_start.input(params);
unique_start.input(&self.seed);
Expand Down Expand Up @@ -1032,7 +1034,7 @@ impl KeysInterface for KeysManager {

fn get_channel_signer(&self, _inbound: bool, channel_value_satoshis: u64) -> Self::Signer {
let child_ix = self.channel_child_index.fetch_add(1, Ordering::AcqRel);
assert!(child_ix <= std::u32::MAX as usize);
assert!(child_ix <= core::u32::MAX as usize);
let mut id = [0; 32];
id[0..8].copy_from_slice(&byte_utils::be64_to_array(child_ix as u64));
id[8..16].copy_from_slice(&byte_utils::be64_to_array(self.starting_time_nanos as u64));
Expand Down
6 changes: 4 additions & 2 deletions lightning/src/chain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

//! Structs and traits which allow other parts of rust-lightning to interact with the blockchain.

use alloc::vec::Vec;

use bitcoin::blockdata::block::{Block, BlockHeader};
use bitcoin::blockdata::script::Script;
use bitcoin::blockdata::transaction::{Transaction, TxOut};
Expand Down Expand Up @@ -246,7 +248,7 @@ pub struct WatchedOutput {
pub script_pubkey: Script,
}

impl<T: Listen> Listen for std::ops::Deref<Target = T> {
impl<T: Listen> Listen for core::ops::Deref<Target = T> {
fn block_connected(&self, block: &Block, height: u32) {
(**self).block_connected(block, height);
}
Expand All @@ -256,7 +258,7 @@ impl<T: Listen> Listen for std::ops::Deref<Target = T> {
}
}

impl<T: std::ops::Deref, U: std::ops::Deref> Listen for (T, U)
impl<T: core::ops::Deref, U: core::ops::Deref> Listen for (T, U)
where
T::Target: Listen,
U::Target: Listen,
Expand Down
10 changes: 10 additions & 0 deletions lightning/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#![cfg_attr(not(any(feature = "fuzztarget", feature = "_test_utils")), deny(missing_docs))]
#![cfg_attr(not(any(test, feature = "fuzztarget", feature = "_test_utils")), forbid(unsafe_code))]
#![deny(broken_intra_doc_links)]
#![cfg_attr(feature = "core", no_std)]

// In general, rust is absolutely horrid at supporting users doing things like,
// for example, compiling Rust code for real environments. Disable useless lints
Expand All @@ -35,6 +36,15 @@ extern crate bitcoin;
#[cfg(any(test, feature = "_test_utils"))] extern crate hex;
#[cfg(any(test, feature = "fuzztarget", feature = "_test_utils"))] extern crate regex;

extern crate alloc;
#[cfg(feature = "std")] extern crate core;
#[cfg(feature = "core")] extern crate hashbrown;

#[cfg(feature = "core")]
use hashbrown::{HashMap, HashSet, hash_map};
#[cfg(feature = "std")]
use std::collections::{HashMap, HashSet, hash_map};

#[macro_use]
pub mod util;
pub mod chain;
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,12 +31,12 @@ use bitcoin::secp256k1::{Secp256k1, Signature, Message};
use bitcoin::secp256k1::Error as SecpError;
use bitcoin::secp256k1;

use std::cmp;
use alloc::vec::Vec;
use core::{cmp, ops::Deref};
use ln::chan_utils;
use util::transaction_utils::sort_outputs;
use ln::channel::INITIAL_COMMITMENT_NUMBER;
use std::io::Read;
use std::ops::Deref;
use chain;

// Maximum size of a serialized HTLCOutputInCommitment
Expand Down Expand Up @@ -1235,6 +1235,7 @@ fn script_for_p2wpkh(key: &PublicKey) -> Script {
mod tests {
use super::CounterpartyCommitmentSecrets;
use hex;
use alloc::vec::Vec;

#[test]
fn test_per_commitment_storage() {
Expand Down
3 changes: 3 additions & 0 deletions lightning/src/ln/chanmon_update_fail_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ use ln::functional_test_utils::*;

use util::test_utils;

#[macro_use]
use alloc::{vec, vec::Vec};

// If persister_fail is true, we have the persister return a PermanentFailure
// instead of the higher-level ChainMonitor.
fn do_test_simple_monitor_permanent_update_fail(persister_fail: bool) {
Expand Down
21 changes: 12 additions & 9 deletions lightning/src/ln/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ use util::errors::APIError;
use util::config::{UserConfig,ChannelConfig};
use util::scid_utils::scid_from_parts;

use std;
use std::{cmp,mem,fmt};
use std::ops::Deref;
#[macro_use]
use alloc::{format, boxed::Box, string::String, vec, vec::Vec};
use core::{cmp, mem, fmt, ops::Deref};
#[cfg(any(test, feature = "fuzztarget"))]
use std::sync::Mutex;
use bitcoin::hashes::hex::ToHex;
Expand Down Expand Up @@ -1220,7 +1220,7 @@ impl<Signer: Sign> Channel<Signer> {
// on-chain ChannelsMonitors during block rescan. Ideally we'd figure out a way to drop
// these, but for now we just have to treat them as normal.

let mut pending_idx = std::usize::MAX;
let mut pending_idx = core::usize::MAX;
for (idx, htlc) in self.pending_inbound_htlcs.iter().enumerate() {
if htlc.htlc_id == htlc_id_arg {
assert_eq!(htlc.payment_hash, payment_hash_calc);
Expand All @@ -1243,7 +1243,7 @@ impl<Signer: Sign> Channel<Signer> {
break;
}
}
if pending_idx == std::usize::MAX {
if pending_idx == core::usize::MAX {
return Err(ChannelError::Ignore("Unable to find a pending HTLC which matched the given HTLC ID".to_owned()));
}

Expand Down Expand Up @@ -1342,7 +1342,7 @@ impl<Signer: Sign> Channel<Signer> {
// on-chain ChannelsMonitors during block rescan. Ideally we'd figure out a way to drop
// these, but for now we just have to treat them as normal.

let mut pending_idx = std::usize::MAX;
let mut pending_idx = core::usize::MAX;
for (idx, htlc) in self.pending_inbound_htlcs.iter().enumerate() {
if htlc.htlc_id == htlc_id_arg {
match htlc.state {
Expand All @@ -1359,7 +1359,7 @@ impl<Signer: Sign> Channel<Signer> {
pending_idx = idx;
}
}
if pending_idx == std::usize::MAX {
if pending_idx == core::usize::MAX {
return Err(ChannelError::Ignore("Unable to find a pending HTLC which matched the given HTLC ID".to_owned()));
}

Expand Down Expand Up @@ -4410,8 +4410,8 @@ impl<Signer: Sign> Writeable for Channel<Signer> {

let mut key_data = VecWriter(Vec::new());
self.holder_signer.write(&mut key_data)?;
assert!(key_data.0.len() < std::usize::MAX);
assert!(key_data.0.len() < std::u32::MAX as usize);
assert!(key_data.0.len() < core::usize::MAX);
assert!(key_data.0.len() < core::u32::MAX as usize);
(key_data.0.len() as u32).write(writer)?;
writer.write_all(&key_data.0[..])?;

Expand Down Expand Up @@ -4879,6 +4879,9 @@ mod tests {
use bitcoin::hash_types::{Txid, WPubkeyHash};
use std::sync::Arc;

#[macro_use]
use alloc::{vec, vec::Vec};

struct TestFeeEstimator {
fee_est: u32
}
Expand Down
22 changes: 14 additions & 8 deletions lightning/src/ln/channelmanager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,20 @@ use util::chacha20::{ChaCha20, ChaChaReader};
use util::logger::Logger;
use util::errors::APIError;

use std::{cmp, mem};
use std::collections::{HashMap, hash_map, HashSet};
#[macro_use]
use alloc::{format, vec, string::String, vec::Vec};
use core::{
cmp,
mem,
ops::Deref,
sync::atomic::{AtomicUsize, Ordering},
time::Duration,
};
use crate::{HashMap, HashSet, hash_map};
use std::io::{Cursor, Read};
use std::sync::{Arc, Condvar, Mutex, MutexGuard, RwLock, RwLockReadGuard};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::time::Duration;
#[cfg(any(test, feature = "allow_wallclock_use"))]
use std::time::Instant;
use std::ops::Deref;
use bitcoin::hashes::hex::ToHex;

// We hold various information about HTLC relay in the HTLC objects in Channel itself:
Expand Down Expand Up @@ -1766,7 +1771,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
// be absurd. We ensure this by checking that at least 500 (our stated public contract on when
// broadcast_node_announcement panics) of the maximum-length addresses would fit in a 64KB
// message...
const HALF_MESSAGE_IS_ADDRS: u32 = ::std::u16::MAX as u32 / (NetAddress::MAX_LEN as u32 + 1) / 2;
const HALF_MESSAGE_IS_ADDRS: u32 = core::u16::MAX as u32 / (NetAddress::MAX_LEN as u32 + 1) / 2;
#[deny(const_err)]
#[allow(dead_code)]
// ...by failing to compile if the number of addresses that would be half of a message is
Expand Down Expand Up @@ -4763,9 +4768,8 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
mod tests {
use ln::channelmanager::PersistenceNotifier;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use core::{sync::atomic::{AtomicBool, Ordering}, time::Duration};
use std::thread;
use std::time::Duration;

#[test]
fn test_wait_timeout() {
Expand Down Expand Up @@ -4830,6 +4834,8 @@ pub mod bench {
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::{Block, BlockHeader, Transaction, TxOut};

use alloc::vec::Vec;
use core::default::Default;
use std::sync::Mutex;

use test::Bencher;
Expand Down