Skip to content

Feature/api server mempool txs#2029

Open
OBorce wants to merge 2 commits intomasterfrom
feature/api-server-mempool-txs
Open

Feature/api server mempool txs#2029
OBorce wants to merge 2 commits intomasterfrom
feature/api-server-mempool-txs

Conversation

@OBorce
Copy link
Copy Markdown
Contributor

@OBorce OBorce commented Mar 24, 2026

API Server now scans the mempool after finishing syncing to the latest block.
New address and transaction endpoints for things from the mempool.

@OBorce OBorce changed the base branch from master to fix/api-server-balance-overflow March 24, 2026 09:39
@OBorce OBorce force-pushed the feature/api-server-mempool-txs branch 2 times, most recently from 554e4e2 to b00d078 Compare March 26, 2026 08:50
@OBorce OBorce force-pushed the fix/api-server-balance-overflow branch from e19ea86 to 184291a Compare March 26, 2026 08:51
@OBorce OBorce marked this pull request as draft March 27, 2026 09:49
@OBorce OBorce force-pushed the feature/api-server-mempool-txs branch from b00d078 to 8a9d0ce Compare April 1, 2026 08:43
@OBorce OBorce force-pushed the feature/api-server-mempool-txs branch from 8a9d0ce to 6496fe8 Compare April 1, 2026 08:47
@OBorce OBorce changed the base branch from fix/api-server-balance-overflow to master April 1, 2026 08:49
@OBorce OBorce force-pushed the feature/api-server-mempool-txs branch from 6496fe8 to b916d76 Compare April 1, 2026 08:51
@OBorce OBorce force-pushed the feature/api-server-mempool-txs branch from b916d76 to 1f9d564 Compare April 1, 2026 08:57
@OBorce OBorce marked this pull request as ready for review April 1, 2026 08:57
Copy link
Copy Markdown
Contributor

@ImplOfAnImpl ImplOfAnImpl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CURRENT_STORAGE_VERSION wasn't updated - is this intended?

Comment on lines +45 to +52
- API Server:
- new endpoints for addresses and transactions from the mempool:
- `/mempool/transaction`
- `/mempool/transaction/:id`
- `/mempool/transaction/:id/output/:idx`
- `/mempool/address/:address`
- `/mempool/address/:address/all-utxos`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API server has a separate changelog - api-server/CHANGELOG.md

transaction_id: Id<Transaction>,
transaction: &TransactionInfo,
) -> Result<(), ApiServerStorageError> {
// Because of ON DELETE CASCADE on other tables, we insert the transaction first.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Outdated comment? This function only inserts the transaction and does nothing else, so "we insert the transaction first" doesn't seem to make much sense.

pub enum BlockchainStateError {
#[error("Unexpected storage error: {0}")]
StorageError(#[from] ApiServerStorageError),
#[error("Token decimals not found for token id: {0}")]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, the ids are printed in contracted form by default (due to how Display is implemented for fixed_hash types), which is not very useful, especially in error messages. You can force the full form by using {0:x}.

&self,
tx_id: Id<Transaction>,
) -> Result<Option<SignedTransaction>, Self::Error>;
async fn mempool_get_transactions(&self) -> Result<Vec<SignedTransaction>, Self::Error>;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, the doc comment for MempoolRpc::get_all_transactions still says "This function is mostly used for testing purposes", which is no longer true.

address: &str,
) -> Result<BTreeMap<CoinOrTokenId, AmountWithDecimals>, ApiServerStorageError>;

async fn get_utxo_mempool_fallback(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_mempool_utxo_with_fallback?

Also,

  1. As I can see, a bunch of other functions also fall back to non-mempool ones if the info is not found in the mempool - get_mempool_address_balance, get_mempool_locked_address_balance, get_mempool_token_num_decimals, get_mempool_order. Why aren't they named in the same way?
  2. Maybe add doc comments describing what the functions are supposed to do exactly, especially the "fallback" ones?

)
.await;
} else {
increase_mempool_locked_address_balance(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that you increase locked balances in the mempool but never decrease them.
Mempool has some timelock tolerance defined by constants FUTURE_TIMELOCK_TOLERANCE/FUTURE_TIMELOCK_TOLERANCE_BLOCKS. So it should be possible to have e.g. a tx with LockThenTransfer output for 2 blocks and then a tx that consumes that output both in the mempool at the same time.

Probably you should decrease locked balances if a LockThenTransfer utxo is spent by a mempool tx.

let (best_block_height, _, best_block_timestamp) = self.best_block().await?;
let next_block_height = best_block_height.next_height();

let mut db_tx = self.storage.transaction_rw().await.expect("Unable to connect to database");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw why do you panic on storage errors everywhere, when this function already returns an error type constructible from ApiServerStorageError?

}

fn get_tx_output_destination(txo: &TxOutput) -> Option<&Destination> {
fn get_tx_output_destination(txo: &TxOutput) -> Vec<&Destination> {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

destinations

Comment on lines +2723 to +2725
let input_tasks: FuturesOrdered<_> =
tx.inputs().iter().map(|input| fetch_mempool_utxo(input, db_tx)).collect();
let input_utxos: Vec<Option<Utxo>> = input_tasks.try_collect().await?;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, this will fail if the utxo belongs to a mempool tx that hasn't been handled yet.

Comment on lines +107 to +110
.route(
"/mempool/transaction/:id/output/:idx",
get(mempool_transaction_output),
);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this accepts both txs in mempool and already mined ones. Why not add an option to the existing /transaction/:id/output/:idx so that it would consider mempool txs as well?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants