diff --git a/packages/rs-drive-proof-verifier/src/error.rs b/packages/rs-drive-proof-verifier/src/error.rs index 3203eb73174..8c0664c8257 100644 --- a/packages/rs-drive-proof-verifier/src/error.rs +++ b/packages/rs-drive-proof-verifier/src/error.rs @@ -1,4 +1,5 @@ use dpp::ProtocolError; +use drive::grovedb::operations::proof::GroveDBProof; /// Errors #[derive(Debug, thiserror::Error)] @@ -15,6 +16,15 @@ pub enum Error { #[error("dash drive: {error}")] DriveError { error: String }, + /// GroveDB error, often for issues with proofs + #[error("grovedb: {error}")] + GroveDBError { + proof_bytes: Vec, + height: u64, + time_ms: u64, + error: String, + }, + /// Dash Protocol error #[error("dash protocol: {error}")] ProtocolError { error: String }, diff --git a/packages/rs-drive-proof-verifier/src/proof.rs b/packages/rs-drive-proof-verifier/src/proof.rs index 3685df1779d..6399a3e691d 100644 --- a/packages/rs-drive-proof-verifier/src/proof.rs +++ b/packages/rs-drive-proof-verifier/src/proof.rs @@ -274,8 +274,14 @@ impl FromProof for Identity { id.into_buffer(), platform_version, ) - .map_err(|e| Error::DriveError { - error: e.to_string(), + .map_err(|e| match e { + drive::error::Error::GroveDB(e) => Error::GroveDBError { + proof_bytes: proof.grovedb_proof.clone(), + height: mtd.height, + time_ms: mtd.time_ms, + error: e.to_string(), + }, + _ => e.into(), })?; verify_tenderdash_proof(proof, mtd, &root_hash, provider)?; @@ -324,8 +330,14 @@ impl FromProof for Identity { public_key_hash, platform_version, ) - .map_err(|e| Error::DriveError { - error: e.to_string(), + .map_err(|e| match e { + drive::error::Error::GroveDB(e) => Error::GroveDBError { + proof_bytes: proof.grovedb_proof.clone(), + height: mtd.height, + time_ms: mtd.time_ms, + error: e.to_string(), + }, + _ => e.into(), })?; verify_tenderdash_proof(proof, mtd, &root_hash, provider)?; @@ -391,8 +403,14 @@ impl FromProof for IdentityPublicKeys { false, platform_version, ) - .map_err(|e| Error::DriveError { - error: e.to_string(), + .map_err(|e| match e { + drive::error::Error::GroveDB(e) => Error::GroveDBError { + proof_bytes: proof.grovedb_proof.clone(), + height: mtd.height, + time_ms: mtd.time_ms, + error: e.to_string(), + }, + _ => e.into(), })?; let maybe_keys: Option = if let Some(identity) = maybe_identity { @@ -520,8 +538,14 @@ impl FromProof for IdentityNonceFetcher { false, platform_version, ) - .map_err(|e| Error::DriveError { - error: e.to_string(), + .map_err(|e| match e { + drive::error::Error::GroveDB(e) => Error::GroveDBError { + proof_bytes: proof.grovedb_proof.clone(), + height: mtd.height, + time_ms: mtd.time_ms, + error: e.to_string(), + }, + _ => e.into(), })?; verify_tenderdash_proof(proof, mtd, &root_hash, provider)?; @@ -577,8 +601,14 @@ impl FromProof for IdentityContractNo false, platform_version, ) - .map_err(|e| Error::DriveError { - error: e.to_string(), + .map_err(|e| match e { + drive::error::Error::GroveDB(e) => Error::GroveDBError { + proof_bytes: proof.grovedb_proof.clone(), + height: mtd.height, + time_ms: mtd.time_ms, + error: e.to_string(), + }, + _ => e.into(), })?; verify_tenderdash_proof(proof, mtd, &root_hash, provider)?; @@ -627,8 +657,14 @@ impl FromProof for IdentityBalance { false, platform_version, ) - .map_err(|e| Error::DriveError { - error: e.to_string(), + .map_err(|e| match e { + drive::error::Error::GroveDB(e) => Error::GroveDBError { + proof_bytes: proof.grovedb_proof.clone(), + height: mtd.height, + time_ms: mtd.time_ms, + error: e.to_string(), + }, + _ => e.into(), })?; verify_tenderdash_proof(proof, mtd, &root_hash, provider)?; @@ -678,8 +714,14 @@ impl FromProof for IdentityBalances { &identity_ids, platform_version, ) - .map_err(|e| Error::DriveError { - error: e.to_string(), + .map_err(|e| match e { + drive::error::Error::GroveDB(e) => Error::GroveDBError { + proof_bytes: proof.grovedb_proof.clone(), + height: mtd.height, + time_ms: mtd.time_ms, + error: e.to_string(), + }, + _ => e.into(), })?; verify_tenderdash_proof(proof, mtd, &root_hash, provider)?; @@ -726,8 +768,14 @@ impl FromProof for IdentityBalan false, platform_version, ) - .map_err(|e| Error::DriveError { - error: e.to_string(), + .map_err(|e| match e { + drive::error::Error::GroveDB(e) => Error::GroveDBError { + proof_bytes: proof.grovedb_proof.clone(), + height: mtd.height, + time_ms: mtd.time_ms, + error: e.to_string(), + }, + _ => e.into(), })?; verify_tenderdash_proof(proof, mtd, &root_hash, provider)?; @@ -775,8 +823,14 @@ impl FromProof for DataContract { id.into_buffer(), platform_version, ) - .map_err(|e| Error::DriveError { - error: e.to_string(), + .map_err(|e| match e { + drive::error::Error::GroveDB(e) => Error::GroveDBError { + proof_bytes: proof.grovedb_proof.clone(), + height: mtd.height, + time_ms: mtd.time_ms, + error: e.to_string(), + }, + _ => e.into(), })?; verify_tenderdash_proof(proof, mtd, &root_hash, provider)?; @@ -827,8 +881,14 @@ impl FromProof for DataContracts { ids.as_slice(), platform_version, ) - .map_err(|e| Error::DriveError { - error: e.to_string(), + .map_err(|e| match e { + drive::error::Error::GroveDB(e) => Error::GroveDBError { + proof_bytes: proof.grovedb_proof.clone(), + height: mtd.height, + time_ms: mtd.time_ms, + error: e.to_string(), + }, + _ => e.into(), })?; verify_tenderdash_proof(proof, mtd, &root_hash, provider)?; @@ -896,8 +956,14 @@ impl FromProof for DataContractHistory offset, platform_version, ) - .map_err(|e| Error::DriveError { - error: e.to_string(), + .map_err(|e| match e { + drive::error::Error::GroveDB(e) => Error::GroveDBError { + proof_bytes: proof.grovedb_proof.clone(), + height: mtd.height, + time_ms: mtd.time_ms, + error: e.to_string(), + }, + _ => e.into(), })?; verify_tenderdash_proof(proof, mtd, &root_hash, provider)?; @@ -935,17 +1001,17 @@ impl FromProof for StateTransitionPro error: e.to_string(), })?; - let metadata = response.metadata().or(Err(Error::EmptyResponseMetadata))?; + let mtd = response.metadata().or(Err(Error::EmptyResponseMetadata))?; - if metadata.epoch > MAX_EPOCH as u32 { - return Err(drive::error::Error::Proof(ProofError::InvalidMetadata(format!("platform returned an epoch {} that was higher that maximum of a 16 bit integer", metadata.epoch))).into()); + if mtd.epoch > MAX_EPOCH as u32 { + return Err(drive::error::Error::Proof(ProofError::InvalidMetadata(format!("platform returned an epoch {} that was higher that maximum of a 16 bit integer", mtd.epoch))).into()); } let block_info = BlockInfo { - time_ms: metadata.time_ms, - height: metadata.height, - core_height: metadata.core_chain_locked_height, - epoch: (metadata.epoch as u16).try_into()?, + time_ms: mtd.time_ms, + height: mtd.height, + core_height: mtd.core_chain_locked_height, + epoch: (mtd.epoch as u16).try_into()?, }; let contracts_provider_fn = provider.as_contract_lookup_fn(); @@ -957,13 +1023,19 @@ impl FromProof for StateTransitionPro &contracts_provider_fn, platform_version, ) - .map_err(|e| Error::DriveError { - error: e.to_string(), + .map_err(|e| match e { + drive::error::Error::GroveDB(e) => Error::GroveDBError { + proof_bytes: proof.grovedb_proof.clone(), + height: mtd.height, + time_ms: mtd.time_ms, + error: e.to_string(), + }, + _ => e.into(), })?; - verify_tenderdash_proof(proof, metadata, &root_hash, provider)?; + verify_tenderdash_proof(proof, mtd, &root_hash, provider)?; - Ok((Some(result), metadata.clone(), proof.clone())) + Ok((Some(result), mtd.clone(), proof.clone())) } } @@ -1044,8 +1116,14 @@ impl FromProof for ExtendedEpochInfos { ascending, platform_version, ) - .map_err(|e| Error::DriveError { - error: e.to_string(), + .map_err(|e| match e { + drive::error::Error::GroveDB(e) => Error::GroveDBError { + proof_bytes: proof.grovedb_proof.clone(), + height: mtd.height, + time_ms: mtd.time_ms, + error: e.to_string(), + }, + _ => e.into(), })?; let epoch_info = epoch_info @@ -1093,7 +1171,17 @@ impl FromProof for ProtocolVersionUpgrade let mtd = response.metadata().or(Err(Error::EmptyResponseMetadata))?; let (root_hash, objects) = - Drive::verify_upgrade_state(&proof.grovedb_proof, platform_version)?; + Drive::verify_upgrade_state(&proof.grovedb_proof, platform_version).map_err( + |e| match e { + drive::error::Error::GroveDB(e) => Error::GroveDBError { + proof_bytes: proof.grovedb_proof.clone(), + height: mtd.height, + time_ms: mtd.time_ms, + error: e.to_string(), + }, + _ => e.into(), + }, + )?; verify_tenderdash_proof(proof, mtd, &root_hash, provider)?; @@ -1145,7 +1233,16 @@ impl FromProof for MasternodeProtoco start_pro_tx_hash, try_u32_to_u16(request_v0.count)?, platform_version, - )?; + ) + .map_err(|e| match e { + drive::error::Error::GroveDB(e) => Error::GroveDBError { + proof_bytes: proof.grovedb_proof.clone(), + height: mtd.height, + time_ms: mtd.time_ms, + error: e.to_string(), + }, + _ => e.into(), + })?; verify_tenderdash_proof(proof, mtd, &root_hash, provider)?; @@ -1250,9 +1347,16 @@ where let (root_hash, documents) = request .verify_proof(&proof.grovedb_proof, platform_version) - .map_err(|e| Error::DriveError { - error: e.to_string(), + .map_err(|e| match e { + drive::error::Error::GroveDB(e) => Error::GroveDBError { + proof_bytes: proof.grovedb_proof.clone(), + height: mtd.height, + time_ms: mtd.time_ms, + error: e.to_string(), + }, + _ => e.into(), })?; + let documents = documents .into_iter() .map(|d| (d.id(), Some(d))) @@ -1333,8 +1437,14 @@ impl FromProof for IdentitiesContrac false, platform_version, ) - .map_err(|e| Error::DriveError { - error: e.to_string(), + .map_err(|e| match e { + drive::error::Error::GroveDB(e) => Error::GroveDBError { + proof_bytes: proof.grovedb_proof.clone(), + height: mtd.height, + time_ms: mtd.time_ms, + error: e.to_string(), + }, + _ => e.into(), })?; verify_tenderdash_proof(proof, mtd, &root_hash, provider)?; @@ -1375,8 +1485,14 @@ impl FromProof for ContestedResources { let (root_hash, items) = resolved_request .verify_contests_proof(&proof.grovedb_proof, platform_version) - .map_err(|e| Error::DriveError { - error: e.to_string(), + .map_err(|e| match e { + drive::error::Error::GroveDB(e) => Error::GroveDBError { + proof_bytes: proof.grovedb_proof.clone(), + height: mtd.height, + time_ms: mtd.time_ms, + error: e.to_string(), + }, + _ => e.into(), })?; verify_tenderdash_proof(proof, mtd, &root_hash, provider)?; @@ -1419,8 +1535,14 @@ impl FromProof for Contenders { let (root_hash, contested_resource_vote_state) = resolved_request .verify_vote_poll_vote_state_proof(&proof.grovedb_proof, platform_version) - .map_err(|e| Error::DriveError { - error: e.to_string(), + .map_err(|e| match e { + drive::error::Error::GroveDB(e) => Error::GroveDBError { + proof_bytes: proof.grovedb_proof.clone(), + height: mtd.height, + time_ms: mtd.time_ms, + error: e.to_string(), + }, + _ => e.into(), })?; verify_tenderdash_proof(proof, mtd, &root_hash, provider)?; @@ -1473,8 +1595,14 @@ impl FromProof for Voters { let (root_hash, voters) = resolved_request .verify_vote_poll_votes_proof(&proof.grovedb_proof, platform_version) - .map_err(|e| Error::DriveError { - error: e.to_string(), + .map_err(|e| match e { + drive::error::Error::GroveDB(e) => Error::GroveDBError { + proof_bytes: proof.grovedb_proof.clone(), + height: mtd.height, + time_ms: mtd.time_ms, + error: e.to_string(), + }, + _ => e.into(), })?; verify_tenderdash_proof(proof, mtd, &root_hash, provider)?; @@ -1519,8 +1647,14 @@ impl FromProof for ResourceV &contract_provider_fn, platform_version, ) - .map_err(|e| Error::DriveError { - error: e.to_string(), + .map_err(|e| match e { + drive::error::Error::GroveDB(e) => Error::GroveDBError { + proof_bytes: proof.grovedb_proof.clone(), + height: mtd.height, + time_ms: mtd.time_ms, + error: e.to_string(), + }, + _ => e.into(), })?; verify_tenderdash_proof(proof, mtd, &root_hash, provider)?; @@ -1563,8 +1697,14 @@ impl FromProof for VotePollsGroupedByTim &proof.grovedb_proof, platform_version, ) - .map_err(|e| Error::DriveError { - error: e.to_string(), + .map_err(|e| match e { + drive::error::Error::GroveDB(e) => Error::GroveDBError { + proof_bytes: proof.grovedb_proof.clone(), + height: mtd.height, + time_ms: mtd.time_ms, + error: e.to_string(), + }, + _ => e.into(), })?; verify_tenderdash_proof(proof, mtd, &root_hash, provider)?; @@ -1602,14 +1742,23 @@ impl FromProof for PrefundedSpe let proof = response.proof().or(Err(Error::NoProofInResult))?; + let mtd = response.metadata().or(Err(Error::EmptyResponseMetadata))?; + let (root_hash, balance) = Drive::verify_specialized_balance( &proof.grovedb_proof, balance_id.into_buffer(), false, platform_version, - )?; - - let mtd = response.metadata().or(Err(Error::EmptyResponseMetadata))?; + ) + .map_err(|e| match e { + drive::error::Error::GroveDB(e) => Error::GroveDBError { + proof_bytes: proof.grovedb_proof.clone(), + height: mtd.height, + time_ms: mtd.time_ms, + error: e.to_string(), + }, + _ => e.into(), + })?; verify_tenderdash_proof(proof, mtd, &root_hash, provider)?; @@ -1707,8 +1856,14 @@ impl FromProof for TotalCreditsInPla mtd.core_chain_locked_height, platform_version, ) - .map_err(|e| Error::DriveError { - error: e.to_string(), + .map_err(|e| match e { + drive::error::Error::GroveDB(e) => Error::GroveDBError { + proof_bytes: proof.grovedb_proof.clone(), + height: mtd.height, + time_ms: mtd.time_ms, + error: e.to_string(), + }, + _ => e.into(), })?; verify_tenderdash_proof(proof, mtd, &root_hash, provider)?; @@ -1754,8 +1909,14 @@ impl FromProof for Propose ProposerQueryType::ByIds(ids), platform_version, ) - .map_err(|e| Error::DriveError { - error: e.to_string(), + .map_err(|e| match e { + drive::error::Error::GroveDB(e) => Error::GroveDBError { + proof_bytes: proof.grovedb_proof.clone(), + height: mtd.height, + time_ms: mtd.time_ms, + error: e.to_string(), + }, + _ => e.into(), })?; verify_tenderdash_proof(proof, mtd, &root_hash, provider)?; @@ -1818,8 +1979,14 @@ impl FromProof for Propo ProposerQueryType::ByRange(limit.map(|l| l as u16), formatted_start), platform_version, ) - .map_err(|e| Error::DriveError { - error: e.to_string(), + .map_err(|e| match e { + drive::error::Error::GroveDB(e) => Error::GroveDBError { + proof_bytes: proof.grovedb_proof.clone(), + height: mtd.height, + time_ms: mtd.time_ms, + error: e.to_string(), + }, + _ => e.into(), })?; verify_tenderdash_proof(proof, mtd, &root_hash, provider)?;