mina-indexer icon indicating copy to clipboard operation
mina-indexer copied to clipboard

Using `unwrap` may cause a panic and in most cases this isn't intended behavior

Open trevorbernard opened this issue 1 year ago • 2 comments

Using unwrap is convenient for quickly prototyping but we need to explicitly handle our error conditions and decide which are recoverable and which should actually panic.

trevorbernard avatar Nov 12 '23 19:11 trevorbernard

@jhult Let me know if you have an appetite for auditing the code for instances of 'unwrap'.

robinbb avatar Mar 07 '24 01:03 robinbb

Running ripgrep inside src directory.

❯ rg -iFl "unwrap("
block/parser.rs
block/mod.rs
block/precomputed.rs
block/vrf_output.rs
block/blockchain_length.rs
store.rs
ipc.rs
bin/mina-indexer.rs
snark_work/mod.rs
command/signed.rs
web/rest/blockchain.rs
state/summary.rs
command/mod.rs
web/rest/accounts.rs
web/rest/blocks.rs
state/mod.rs
state/branch.rs
ledger/account/mod.rs
protocol/bin_prot/loose_deserializer.rs
ledger/public_key.rs
ledger/genesis.rs
canonicity/canonical_chain_discovery.rs
protocol/bin_prot/README.md
protocol/bin_prot/value/layout/traverse.rs
ledger/mod.rs
❯ rg -iF "unwrap("
block/parser.rs
131:                println!("{}", path.file_name().unwrap().to_str().unwrap());

block/mod.rs
52:        Self(versioned.to_base58_string().unwrap())
291:                        let is_valid_length = parts.get(1).unwrap().parse::<u32>().is_ok();
309:    let filename = path.file_name().and_then(|x| x.to_str()).unwrap();
324:    let name = path.file_stem().and_then(|x| x.to_str()).unwrap();
325:    let dash_pos = name.rfind('-').unwrap();

block/precomputed.rs
374:            .map(|cmd| cmd.hash_signed_command().unwrap())

block/vrf_output.rs
33:        let mut hasher = Blake2bVar::new(32).unwrap();

block/blockchain_length.rs
56:                .unwrap(),

state/summary.rs
151:    // let db_stats = state.db_stats.as_ref().unwrap();
191:        self.db_stats.as_ref().unwrap().clone()
249:        self.db_stats.as_ref().unwrap().clone()
290:        let memory = lines.next().unwrap().parse::<u64>()?;
291:        lines.nth(1).unwrap(); // skip header
307:    let line = lines.next().unwrap();
308:    let idx = line.find(':').unwrap();

state/mod.rs
241:            let store = IndexerStore::new(path).unwrap();
286:        let primary_path = self.indexer_store.as_ref().unwrap().db_path.clone();
444:                .for_each(|block| self.add_canonical_block_to_store(block).unwrap());
540:                    .unwrap()
580:            let max_length = dangling_branch.best_tip().unwrap().blockchain_length;
636:                let branch_to_update = self.dangling_branches.get_mut(index).unwrap();
683:        let (id, block) = self.root_branch.best_tip_with_id().unwrap();
722:        self.root_branch.branches.get(node_id).unwrap().data()
1041:            .unwrap()
1099:            .unwrap()
1146:            db_stats: db_stats_str.map(|s| DbStats::from_str(&format!("{mem}\n{s}")).unwrap()),
1188:            db_stats: db_stats_str.map(|s| DbStats::from_str(&format!("{mem}\n{s}")).unwrap()),

bin/mina-indexer.rs
142:                .unwrap();

store.rs
625:            .map(|bytes| Ledger::from_str(&String::from_utf8(bytes).unwrap()).unwrap())
648:            .map(|bytes| Ledger::from_str(&String::from_utf8(bytes).unwrap()).unwrap())
700:        let event = event.map(|bytes| serde_json::from_slice(&bytes).unwrap());
702:        trace!("Getting event {seq_num}: {:?}", event.clone().unwrap());
1042:            .unwrap()
1043:            .unwrap()
1049:            .unwrap()
1050:            .unwrap()
1056:            .unwrap()
1057:            .unwrap()
1063:            .unwrap()
1064:            .unwrap()
1070:            .unwrap()
1071:            .unwrap()

snark_work/mod.rs
123:        write!(f, "{}", serde_json::to_string_pretty(&json).unwrap())
130:        write!(f, "{}", serde_json::to_string_pretty(&json).unwrap())
148:                        Value::Number(Number::from((num * dec!(1_000_000_000)).to_u64().unwrap()))

canonicity/canonical_chain_discovery.rs
55:        let mut curr_length = extract_block_height_or_max(paths.first().unwrap());
74:            .unwrap_or(length_start_indices_and_diffs.last().unwrap().0);
99:        let (mut curr_length_idx, mut curr_start_idx) = canonical_tip_opt.unwrap();

ipc.rs
110:    let command = buffers.next().unwrap();
111:    let command_string = String::from_utf8(command.to_vec()).unwrap();
114:            let pk_buffer = buffers.next().unwrap();
152:            let verbose: bool = String::from_utf8(buffers.next().unwrap().to_vec())?.parse()?;
153:            let path = String::from_utf8(buffers.next().unwrap().to_vec())?;
195:            let state_hash = String::from_utf8(buffers.next().unwrap().to_vec())?;
196:            let verbose: bool = String::from_utf8(buffers.next().unwrap().to_vec())?.parse()?;
197:            let path = String::from_utf8(buffers.next().unwrap().to_vec())?;
241:            let height: u32 = String::from_utf8(buffers.next().unwrap().to_vec())?.parse()?;
242:            let verbose: bool = String::from_utf8(buffers.next().unwrap().to_vec())?.parse()?;
243:            let path = String::from_utf8(buffers.next().unwrap().to_vec())?;
305:            let slot: u32 = String::from_utf8(buffers.next().unwrap().to_vec())?.parse()?;
306:            let verbose: bool = String::from_utf8(buffers.next().unwrap().to_vec())?.parse()?;
307:            let path = String::from_utf8(buffers.next().unwrap().to_vec())?;
369:            let pk = String::from_utf8(buffers.next().unwrap().to_vec())?;
370:            let verbose: bool = String::from_utf8(buffers.next().unwrap().to_vec())?.parse()?;
371:            let path = String::from_utf8(buffers.next().unwrap().to_vec())?;
435:            let num = String::from_utf8(buffers.next().unwrap().to_vec())?.parse::<u32>()?;
436:            let verbose = String::from_utf8(buffers.next().unwrap().to_vec())?.parse()?;
438:                String::from_utf8(buffers.next().unwrap().to_vec())?.into();
442:                    let hash = String::from_utf8(buffers.next().unwrap().to_vec())?;
450:                let path = String::from_utf8(buffers.next().unwrap().to_vec())?;
534:            let path: PathBuf = String::from_utf8(buffers.next().unwrap().to_vec())?
559:                    let path = String::from_utf8(buffers.next().unwrap().to_vec())?;
592:            let hash = String::from_utf8(buffers.next().unwrap().to_vec())?;
593:            let path = String::from_utf8(buffers.next().unwrap().to_vec())?;
658:            let height = String::from_utf8(buffers.next().unwrap().to_vec())?.parse::<u32>()?;
659:            let path = String::from_utf8(buffers.next().unwrap().to_vec())?;
688:                            best_tip_missing_from_db().unwrap()
720:            let pk = String::from_utf8(buffers.next().unwrap().to_vec())?;
721:            let path = String::from_utf8(buffers.next().unwrap().to_vec())?;
756:            let state_hash = String::from_utf8(buffers.next().unwrap().to_vec())?;
757:            let path = String::from_utf8(buffers.next().unwrap().to_vec())?;
778:                                std::fs::write(&path, snarks_str).unwrap();
801:            let verbose = String::from_utf8(buffers.next().unwrap().to_vec())?.parse::<bool>()?;
802:            let json = String::from_utf8(buffers.next().unwrap().to_vec())?.parse::<bool>()?;
803:            let path = String::from_utf8(buffers.next().unwrap().to_vec())?;
822:                        std::fs::write(&path, summary_str).unwrap();
833:            let pk = String::from_utf8(buffers.next().unwrap().to_vec())?;
834:            let verbose = String::from_utf8(buffers.next().unwrap().to_vec())?.parse::<bool>()?;
836:                String::from_utf8(buffers.next().unwrap().to_vec())?.into();
838:                let raw = String::from_utf8(buffers.next().unwrap().to_vec())?;
844:                        best_tip_missing_from_db().unwrap().into()
859:                let path = String::from_utf8(buffers.next().unwrap().to_vec())?;
891:            let tx_hash = String::from_utf8(buffers.next().unwrap().to_vec())?;
892:            let verbose = String::from_utf8(buffers.next().unwrap().to_vec())?
911:            let state_hash = String::from_utf8(buffers.next().unwrap().to_vec())?;
912:            let verbose = String::from_utf8(buffers.next().unwrap().to_vec())?
976:    /// Always returns `Some`, safe to `.unwrap()`
995:            serde_json::to_string(input).unwrap()

