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

Feat/tx tracking #5484

Draft
wants to merge 19 commits into
base: develop
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions .github/workflows/bitcoin-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ jobs:
- tests::nakamoto_integrations::sip029_coinbase_change
- tests::nakamoto_integrations::clarity_cost_spend_down
- tests::nakamoto_integrations::v3_blockbyheight_api_endpoint
- tests::nakamoto_integrations::v3_transactions_api_endpoint
# TODO: enable these once v1 signer is supported by a new nakamoto epoch
# - tests::signer::v1::dkg
# - tests::signer::v1::sign_request_rejected
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE
## [Unreleased]

### Added
- Add `/v3/transactions/:txid` rpc endpoint

### Changed

Expand Down Expand Up @@ -38,6 +39,7 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE
### Changed

- Use the same burn view loader in both block validation and block processing
>>>>>>> develop
Copy link
Member

Choose a reason for hiding this comment

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

Merge artifact


## [3.0.0.0.3]

Expand Down
21 changes: 21 additions & 0 deletions docs/rpc-endpoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -578,3 +578,24 @@ tenure, `tip_block_id` identifies the highest-known block in this tenure, and
Get number of blocks signed by signer during a given reward cycle

Returns a non-negative integer

### GET /v3/transactions/[Transaction ID]

Returns the index_block_hash and the transaction body (as hex) given the TXID.

```json
{
"index_block_hash": "...",
"tx": "..."
}
```

This feature requires enabling of transaction log by setting the STACKS_TRANSACTION_LOG
environment variable to "1"

This will return 404 if the transaction does not exist and 501 (Not Implemented) if
transaction log is not enabled.

This endpoint also accepts a query string parameter `?tip=` which when supplied will ensure
the returned transaction is an a block relative to the specified tip (as the transaction log
could store even non canonical tip transactions).
37 changes: 37 additions & 0 deletions docs/rpc/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -866,3 +866,40 @@ paths:
schema:
type: integer
example: 7

/v3/transactions/{txid}:
post:
summary: Returns index_block_hash and Transaction body given a TXID
tags:
- Transactions
description: Get a JSON with the index_block_hash and the Transaction body as hex.
operationId: get_transaction
parameters:
- name: txid
in: path
required: true
description: Transaction ID
schema:
type: string
- name: tip
in: query
schema:
type: string
description: The Stacks chain tip to check for the block containing the transaction.
If tip == latest (the default), the latest known tip will be used.
responses:
"200":
description: Transaction ID of successful post of a raw tx to the node's mempool
content:
text/plain:
schema:
type: string
example: '"e161978626f216b2141b156ade10501207ae535fa365a13ef5d7a7c9310a09f2"'
"400":
description: Rejections result in a 400 error
content:
application/json:
schema:
$ref: ./api/transaction/post-core-node-transactions-error.schema.json
example:
$ref: ./api/transaction/post-core-node-transactions-error.example.json
6 changes: 6 additions & 0 deletions stackslib/src/chainstate/burn/db/sortdb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,12 @@ impl FromRow<ConsensusHash> for ConsensusHash {
}
}

impl FromRow<StacksBlockId> for StacksBlockId {
fn from_row<'a>(row: &'a Row) -> Result<StacksBlockId, db_error> {
StacksBlockId::from_column(row, "index_block_hash")
}
}

impl FromRow<BurnchainHeaderHash> for BurnchainHeaderHash {
fn from_row<'a>(row: &'a Row) -> Result<BurnchainHeaderHash, db_error> {
BurnchainHeaderHash::from_column(row, "burn_header_hash")
Expand Down
23 changes: 22 additions & 1 deletion stackslib/src/chainstate/nakamoto/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ use crate::chainstate::stacks::address::PoxAddress;
use crate::chainstate::stacks::boot::{POX_4_NAME, SIGNERS_UPDATE_STATE};
use crate::chainstate::stacks::db::blocks::DummyEventDispatcher;
use crate::chainstate::stacks::db::{
DBConfig as ChainstateConfig, StacksChainState, StacksDBConn, StacksDBTx,
is_transaction_log_enabled, DBConfig as ChainstateConfig, StacksChainState, StacksDBConn,
StacksDBTx,
};
use crate::chainstate::stacks::index::marf::MarfConnection;
use crate::chainstate::stacks::{
Expand Down Expand Up @@ -4885,6 +4886,26 @@ impl NakamotoChainState {
clarity.save_analysis(&contract_id, &analysis).unwrap();
})
}

/// Get transactions by txid from the transaction log
/// NOTE: multiple rows could match as the transaction log contains unconfirmed/orphaned
/// transactions too
pub fn get_index_block_hashes_from_txid(
conn: &Connection,
txid: Txid,
) -> Result<Vec<StacksBlockId>, chainstate::stacks::Error> {
if is_transaction_log_enabled() {
let args = params![txid];
query_rows(
conn,
"SELECT index_block_hash FROM transactions WHERE txid = ?",
args,
)
.map_err(|e| e.into())
} else {
Err(chainstate::stacks::Error::NoTransactionLog)
}
}
}

impl StacksMessageCodec for NakamotoBlock {
Expand Down
17 changes: 16 additions & 1 deletion stackslib/src/chainstate/stacks/db/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

use std::cell::RefCell;
use std::collections::btree_map::Entry;
use std::collections::{BTreeMap, HashSet};
use std::io::prelude::*;
Expand Down Expand Up @@ -97,10 +98,24 @@ pub mod headers;
pub mod transactions;
pub mod unconfirmed;

#[cfg(not(test))]
lazy_static! {
pub static ref TRANSACTION_LOG: bool =
std::env::var("STACKS_TRANSACTION_LOG") == Ok("1".into());
}
#[cfg(not(test))]
pub fn is_transaction_log_enabled() -> bool {
*TRANSACTION_LOG
}

#[cfg(test)]
thread_local! {
pub static TRANSACTION_LOG: RefCell<bool> = RefCell::new(false);
rdeioris marked this conversation as resolved.
Show resolved Hide resolved
}
#[cfg(test)]
pub fn is_transaction_log_enabled() -> bool {
TRANSACTION_LOG.with(|v| *v.borrow())
}

/// Fault injection struct for various kinds of faults we'd like to introduce into the system
pub struct StacksChainStateFaults {
Expand Down Expand Up @@ -646,7 +661,7 @@ impl<'a> ChainstateTx<'a> {
block_id: &StacksBlockId,
events: &[StacksTransactionReceipt],
) {
if *TRANSACTION_LOG {
if is_transaction_log_enabled() {
let insert =
"INSERT INTO transactions (txid, index_block_hash, tx_hex, result) VALUES (?, ?, ?, ?)";
for tx_event in events.iter() {
Expand Down
6 changes: 6 additions & 0 deletions stackslib/src/chainstate/stacks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ pub enum Error {
/// This error indicates a Epoch2 block attempted to build off of a Nakamoto block.
InvalidChildOfNakomotoBlock,
NoRegisteredSigners(u64),
NoTransactionLog,
}

impl From<marf_error> for Error {
Expand Down Expand Up @@ -232,6 +233,9 @@ impl fmt::Display for Error {
Error::NotInSameFork => {
write!(f, "The supplied block identifiers are not in the same fork")
}
Error::NoTransactionLog => {
write!(f, "TransactionLog is not enabled")
}
}
}
}
Expand Down Expand Up @@ -277,6 +281,7 @@ impl error::Error for Error {
Error::ExpectedTenureChange => None,
Error::NoRegisteredSigners(_) => None,
Error::NotInSameFork => None,
Error::NoTransactionLog => None,
}
}
}
Expand Down Expand Up @@ -322,6 +327,7 @@ impl Error {
Error::ExpectedTenureChange => "ExpectedTenureChange",
Error::NoRegisteredSigners(_) => "NoRegisteredSigners",
Error::NotInSameFork => "NotInSameFork",
Error::NoTransactionLog => "NoTransactionLog",
}
}

Expand Down
Loading