Skip to content

Commit d4a85fa

Browse files
authored
Merge pull request #32 from buffrr/consensus-updates
Mainnet updates
2 parents ba5b2ff + e198720 commit d4a85fa

22 files changed

+1251
-1356
lines changed

Cargo.lock

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node/src/bin/space-cli.rs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ use jsonrpsee::{
1111
use protocol::{
1212
bitcoin::{Amount, FeeRate, OutPoint, Txid},
1313
hasher::{KeyHasher, SpaceKey},
14-
opcodes::OP_SETALL,
15-
sname::{NameLike, SName},
14+
slabel::SLabel,
1615
Covenant, FullSpaceOut,
1716
};
1817
use serde::{Deserialize, Serialize};
@@ -232,6 +231,13 @@ enum Commands {
232231
/// The space name
233232
space: String,
234233
},
234+
/// Force spend an output owned by wallet (for testing only)
235+
#[command(name = "forcespend")]
236+
ForceSpend {
237+
outpoint: OutPoint,
238+
#[arg(long, short)]
239+
fee_rate: u64,
240+
},
235241
}
236242

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

373379
fn space_hash(spaceish: &str) -> anyhow::Result<String> {
374380
let space = normalize_space(&spaceish);
375-
let sname = SName::from_str(&space)?;
376-
let spacehash = SpaceKey::from(Sha256::hash(sname.to_bytes()));
381+
let sname = SLabel::from_str(&space)?;
382+
let spacehash = SpaceKey::from(Sha256::hash(sname.as_ref()));
377383
Ok(hex::encode(spacehash.as_slice()))
378384
}
379385

@@ -553,13 +559,13 @@ async fn handle_commands(
553559
)))
554560
}
555561
};
556-
let builder = protocol::script::ScriptBuilder::new()
557-
.push_slice(data.as_slice())
558-
.push_opcode(OP_SETALL.into());
562+
563+
let space_script = protocol::script::SpaceScript::create_set_fallback(data.as_slice());
564+
559565
cli.send_request(
560566
Some(RpcWalletRequest::Execute(ExecuteParams {
561567
context: vec![space],
562-
space_script: builder,
568+
space_script,
563569
})),
564570
None,
565571
fee_rate,
@@ -610,6 +616,17 @@ async fn handle_commands(
610616
space_hash(&space).map_err(|e| ClientError::Custom(e.to_string()))?
611617
);
612618
}
619+
Commands::ForceSpend { outpoint, fee_rate } => {
620+
let result = cli
621+
.client
622+
.wallet_force_spend(
623+
&cli.wallet,
624+
outpoint,
625+
FeeRate::from_sat_per_vb(fee_rate).unwrap(),
626+
)
627+
.await?;
628+
println!("{}", serde_json::to_string_pretty(&result).expect("result"));
629+
}
613630
}
614631

615632
Ok(())

node/src/bin/spaced.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ impl Composer {
128128
}
129129

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

node/src/config.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,16 @@ pub struct Args {
7373
/// Listen for JSON-RPC connections on <port>
7474
#[arg(long, help_heading = Some(RPC_OPTIONS), env = "SPACED_RPC_PORT")]
7575
rpc_port: Option<u16>,
76+
/// Index blocks including the full transaction data
77+
#[arg(long, env = "SPACED_BLOCK_INDEX_FULL", default_value = "false")]
78+
block_index_full: bool,
7679
}
7780

