Skip to content

Commit

Permalink
minor improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
janmazak committed Dec 20, 2023
1 parent c5a932d commit dd8f241
Show file tree
Hide file tree
Showing 9 changed files with 281 additions and 190 deletions.
1 change: 0 additions & 1 deletion .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
"multiassets",
"reserialized",
"unfixable",
"UNREG",
"vacuumlabs"
]
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cardano-hw-interop-lib",
"version": "2.0.2",
"version": "2.0.3",
"files": [
"dist"
],
Expand Down
14 changes: 5 additions & 9 deletions src/errors/validationError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,10 @@ export enum ValidationErrorReason {
INTEGER_NOT_INT64 = 'Hardware wallets support integers up to int64, integers from -2^63 to 2^63-1',
UNSIGNED_INTEGER_NOT_UINT64 = 'Hardware wallets support unsigned integers up to uint64, unsigned integers from 0 to 2^64-1',
NUMBER_OF_ELEMENTS_EXCEEDS_UINT16 = 'The number of transaction elements individually must not exceed UINT16_MAX, i.e. 65535',
CERTIFICATES_MUST_HAVE_THE_SAME_TYPE_OF_STAKE_CREDENTIAL = 'All certificates included in a transaction must have the same type of stake credential',
WITHDRAWALS_MUST_HAVE_THE_SAME_TYPE_OF_STAKE_CREDENTIAL = 'All withdrawals included in a transaction must have the same type of stake credential',
CERTIFICATES_AND_WITHDRAWALS_STAKE_CREDENTIAL_TYPES_MUST_BE_CONSISTENT = 'The stake credential type of certificates must be consistent with the type used for withdrawals',
POOL_REGISTRATION_CERTIFICATE_WITH_OTHER_CERTIFICATES = 'If a transaction contains a pool registration certificate, then it must not contain any other certificate',
POOL_REGISTRATION_CERTIFICATE_WITH_WITHDRAWALS = 'If a transaction contains a pool registration certificate, then it must not contain any withdrawal',
POOL_REGISTRATION_CERTIFICATE_WITH_MINT_ENTRY = 'If a transaction contains a pool registration certificate, then it must not contain mint entry',
TOO_MANY_VOTING_PROCEDURES = 'Only a single voter and a single vote is allowed in voting procedures',

// Fixable validation errors
CBOR_IS_NOT_CANONICAL = 'CBOR is not canonical',
Expand All @@ -32,6 +30,7 @@ const FIXABLE = true
const UNFIXABLE = false

const validationErrorFixability: Record<ValidationErrorReason, boolean> = {
// unfixable
[ValidationErrorReason.UNSUPPORTED_TX_UPDATE]: UNFIXABLE,
[ValidationErrorReason.UNSUPPORTED_TX_PROPOSAL_PROCEDURES]: UNFIXABLE,
[ValidationErrorReason.UNSUPPORTED_CERTIFICATE_GENESIS_KEY_DELEGATION]:
Expand All @@ -46,18 +45,15 @@ const validationErrorFixability: Record<ValidationErrorReason, boolean> = {
[ValidationErrorReason.INTEGER_NOT_INT64]: UNFIXABLE,
[ValidationErrorReason.UNSIGNED_INTEGER_NOT_UINT64]: UNFIXABLE,
[ValidationErrorReason.NUMBER_OF_ELEMENTS_EXCEEDS_UINT16]: UNFIXABLE,
[ValidationErrorReason.CERTIFICATES_MUST_HAVE_THE_SAME_TYPE_OF_STAKE_CREDENTIAL]:
UNFIXABLE,
[ValidationErrorReason.WITHDRAWALS_MUST_HAVE_THE_SAME_TYPE_OF_STAKE_CREDENTIAL]:
UNFIXABLE,
[ValidationErrorReason.CERTIFICATES_AND_WITHDRAWALS_STAKE_CREDENTIAL_TYPES_MUST_BE_CONSISTENT]:
UNFIXABLE,
[ValidationErrorReason.POOL_REGISTRATION_CERTIFICATE_WITH_OTHER_CERTIFICATES]:
UNFIXABLE,
[ValidationErrorReason.POOL_REGISTRATION_CERTIFICATE_WITH_WITHDRAWALS]:
UNFIXABLE,
[ValidationErrorReason.POOL_REGISTRATION_CERTIFICATE_WITH_MINT_ENTRY]:
UNFIXABLE,
[ValidationErrorReason.TOO_MANY_VOTING_PROCEDURES]: UNFIXABLE,

// fixable
[ValidationErrorReason.CBOR_IS_NOT_CANONICAL]: FIXABLE,
[ValidationErrorReason.OPTIONAL_EMPTY_LISTS_AND_MAPS_MUST_NOT_BE_INCLUDED]:
FIXABLE,
Expand Down
74 changes: 39 additions & 35 deletions src/txParsers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ import {
DRepType,
KeyHashDRep,
ScriptHashDRep,
AlwaysAbstainDRep,
AlwaysNoConfidenceDRep,
AbstainDRep,
NoConfidenceDRep,
StakeAndVoteDelegationCertificate,
StakeRegistrationAndDelegationCertificate,
StakeRegistrationWithVoteDelegationCertificate,
Expand Down Expand Up @@ -129,6 +129,8 @@ import {Tagged} from 'cbor'

// ======================== universal parsers / parsers for CDDL data types

// parsers for tx body elements and certain CDDL "datatypes" are exported

const doNotParse: Parser<Unparsed> = (data: unknown) => data

export const parseCoin = createParser(parseUint, ParseErrorReason.INVALID_COIN)
Expand All @@ -150,7 +152,7 @@ const parseCredentialType = (
const parseKeyCredential = (data: unknown[]): WithoutType<KeyCredential> => {
validate(data.length === 1, ParseErrorReason.INVALID_CREDENTIAL)
return {
hash: parseBufferOfLength(
keyHash: parseBufferOfLength(
data[0],
KEY_HASH_LENGTH,
ParseErrorReason.INVALID_CREDENTIAL_KEY_HASH,
Expand All @@ -163,7 +165,7 @@ const parseScriptCredential = (
): WithoutType<ScriptCredential> => {
validate(data.length === 1, ParseErrorReason.INVALID_CREDENTIAL)
return {
hash: parseBufferOfLength(
scriptHash: parseBufferOfLength(
data[0],
SCRIPT_HASH_LENGTH,
ParseErrorReason.INVALID_CREDENTIAL_SCRIPT_HASH,
Expand Down Expand Up @@ -203,7 +205,7 @@ export const parseInputs = createParser(
ParseErrorReason.INVALID_TX_INPUTS,
)

export const parseRewardAccount = createParser(
const parseRewardAccount = createParser(
parseBufferOfLength,
REWARD_ACCOUNT_LENGTH,
ParseErrorReason.INVALID_REWARD_ACCOUNT,
Expand Down Expand Up @@ -500,7 +502,7 @@ const parsePoolMetadata = (unparsedPoolMetadata: unknown): PoolMetadata => {
return {url, metadataHash}
}

export const parsePoolParams = (unparsedPoolParams: unknown): PoolParams => {
const parsePoolParams = (unparsedPoolParams: unknown): PoolParams => {
const [
operator,
vrfKeyHash,
Expand Down Expand Up @@ -579,17 +581,15 @@ const parseScriptHashDRep = (data: unknown[]): WithoutType<ScriptHashDRep> => {
}
}

const parseAlwaysAbstainDRep = (
data: unknown[],
): WithoutType<AlwaysAbstainDRep> => {
const parseAbstainDRep = (data: unknown[]): WithoutType<AbstainDRep> => {
// nothing to parse
validate(data.length === 0, ParseErrorReason.INVALID_DREP)
return {}
}

const parseAlwaysNoConfidenceDRep = (
const parseNoConfidenceDRep = (
data: unknown[],
): WithoutType<AlwaysNoConfidenceDRep> => {
): WithoutType<NoConfidenceDRep> => {
// nothing to parse
validate(data.length === 0, ParseErrorReason.INVALID_DREP)
return {}
Expand Down Expand Up @@ -619,8 +619,8 @@ export const parseDRep = createParser(
parseDRepType,
parseKeyHashDRep,
parseScriptHashDRep,
parseAlwaysAbstainDRep,
parseAlwaysNoConfidenceDRep,
parseAbstainDRep,
parseNoConfidenceDRep,
)

const parseCertificateType = (
Expand Down Expand Up @@ -683,20 +683,23 @@ const parsePoolRetirementCertificate = (
}
}

// removed in Conway, but we keep it here because it might appear
// in erroneous / previously-built transactions
const parseGenesisKeyDelegation = (
data: unknown[],
): WithoutType<GenesisKeyDelegation> => ({
restOfData: data,
})

// TODO these are removed in Conway
// removed in Conway, but we keep it here because it might appear
// in erroneous / previously-built transactions
const parseMoveInstantaneousRewardsCertificate = (
data: unknown[],
): WithoutType<MoveInstantaneousRewardsCertificate> => ({
restOfData: data,
})

const parseStakeRegCertificate = (
const parseStakeRegistrationConwayCertificate = (
data: unknown[],
): WithoutType<StakeRegistrationConwayCertificate> => {
validate(data.length === 2, ParseErrorReason.INVALID_CERTIFICATE)
Expand All @@ -706,7 +709,7 @@ const parseStakeRegCertificate = (
}
}

const parseStakeUnregCertificate = (
const parseStakeDeregistrationConwayCertificate = (
data: unknown[],
): WithoutType<StakeDeregistrationConwayCertificate> => {
validate(data.length === 2, ParseErrorReason.INVALID_CERTIFICATE)
Expand All @@ -716,7 +719,7 @@ const parseStakeUnregCertificate = (
}
}

const parseVoteDelegCertificate = (
const parseVoteDelegationCertificate = (
data: unknown[],
): WithoutType<VoteDelegationCertificate> => {
validate(data.length === 2, ParseErrorReason.INVALID_CERTIFICATE)
Expand All @@ -726,7 +729,7 @@ const parseVoteDelegCertificate = (
}
}

const parseStakeVoteDelegCertificate = (
const parseStakeAndVoteDelegationCertificate = (
data: unknown[],
): WithoutType<StakeAndVoteDelegationCertificate> => {
validate(data.length === 3, ParseErrorReason.INVALID_CERTIFICATE)
Expand All @@ -737,7 +740,7 @@ const parseStakeVoteDelegCertificate = (
}
}

const parseStakeRegDelegCertificate = (
const parseStakeRegistrationAndDelegationCertificate = (
data: unknown[],
): WithoutType<StakeRegistrationAndDelegationCertificate> => {
validate(data.length === 3, ParseErrorReason.INVALID_CERTIFICATE)
Expand All @@ -748,7 +751,7 @@ const parseStakeRegDelegCertificate = (
}
}

const parseVoteRegDelegCertificate = (
const parseStakeRegistrationWithVoteDelegationCertificate = (
data: unknown[],
): WithoutType<StakeRegistrationWithVoteDelegationCertificate> => {
validate(data.length === 3, ParseErrorReason.INVALID_CERTIFICATE)
Expand All @@ -759,7 +762,7 @@ const parseVoteRegDelegCertificate = (
}
}

const parseStakeVoteRegDelegCertificate = (
const parseStakeRegistrationWithStakeAndVoteDelegationCertificate = (
data: unknown[],
): WithoutType<StakeRegistrationWithStakeAndVoteDelegationCertificate> => {
validate(data.length === 4, ParseErrorReason.INVALID_CERTIFICATE)
Expand All @@ -771,7 +774,7 @@ const parseStakeVoteRegDelegCertificate = (
}
}

const parseAuthCommitteeHotCertificate = (
const parseAuthorizeCommitteeHotCertificate = (
data: unknown[],
): WithoutType<AuthorizeCommitteeHotCertificate> => {
validate(data.length === 2, ParseErrorReason.INVALID_CERTIFICATE)
Expand All @@ -791,7 +794,7 @@ const parseResignCommitteeColdCertificate = (
}
}

const parseDRepRegCertificate = (
const parseDRepRegistrationCertificate = (
data: unknown[],
): WithoutType<DRepRegistrationCertificate> => {
validate(data.length === 3, ParseErrorReason.INVALID_CERTIFICATE)
Expand All @@ -802,7 +805,7 @@ const parseDRepRegCertificate = (
}
}

const parseDRepUnregCertificate = (
const parseDRepDeregistrationCertificate = (
data: unknown[],
): WithoutType<DRepDeregistrationCertificate> => {
validate(data.length === 2, ParseErrorReason.INVALID_CERTIFICATE)
Expand Down Expand Up @@ -833,17 +836,17 @@ export const parseCertificate = createParser(
parsePoolRetirementCertificate,
parseGenesisKeyDelegation,
parseMoveInstantaneousRewardsCertificate,
parseStakeRegCertificate,
parseStakeUnregCertificate,
parseVoteDelegCertificate,
parseStakeVoteDelegCertificate,
parseStakeRegDelegCertificate,
parseVoteRegDelegCertificate,
parseStakeVoteRegDelegCertificate,
parseAuthCommitteeHotCertificate,
parseStakeRegistrationConwayCertificate,
parseStakeDeregistrationConwayCertificate,
parseVoteDelegationCertificate,
parseStakeAndVoteDelegationCertificate,
parseStakeRegistrationAndDelegationCertificate,
parseStakeRegistrationWithVoteDelegationCertificate,
parseStakeRegistrationWithStakeAndVoteDelegationCertificate,
parseAuthorizeCommitteeHotCertificate,
parseResignCommitteeColdCertificate,
parseDRepRegCertificate,
parseDRepUnregCertificate,
parseDRepRegistrationCertificate,
parseDRepDeregistrationCertificate,
parseDRepUpdateCertificate,
)

Expand Down Expand Up @@ -1050,7 +1053,7 @@ const parseVoteOption = (unparsed: unknown): VoteOption => {
return unparsed
}

const parseVotingProcedure = (unparsed: unknown): VotingProcedure => {
export const parseVotingProcedure = (unparsed: unknown): VotingProcedure => {
const [voteOption, anchor] = parseTuple(
unparsed,
ParseErrorReason.INVALID_VOTING_PROCEDURE,
Expand Down Expand Up @@ -1118,6 +1121,7 @@ export const parseProposalProcedure = (
anchor,
}
}

export const parseProposalProcedures = createParser(
parseCddlNonEmptyOrderedSet,
parseProposalProcedure,
Expand Down
27 changes: 15 additions & 12 deletions src/txSerializers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
Uint,
Int,
CddlSetBase,
CredentialType,
} from './types'
import {
BabbageTransactionOutputKeys,
Expand All @@ -49,7 +50,7 @@ export const identity = <T>(x: T): T => x

export type Serializer<T> = (data: T) => unknown

const serializeCddlSetBase = <T>(
export const serializeCddlSetBase = <T>(
set: CddlSetBase<T>,
serializeEntry: Serializer<T>,
) => {
Expand All @@ -61,7 +62,7 @@ const serializeCddlSetBase = <T>(
}
}

const serializeCddlSetBaseOrUndefined = <T>(
export const serializeCddlSetBaseOrUndefined = <T>(
set: CddlSetBase<T> | undefined,
serializeEntry: Serializer<T>,
) => {
Expand All @@ -71,7 +72,6 @@ const serializeCddlSetBaseOrUndefined = <T>(
return serializeCddlSetBase(set, serializeEntry)
}

// export needed because of uniqueness check during parsing
export const serializeTxInput = (input: TransactionInput) => [
input.transactionId,
input.index,
Expand Down Expand Up @@ -178,19 +178,25 @@ const serializePoolParams = (poolParams: PoolParams) => [
poolParams.poolMetadata && serializePoolMetadata(poolParams.poolMetadata),
]

const serializeCredential = (credential: Credential) => [
credential.type,
credential.hash,
]
const serializeCredential = (credential: Credential) => {
switch (credential.type) {
case CredentialType.KEY_HASH:
return [credential.type, credential.keyHash]
case CredentialType.SCRIPT_HASH:
return [credential.type, credential.scriptHash]
default:
unreachable(credential)
}
}

const serializeDRep = (dRep: DRep) => {
switch (dRep.type) {
case DRepType.KEY_HASH:
return [dRep.type, dRep.keyHash]
case DRepType.SCRIPT_HASH:
return [dRep.type, dRep.scriptHash]
case DRepType.ALWAYS_ABSTAIN:
case DRepType.ALWAYS_NO_CONFIDENCE:
case DRepType.ABSTAIN:
case DRepType.NO_CONFIDENCE:
return [dRep.type]
default:
unreachable(dRep)
Expand All @@ -204,7 +210,6 @@ const serializeAnchor = (anchor: Anchor | null) => {
return [anchor.url, anchor.dataHash]
}

// export needed because of uniqueness check during parsing
export const serializeCertificate = (certificate: Certificate) => {
switch (certificate.type) {
case CertificateType.STAKE_REGISTRATION:
Expand Down Expand Up @@ -304,7 +309,6 @@ export const serializeCertificate = (certificate: Certificate) => {
}
}

// export needed because of uniqueness check during parsing
export const serializeCollateralInput = (collateralInput: TransactionInput) => [
collateralInput.transactionId,
collateralInput.index,
Expand Down Expand Up @@ -335,7 +339,6 @@ const serializeVotingProcedures = (ballots: VoterVotes[]) =>
]),
)

// export needed because of uniqueness check during parsing
export const serializeProposalProcedure = (procedure: ProposalProcedure) => [
procedure.deposit,
procedure.rewardAccount,
Expand Down
Loading

0 comments on commit dd8f241

Please sign in to comment.