fn transparent_spend_chain_order(
    spend: transparent::OutPoint,
    spend_tx_index_in_block: usize,
    block_new_outputs: &HashMap<transparent::OutPoint, transparent::OrderedUtxo>,
    non_finalized_chain_unspent_utxos: &HashMap<transparent::OutPoint, transparent::Utxo>,
    non_finalized_chain_spent_utxos: &HashSet<transparent::OutPoint>,
    finalized_state: &FinalizedState,
) -> Result<transparent::Utxo, ValidateContextError> {
    if let Some(output) = block_new_outputs.get(&spend) {
        // reject the spend if it uses an output from this block,
        // but the output was not created by an earlier transaction
        //
        // we know the spend is invalid, because transaction IDs are unique
        //
        // (transaction IDs also commit to transaction inputs,
        // so it should be cryptographically impossible for a transaction
        // to spend its own outputs)
        if output.tx_index_in_block >= spend_tx_index_in_block {
            return Err(EarlyTransparentSpend { outpoint: spend });
        } else {
            // a unique spend of a previous transaction's output is ok
            return Ok(output.utxo.clone());
        }
    }

    if non_finalized_chain_spent_utxos.contains(&spend) {
        // reject the spend if its UTXO is already spent in the
        // non-finalized parent chain
        return Err(DuplicateTransparentSpend {
            outpoint: spend,
            location: "the non-finalized chain",
        });
    }

    match (
        non_finalized_chain_unspent_utxos.get(&spend),
        finalized_state.utxo(&spend),
    ) {
        (None, None) => {
            // we don't keep spent UTXOs in the finalized state,
            // so all we can say is that it's missing from both
            // the finalized and non-finalized chains
            // (it might have been spent in the finalized state,
            // or it might never have existed in this chain)
            Err(MissingTransparentOutput {
                outpoint: spend,
                location: "the non-finalized and finalized chain",
            })
        }

        (Some(utxo), _) => Ok(utxo.clone()),
        (_, Some(utxo)) => Ok(utxo),
    }
}
/// Check that transparent spends occur in chain order.
///
/// Because we are in the non-finalized state, we need to check spends within the same block,
/// spent non-finalized UTXOs, and unspent non-finalized and finalized UTXOs.
///
/// "Any input within this block can spend an output which also appears in this block
/// (assuming the spend is otherwise valid).
/// However, the TXID corresponding to the output must be placed at some point
/// before the TXID corresponding to the input.
/// This ensures that any program parsing block chain transactions linearly
/// will encounter each output before it is used as an input."
///
/// https://developer.bitcoin.org/reference/block_chain.html#merkle-trees
///
/// "each output of a particular transaction
/// can only be used as an input once in the block chain.
/// Any subsequent reference is a forbidden double spend-
/// an attempt to spend the same satoshis twice."
///
/// https://developer.bitcoin.org/devguide/block_chain.html#introduction
Check that transparent spends occur in chain order.
Because we are in the non-finalized state, we need to check spends within the same block,
spent non-finalized UTXOs, and unspent non-finalized and finalized UTXOs.

"Any input within this block can spend an output which also appears in this block
(assuming the spend is otherwise valid).
However, the TXID corresponding to the output must be placed at some point
before the TXID corresponding to the input.
This ensures that any program parsing block chain transactions linearly
will encounter each output before it is used as an input."



"each output of a particular transaction
can only be used as an input once in the block chain.
Any subsequent reference is a forbidden double spend
an attempt to spend the same satoshis twice."