7881
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, ValueEnum, Serialize, Deserialize)]
7982
#[serde(rename_all = "lowercase")]
8083
pub enum ExtendedNetwork {
8184
Mainnet,
85+
MainnetAlpha,
8286
Testnet,
8387
Testnet4,
8488
Signet,
@@ -88,7 +92,7 @@ pub enum ExtendedNetwork {
8892
impl ExtendedNetwork {
8993
pub fn fallback_network(&self) -> Network {
9094
match self {
91-
ExtendedNetwork::Mainnet => Network::Bitcoin,
95+
ExtendedNetwork::Mainnet | ExtendedNetwork::MainnetAlpha => Network::Bitcoin,
9296
ExtendedNetwork::Testnet => Network::Testnet,
9397
ExtendedNetwork::Signet => Network::Signet,
9498
ExtendedNetwork::Regtest => Network::Regtest,
@@ -100,7 +104,7 @@ impl ExtendedNetwork {
100104
impl Args {
101105
/// Configures spaced node by processing command line arguments
102106
/// and configuration files
103-
pub fn configure() -> anyhow::Result<Spaced> {
107+
pub async fn configure() -> anyhow::Result<Spaced> {
104108
let mut args = Args::merge_args_config(None);
105109
let default_dirs = get_default_node_dirs();
106110

@@ -126,9 +130,10 @@ impl Args {
126130
}
127131

128132
let data_dir = match args.data_dir {
129-
None => default_dirs.data_dir().join(args.chain.to_string()),
133+
None => default_dirs.data_dir().to_path_buf(),
130134
Some(data_dir) => data_dir,
131-
};
135+
}
136+
.join(args.chain.to_string());
132137

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

147-
let genesis = Spaced::genesis(args.chain);
148152
let bitcoin_rpc_auth = if let Some(cookie) = args.bitcoin_rpc_cookie {
149153
let cookie = std::fs::read_to_string(cookie)?;
150154
BitcoinRpcAuth::Cookie(cookie)
@@ -159,6 +163,8 @@ impl Args {
159163
bitcoin_rpc_auth,
160164
);
161165

166+
let genesis = Spaced::genesis(&rpc, args.chain).await?;
167+
162168
fs::create_dir_all(data_dir.clone())?;
163169

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

173-
let block_index = if args.block_index {
179+
let block_index_enabled = args.block_index || args.block_index_full;
180+
let block_index = if block_index_enabled {
174181
let block_db_path = data_dir.join("block_index.sdb");
175182
if !initial_sync && !block_db_path.exists() {
176183
return Err(anyhow::anyhow!(
@@ -203,6 +210,7 @@ impl Args {
203210
bind: rpc_bind_addresses,
204211
chain,
205212
block_index,
213+
block_index_full: args.block_index_full,
206214
num_workers: args.jobs as usize,
207215
})
208216
}
@@ -259,9 +267,9 @@ pub fn safe_exit(code: i32) -> ! {
259267
std::process::exit(code)
260268
}
261269

262-
fn default_bitcoin_rpc_url(network: &ExtendedNetwork) -> &'static str {
270+
pub fn default_bitcoin_rpc_url(network: &ExtendedNetwork) -> &'static str {
263271
match network {
264-
ExtendedNetwork::Mainnet => "http://127.0.0.1:8332",
272+
ExtendedNetwork::Mainnet | ExtendedNetwork::MainnetAlpha => "http://127.0.0.1:8332",
265273
ExtendedNetwork::Testnet4 => "http://127.0.0.1:48332",
266274
ExtendedNetwork::Signet => "http://127.0.0.1:38332",
267275
ExtendedNetwork::Testnet => "http://127.0.0.1:18332",
@@ -359,6 +367,7 @@ impl Display for ExtendedNetwork {
359367
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
360368
let str = match self {
361369
ExtendedNetwork::Mainnet => "mainnet".to_string(),
370+
ExtendedNetwork::MainnetAlpha => "mainnet-alpha".to_string(),
362371
ExtendedNetwork::Testnet => "testnet".to_string(),
363372
ExtendedNetwork::Testnet4 => "testnet4".to_string(),
364373
ExtendedNetwork::Signet => "signet".to_string(),
@@ -371,6 +380,7 @@ impl Display for ExtendedNetwork {
371380
pub fn default_spaces_rpc_port(chain: &ExtendedNetwork) -> u16 {
372381
match chain {
373382
ExtendedNetwork::Mainnet => 7225,
383+
ExtendedNetwork::MainnetAlpha => 7225,
374384
ExtendedNetwork::Testnet4 => 7224,
375385
ExtendedNetwork::Testnet => 7223,
376386
ExtendedNetwork::Signet => 7221,

node/src/node.rs

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ use protocol::{
1010
constants::{ChainAnchor, ROLLOUT_BATCH_SIZE, ROLLOUT_BLOCK_INTERVAL},
1111
hasher::{BidKey, KeyHasher, OutpointKey, SpaceKey},
1212
prepare::TxContext,
13-
sname::NameLike,
1413
validate::{TxChangeSet, UpdateKind, Validator},
15-
Covenant, FullSpaceOut, RevokeReason, SpaceOut,
14+
Bytes, Covenant, FullSpaceOut, RevokeReason, SpaceOut,
1615
};
1716
use serde::{Deserialize, Serialize};
1817
use wallet::bitcoin::Transaction;
@@ -33,13 +32,29 @@ pub trait BlockSource {
3332
#[derive(Debug, Clone)]
3433
pub struct Node {
3534
validator: Validator,
35+
tx_data: bool,
3636
}
3737

3838
/// A block structure containing validated transaction metadata
3939
/// relevant to the Spaces protocol
4040
#[derive(Clone, Serialize, Deserialize, Encode, Decode)]
4141
pub struct BlockMeta {
42-
pub tx_meta: Vec<TxChangeSet>,
42+
pub height: u32,
43+
pub tx_meta: Vec<TxEntry>,
44+
}
45+
46+
#[derive(Clone, Serialize, Deserialize, Encode, Decode)]
47+
pub struct TxEntry {
48+
#[serde(flatten)]
49+
pub changeset: TxChangeSet,
50+
#[serde(skip_serializing_if = "Option::is_none", flatten)]
51+
pub tx: Option<TxData>,
52+
}
53+
54+
#[derive(Clone, Serialize, Deserialize, Encode, Decode)]
55+
pub struct TxData {
56+
pub position: u32,
57+
pub raw: Bytes,
4358
}
4459

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

6378
impl Node {
64-
pub fn new() -> Self {
79+
pub fn new(tx_data: bool) -> Self {
6580
Self {
6681
validator: Validator::new(),
82+
tx_data,
6783
}
6884
}
6985

@@ -86,7 +102,10 @@ impl Node {
86102
}
87103
}
88104

89-
let mut block_data = BlockMeta { tx_meta: vec![] };
105+
let mut block_data = BlockMeta {
106+
height,
107+
tx_meta: vec![],
108+
};
90109

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

98117
let validated = self.validator.rollout(height, &coinbase, batch);
99118
if get_block_data {
100-
block_data.tx_meta.push(validated.clone());
119+
block_data.tx_meta.push(TxEntry {
120+
changeset: validated.clone(),
121+
tx: if self.tx_data {
122+
Some(TxData {
123+
position: 0,
124+
raw: Bytes::new(protocol::bitcoin::consensus::encode::serialize(
125+
&coinbase,
126+
)),
127+
})
128+
} else {
129+
None
130+
},
131+
});
101132
}
102-
103133
self.apply_tx(&mut chain.state, &coinbase, validated);
104134
}
105135

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

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

113143
if get_block_data {
114-
block_data.tx_meta.push(validated_tx.clone());
144+
block_data.tx_meta.push(TxEntry {
145+
changeset: validated_tx.clone(),
146+
tx: if self.tx_data {
147+
Some(TxData {
148+
position: position as u32,
149+
raw: Bytes::new(protocol::bitcoin::consensus::encode::serialize(
150+
&tx,
151+
)),
152+
})
153+
} else {
154+
None
155+
},
156+
});
115157
}
116158
self.apply_tx(&mut chain.state, &tx, validated_tx);
117159
}
@@ -149,7 +191,7 @@ impl Node {
149191

150192
// Space => Outpoint
151193
if let Some(space) = create.space.as_ref() {
152-
let space_key = SpaceKey::from(Sha256::hash(space.name.to_bytes()));
194+
let space_key = SpaceKey::from(Sha256::hash(space.name.as_ref()));
153195
state.insert_space(space_key, outpoint.into());
154196
}
155197
// Outpoint => SpaceOut
@@ -168,7 +210,7 @@ impl Node {
168210
// Since these are caused by spends
169211
// Outpoint -> Spaceout mapping is already removed,
170212
let space = update.output.spaceout.space.unwrap();
171-
let base_hash = Sha256::hash(space.name.to_bytes());
213+
let base_hash = Sha256::hash(space.name.as_ref());
172214

173215
// Remove Space -> Outpoint
174216
let space_key = SpaceKey::from(base_hash);
@@ -209,7 +251,7 @@ impl Node {
209251
.as_ref()
210252
.expect("a space in rollout")
211253
.name
212-
.to_bytes(),
254+
.as_ref(),
213255
);
214256
let bid_key = BidKey::from_bid(rollout.priority, base_hash);
215257

@@ -229,7 +271,7 @@ impl Node {
229271
.as_ref()
230272
.expect("space")
231273
.name
232-
.to_bytes(),
274+
.as_ref(),
233275
);
234276

235277
let (bid_value, previous_bid) = unwrap_bid_value(&update.output.spaceout);

0 commit comments

Comments
 (0)