Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ifl-744 add test/updates for calculating raw transaction size #3854

Merged
merged 1 commit into from
May 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions ironfish-rust-nodejs/src/structs/note_encrypted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,6 @@ pub const ENCRYPTED_NOTE_PLAINTEXT_LENGTH: u32 = ENCRYPTED_NOTE_SIZE as u32 + MA
#[napi]
pub const ENCRYPTED_NOTE_LENGTH: u32 =
NOTE_ENCRYPTION_KEY_LENGTH + ENCRYPTED_NOTE_PLAINTEXT_LENGTH + 96;
// 32 value commitment
//+ 32 note commitment
//+ 32 ephemeral public key
//+ 120 encrypted note
//+ 80 note encryption keys
//= 296 bytes

#[napi(js_name = "NoteEncrypted")]
pub struct NativeNoteEncrypted {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,5 +196,44 @@
"publicAddress": "c96cc22b0a0e958c055eb6b357418e4a779b90f85750dfc9e618b36688eab944",
"createdAt": null
}
],
"RawTransaction should equal": [
{
"version": 2,
"id": "fb52a88e-3e8c-466f-bd34-c4dd7d75532d",
"name": "test",
"spendingKey": "4c3d51b6596832c4dc539aa5d6ecd036d338fbc21b6a64d26a7ccc838a87a000",
"viewKey": "a33795eafe7851f52fc4bfbe2a2ff60ad7bb409d6cc4bc19996a4d941a4f8cc526aee6da70f63bcac90ec4bd678b16bbe64299bed09da120bf28e321d3aab1aa",
"incomingViewKey": "cee508b90f3963e4099798a355ed0da0e123b193ff0f7cd6b7b4596caadf1e02",
"outgoingViewKey": "79f6d37e22fd3d9ca88b0d26a1dedebb4ef7e89fa31ac7632c1ee06a3f30628a",
"publicAddress": "6b971b1e7217ff4fe81c457c65d85ce8d7723fa52061a2194041efb556a99c19",
"createdAt": null
},
{
"header": {
"sequence": 2,
"previousBlockHash": "88B6FA8D745A4E53BDA001318E60B04EE2E4EE06A38095688D58049CB6F15ACA",
"noteCommitment": {
"type": "Buffer",
"data": "base64:9DdIBOwIdxNRoPgyIcDSxyCQwTV2oALwWD2w/K2dPEM="
},
"transactionCommitment": {
"type": "Buffer",
"data": "base64:v2mDXwx+HgVnlnZwDaTJfEzBSmmEHpHcvjPYjXbGJOg="
},
"target": "883423532389192164791648750371459257913741948437809479060803100646309888",
"randomness": "0",
"timestamp": 1682541250417,
"graffiti": "0000000000000000000000000000000000000000000000000000000000000000",
"noteSize": 4,
"work": "0"
},
"transactions": [
{
"type": "Buffer",
"data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAqZz03fllUAxM/C47JUjjmcVrt8H1IKtQY662BbzJsHOBBsM9VGn0kEUU/Da9UFfHfzW+n3Zud2xziSEG76e0SpoXl66oysLTkLvWcTycsumpWYVw5JNcPU7SBt2HACwfKN4awPDtSihU8dsjIbE+NBdMfLF6KMdBKjTC5fykZl0AjgmGflqizCNi3uucrM2Nm3HYjXIJvdv/R3AXA4TZD8BhduPvJEagPzLOcFxDwWuKLBAyjSrWU5SOmwrcqvJtvtJCwbIFNiUOIr5CO09PL+5ko/oVP4eZ2EHYNoKZRX0T8iZvPxVLuVIDlocEOn8zt2th/D2Erz1YHVbMw6B2VVoe9pmeJqQwwmI8yg1doZxhvPw8I7YjBPzwSGNQQp9x9vuW/n4O+bcopYA56O+eepc1r8CWU7+qmP9WjBCCskhK745L4B7hI3MTNwAyJ96m4S+PkHydl7m6QIZYIUGCLuYZSXKMd+QFXQJwfiyE8P+0I+gTtjaglmboCIZNCTyLbI4re2Xa2SXzqQk9agNVcyKHqG1j0D4qMVDBMCuvuhVCyFjBIy2yzQ9MCbV4mkE9AEsDjBdn4ehLB6Pi82M43awCFE0SblLFcEjryLy3OoZ3pK3IBVhliUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwxGhqNFhJQIu38oTMYoOTmInFtc4F/l21An0Z112s1dWXZ6OIGS8Xsdi8KJwm8vzAtBo7osJ/1NFTnjYT9uznAw=="
}
]
}
]
}
4 changes: 4 additions & 0 deletions ironfish/src/primitives/rawTransaction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ describe('RawTransaction', () => {
const mintedValue = valuesByAsset.get(asset.id())
Assert.isNotUndefined(mintedValue)
expect(mintedValue).toEqual(1n)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a nice future proofing test


// should have same size for posted transaction and estimated size from raw transaction
const serializedPost = posted.serialize()
expect(raw.postedSize(account.publicAddress)).toEqual(serializedPost.byteLength)
})