Check that transparent spends occur in chain order . Because we are in the non - finalized state we need to check spends within the same block spent non - finalized UTXOs and unspent non - finalized and finalized UTXOs . " Any input within this block can spend an output which also appears in this block ( assuming the spend is otherwise valid ) . However the TXID corresponding to the output must be placed at some point before the TXID corresponding to the input . This ensures that any program parsing block chain transactions linearly will encounter each output before it is used as an input . " " each output of a particular transaction can only be used as an input once in the block chain . Any subsequent reference is a forbidden double spend an attempt to spend the same satoshis twice . "
fn transparent_spend_chain_order(
    spend: transparent::OutPoint,
    spend_tx_index_in_block: usize,
    block_new_outputs: &HashMap<transparent::OutPoint, transparent::OrderedUtxo>,
    non_finalized_chain_unspent_utxos: &HashMap<transparent::OutPoint, transparent::Utxo>,
    non_finalized_chain_spent_utxos: &HashSet<transparent::OutPoint>,
    finalized_state: &FinalizedState,
) -> Result<transparent::Utxo, ValidateContextError> {
    if let Some(output) = block_new_outputs.get(&spend) {
        // reject the spend if it uses an output from this block,
        // but the output was not created by an earlier transaction
        //
        // we know the spend is invalid, because transaction IDs are unique
        //
        // (transaction IDs also commit to transaction inputs,
        // so it should be cryptographically impossible for a transaction
        // to spend its own outputs)
        if output.tx_index_in_block >= spend_tx_index_in_block {
            return Err(EarlyTransparentSpend { outpoint: spend });
        } else {
            // a unique spend of a previous transaction's output is ok
            return Ok(output.utxo.clone());
        }
    }
    if non_finalized_chain_spent_utxos.contains(&spend) {
        // reject the spend if its UTXO is already spent in the
        // non-finalized parent chain
        return Err(DuplicateTransparentSpend {
            outpoint: spend,
            location: "the non-finalized chain",
        });
    }
    match (
        non_finalized_chain_unspent_utxos.get(&spend),
        finalized_state.utxo(&spend),
    ) {
        (None, None) => {
            // we don't keep spent UTXOs in the finalized state,
            // so all we can say is that it's missing from both
            // the finalized and non-finalized chains
            // (it might have been spent in the finalized state,
            // or it might never have existed in this chain)
            Err(MissingTransparentOutput {
                outpoint: spend,
                location: "the non-finalized and finalized chain",
            })
        }
        (Some(utxo), _) => Ok(utxo.clone()),
        (_, Some(utxo)) => Ok(utxo),
    }
}
fn transparent_spend_chain_order ( spend : transparent :: OutPoint , spend_tx_index_in_block : usize , block_new_outputs : & HashMap < transparent :: OutPoint , transparent :: OrderedUtxo > , non_finalized_chain_unspent_utxos : & HashMap < transparent :: OutPoint , transparent :: Utxo > , non_finalized_chain_spent_utxos : & HashSet < transparent :: OutPoint > , finalized_state : & FinalizedState , ) -> Result < transparent :: Utxo , ValidateContextError > { if let Some ( output ) = block_new_outputs . get ( & spend ) { // reject the spend if it uses an output from this block, // but the output was not created by an earlier transaction // // we know the spend is invalid, because transaction IDs are unique // // (transaction IDs also commit to transaction inputs, // so it should be cryptographically impossible for a transaction // to spend its own outputs) if output . tx_index_in_block >= spend_tx_index_in_block { return Err ( EarlyTransparentSpend { outpoint : spend } ) ; } else { // a unique spend of a previous transaction's output is ok return Ok ( output . utxo . clone ( ) ) ; } } if non_finalized_chain_spent_utxos . contains ( & spend ) { // reject the spend if its UTXO is already spent in the // non-finalized parent chain return Err ( DuplicateTransparentSpend { outpoint : spend , location : " " , } ) ; } match ( non_finalized_chain_unspent_utxos . get ( & spend ) , finalized_state . utxo ( & spend ) , ) { ( None , None ) => { // we don't keep spent UTXOs in the finalized state, // so all we can say is that it's missing from both // the finalized and non-finalized chains // (it might have been spent in the finalized state, // or it might never have existed in this chain) Err ( MissingTransparentOutput { outpoint : spend , location : " " , } ) } ( Some ( utxo ) , _ ) => Ok ( utxo . clone ( ) ) , ( _ , Some ( utxo ) ) => Ok ( utxo ) , } }
Check that transparent spends occur in chain order.
Check that transparent spends occur in chain order .
spend
transparent::OutPoint
spend_tx_index_in_block
usize
block_new_outputs
&HashMap<transparent::OutPoint, transparent::OrderedUtxo>
non_finalized_chain_unspent_utxos
&HashMap<transparent::OutPoint, transparent::Utxo>
non_finalized_chain_spent_utxos
&HashSet<transparent::OutPoint>
finalized_state
&FinalizedState