Skip to content

Commit

Permalink
feat: add id_from_pos support
Browse files Browse the repository at this point in the history
  • Loading branch information
LagginTimes committed Nov 1, 2024
1 parent 6fe96fd commit 61ff632
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,17 @@ pub trait ElectrumApi {
/// Returns the merkle path for the transaction `txid` confirmed in the block at `height`.
fn transaction_get_merkle(&self, txid: &Txid, height: usize) -> Result<GetMerkleRes, Error>;

/// Returns a transaction hash, given a block `height` and a `tx_pos` in the block.
fn transaction_id_from_pos(&self, height: usize, tx_pos: usize) -> Result<Txid, Error>;

/// Returns a transaction hash and a merkle path, given a block `height` and a `tx_pos` in the
/// block.
fn transaction_id_from_pos_with_merkle(
&self,
height: usize,
tx_pos: usize,
) -> Result<GetIdFromPosRes, Error>;

/// Returns the capabilities of the server.
fn server_features(&self) -> Result<ServerFeaturesRes, Error>;

Expand Down
14 changes: 14 additions & 0 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,20 @@ impl ElectrumApi for Client {
impl_inner_call!(self, transaction_get_merkle, txid, height)
}

#[inline]
fn transaction_id_from_pos(&self, height: usize, tx_pos: usize) -> Result<Txid, Error> {
impl_inner_call!(self, transaction_id_from_pos, height, tx_pos)
}

#[inline]
fn transaction_id_from_pos_with_merkle(
&self,
height: usize,
tx_pos: usize,
) -> Result<GetIdFromPosRes, Error> {
impl_inner_call!(self, transaction_id_from_pos_with_merkle, height, tx_pos)
}

#[inline]
fn server_features(&self) -> Result<ServerFeaturesRes, Error> {
impl_inner_call!(self, server_features)
Expand Down
71 changes: 71 additions & 0 deletions src/raw_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1102,6 +1102,42 @@ impl<T: Read + Write> ElectrumApi for RawClient<T> {
Ok(serde_json::from_value(result)?)
}

fn transaction_id_from_pos(&self, height: usize, tx_pos: usize) -> Result<Txid, Error> {
let params = vec![
Param::Usize(height),
Param::Usize(tx_pos),
Param::Bool(false),
];
let req = Request::new_id(
self.last_id.fetch_add(1, Ordering::SeqCst),
"blockchain.transaction.id_from_pos",
params,
);
let result = self.call(req)?;

Ok(serde_json::from_value(result)?)
}

fn transaction_id_from_pos_with_merkle(
&self,
height: usize,
tx_pos: usize,
) -> Result<GetIdFromPosRes, Error> {
let params = vec![
Param::Usize(height),
Param::Usize(tx_pos),
Param::Bool(true),
];
let req = Request::new_id(
self.last_id.fetch_add(1, Ordering::SeqCst),
"blockchain.transaction.id_from_pos",
params,
);
let result = self.call(req)?;

Ok(serde_json::from_value(result)?)
}

fn server_features(&self) -> Result<ServerFeaturesRes, Error> {
let req = Request::new_id(
self.last_id.fetch_add(1, Ordering::SeqCst),
Expand Down Expand Up @@ -1396,6 +1432,41 @@ mod test {
));
}

#[test]
fn test_transaction_id_from_pos() {
use bitcoin::Txid;

let client = RawClient::new(get_test_server(), None).unwrap();

let txid =
Txid::from_str("1f7ff3c407f33eabc8bec7d2cc230948f2249ec8e591bcf6f971ca9366c8788d")
.unwrap();
let resp = client.transaction_id_from_pos(630000, 68).unwrap();
assert_eq!(resp, txid);
}

#[test]
fn test_transaction_id_from_pos_with_merkle() {
use bitcoin::Txid;

let client = RawClient::new(get_test_server(), None).unwrap();

let txid =
Txid::from_str("1f7ff3c407f33eabc8bec7d2cc230948f2249ec8e591bcf6f971ca9366c8788d")
.unwrap();
let resp = client
.transaction_id_from_pos_with_merkle(630000, 68)
.unwrap();
assert_eq!(resp.tx_hash, txid);
assert_eq!(
resp.merkle[0],
[
34, 65, 51, 64, 49, 139, 115, 189, 185, 246, 70, 225, 168, 193, 217, 195, 47, 66,
179, 240, 153, 24, 114, 215, 144, 196, 212, 41, 39, 155, 246, 25
]
);
}

#[test]
fn test_ping() {
let client = RawClient::new(get_test_server(), None).unwrap();
Expand Down
11 changes: 11 additions & 0 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,17 @@ pub struct GetMerkleRes {
pub merkle: Vec<[u8; 32]>,
}

/// Response to a [`transaction_id_from_pos_with_merkle`](../client/struct.Client.html#method.transaction_id_from_pos_with_merkle)
/// request.
#[derive(Clone, Debug, Deserialize)]
pub struct GetIdFromPosRes {
/// Txid of the transaction.
pub tx_hash: Txid,
/// The merkle path of the transaction.
#[serde(deserialize_with = "from_hex_array")]
pub merkle: Vec<[u8; 32]>,
}

/// Notification of a new block header
#[derive(Clone, Debug, Deserialize)]
pub struct HeaderNotification {
Expand Down

0 comments on commit 61ff632

Please sign in to comment.