• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Neptune-Crypto / neptune-core / 14919393916

09 May 2025 01:23AM UTC coverage: 71.653% (-3.3%) from 74.963%
14919393916

push

github

dan-da
style: address review comments

Addresses review comments for #583:

+ use #[cfg(not(test))] instead of bool param to disable initial sleep
  in mining loop for unit tests
+ improve comment in mining loop when checking composer_task error
+ rename RpcError::Error to RpcError::WalletError
+ remove redundant copy_dir_recursive() in src/tests/shared.rs

0 of 4 new or added lines in 2 files covered. (0.0%)

172 existing lines in 18 files now uncovered.

19870 of 27731 relevant lines covered (71.65%)

367043.22 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

73.97
/src/models/blockchain/type_scripts/mod.rs
1
pub mod known_type_scripts;
2
pub mod native_currency;
3
pub mod native_currency_amount;
4
pub mod time_lock;
5

6
use std::collections::HashMap;
7
use std::hash::Hasher as StdHasher;
8
use std::sync::Arc;
9

10
#[cfg(any(test, feature = "arbitrary-impls"))]
11
use arbitrary::Arbitrary;
12
use get_size2::GetSize;
13
use itertools::Itertools;
14
use serde::Deserialize;
15
use serde::Serialize;
16
use tasm_lib::prelude::Digest;
17
use tasm_lib::triton_vm::prelude::*;
18
use tasm_lib::twenty_first::math::bfield_codec::BFieldCodec;
19

20
use super::transaction::primitive_witness::SaltedUtxos;
21
use super::transaction::transaction_kernel::TransactionKernel;
22
use super::transaction::utxo::Coin;
23
use crate::api::tx_initiation::builder::proof_builder::ProofBuilder;
24
use crate::api::tx_initiation::error::CreateProofError;
25
use crate::models::blockchain::transaction::validity::neptune_proof::Proof;
26
use crate::models::proof_abstractions::mast_hash::MastHash;
27
use crate::models::proof_abstractions::tasm::program::ConsensusProgram;
28
use crate::models::proof_abstractions::tasm::program::TritonVmProofJobOptions;
29
use crate::triton_vm_job_queue::TritonVmJobQueue;
30
use crate::Hash;
31

32
pub(crate) trait TypeScript: ConsensusProgram {
33
    type State: BFieldCodec;
34

35
    fn try_decode_state(
11,655✔
36
        &self,
11,655✔
37
        state: &[BFieldElement],
11,655✔
38
    ) -> Result<Box<Self::State>, <Self::State as BFieldCodec>::Error> {
11,655✔
39
        Self::State::decode(state)
11,655✔
40
    }
11,655✔
41

42
    fn matches_coin(&self, coin: &Coin) -> bool {
11,651✔
43
        self.try_decode_state(&coin.state).is_ok() && coin.type_script_hash == self.hash()
11,651✔
44
    }
11,651✔
45
}
46

47
pub(crate) trait TypeScriptWitness {
48
    fn new(
49
        transaction_kernel: TransactionKernel,
50
        salted_input_utxos: SaltedUtxos,
51
        salted_output_utxos: SaltedUtxos,
52
    ) -> Self;
53
    fn transaction_kernel(&self) -> TransactionKernel;
54
    fn salted_input_utxos(&self) -> SaltedUtxos;
55
    fn salted_output_utxos(&self) -> SaltedUtxos;
56
    fn type_script_and_witness(&self) -> TypeScriptAndWitness;
57
    fn type_script_standard_input(&self) -> PublicInput {
3,626✔
58
        PublicInput::new(
3,626✔
59
            [
3,626✔
60
                self.transaction_kernel().mast_hash().reversed().values(),
3,626✔
61
                Hash::hash(&self.salted_input_utxos()).reversed().values(),
3,626✔
62
                Hash::hash(&self.salted_output_utxos()).reversed().values(),
3,626✔
63
            ]
3,626✔
64
            .concat()
3,626✔
65
            .to_vec(),
3,626✔
66
        )
67
    }
3,626✔
68
}
69

70
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, GetSize, BFieldCodec)]
71
pub struct TypeScriptAndWitness {
72
    pub program: Program,
73
    nd_tokens: Vec<BFieldElement>,
74
    nd_memory: Vec<(BFieldElement, BFieldElement)>,
75
    nd_digests: Vec<Digest>,
76
}
77

