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

Mainnet updates #32

Merged
merged 8 commits into from
Nov 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 4 additions & 2 deletions Cargo.lock

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

33 changes: 25 additions & 8 deletions node/src/bin/space-cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ use jsonrpsee::{
use protocol::{
bitcoin::{Amount, FeeRate, OutPoint, Txid},
hasher::{KeyHasher, SpaceKey},
opcodes::OP_SETALL,
sname::{NameLike, SName},
slabel::SLabel,
Covenant, FullSpaceOut,
};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -232,6 +231,13 @@ enum Commands {
/// The space name
space: String,
},
/// Force spend an output owned by wallet (for testing only)
#[command(name = "forcespend")]
ForceSpend {
outpoint: OutPoint,
#[arg(long, short)]
fee_rate: u64,
},
}

struct SpaceCli {
Expand Down Expand Up @@ -372,8 +378,8 @@ async fn main() -> anyhow::Result<()> {

fn space_hash(spaceish: &str) -> anyhow::Result<String> {
let space = normalize_space(&spaceish);
let sname = SName::from_str(&space)?;
let spacehash = SpaceKey::from(Sha256::hash(sname.to_bytes()));
let sname = SLabel::from_str(&space)?;
let spacehash = SpaceKey::from(Sha256::hash(sname.as_ref()));
Ok(hex::encode(spacehash.as_slice()))
}

Expand Down Expand Up @@ -553,13 +559,13 @@ async fn handle_commands(
)))
}
};
let builder = protocol::script::ScriptBuilder::new()
.push_slice(data.as_slice())
.push_opcode(OP_SETALL.into());

let space_script = protocol::script::SpaceScript::create_set_fallback(data.as_slice());

cli.send_request(
Some(RpcWalletRequest::Execute(ExecuteParams {
context: vec![space],
space_script: builder,
space_script,
})),
None,
fee_rate,
Expand Down Expand Up @@ -610,6 +616,17 @@ async fn handle_commands(
space_hash(&space).map_err(|e| ClientError::Custom(e.to_string()))?
);
}
Commands::ForceSpend { outpoint, fee_rate } => {
let result = cli
.client
.wallet_force_spend(
&cli.wallet,
outpoint,
FeeRate::from_sat_per_vb(fee_rate).unwrap(),
)
.await?;
println!("{}", serde_json::to_string_pretty(&result).expect("result"));
}
}

Ok(())
Expand Down
2 changes: 1 addition & 1 deletion node/src/bin/spaced.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ impl Composer {
}

async fn run(&mut self) -> anyhow::Result<()> {
let spaced = Args::configure()?;
let spaced = Args::configure().await?;
self.setup_rpc_services(&spaced).await;
self.setup_sync_service(spaced).await;

Expand Down
26 changes: 18 additions & 8 deletions node/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,16 @@ pub struct Args {
/// Listen for JSON-RPC connections on <port>
#[arg(long, help_heading = Some(RPC_OPTIONS), env = "SPACED_RPC_PORT")]
rpc_port: Option<u16>,
/// Index blocks including the full transaction data
#[arg(long, env = "SPACED_BLOCK_INDEX_FULL", default_value = "false")]
block_index_full: bool,
}

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, ValueEnum, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ExtendedNetwork {
Mainnet,
MainnetAlpha,
Testnet,
Testnet4,
Signet,
Expand All @@ -88,7 +92,7 @@ pub enum ExtendedNetwork {
impl ExtendedNetwork {
pub fn fallback_network(&self) -> Network {
match self {
ExtendedNetwork::Mainnet => Network::Bitcoin,
ExtendedNetwork::Mainnet | ExtendedNetwork::MainnetAlpha => Network::Bitcoin,
ExtendedNetwork::Testnet => Network::Testnet,
ExtendedNetwork::Signet => Network::Signet,
ExtendedNetwork::Regtest => Network::Regtest,
Expand All @@ -100,7 +104,7 @@ impl ExtendedNetwork {
impl Args {
/// Configures spaced node by processing command line arguments
/// and configuration files
pub fn configure() -> anyhow::Result<Spaced> {
pub async fn configure() -> anyhow::Result<Spaced> {
let mut args = Args::merge_args_config(None);
let default_dirs = get_default_node_dirs();

Expand All @@ -126,9 +130,10 @@ impl Args {
}

let data_dir = match args.data_dir {
None => default_dirs.data_dir().join(args.chain.to_string()),
None => default_dirs.data_dir().to_path_buf(),
Some(data_dir) => data_dir,
};
}
.join(args.chain.to_string());

let default_port = args.rpc_port.unwrap();
let rpc_bind_addresses: Vec<SocketAddr> = args
Expand All @@ -144,7 +149,6 @@ impl Args {
})
.collect();

let genesis = Spaced::genesis(args.chain);
let bitcoin_rpc_auth = if let Some(cookie) = args.bitcoin_rpc_cookie {
let cookie = std::fs::read_to_string(cookie)?;
BitcoinRpcAuth::Cookie(cookie)
Expand All @@ -159,6 +163,8 @@ impl Args {
bitcoin_rpc_auth,
);

let genesis = Spaced::genesis(&rpc, args.chain).await?;

fs::create_dir_all(data_dir.clone())?;

let proto_db_path = data_dir.join("protocol.sdb");
Expand All @@ -170,7 +176,8 @@ impl Args {
store: chain_store,
};

let block_index = if args.block_index {
let block_index_enabled = args.block_index || args.block_index_full;
let block_index = if block_index_enabled {
let block_db_path = data_dir.join("block_index.sdb");
if !initial_sync && !block_db_path.exists() {
return Err(anyhow::anyhow!(
Expand Down Expand Up @@ -203,6 +210,7 @@ impl Args {
bind: rpc_bind_addresses,
chain,
block_index,
block_index_full: args.block_index_full,
num_workers: args.jobs as usize,
})
}
Expand Down Expand Up @@ -259,9 +267,9 @@ pub fn safe_exit(code: i32) -> ! {
std::process::exit(code)
}

fn default_bitcoin_rpc_url(network: &ExtendedNetwork) -> &'static str {
pub fn default_bitcoin_rpc_url(network: &ExtendedNetwork) -> &'static str {
match network {
ExtendedNetwork::Mainnet => "http://127.0.0.1:8332",
ExtendedNetwork::Mainnet | ExtendedNetwork::MainnetAlpha => "http://127.0.0.1:8332",
ExtendedNetwork::Testnet4 => "http://127.0.0.1:48332",
ExtendedNetwork::Signet => "http://127.0.0.1:38332",
ExtendedNetwork::Testnet => "http://127.0.0.1:18332",
Expand Down Expand Up @@ -359,6 +367,7 @@ impl Display for ExtendedNetwork {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let str = match self {
ExtendedNetwork::Mainnet => "mainnet".to_string(),
ExtendedNetwork::MainnetAlpha => "mainnet-alpha".to_string(),
ExtendedNetwork::Testnet => "testnet".to_string(),
ExtendedNetwork::Testnet4 => "testnet4".to_string(),
ExtendedNetwork::Signet => "signet".to_string(),
Expand All @@ -371,6 +380,7 @@ impl Display for ExtendedNetwork {
pub fn default_spaces_rpc_port(chain: &ExtendedNetwork) -> u16 {
match chain {
ExtendedNetwork::Mainnet => 7225,
ExtendedNetwork::MainnetAlpha => 7225,
ExtendedNetwork::Testnet4 => 7224,
ExtendedNetwork::Testnet => 7223,
ExtendedNetwork::Signet => 7221,
Expand Down
68 changes: 55 additions & 13 deletions node/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ use protocol::{
constants::{ChainAnchor, ROLLOUT_BATCH_SIZE, ROLLOUT_BLOCK_INTERVAL},
hasher::{BidKey, KeyHasher, OutpointKey, SpaceKey},
prepare::TxContext,
sname::NameLike,
validate::{TxChangeSet, UpdateKind, Validator},
Covenant, FullSpaceOut, RevokeReason, SpaceOut,
Bytes, Covenant, FullSpaceOut, RevokeReason, SpaceOut,
};
use serde::{Deserialize, Serialize};
use wallet::bitcoin::Transaction;
Expand All @@ -33,13 +32,29 @@ pub trait BlockSource {
#[derive(Debug, Clone)]
pub struct Node {
validator: Validator,
tx_data: bool,
}

/// A block structure containing validated transaction metadata
/// relevant to the Spaces protocol
#[derive(Clone, Serialize, Deserialize, Encode, Decode)]
pub struct BlockMeta {
pub tx_meta: Vec<TxChangeSet>,
pub height: u32,
pub tx_meta: Vec<TxEntry>,
}

#[derive(Clone, Serialize, Deserialize, Encode, Decode)]
pub struct TxEntry {
#[serde(flatten)]
pub changeset: TxChangeSet,
#[serde(skip_serializing_if = "Option::is_none", flatten)]
pub tx: Option<TxData>,
}

#[derive(Clone, Serialize, Deserialize, Encode, Decode)]
pub struct TxData {
pub position: u32,
pub raw: Bytes,
}

#[derive(Debug)]
Expand All @@ -61,9 +76,10 @@ impl fmt::Display for SyncError {
impl Error for SyncError {}

impl Node {
pub fn new() -> Self {
pub fn new(tx_data: bool) -> Self {
Self {
validator: Validator::new(),
tx_data,
}
}

Expand All @@ -86,7 +102,10 @@ impl Node {
}
}

let mut block_data = BlockMeta { tx_meta: vec![] };
let mut block_data = BlockMeta {
height,
tx_meta: vec![],
};

if (height - 1) % ROLLOUT_BLOCK_INTERVAL == 0 {
let batch = Self::get_rollout_batch(ROLLOUT_BATCH_SIZE, chain)?;
Expand All @@ -97,21 +116,44 @@ impl Node {

let validated = self.validator.rollout(height, &coinbase, batch);
if get_block_data {
block_data.tx_meta.push(validated.clone());
block_data.tx_meta.push(TxEntry {
changeset: validated.clone(),
tx: if self.tx_data {
Some(TxData {
position: 0,
raw: Bytes::new(protocol::bitcoin::consensus::encode::serialize(
&coinbase,
)),
})
} else {
None
},
});
}

self.apply_tx(&mut chain.state, &coinbase, validated);
}

for tx in block.txdata {
for (position, tx) in block.txdata.into_iter().enumerate() {
let prepared_tx =
{ TxContext::from_tx::<LiveSnapshot, Sha256>(&mut chain.state, &tx)? };

if let Some(prepared_tx) = prepared_tx {
let validated_tx = self.validator.process(height, &tx, prepared_tx);

if get_block_data {
block_data.tx_meta.push(validated_tx.clone());
block_data.tx_meta.push(TxEntry {
changeset: validated_tx.clone(),
tx: if self.tx_data {
Some(TxData {
position: position as u32,
raw: Bytes::new(protocol::bitcoin::consensus::encode::serialize(
&tx,
)),
})
} else {
None
},
});
}
self.apply_tx(&mut chain.state, &tx, validated_tx);
}
Expand Down Expand Up @@ -149,7 +191,7 @@ impl Node {

// Space => Outpoint
if let Some(space) = create.space.as_ref() {
let space_key = SpaceKey::from(Sha256::hash(space.name.to_bytes()));
let space_key = SpaceKey::from(Sha256::hash(space.name.as_ref()));
state.insert_space(space_key, outpoint.into());
}
// Outpoint => SpaceOut
Expand All @@ -168,7 +210,7 @@ impl Node {
// Since these are caused by spends
// Outpoint -> Spaceout mapping is already removed,
let space = update.output.spaceout.space.unwrap();
let base_hash = Sha256::hash(space.name.to_bytes());
let base_hash = Sha256::hash(space.name.as_ref());

// Remove Space -> Outpoint
let space_key = SpaceKey::from(base_hash);
Expand Down Expand Up @@ -209,7 +251,7 @@ impl Node {
.as_ref()
.expect("a space in rollout")
.name
.to_bytes(),
.as_ref(),
);
let bid_key = BidKey::from_bid(rollout.priority, base_hash);

Expand All @@ -229,7 +271,7 @@ impl Node {
.as_ref()
.expect("space")
.name
.to_bytes(),
.as_ref(),
);

let (bid_value, previous_bid) = unwrap_bid_value(&update.output.spaceout);
Expand Down
Loading
Loading