Skip to content

Commit 41e2158

Browse files
authored
Merge pull request #1124 from input-output-hk/fix/LW-9418
LW-9418 fixes for Conway era e2e tests
2 parents b968b88 + c36a4d2 commit 41e2158

File tree

11 files changed

+88
-26
lines changed

11 files changed

+88
-26
lines changed

packages/cardano-services-client/src/TxSubmitProvider/TxSubmitApiProvider.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,11 @@ export class TxSubmitApiProvider implements TxSubmitProvider {
4343

4444
if (typeof status === 'number' && status >= 400 && status < 500) this.#healthStatus = true;
4545

46-
throw new ProviderError(ProviderFailure.BadRequest, mapCardanoTxSubmitError(data), data as string);
46+
throw new ProviderError(
47+
ProviderFailure.BadRequest,
48+
mapCardanoTxSubmitError(data),
49+
typeof data === 'string' ? data : JSON.stringify(data)
50+
);
4751
}
4852

4953
throw new ProviderError(ProviderFailure.Unknown, error, 'submitting tx');

packages/core/src/Cardano/util/computeImplicitCoin.ts

+17-7
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ const computeShellyDeposits = (
7777
const computeConwayDeposits = (
7878
certificates: Cardano.Certificate[],
7979
rewardAccounts: Cardano.RewardAccount[],
80-
dRepKeyHash?: Crypto.Ed25519KeyHashHex
80+
dRepKeyHash?: Crypto.Ed25519KeyHashHex,
81+
proposalProcedures?: Cardano.ProposalProcedure[]
8182
): { deposit: Cardano.Lovelace; reclaimDeposit: Cardano.Lovelace } => {
8283
let deposit = 0n;
8384
let reclaimDeposit = 0n;
@@ -108,6 +109,8 @@ const computeConwayDeposits = (
108109
}
109110
}
110111

112+
if (proposalProcedures) for (const proposal of proposalProcedures) deposit += proposal.deposit;
113+
111114
return {
112115
deposit,
113116
reclaimDeposit
@@ -119,17 +122,19 @@ const getTxDeposits = (
119122
{ stakeKeyDeposit, poolDeposit }: Pick<Cardano.ProtocolParameters, 'stakeKeyDeposit' | 'poolDeposit'>,
120123
certificates: Cardano.Certificate[],
121124
rewardAccounts: Cardano.RewardAccount[] = [],
122-
dRepKeyHash?: Crypto.Ed25519KeyHashHex
125+
dRepKeyHash?: Crypto.Ed25519KeyHashHex,
126+
proposalProcedures?: Cardano.ProposalProcedure[]
123127
): { deposit: Cardano.Lovelace; reclaimDeposit: Cardano.Lovelace } => {
124-
if (certificates.length === 0) return { deposit: 0n, reclaimDeposit: 0n };
128+
if (certificates.length === 0 && (!proposalProcedures || proposalProcedures.length === 0))
129+
return { deposit: 0n, reclaimDeposit: 0n };
125130

126131
const depositParams = {
127132
poolDeposit: poolDeposit ? BigInt(poolDeposit) : 0n,
128133
stakeKeyDeposit: BigInt(stakeKeyDeposit)
129134
};
130135

131136
const shelleyDeposits = computeShellyDeposits(depositParams, certificates, rewardAccounts);
132-
const conwayDeposits = computeConwayDeposits(certificates, rewardAccounts, dRepKeyHash);
137+
const conwayDeposits = computeConwayDeposits(certificates, rewardAccounts, dRepKeyHash, proposalProcedures);
133138

134139
return {
135140
deposit: shelleyDeposits.deposit + conwayDeposits.deposit,
@@ -150,19 +155,24 @@ const getTxDeposits = (
150155
* On the other hand, the transaction summary/display could receive a transaction from a dApp,
151156
* and can have mixed certificates (foreign and ours), so we need the list of reward accounts and drepKeyHash
152157
* to be able to distinguish the deposits that are going to our rewardAccounts from the ones that could
153-
* potentially go to a different reward accounts that we dont control (same with reclaims).
158+
* potentially go to a different reward accounts that we don't control (same with reclaims).
154159
*/
155160
export const computeImplicitCoin = (
156161
{ stakeKeyDeposit, poolDeposit }: Pick<Cardano.ProtocolParameters, 'stakeKeyDeposit' | 'poolDeposit'>,
157-
{ certificates, withdrawals }: Pick<HydratedTxBody, 'certificates' | 'withdrawals'>,
162+
{
163+
certificates,
164+
proposalProcedures,
165+
withdrawals
166+
}: Pick<HydratedTxBody, 'certificates' | 'proposalProcedures' | 'withdrawals'>,
158167
rewardAccounts?: Cardano.RewardAccount[],
159168
dRepKeyHash?: Crypto.Ed25519KeyHashHex
160169
): ImplicitCoin => {
161170
const { deposit, reclaimDeposit } = getTxDeposits(
162171
{ poolDeposit, stakeKeyDeposit },
163172
certificates ?? [],
164173
rewardAccounts,
165-
dRepKeyHash
174+
dRepKeyHash,
175+
proposalProcedures
166176
);
167177

168178
const withdrawalsTotal = (withdrawals && BigIntMath.sum(withdrawals.map(({ quantity }) => quantity))) || 0n;

packages/core/src/Serialization/TransactionBody/ProposalProcedure/InfoAction.ts

+11
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { CborReader, CborWriter } from '../../CBOR';
33
import { GovernanceActionKind } from './GovernanceActionKind';
44
import { HexBlob, InvalidArgumentError } from '@cardano-sdk/util';
55

6+
const EMBEDDED_GROUP_SIZE = 1;
7+
68
/**
79
* Represents an action that has no direct effect on the blockchain,
810
* but serves as an on-chain record or informative notice.
@@ -22,6 +24,7 @@ export class InfoAction {
2224

2325
// CDDL
2426
// info_action = 6
27+
writer.writeStartArray(EMBEDDED_GROUP_SIZE);
2528
writer.writeInt(GovernanceActionKind.Info);
2629
return writer.encodeAsHex();
2730
}
@@ -35,6 +38,14 @@ export class InfoAction {
3538
static fromCbor(cbor: HexBlob): InfoAction {
3639
const reader = new CborReader(cbor);
3740

41+
const length = reader.readStartArray();
42+
43+
if (length !== EMBEDDED_GROUP_SIZE)
44+
throw new InvalidArgumentError(
45+
'cbor',
46+
`Expected an array of ${EMBEDDED_GROUP_SIZE} elements, but got an array of ${length} elements`
47+
);
48+
3849
const kind = Number(reader.readUInt());
3950

4051
if (kind !== GovernanceActionKind.Info)

packages/core/src/Serialization/TransactionBody/ProposalProcedure/ProposalProcedure.ts

+4-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as Cardano from '../../../Cardano';
22
import { Anchor } from '../../Common/Anchor';
3-
import { CborReader, CborReaderState, CborWriter } from '../../CBOR';
3+
import { CborReader, CborWriter } from '../../CBOR';
44
import { GovernanceActionKind } from './GovernanceActionKind';
55
import { HardForkInitiationAction } from './HardForkInitiationAction';
66
import { HexBlob, InvalidStateError } from '@cardano-sdk/util';
@@ -116,15 +116,10 @@ export class ProposalProcedure {
116116

117117
const actionReader = new CborReader(actionCbor);
118118

119-
let kind;
120-
let action;
119+
actionReader.readStartArray();
121120

122-
if (actionReader.peekState() === CborReaderState.UnsignedInteger) {
123-
kind = Number(actionReader.readInt());
124-
} else {
125-
actionReader.readStartArray();
126-
kind = Number(actionReader.readInt());
127-
}
121+
let action;
122+
const kind = Number(actionReader.readInt());
128123

129124
switch (kind) {
130125
case GovernanceActionKind.ParameterChange:

packages/core/src/Serialization/Update/ProtocolParamUpdate.ts

+12-4
Original file line numberDiff line numberDiff line change
@@ -443,10 +443,18 @@ export class ProtocolParamUpdate {
443443
params.#poolDeposit = parametersUpdate.poolDeposit ? BigInt(parametersUpdate.poolDeposit) : undefined;
444444
params.#maxEpoch = parametersUpdate.poolRetirementEpochBound;
445445
params.#nOpt = parametersUpdate.desiredNumberOfPools;
446-
params.#poolPledgeInfluence = UnitInterval.fromFloat(Number(parametersUpdate.poolInfluence));
447-
params.#expansionRate = UnitInterval.fromFloat(Number(parametersUpdate.monetaryExpansion));
448-
params.#treasuryGrowthRate = UnitInterval.fromFloat(Number(parametersUpdate.treasuryExpansion));
449-
params.#d = UnitInterval.fromFloat(Number(parametersUpdate.decentralizationParameter));
446+
params.#poolPledgeInfluence = parametersUpdate.poolInfluence
447+
? UnitInterval.fromFloat(Number(parametersUpdate.poolInfluence))
448+
: undefined;
449+
params.#expansionRate = parametersUpdate.monetaryExpansion
450+
? UnitInterval.fromFloat(Number(parametersUpdate.monetaryExpansion))
451+
: undefined;
452+
params.#treasuryGrowthRate = parametersUpdate.treasuryExpansion
453+
? UnitInterval.fromFloat(Number(parametersUpdate.treasuryExpansion))
454+
: undefined;
455+
params.#d = parametersUpdate.decentralizationParameter
456+
? UnitInterval.fromFloat(Number(parametersUpdate.decentralizationParameter))
457+
: undefined;
450458
params.#minPoolCost = parametersUpdate.minPoolCost ? BigInt(parametersUpdate.minPoolCost) : undefined;
451459
params.#protocolVersion = parametersUpdate.protocolVersion
452460
? ProtocolVersion.fromCore(parametersUpdate.protocolVersion)

packages/core/test/Cardano/util/computeImplicitCoin.test.ts

+31
Original file line numberDiff line numberDiff line change
@@ -198,4 +198,35 @@ describe('Cardano.util.computeImplicitCoin', () => {
198198
expect(coin.input).toBe(withdrawals[0].quantity + expectedReclaim);
199199
expect(coin.withdrawals).toBe(withdrawals[0].quantity);
200200
});
201+
202+
it('sums certificates and proposal procedures for deposit', () => {
203+
const protocolParameters = { governanceActionDeposit: 4, stakeKeyDeposit: 2 } as Cardano.ProtocolParameters;
204+
const governanceActionDeposit = BigInt(protocolParameters.governanceActionDeposit);
205+
const stakeKeyDeposit = BigInt(protocolParameters.stakeKeyDeposit);
206+
207+
const anchor = {
208+
dataHash: '3e33018e8293d319ef5b3ac72366dd28006bd315b715f7e7cfcbd3004129b80d' as Crypto.Hash32ByteBase16,
209+
url: 'https://testing.this'
210+
};
211+
const certificates: Cardano.Certificate[] = [
212+
{ __typename: Cardano.CertificateType.Registration, deposit: stakeKeyDeposit, stakeCredential }
213+
];
214+
const proposalProcedures: Cardano.ProposalProcedure[] = [
215+
{
216+
anchor,
217+
deposit: governanceActionDeposit,
218+
governanceAction: { __typename: Cardano.GovernanceActionType.info_action },
219+
rewardAccount
220+
}
221+
];
222+
223+
const coin = Cardano.util.computeImplicitCoin(
224+
protocolParameters,
225+
{ certificates, proposalProcedures },
226+
[rewardAccount],
227+
dRepKeyHash
228+
);
229+
230+
expect(coin.deposit).toBe(stakeKeyDeposit + governanceActionDeposit);
231+
});
201232
});

packages/core/test/Serialization/TransactionBody/ProposalProcedure/InfoAction.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { HexBlob } from '@cardano-sdk/util';
44
import { InfoAction } from '../../../../src/Serialization';
55

66
// Test data used in the following tests was generated with the cardano-serialization-lib
7-
const cbor = HexBlob('06');
7+
const cbor = HexBlob('8106');
88
const core = {
99
__typename: Cardano.GovernanceActionType.info_action
1010
} as Cardano.InfoAction;

packages/core/test/Serialization/TransactionBody/ProposalProcedure/ProposalProcedure.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { HexBlob } from '@cardano-sdk/util';
44
import { ProposalProcedure } from '../../../../src/Serialization';
55

66
const infoActionCbor = HexBlob(
7-
'841a000f4240581de1cb0ec2692497b458e46812c8a5bfa2931d1a2d965a99893828ec810f06827668747470733a2f2f7777772e736f6d6575726c2e696f58200000000000000000000000000000000000000000000000000000000000000000'
7+
'841a000f4240581de1cb0ec2692497b458e46812c8a5bfa2931d1a2d965a99893828ec810f8106827668747470733a2f2f7777772e736f6d6575726c2e696f58200000000000000000000000000000000000000000000000000000000000000000'
88
);
99

1010
const infoActionCore = {

packages/tx-construction/src/tx-builder/TxBuilder.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ export class GenericTxBuilder implements TxBuilder {
260260
customizeCb: this.#customizeCb,
261261
handleResolutions: this.#handleResolutions,
262262
outputs: new Set(this.partialTxBody.outputs || []),
263+
proposalProcedures: this.partialTxBody.proposalProcedures,
263264
signingOptions: partialSigningOptions,
264265
witness: { extraSigners }
265266
},
@@ -361,15 +362,15 @@ export class GenericTxBuilder implements TxBuilder {
361362
);
362363

363364
// Reward accounts already delegated to the correct pool. Change must be distributed accordingly
364-
for (const accnt of rewardAccounts.filter(
365+
for (const account of rewardAccounts.filter(
365366
(rewardAccount) =>
366367
rewardAccount.keyStatus === Cardano.StakeKeyStatus.Registered &&
367368
rewardAccount.delegatee?.nextNextEpoch &&
368369
this.#requestedPortfolio?.some(({ id }) => id === rewardAccount.delegatee?.nextNextEpoch?.id)
369370
))
370371
rewardAccountsWithWeights.set(
371-
accnt.address,
372-
this.#requestedPortfolio!.find(({ id }) => id === accnt.delegatee?.nextNextEpoch?.id)!.weight
372+
account.address,
373+
this.#requestedPortfolio!.find(({ id }) => id === account.delegatee?.nextNextEpoch?.id)!.weight
373374
);
374375

375376
// Reward accounts which don't have the stake key registered or that were delegated but should not be anymore

packages/tx-construction/src/tx-builder/initializeTx.ts

+1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ export const initializeTx = async (
8888

8989
const implicitCoin = Cardano.util.computeImplicitCoin(protocolParameters, {
9090
certificates: bodyPreInputSelection.certificates,
91+
proposalProcedures: bodyPreInputSelection.proposalProcedures,
9192
withdrawals: bodyPreInputSelection.withdrawals
9293
});
9394

packages/tx-construction/src/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export interface InitializeTxProps {
4848
witness?: InitializeTxWitness;
4949
signingOptions?: Pick<SignTransactionOptions, 'additionalKeyPaths'>;
5050
handleResolutions?: HandleResolution[];
51+
proposalProcedures?: Cardano.ProposalProcedure[];
5152
/** callback function that allows updating the transaction before input selection */
5253
customizeCb?: CustomizeCb;
5354
}

0 commit comments

Comments
 (0)