78
impl TypeScriptAndWitness {
79
    pub(crate) fn new_with_nondeterminism(program: Program, witness: NonDeterminism) -> Self {
7,865✔
80
        Self {
7,865✔
81
            program,
7,865✔
82
            nd_memory: witness.ram.into_iter().collect(),
7,865✔
83
            nd_tokens: witness.individual_tokens,
7,865✔
84
            nd_digests: witness.digests,
7,865✔
85
        }
7,865✔
86
    }
7,865✔
87

88
    #[cfg(any(test, feature = "arbitrary-impls"))]
89
    pub(crate) fn new_with_tokens(program: Program, tokens: Vec<BFieldElement>) -> Self {
×
90
        Self {
×
91
            program,
×
92
            nd_memory: vec![],
×
93
            nd_tokens: tokens,
×
94
            nd_digests: vec![],
×
95
        }
×
UNCOV
96
    }
×
97

98
    pub(crate) fn nondeterminism(&self) -> NonDeterminism {
311✔
99
        NonDeterminism::new(self.nd_tokens.clone())
311✔
100
            .with_digests(self.nd_digests.clone())
311✔
101
            .with_ram(self.nd_memory.iter().copied().collect::<HashMap<_, _>>())
311✔
102
    }
311✔
103

104
    /// Assuming the type script halts gracefully, prove it.
105
    pub(crate) async fn prove(
228✔
106
        &self,
228✔
107
        txk_mast_hash: Digest,
228✔
108
        salted_inputs_hash: Digest,
228✔
109
        salted_outputs_hash: Digest,
228✔
110
        triton_vm_job_queue: Arc<TritonVmJobQueue>,
228✔
111
        proof_job_options: TritonVmProofJobOptions,
228✔
112
    ) -> Result<Proof, CreateProofError> {
228✔
113
        let input = [txk_mast_hash, salted_inputs_hash, salted_outputs_hash]
228✔
114
            .into_iter()
228✔
115
            .flat_map(|d| d.reversed().values())
684✔
116
            .collect_vec();
228✔
117
        let claim = Claim::new(self.program.hash()).with_input(input);
228✔
118

119
        ProofBuilder::new()
228✔
120
            .program(self.program.clone())
228✔
121
            .claim(claim)
228✔
122
            .nondeterminism(self.nondeterminism())
228✔
123
            .job_queue(triton_vm_job_queue)
228✔
124
            .proof_job_options(proof_job_options)
228✔
125
            .build()
228✔
126
            .await
228✔
127
    }
228✔
128
}
129

130
#[cfg(any(test, feature = "arbitrary-impls"))]
131
impl<'a> Arbitrary<'a> for TypeScriptAndWitness {
132
    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
×
133
        let program = Program::arbitrary(u)?;
×
134
        let tokens = Digest::arbitrary(u)?.reversed().values().to_vec();
×
135
        Ok(TypeScriptAndWitness::new_with_tokens(program, tokens))
×
UNCOV
136
    }
×
137
}
138

139
impl std::hash::Hash for TypeScriptAndWitness {
140
    fn hash<H: StdHasher>(&self, state: &mut H) {
×
141
        self.program.instructions.hash(state);
×
142
        self.nd_tokens.hash(state);
×
143
        self.nd_memory.hash(state);
×
144
        self.nd_digests.hash(state);
×
UNCOV
145
    }
×
146
}
147

148
#[cfg(test)]
149
#[cfg_attr(coverage_nightly, coverage(off))]
150
pub(crate) mod tests {
151
    use rand::rngs::StdRng;
152
    use rand::Rng;
153
    use rand::SeedableRng;
154

155
    use super::*;
156

157
    impl TypeScriptAndWitness {
158
        pub(crate) fn halts_gracefully(
159
            &self,
160
            txk_mast_hash: Digest,
161
            salted_inputs_hash: Digest,
162
            salted_outputs_hash: Digest,
163
        ) -> bool {
164
            let standard_input = [txk_mast_hash, salted_inputs_hash, salted_outputs_hash]
165
                .into_iter()
166
                .flat_map(|d| d.reversed().values().to_vec())
167
                .collect_vec();
168
            let public_input = PublicInput::new(standard_input);
169

170
            VM::run(self.program.clone(), public_input, self.nondeterminism()).is_ok()
171
        }
172

173
        /// Scramble witness data without affecting program. For negative
174
        /// tests.
175
        pub(crate) fn scramble_non_determinism(&mut self, seed: u64) {
176
            let mut rng: StdRng = SeedableRng::seed_from_u64(seed);
177

178
            if !self.nd_tokens.is_empty() {
179
                let idx = rng.random_range(0..self.nd_tokens.len());
180
                self.nd_tokens[idx] = rng.random();
181
            }
182

183
            if !self.nd_memory.is_empty() {
184
                let idx = rng.random_range(0..self.nd_memory.len());
185
                let (address, _value) = self.nd_memory[idx];
186
                self.nd_memory[idx] = (address, rng.random());
187
            }
188

189
            if !self.nd_digests.is_empty() {
190
                let idx = rng.random_range(0..self.nd_digests.len());
191
                self.nd_digests[idx] = rng.random();
192
            }
193
        }
194
    }
195
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc