Skip to content

Commit 145937c

Browse files
authored
Merge pull request #399 from Concordium/bugfix/tx-energy-cost
Bugfix/tx energy cost
2 parents c4e665a + 24580eb commit 145937c

File tree

5 files changed

+26
-15
lines changed

5 files changed

+26
-15
lines changed

packages/sdk/CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
## 8.1.1
6+
7+
### Fixed
8+
9+
- `getEnergyCost` returning energy amounts that were off by one due to not including the transaction type in the
10+
transaction payload serialization.
11+
312
## 8.1.0
413

514
### Added

packages/sdk/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@concordium/web-sdk",
3-
"version": "8.1.0",
3+
"version": "8.1.1",
44
"license": "Apache-2.0",
55
"engines": {
66
"node": ">=16"

packages/sdk/src/accountTransactions.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ export interface AccountTransactionHandler<
4949
> {
5050
/**
5151
* Serializes the payload to a buffer.
52+
* This does NOT include the serialized transaction type. To have this included, use {@linkcode serializeAccountTransactionPayload} instead.
53+
*
5254
* @param payload - The payload to serialize.
5355
* @returns The serialized payload.
5456
*/

packages/sdk/src/energyCost.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { getAccountTransactionHandler } from './accountTransactions.js';
22
import { collapseRatio, multiplyRatio } from './ratioHelpers.js';
3+
import { serializeAccountTransactionPayload } from './serialization.js';
34
import { AccountTransactionPayload, AccountTransactionType, ChainParameters, Ratio } from './types.js';
45
import * as CcdAmount from './types/CcdAmount.js';
56
import * as Energy from './types/Energy.js';
@@ -12,7 +13,7 @@ export const constantA = 100n;
1213
export const constantB = 1n;
1314

1415
// Account address (32 bytes), nonce (8 bytes), energy (8 bytes), payload size (4 bytes), expiry (8 bytes);
15-
const accountTransactionHeaderSize = BigInt(32 + 8 + 8 + 4 + 8);
16+
const ACCOUNT_TRANSACTION_HEADER_SIZE = BigInt(32 + 8 + 8 + 4 + 8);
1617

1718
/**
1819
* The energy cost is assigned according to the formula:
@@ -30,7 +31,9 @@ export function calculateEnergyCost(
3031
transactionSpecificCost: bigint
3132
): Energy.Type {
3233
return Energy.create(
33-
constantA * signatureCount + constantB * (accountTransactionHeaderSize + payloadSize) + transactionSpecificCost
34+
constantA * signatureCount +
35+
constantB * (ACCOUNT_TRANSACTION_HEADER_SIZE + payloadSize) +
36+
transactionSpecificCost
3437
);
3538
}
3639

@@ -44,8 +47,8 @@ export function getEnergyCost(
4447
payload: AccountTransactionPayload,
4548
signatureCount = 1n
4649
): Energy.Type {
50+
const size = serializeAccountTransactionPayload({ payload, type: transactionType }).length;
4751
const handler = getAccountTransactionHandler(transactionType);
48-
const size = handler.serialize(payload).length;
4952
return calculateEnergyCost(signatureCount, BigInt(size), handler.getBaseEnergyCost(payload));
5053
}
5154

packages/sdk/src/serialization.ts

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -98,28 +98,25 @@ export function serializeAccountTransaction(
9898
const serializedBlockItemKind = encodeWord8(BlockItemKind.AccountTransactionKind);
9999
const serializedAccountTransactionSignatures = serializeAccountTransactionSignature(signatures);
100100

101-
const serializedType = serializeAccountTransactionType(accountTransaction.type);
102-
103101
const accountTransactionHandler = getAccountTransactionHandler(accountTransaction.type);
104-
const serializedPayload = accountTransactionHandler.serialize(accountTransaction.payload);
102+
const serializedPayload = serializeAccountTransactionPayload(accountTransaction);
105103

106104
const baseEnergyCost = accountTransactionHandler.getBaseEnergyCost(accountTransaction.payload);
107105
const energyCost = calculateEnergyCost(
108106
countSignatures(signatures),
109-
BigInt(serializedPayload.length + 1),
107+
BigInt(serializedPayload.length),
110108
baseEnergyCost
111109
);
112110
const serializedHeader = serializeAccountTransactionHeader(
113111
accountTransaction.header,
114-
serializedPayload.length + 1,
112+
serializedPayload.length,
115113
energyCost
116114
);
117115

118116
return Buffer.concat([
119117
serializedBlockItemKind,
120118
serializedAccountTransactionSignatures,
121119
serializedHeader,
122-
serializedType,
123120
serializedPayload,
124121
]);
125122
}
@@ -129,7 +126,7 @@ export function serializeAccountTransaction(
129126
* @param accountTransaction the transaction which payload is to be serialized
130127
* @returns the account transaction payload serialized as a buffer.
131128
*/
132-
export function serializeAccountTransactionPayload(accountTransaction: AccountTransaction): Buffer {
129+
export function serializeAccountTransactionPayload(accountTransaction: Omit<AccountTransaction, 'header'>): Buffer {
133130
const serializedType = serializeAccountTransactionType(accountTransaction.type);
134131

135132
const accountTransactionHandler = getAccountTransactionHandler(accountTransaction.type);
@@ -160,17 +157,17 @@ export function getAccountTransactionHash(
160157
*/
161158
export function getAccountTransactionSignDigest(accountTransaction: AccountTransaction, signatureCount = 1n): Buffer {
162159
const accountTransactionHandler = getAccountTransactionHandler(accountTransaction.type);
163-
const serializedPayload = accountTransactionHandler.serialize(accountTransaction.payload);
160+
const serializedPayload = serializeAccountTransactionPayload(accountTransaction);
164161

165162
const baseEnergyCost = accountTransactionHandler.getBaseEnergyCost(accountTransaction.payload);
166-
const energyCost = calculateEnergyCost(signatureCount, BigInt(serializedPayload.length + 1), baseEnergyCost);
163+
const energyCost = calculateEnergyCost(signatureCount, BigInt(serializedPayload.length), baseEnergyCost);
167164
const serializedHeader = serializeAccountTransactionHeader(
168165
accountTransaction.header,
169-
serializedPayload.length + 1,
166+
serializedPayload.length,
170167
energyCost
171168
);
172169

173-
return sha256([serializedHeader, serializeAccountTransactionType(accountTransaction.type), serializedPayload]);
170+
return sha256([serializedHeader, serializedPayload]);
174171
}
175172

176173
/**

0 commit comments

Comments
 (0)