1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
crate::ix!();

#[derive(Default)]
pub struct PrecomputedTransactionData {

    /**
      | BIP341 precomputed data.
      | 
      | These are single-SHA256, 
      | see https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#cite_note-15.
      |
      */
    prevouts_single_hash:      u256,

    sequences_single_hash:     u256,
    outputs_single_hash:       u256,
    spent_amounts_single_hash: u256,
    spent_scripts_single_hash: u256,

    /**
      | Whether the 5 fields above are initialized.
      |
      */
    bip341_taproot_ready:      bool, // default = false

    /**
      | BIP143 precomputed data (double-SHA256).
      |
      */
    hash_prevouts:             u256,

    /**
      | BIP143 precomputed data (double-SHA256).
      |
      */
    hash_sequence:             u256,

    /**
      | BIP143 precomputed data (double-SHA256).
      |
      */
    hash_outputs:              u256,

    /**
      | Whether the 3 fields above are initialized.
      |
      */
    bip143_segwit_ready:       bool, // default = false

    spent_outputs:             Vec<TxOut>,

    /**
      | Whether m_spent_outputs is initialized.
      |
      */
    spent_outputs_ready:       bool, // default = false
}

impl PrecomputedTransactionData {

    /**
      | Initialize this PrecomputedTransactionData
      | with transaction data.
      | 
      | -----------
      | @param[in] tx
      | 
      | The transaction for which data is being
      | precomputed.
      | ----------
      | @param[in] spent_outputs
      | 
      | The CTxOuts being spent, one for each
      | tx.vin, in order.
      | ----------
      | @param[in] force
      | 
      | Whether to precompute data for all optional
      | features, regardless of what is in the
      | inputs (used at signing time, when the
      | inputs aren't filled in yet).
      |
      */
    pub fn init<T>(&mut self, 
        tx_to:         &T,
        spent_outputs: Vec<TxOut>,
        force:         Option<bool>)  {

        let force: bool = force.unwrap_or(false);
    
        todo!();
        /*
            assert(!m_spent_outputs_ready);

        m_spent_outputs = std::move(spent_outputs);
        if (!m_spent_outputs.empty()) {
            assert(m_spent_outputs.size() == txTo.vin.size());
            m_spent_outputs_ready = true;
        }

        // Determine which precomputation-impacting features this transaction uses.
        bool uses_bip143_segwit = force;
        bool uses_bip341_taproot = force;
        for (size_t inpos = 0; inpos < txTo.vin.size() && !(uses_bip143_segwit && uses_bip341_taproot); ++inpos) {
            if (!txTo.vin[inpos].scriptWitness.IsNull()) {
                if (m_spent_outputs_ready && m_spent_outputs[inpos].scriptPubKey.size() == 2 + WITNESS_V1_TAPROOT_SIZE &&
                    m_spent_outputs[inpos].scriptPubKey[0] == OP_1) {
                    // Treat every witness-bearing spend with 34-byte scriptPubKey that starts with OP_1 as a Taproot
                    // spend. This only works if spent_outputs was provided as well, but if it wasn't, actual validation
                    // will fail anyway. Note that this branch may trigger for scriptPubKeys that aren't actually segwit
                    // but in that case validation will fail as SCRIPT_ERR_WITNESS_UNEXPECTED anyway.
                    uses_bip341_taproot = true;
                } else {
                    // Treat every spend that's not known to native witness v1 as a Witness v0 spend. This branch may
                    // also be taken for unknown witness versions, but it is harmless, and being precise would require
                    // P2SH evaluation to find the redeemScript.
                    uses_bip143_segwit = true;
                }
            }
            if (uses_bip341_taproot && uses_bip143_segwit) break; // No need to scan further if we already need all.
        }

        if (uses_bip143_segwit || uses_bip341_taproot) {
            // Computations shared between both sighash schemes.
            m_prevouts_single_hash = GetPrevoutsSHA256(txTo);
            m_sequences_single_hash = GetSequencesSHA256(txTo);
            m_outputs_single_hash = GetOutputsSHA256(txTo);
        }
        if (uses_bip143_segwit) {
            hashPrevouts = SHA256Uint256(m_prevouts_single_hash);
            hashSequence = SHA256Uint256(m_sequences_single_hash);
            hashOutputs = SHA256Uint256(m_outputs_single_hash);
            m_bip143_segwit_ready = true;
        }
        if (uses_bip341_taproot) {
            m_spent_amounts_single_hash = GetSpentAmountsSHA256(m_spent_outputs);
            m_spent_scripts_single_hash = GetSpentScriptsSHA256(m_spent_outputs);
            m_bip341_taproot_ready = true;
        }
        */
    }
    
    pub fn new<T>(tx_to: &T) -> Self {
    
        todo!();
        /*
            Init(txTo, {});
        */
    }
}