it('should throw an error if the max mint value is exceeded', async () => {
Expand Down
43 changes: 37 additions & 6 deletions ironfish/src/primitives/rawTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,20 @@ import {
AMOUNT_VALUE_LENGTH,
ASSET_LENGTH,
generateKeyFromPrivateKey,
PROOF_LENGTH,
Transaction as NativeTransaction,
TRANSACTION_EXPIRATION_LENGTH,
TRANSACTION_FEE_LENGTH,
TRANSACTION_PUBLIC_KEY_RANDOMNESS_LENGTH,
TRANSACTION_SIGNATURE_LENGTH,
} from '@ironfish/rust-nodejs'
import { Asset, ASSET_ID_LENGTH } from '@ironfish/rust-nodejs'
import bufio from 'bufio'
import { Witness } from '../merkletree'
import { NoteHasher } from '../merkletree/hasher'
import { Side } from '../merkletree/merkletree'
import { CurrencyUtils } from '../utils/currency'
import { AssetBalances } from '../wallet/assetBalances'
import { BurnDescription } from './burnDescription'
import { Note } from './note'
import {
Expand Down Expand Up @@ -54,17 +58,44 @@ export class RawTransaction {
>
}[] = []

size(): number {
postedSize(publicAddress: string): number {
let size = 0
size += 1 // version
size += 8 // spends length
size += 8 // notes length
size += 8 // fee
size += 4 // expiration
size += 64 // signature
size += 8 // mints length
size += 8 // burns length
size += TRANSACTION_FEE_LENGTH // fee
size += TRANSACTION_EXPIRATION_LENGTH // expiration
size += TRANSACTION_PUBLIC_KEY_RANDOMNESS_LENGTH // public key randomness
size += this.spends.length * SPEND_SERIALIZED_SIZE_IN_BYTE
size += this.outputs.length * NOTE_ENCRYPTED_SERIALIZED_SIZE_IN_BYTE
size += this.mints.length * (ASSET_LENGTH + 8)
size +=
this.mints.length *
(PROOF_LENGTH + ASSET_LENGTH + AMOUNT_VALUE_LENGTH + TRANSACTION_SIGNATURE_LENGTH)
size += this.burns.length * (ASSET_ID_LENGTH + 8)
size += this.spends.length * SPEND_SERIALIZED_SIZE_IN_BYTE
size += TRANSACTION_SIGNATURE_LENGTH // signature

// Each asset might have a change note, which would need to be accounted for
const assetTotals = new AssetBalances()
for (const mint of this.mints) {
const asset = new Asset(publicAddress, mint.name, mint.metadata)
assetTotals.increment(asset.id(), mint.value)
}
for (const burn of this.burns) {
assetTotals.increment(burn.assetId, -burn.value)
}
for (const spend of this.spends) {
assetTotals.increment(spend.note.assetId(), -spend.note.value())
}
for (const output of this.outputs) {
assetTotals.increment(output.note.assetId(), output.note.value())
}
for (const [, value] of assetTotals) {
if (value !== 0n) {
size += NOTE_ENCRYPTED_SERIALIZED_SIZE_IN_BYTE
}
}
return size
}

Expand Down
2 changes: 1 addition & 1 deletion ironfish/src/primitives/spend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import { Nullifier } from './nullifier'

export const SPEND_SERIALIZED_SIZE_IN_BYTE = 388
export const SPEND_SERIALIZED_SIZE_IN_BYTE = 356

export interface Spend {
nullifier: Nullifier
Expand Down
6 changes: 3 additions & 3 deletions ironfish/src/primitives/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export class Transaction {

// spend description
this.spends = Array.from({ length: _spendsLength }, () => {
// proof
// proof 192
reader.seek(PROOF_LENGTH)
// value commitment
reader.seek(32)
Expand All @@ -68,10 +68,10 @@ export class Transaction {
const treeSize = reader.readU32() // 4
const nullifier = reader.readHash() // 32

// signature
// signature 64
reader.seek(TRANSACTION_SIGNATURE_LENGTH)

// total serialized size: 192 + 32 + 32 + 32 + 4 + 32 + 64 = 388 bytes
// total serialized size: 192 + 32 + 32 + 4 + 32 + 64 = 356 bytes
return {
size: treeSize,
commitment: rootHash,
Expand Down
4 changes: 2 additions & 2 deletions ironfish/src/wallet/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -918,7 +918,7 @@ export class Wallet {
}

if (options.feeRate) {
raw.fee = getFee(options.feeRate, raw.size())
raw.fee = getFee(options.feeRate, raw.postedSize(options.account.publicAddress))
}

await this.fund(raw, {
Expand All @@ -928,7 +928,7 @@ export class Wallet {
})

if (options.feeRate) {
raw.fee = getFee(options.feeRate, raw.size())
raw.fee = getFee(options.feeRate, raw.postedSize(options.account.publicAddress))
raw.spends = []

await this.fund(raw, {
Expand Down