state/branch.rs
54:        let root = branches.insert(Node::new(root_block), AsRoot).unwrap();
104:            .unwrap()
107:            let state_hash = &self.branches.get(ancestor_id).unwrap().data().state_hash;
145:        let best_tip_id = self.leaf_node_id(best_tip).unwrap();
147:        for ancestor_id in self.branches.ancestor_ids(&best_tip_id).unwrap().cloned() {
158:        let new_root_id = new_root_id.unwrap();
159:        let prune_point_id = prune_point_id.unwrap();
165:            .unwrap()
172:                    .unwrap();
179:            .unwrap();
183:            .remove_node(self.branches.root_node_id().unwrap().clone(), DropChildren)
184:            .unwrap();
187:        self.branches.move_node(&new_root_id, ToRoot).unwrap();
190:        let n = self.branches.get(&new_root_id).unwrap().data().height;
194:            .unwrap()
198:            let node = self.branches.get_mut(&node_id).unwrap();
209:            block.state_hash == self.branches.get(node_id).unwrap().data().state_hash
218:        let (merged_tip_id, _) = incoming.best_tip_with_id().unwrap();
319:        self.branches.get(&self.root).unwrap().data()
326:            let node = self.branches.get(&node_id).unwrap();
378:                    .unwrap()
404:            .traverse_post_order(self.branches.root_node_id().unwrap())
405:            .unwrap()

web/rest/blockchain.rs
49:        Self(versioned.to_base58_string().unwrap())
54:    let date_time = DateTime::from_timestamp_millis(millis).unwrap();
66:    let date_time = millis_to_date_string(best_tip.timestamp().try_into().unwrap());
189:                let body = serde_json::to_string_pretty(summary).unwrap();

ledger/account/mod.rs
125:    dec.set_scale(MINA_SCALE).unwrap();

web/rest/blocks.rs
49:        let body = serde_json::to_string(&best_chain).unwrap();
64:        let body = serde_json::to_string(block).unwrap();

command/signed.rs
124:        let mut hasher = blake2::Blake2bVar::new(32).unwrap();
126:        hasher.write_all(binprot_bytes_bs58.as_bytes()).unwrap();
321:        write!(f, "{}", to_string_pretty(&json).unwrap())
330:        write!(f, "{}", to_string_pretty(&json).unwrap())
344:        write!(f, "{}", to_string_pretty(&json).unwrap())
477:        let precomputed_block = PrecomputedBlock::parse_file(&block_file).unwrap();

web/rest/accounts.rs
24:                let body = serde_json::to_string(account).unwrap();

protocol/bin_prot/loose_deserializer.rs
136:                                let element_rule = rules.first().unwrap();
224:                    index: summand.index.try_into().unwrap(),
241:        to_writer(&mut buf, &enum_data).unwrap();

command/mod.rs
400:        write!(f, "{}", to_string_pretty(&json).unwrap())
424:        write!(f, "{}", to_string_pretty(&json).unwrap())
503:        .unwrap();
507:            .unwrap();
677:                                let nanomina = x.clone().to_string().parse::<u64>().unwrap();

ledger/genesis.rs
68:        let block_creator = Account::from(GenesisBlock::new().unwrap());
127:            root.ledger.accounts.first().unwrap().pk
129:        assert_eq!(None, root.ledger.accounts.first().unwrap().delegate);
137:            .unwrap();

ledger/public_key.rs
59:        let pk = CompressedPubKey::from_address(&value.0).unwrap();
66:        PubKey::from_address(&value.0).unwrap()

ledger/mod.rs
149:        serde_json::to_string_pretty(&accounts).unwrap()
160:        serde_json::to_string(&accounts).unwrap()

protocol/bin_prot/README.md
26:  to_writer(&mut output, &val).unwrap();
29:  let de_val: Vec<i64> = from_reader(output.as_slice()).unwrap();
66:    let rule: BinProtRule = serde_json::from_str(RECORD_RULE).unwrap();
75:    let result: Value = Deserialize::deserialize(&mut de).unwrap();

protocol/bin_prot/value/layout/traverse.rs
135:        let layout: Layout = serde_json::from_str(TEST_LAYOUT).unwrap();
145:        let layout: Layout = serde_json::from_str(TEST_LAYOUT_SUM).unwrap();

jhult avatar Mar 07 '24 20:03 jhult

This is about the journey rather than the destination. Getting to the end of the long tail is likely untenable but we've improved our codebase. Closing.

trevorbernard avatar Jul 10 '24 13:07 trevorbernard