-
Notifications
You must be signed in to change notification settings - Fork 170
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MiningManager, Mempool & BockTemplateBuilder (#103)
* Extend and describe consensus core constants * Enhance MutableTransaction with Clone and id() * Add calculate_transaction_output_estimated_serialized_size to ConsensusAPI * Initial mempool golang to rust rewrite * Refactor process_orphans_after_accepted_transaction and unorphan_transaction * clean-up mempool errors * Minor comments fix * Move mass calculation primitives to consensus-core * Add unit tests for mempool check_transaction_standard * Enhance ConsensusAPI with modify_coinbase_payload * Implement and use BlockTemplateBuilder & its cache * Replace ahash with std siphash in mempool * Some minor code cleanings * Add mempool get_transactions_by_addresses * Explicit overflow cases with checked_add * Use separate calculation paths in is_transaction_output_dust in case of overflow * Make TransactionsPool.all_transactions private * Handle some todos, add/modify/clean comments, rename/simplify some names, enhance code * Rename fill_inputs_and_get_missing_parents.rs to populate_entries_and_try_validate * Add a topological index to the transactions pool * Let revalidate_high_priority_transactions use the topological index and change the returned type * Refactor pools code, add chained txs to orphan pool, document * Move MempoolUtxoSet from Mempool to TransactionsPool * Enforce the pools maximum capacities * Optimize revalidation of high priority txs * Add MiningManager unit tests & fix 3 bugs in Mempool, OrphanPool and MempoolUtxoSet * Add a todo about the need for integration tests * Apply clippy advice * Make the BlockTemplateCache lifetime configurable * Add a todo to test TransactionsSelector * Use Arcs * Verify that now is in the future of last update * todos and rename * Use Mutex + continue removing also on errors * Refactor MutableTx to support internal tx being an Arc * Add SelectorSourceTransaction type and use it to get all ready txs with minimal clone cost * Rename SelectorSourceTransaction to CandidateTransaction and move it under MiningManager * Apply clippy new uninlined-format-args lint Co-authored-by: msutton <[email protected]>
- Loading branch information
1 parent
4a2a3a0
commit 4b842e5
Showing
68 changed files
with
4,807 additions
and
153 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
use crate::{ | ||
subnets::SUBNETWORK_ID_SIZE, | ||
tx::{Transaction, TransactionInput, TransactionOutput}, | ||
}; | ||
use hashes::HASH_SIZE; | ||
|
||
// transaction_estimated_serialized_size is the estimated size of a transaction in some | ||
// serialization. This has to be deterministic, but not necessarily accurate, since | ||
// it's only used as the size component in the transaction and block mass limit | ||
// calculation. | ||
pub fn transaction_estimated_serialized_size(tx: &Transaction) -> u64 { | ||
let mut size: u64 = 0; | ||
size += 2; // Tx version (u16) | ||
size += 8; // Number of inputs (u64) | ||
let inputs_size: u64 = tx.inputs.iter().map(transaction_input_estimated_serialized_size).sum(); | ||
size += inputs_size; | ||
|
||
size += 8; // number of outputs (u64) | ||
let outputs_size: u64 = tx.outputs.iter().map(transaction_output_estimated_serialized_size).sum(); | ||
size += outputs_size; | ||
|
||
size += 8; // lock time (u64) | ||
size += SUBNETWORK_ID_SIZE as u64; | ||
size += 8; // gas (u64) | ||
size += HASH_SIZE as u64; // payload hash | ||
|
||
size += 8; // length of the payload (u64) | ||
size += tx.payload.len() as u64; | ||
size | ||
} | ||
|
||
fn transaction_input_estimated_serialized_size(input: &TransactionInput) -> u64 { | ||
let mut size = 0; | ||
size += outpoint_estimated_serialized_size(); | ||
|
||
size += 8; // length of signature script (u64) | ||
size += input.signature_script.len() as u64; | ||
|
||
size += 8; // sequence (uint64) | ||
size | ||
} | ||
|
||
const fn outpoint_estimated_serialized_size() -> u64 { | ||
let mut size: u64 = 0; | ||
size += HASH_SIZE as u64; // Previous tx ID | ||
size += 4; // Index (u32) | ||
size | ||
} | ||
|
||
pub fn transaction_output_estimated_serialized_size(output: &TransactionOutput) -> u64 { | ||
let mut size: u64 = 0; | ||
size += 8; // value (u64) | ||
size += 2; // output.ScriptPublicKey.Version (u16) | ||
size += 8; // length of script public key (u64) | ||
size += output.script_public_key.script().len() as u64; | ||
size | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
use crate::{ | ||
constants::{MAX_TX_IN_SEQUENCE_NUM, TX_VERSION}, | ||
subnets::SUBNETWORK_ID_NATIVE, | ||
tx::{Transaction, TransactionInput, TransactionOutpoint, TransactionOutput}, | ||
}; | ||
|
||
use super::op_true_script::*; | ||
|
||
// create_transaction create a transaction that spends the first output of provided transaction. | ||
// Assumes that the output being spent has opTrueScript as it's scriptPublicKey. | ||
// Creates the value of the spent output minus provided `fee` (in sompi). | ||
pub fn create_transaction(tx_to_spend: &Transaction, fee: u64) -> Transaction { | ||
let (script_public_key, redeem_script) = op_true_script(); | ||
|
||
// TODO: call txscript.PayToScriptHashSignatureScript(redeemScript, nil) when available | ||
let signature_script = pay_to_script_hash_signature_script(redeem_script, vec![]); | ||
|
||
let previous_outpoint = TransactionOutpoint::new(tx_to_spend.id(), 0); | ||
let input = TransactionInput::new(previous_outpoint, signature_script, MAX_TX_IN_SEQUENCE_NUM, 1); | ||
let output = TransactionOutput::new(tx_to_spend.outputs[0].value - fee, script_public_key); | ||
Transaction::new(TX_VERSION, vec![input], vec![output], 0, SUBNETWORK_ID_NATIVE, 0, vec![]) | ||
} | ||
|
||
pub fn pay_to_script_hash_signature_script(redeem_script: Vec<u8>, signature: Vec<u8>) -> Vec<u8> { | ||
// TODO: replace all calls to this fn with the txscript PayToScriptHashSignatureScript equivalent | ||
let mut signature_script = vec![redeem_script.len() as u8]; | ||
signature_script.extend_from_slice(&redeem_script); | ||
signature_script.push(signature.len() as u8); | ||
signature_script.extend_from_slice(&signature); | ||
|
||
signature_script | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pub mod create_transaction; | ||
pub mod op_true_script; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
use hashes::HasherBase; | ||
|
||
use crate::{ | ||
constants::MAX_SCRIPT_PUBLIC_KEY_VERSION, | ||
tx::{scriptvec, ScriptPublicKey}, | ||
}; | ||
|
||
// op_true_script returns a P2SH script paying to an anyone-can-spend address, | ||
// The second return value is a redeemScript to be used with txscript.PayToScriptHashSignatureScript | ||
pub fn op_true_script() -> (ScriptPublicKey, Vec<u8>) { | ||
// TODO: use txscript.OpTrue instead when available | ||
let redeem_script = vec![81u8]; | ||
|
||
// TODO: use txscript.PayToScriptHashScript(redeemScript) when available | ||
// This is just a hack | ||
let mut hasher = hashes::TransactionSigningHash::new(); | ||
let redeem_script_hash = hasher.update(redeem_script.clone()).clone().finalize(); | ||
let mut script_public_key_script = scriptvec![170u8]; | ||
script_public_key_script.push(redeem_script_hash.as_bytes().len() as u8); | ||
script_public_key_script.extend_from_slice(&redeem_script_hash.as_bytes()); | ||
script_public_key_script.push(135u8); | ||
|
||
let script_public_key = ScriptPublicKey::new(MAX_SCRIPT_PUBLIC_KEY_VERSION, script_public_key_script); | ||
(script_public_key, redeem_script) | ||
} |
Oops, something went wrong.