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

RPC: Output bitcoin address for transaction and object #1891

Merged
merged 4 commits into from
Jun 15, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
18 changes: 18 additions & 0 deletions crates/rooch-open-rpc-spec/schemas/openrpc.json
Original file line number Diff line number Diff line change
Expand Up @@ -1237,6 +1237,12 @@
"owner": {
"$ref": "#/components/schemas/rooch_types::address::RoochAddress"
},
"owner_bitcoin_address": {
"type": [
"string",
"null"
]
},
"size": {
"type": "integer",
"format": "uint64",
Expand Down Expand Up @@ -1676,6 +1682,12 @@
"sender": {
"type": "string"
},
"sender_bitcoin_address": {
"type": [
"string",
"null"
]
},
"sequence_number": {
"type": "integer",
"format": "uint64",
Expand Down Expand Up @@ -1914,6 +1926,12 @@
"owner": {
"$ref": "#/components/schemas/rooch_types::address::RoochAddress"
},
"owner_bitcoin_address": {
"type": [
"string",
"null"
]
},
"size": {
"type": "integer",
"format": "uint64",
Expand Down
9 changes: 7 additions & 2 deletions crates/rooch-rpc-api/src/jsonrpc_types/rooch_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,21 @@ pub struct PageView<T, C> {
pub struct TransactionView {
pub sequence_number: u64,
pub sender: String,
pub sender_bitcoin_address: Option<String>,
pub action_type: MoveActionTypeView,
pub action: MoveActionView,
pub raw: BytesView,
}

impl From<RoochTransaction> for TransactionView {
fn from(transaction: RoochTransaction) -> Self {
impl TransactionView {
pub fn new_from_rooch_transaction(
transaction: RoochTransaction,
sender_bitcoin_address: Option<String>,
) -> Self {
Self {
sequence_number: transaction.sequence_number(),
sender: transaction.sender().to_string(),
sender_bitcoin_address,
action: transaction.action().clone().into(),
action_type: transaction.action().clone().into(),
raw: transaction.encode().into(),
Expand Down
11 changes: 11 additions & 0 deletions crates/rooch-rpc-api/src/jsonrpc_types/state_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ impl From<StateSyncFilterView> for StateSyncFilter {
pub struct IndexerObjectStateView {
pub object_id: ObjectID,
pub owner: RoochAddressView,
pub owner_bitcoin_address: Option<String>,
pub flag: u8,
/// bcs bytes of the Object.
pub value: BytesView,
Expand All @@ -373,12 +374,14 @@ impl IndexerObjectStateView {
pub fn new_from_object_state(
state: IndexerObjectState,
value: Vec<u8>,
owner_bitcoin_address: Option<String>,
decoded_value: Option<AnnotatedMoveStructView>,
display_fields: Option<DisplayFieldsView>,
) -> IndexerObjectStateView {
IndexerObjectStateView {
object_id: state.object_id,
owner: state.owner.into(),
owner_bitcoin_address,
flag: state.flag,
value: value.into(),
decoded_value,
Expand Down Expand Up @@ -437,6 +440,7 @@ impl ObjectStateFilterView {
pub struct ObjectStateView {
pub id: ObjectID,
pub owner: RoochAddressView,
pub owner_bitcoin_address: Option<String>,
pub flag: u8,
pub object_type: StructTagView,
pub state_root: H256View,
Expand All @@ -453,6 +457,7 @@ impl ObjectStateView {
ObjectStateView {
id: object.id,
owner: object.owner.into(),
owner_bitcoin_address: None,
flag: object.flag,
object_type: object.value.type_.clone().into(),
state_root: object.state_root.into(),
Expand All @@ -473,6 +478,7 @@ impl ObjectStateView {
ObjectStateView {
id: object.id,
owner: object.owner.into(),
owner_bitcoin_address: None,
flag: object.flag,
object_type: object.value.struct_tag.into(),
state_root: object.state_root.into(),
Expand All @@ -489,4 +495,9 @@ impl ObjectStateView {
self.display_fields = display_fields;
self
}

pub fn with_owner_bitcoin_address(mut self, owner_bitcoin_address: Option<String>) -> Self {
self.owner_bitcoin_address = owner_bitcoin_address;
self
}
}
32 changes: 23 additions & 9 deletions crates/rooch-rpc-api/src/jsonrpc_types/transaction_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,16 @@ pub enum LedgerTxDataView {
L2Tx(TransactionView),
}

impl From<LedgerTxData> for LedgerTxDataView {
fn from(data: LedgerTxData) -> Self {
impl LedgerTxDataView {
pub fn new_from_ledger_txdata(
data: LedgerTxData,
sender_bitcoin_address: Option<String>,
) -> Self {
match data {
LedgerTxData::L1Block(block) => LedgerTxDataView::L1Block(block.into()),
LedgerTxData::L2Tx(tx) => LedgerTxDataView::L2Tx(tx.into()),
LedgerTxData::L2Tx(tx) => LedgerTxDataView::L2Tx(
TransactionView::new_from_rooch_transaction(tx, sender_bitcoin_address),
),
}
}
}
Expand All @@ -50,10 +55,13 @@ pub struct LedgerTransactionView {
pub sequence_info: TransactionSequenceInfoView,
}

impl From<LedgerTransaction> for LedgerTransactionView {
fn from(tx: LedgerTransaction) -> Self {
impl LedgerTransactionView {
pub fn new_from_ledger_transaction(
tx: LedgerTransaction,
sender_bitcoin_address: Option<String>,
) -> Self {
Self {
data: tx.data.into(),
data: LedgerTxDataView::new_from_ledger_txdata(tx.data, sender_bitcoin_address),
sequence_info: tx.sequence_info.into(),
}
}
Expand All @@ -65,10 +73,16 @@ pub struct TransactionWithInfoView {
pub execution_info: TransactionExecutionInfoView,
}

impl From<TransactionWithInfo> for TransactionWithInfoView {
fn from(tx: TransactionWithInfo) -> Self {
impl TransactionWithInfoView {
pub fn new_from_transaction_with_info(
tx: TransactionWithInfo,
sender_bitcoin_address: Option<String>,
) -> Self {
Self {
transaction: tx.transaction.into(),
transaction: LedgerTransactionView::new_from_ledger_transaction(
tx.transaction,
sender_bitcoin_address,
),
execution_info: tx.execution_info.into(),
}
}
Expand Down
146 changes: 124 additions & 22 deletions crates/rooch-rpc-server/src/server/rooch_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ use rooch_rpc_api::{
};
use rooch_types::indexer::event::IndexerEventID;
use rooch_types::indexer::state::IndexerStateID;
use rooch_types::transaction::rooch::RoochTransaction;
use rooch_types::transaction::{RoochTransaction, TransactionWithInfo};
use std::cmp::min;
use std::str::FromStr;
use tracing::info;
Expand Down Expand Up @@ -116,6 +116,40 @@ impl RoochServer {
}
Ok(display_field_views)
}

async fn transactions_to_view(
&self,
data: Vec<TransactionWithInfo>,
) -> Result<Vec<TransactionWithInfoView>> {
let rooch_addresses = data
.iter()
.map(|tx| tx.transaction.sender())
.flatten()
.collect::<Vec<_>>();
let address_mapping = self
.rpc_service
.get_bitcoin_addresses(rooch_addresses)
.await?;
let bitcoin_network = self.rpc_service.get_bitcoin_network().await?;
let data = data
.into_iter()
.map(|tx| {
let sender_bitcoin_address = match tx.transaction.sender() {
Some(rooch_address) => address_mapping
.get(&rooch_address)
.map(|addr| addr.clone().map(|a| a.format(bitcoin_network))),
None => None,
}
.flatten()
.transpose()?;
Ok(TransactionWithInfoView::new_from_transaction_with_info(
tx,
sender_bitcoin_address,
))
})
.collect::<Result<Vec<_>>>()?;
Ok(data)
}
}

#[async_trait]
Expand Down Expand Up @@ -362,6 +396,31 @@ impl RoochAPIServer for RoochServer {
})
.collect()
};

// Get owner_bitcoin_address
let addresses = objects_view
.iter()
.filter_map(|o| o.as_ref().map(|s| s.owner.into()))
.collect::<Vec<_>>();
let btc_network = self.rpc_service.get_bitcoin_network().await?;
let address_mapping = self.rpc_service.get_bitcoin_addresses(addresses).await?;

let objects_view = objects_view
.into_iter()
.map(|o| {
o.map(|s| {
let rooch_address = s.owner.into();
let bitcoin_address = address_mapping
.get(&rooch_address)
.expect("should exist.")
.clone()
.map(|a| a.format(btc_network))
.transpose()?;
Ok(s.with_owner_bitcoin_address(bitcoin_address))
})
.transpose()
})
.collect::<Result<Vec<_>>>()?;
Ok(objects_view)
}

Expand Down Expand Up @@ -427,13 +486,41 @@ impl RoochAPIServer for RoochServer {
) -> RpcResult<Vec<Option<TransactionWithInfoView>>> {
let tx_hashes: Vec<H256> = tx_hashes.iter().map(|m| (*m).into()).collect::<Vec<_>>();

let bitcoin_network = self.rpc_service.get_bitcoin_network().await?;
let data = self
.aggregate_service
.get_transaction_with_info(tx_hashes)
.await?
.into_iter()
.map(|item| item.map(TransactionWithInfoView::from))
.await?;

let rooch_addresses = data
.iter()
.filter_map(|tx| tx.as_ref().map(|tx| tx.transaction.sender()).flatten())
.collect::<Vec<_>>();
let address_mapping = self
.rpc_service
.get_bitcoin_addresses(rooch_addresses)
.await?;

let data = data
.into_iter()
.map(|item| {
item.map(|tx| {
let sender_bitcoin_address = match tx.transaction.sender() {
Some(rooch_address) => address_mapping
.get(&rooch_address)
.map(|addr| addr.clone().map(|a| a.format(bitcoin_network))),
None => None,
}
.flatten()
.transpose()?;
Ok(TransactionWithInfoView::new_from_transaction_with_info(
tx,
sender_bitcoin_address,
))
})
.transpose()
})
.collect::<Result<Vec<_>>>()?;

Ok(data)
}
Expand Down Expand Up @@ -502,9 +589,10 @@ impl RoochAPIServer for RoochServer {
.await?
.into_iter()
.flatten()
.map(TransactionWithInfoView::from)
.collect::<Vec<_>>();

let data = self.transactions_to_view(data).await?;

Ok(TransactionWithInfoPageView {
data,
next_cursor,
Expand Down Expand Up @@ -582,13 +670,13 @@ impl RoochAPIServer for RoochServer {
let mut data = self
.aggregate_service
.build_transaction_with_infos(txs)
.await?
.into_iter()
.map(TransactionWithInfoView::from)
.collect::<Vec<_>>();
.await?;

let has_next_page = data.len() > limit_of;
data.truncate(limit_of);

let data = self.transactions_to_view(data).await?;

let next_cursor = data
.last()
.cloned()
Expand Down Expand Up @@ -703,22 +791,36 @@ impl RoochAPIServer for RoochServer {
.collect::<Vec<_>>()
};

let network = self.rpc_service.get_bitcoin_network().await?;
let rooch_addresses = states.iter().map(|s| s.owner.clone()).collect::<Vec<_>>();
let bitcoin_addresses = self
.rpc_service
.get_bitcoin_addresses(rooch_addresses)
.await?
.into_iter()
.map(|(_, btc_addr)| btc_addr.map(|addr| addr.format(network)).transpose())
.collect::<Result<Vec<Option<String>>>>()?;

let mut data = annotated_states_with_display
.into_iter()
.zip(states)
.map(|((value, annotated_state, display_fields), state)| {
let decoded_value = if decode {
Some(AnnotatedMoveStructView::from(annotated_state.value))
} else {
None
};
IndexerObjectStateView::new_from_object_state(
state,
value,
decoded_value,
display_fields,
)
})
.zip(bitcoin_addresses)
.map(
|(((value, annotated_state, display_fields), state), bitcoin_address)| {
let decoded_value = if decode {
Some(AnnotatedMoveStructView::from(annotated_state.value))
} else {
None
};
IndexerObjectStateView::new_from_object_state(
state,
value,
bitcoin_address,
decoded_value,
display_fields,
)
},
)
.collect::<Vec<_>>();

let has_next_page = data.len() > limit_of;
Expand Down
Loading
Loading