From 58f783cbacce81e1db14129ebde1f357cb8eb4af Mon Sep 17 00:00:00 2001 From: Jason Spafford Date: Mon, 13 Feb 2023 12:39:00 -0500 Subject: [PATCH 01/43] Add note.hash() (#3407) This PR exposes the ability to get the hash from a decrypted note. It also exposes hash() in the JS side for both encrypted and decrypted notes but renaming merkle_hash() to hash(). --- ironfish-rust-nodejs/index.d.ts | 11 +++++- ironfish-rust-nodejs/src/structs/note.rs | 7 ++++ .../src/structs/note_encrypted.rs | 4 +- ironfish-rust-nodejs/tests/demo.test.slow.ts | 4 +- .../__fixtures__/note.test.ts.fixture | 38 +++++++++++++++++++ ironfish/src/primitives/note.test.ts | 21 ++++++++++ ironfish/src/primitives/note.ts | 7 ++++ 7 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 ironfish/src/primitives/__fixtures__/note.test.ts.fixture create mode 100644 ironfish/src/primitives/note.test.ts diff --git a/ironfish-rust-nodejs/index.d.ts b/ironfish-rust-nodejs/index.d.ts index 48660d0ec9..2f81614d53 100644 --- a/ironfish-rust-nodejs/index.d.ts +++ b/ironfish-rust-nodejs/index.d.ts @@ -91,7 +91,11 @@ export class NoteEncrypted { constructor(jsBytes: Buffer) serialize(): Buffer equals(other: NoteEncrypted): boolean - merkleHash(): Buffer + /** + * The commitment hash of the note + * This hash is what gets used for the leaf nodes in a Merkle Tree. + */ + hash(): Buffer /** * Hash two child hashes together to calculate the hash of the * new parent @@ -107,6 +111,11 @@ export class Note { constructor(owner: string, value: bigint, memo: string, assetId: Buffer, sender: string) static deserialize(jsBytes: Buffer): NativeNote serialize(): Buffer + /** + * The commitment hash of the note + * This hash is what gets used for the leaf nodes in a Merkle Tree. + */ + hash(): Buffer /** Value this note represents. */ value(): bigint /** diff --git a/ironfish-rust-nodejs/src/structs/note.rs b/ironfish-rust-nodejs/src/structs/note.rs index 292d04aa57..daa5568ef6 100644 --- a/ironfish-rust-nodejs/src/structs/note.rs +++ b/ironfish-rust-nodejs/src/structs/note.rs @@ -99,6 +99,13 @@ impl NativeNote { Ok(Buffer::from(arr)) } + /// The commitment hash of the note + /// This hash is what gets used for the leaf nodes in a Merkle Tree. + #[napi] + pub fn hash(&self) -> Buffer { + Buffer::from(&self.note.commitment()[..]) + } + /// Value this note represents. #[napi] pub fn value(&self) -> u64 { diff --git a/ironfish-rust-nodejs/src/structs/note_encrypted.rs b/ironfish-rust-nodejs/src/structs/note_encrypted.rs index 131f321db2..37060973a8 100644 --- a/ironfish-rust-nodejs/src/structs/note_encrypted.rs +++ b/ironfish-rust-nodejs/src/structs/note_encrypted.rs @@ -63,8 +63,10 @@ impl NativeNoteEncrypted { self.note.eq(&other.note) } + /// The commitment hash of the note + /// This hash is what gets used for the leaf nodes in a Merkle Tree. #[napi] - pub fn merkle_hash(&self) -> Result { + pub fn hash(&self) -> Result { let mut vec: Vec = Vec::with_capacity(32); self.note .merkle_hash() diff --git a/ironfish-rust-nodejs/tests/demo.test.slow.ts b/ironfish-rust-nodejs/tests/demo.test.slow.ts index 8cb8fbe66b..413d634c86 100644 --- a/ironfish-rust-nodejs/tests/demo.test.slow.ts +++ b/ironfish-rust-nodejs/tests/demo.test.slow.ts @@ -66,7 +66,7 @@ describe('Demonstrate the Sapling API', () => { expect(postedTransaction.verify()).toBe(true) const encryptedNote = new NoteEncrypted(postedTransaction.getNote(0)) - expect(encryptedNote.merkleHash().byteLength).toBe(32) + expect(encryptedNote.hash().byteLength).toBe(32) expect(encryptedNote.equals(encryptedNote)).toBe(true) const decryptedNoteBuffer = encryptedNote.decryptNoteForOwner(key.incoming_view_key) @@ -100,7 +100,7 @@ describe('Demonstrate the Sapling API', () => { const decryptedNote = Note.deserialize(encryptedNote.decryptNoteForOwner(key.incoming_view_key)!) const newNote = new Note(recipientKey.public_address, BigInt(15), 'receive', Asset.nativeId(), minersFeeNote.owner()) - let currentHash = encryptedNote.merkleHash() + let currentHash = encryptedNote.hash() let authPath = Array.from({ length: 32 }, (_, depth) => { const tempHash = currentHash const witnessNode = { diff --git a/ironfish/src/primitives/__fixtures__/note.test.ts.fixture b/ironfish/src/primitives/__fixtures__/note.test.ts.fixture new file mode 100644 index 0000000000..c5d65e2db8 --- /dev/null +++ b/ironfish/src/primitives/__fixtures__/note.test.ts.fixture @@ -0,0 +1,38 @@ +{ + "Note should post": [ + { + "id": "9e8fa3cc-e071-47bc-b633-4ed634d27173", + "name": "test", + "spendingKey": "a8e97ef506cd750a7d29cc849161b0c98b79cb396df7b040eca2dd5d361dc37b", + "incomingViewKey": "4e8f0954a08e363b04322652fb1bc4f88923c579cecabae7236fdd94a4603006", + "outgoingViewKey": "12a2777a88d02c9214b069a3d32f87d82bf0302ccf9281fb4f313a5c33fa16b6", + "publicAddress": "edddea968cb3aefdd98cfb7c79e2ac373ce996c455fb4cf1aa6bc1a8d69602ca" + }, + { + "header": { + "sequence": 2, + "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", + "noteCommitment": { + "type": "Buffer", + "data": "base64:Io4HVIP9JI9UEMvjfdOdiHzJnzLyZzhl2nx5PLhRbkM=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:+R4nZTSiNHRzvlKTsFY60ExGnbAHAsl0GnIZktua0MM=" + }, + "target": "883423532389192164791648750371459257913741948437809479060803100646309888", + "randomness": "0", + "timestamp": 1676308908327, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 4, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA63B1kqcM3ehyw9TxqVk91GWNRsYX81ubnsMBAIbQ7bukQBdvwx+uAIec+HJy5mup7MKXxm03J9wtSAo28E5rNe7iM1hbGaPAZU1RwFbrE3izuPfEN1fjWoyXvZHG1vzlTI3ic9j7jcD9q4lCziO6NBfuATB5Eleg3k7KBF3YzHAVVSOv34atVUMLu9zCIXz3rN3KyHr9hEiq6heXnPUK/zQCvMdQydt3No2ACsGJw8SiC2CSkqCiGvkt+6VAM5XX8xv7KEypR9b01mRPLLygVD65hKvYPVYl1ncCNa2SnBc3QnZR4RYN11+P9Yx2diIhEqLuM//0tiqICgK95X43IqJ1N32fmwZgB8F/gw04iWI5Zr6NnY2LNLiCM6bDvoc857mMKNbxWL9o+jjnVN1hxH4coAFnWyX2tc2e4HOIclOUWZU9vpdxqqZPlFauX1TI1dtIySfBbJ7bnbYWqOz1zfWYvYYVXZtXSUdfATjt4mxEPkq6bOmwjHEnRP+cJ0Z5sbTJgYTCb0KcPoVNoTNAb0bo/1QNOFoo56pIBriGlk8IgyHD49AZG36wK13sM0VHiH45YpJz3MI8rmzMtCAUdPjvuwL1hDjbxSwEX71fjxsTQ1zrTdYcTUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwb+XkBVc6Hq/HmX4DWNmWAi2IZltUKBimGIKRRWi6m96Os1Cj3iKjpwyZ0Oc1dII+bWg2o5QrIkdBxLoHLjerBg==" + } + ] + } + ] +} \ No newline at end of file diff --git a/ironfish/src/primitives/note.test.ts b/ironfish/src/primitives/note.test.ts new file mode 100644 index 0000000000..59bec8672c --- /dev/null +++ b/ironfish/src/primitives/note.test.ts @@ -0,0 +1,21 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +import { Assert } from '../assert' +import { useAccountFixture, useMinerBlockFixture } from '../testUtilities/fixtures' +import { createNodeTest } from '../testUtilities/nodeTest' + +describe('Note', () => { + const nodeTest = createNodeTest() + + it('should post', async () => { + const account = await useAccountFixture(nodeTest.wallet) + const block = await useMinerBlockFixture(nodeTest.chain, undefined, account) + + const encrypted = block.minersFee.notes[0] + const decrypted = encrypted.decryptNoteForOwner(account.incomingViewKey) + + Assert.isNotUndefined(decrypted) + expect(encrypted.hash().equals(decrypted.hash())).toBe(true) + }) +}) diff --git a/ironfish/src/primitives/note.ts b/ironfish/src/primitives/note.ts index 0243c5f959..86dfeec86d 100644 --- a/ironfish/src/primitives/note.ts +++ b/ironfish/src/primitives/note.ts @@ -11,6 +11,7 @@ import { } from '@ironfish/rust-nodejs' import bufio from 'bufio' import { BufferUtils } from '../utils/buffer' +import { NoteEncryptedHash } from './noteEncrypted' export class Note { private readonly noteSerialized: Buffer @@ -62,6 +63,12 @@ export class Note { } } + hash(): NoteEncryptedHash { + const hash = this.takeReference().hash() + this.returnReference() + return hash + } + value(): bigint { return this._value } From e2cd52c5677d2c1113def3771916fd0f34118c31 Mon Sep 17 00:00:00 2001 From: Rohan Jadvani <5459049+rohanjadvani@users.noreply.github.com> Date: Mon, 13 Feb 2023 12:39:43 -0500 Subject: [PATCH 02/43] feat(ironfish): Remove `/chain/getBlock` (#3406) --- ironfish/src/rpc/clients/client.ts | 6 - .../src/rpc/routes/chain/getBlock.test.ts | 72 ------- ironfish/src/rpc/routes/chain/getBlock.ts | 200 ------------------ ironfish/src/rpc/routes/chain/index.ts | 1 - 4 files changed, 279 deletions(-) delete mode 100644 ironfish/src/rpc/routes/chain/getBlock.test.ts delete mode 100644 ironfish/src/rpc/routes/chain/getBlock.ts diff --git a/ironfish/src/rpc/clients/client.ts b/ironfish/src/rpc/clients/client.ts index b1fab778bb..84716dc51d 100644 --- a/ironfish/src/rpc/clients/client.ts +++ b/ironfish/src/rpc/clients/client.ts @@ -23,8 +23,6 @@ import { GetBalanceResponse, GetBlockInfoRequest, GetBlockInfoResponse, - GetBlockRequest, - GetBlockResponse, GetChainInfoRequest, GetChainInfoResponse, GetConfigRequest, @@ -425,10 +423,6 @@ export abstract class RpcClient { ).waitForEnd() } - async getBlock(params: GetBlockRequest): Promise> { - return this.request(`${ApiNamespace.chain}/getBlock`, params).waitForEnd() - } - async getChainInfo( params: GetChainInfoRequest = undefined, ): Promise> { diff --git a/ironfish/src/rpc/routes/chain/getBlock.test.ts b/ironfish/src/rpc/routes/chain/getBlock.test.ts deleted file mode 100644 index e1cbb870d6..0000000000 --- a/ironfish/src/rpc/routes/chain/getBlock.test.ts +++ /dev/null @@ -1,72 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ - -import '../../../testUtilities/matchers' -import { GENESIS_BLOCK_SEQUENCE } from '../../../primitives/block' -import { BlockHashSerdeInstance } from '../../../serde' -import { useMinerBlockFixture } from '../../../testUtilities/fixtures' -import { createRouteTest } from '../../../testUtilities/routeTest' -import { GetBlockResponse } from './getBlock' - -describe('Route chain.getBlock', () => { - const routeTest = createRouteTest() - - it('should fail if no sequence or hash provided', async () => { - await expect(routeTest.client.request('chain/getBlock', {}).waitForEnd()).rejects.toThrow( - 'Missing hash or sequence', - ) - }) - - it(`should fail if block can't be found with hash`, async () => { - const hash = BlockHashSerdeInstance.serialize(Buffer.alloc(32, 'blockhashnotfound')) - - await expect( - routeTest.client.request('chain/getBlock', { hash }).waitForEnd(), - ).rejects.toThrow('No block found') - }) - - it(`should fail if block can't be found with sequence`, async () => { - await expect( - routeTest.client.request('chain/getBlock', { index: 5 }).waitForEnd(), - ).rejects.toThrow('No block found') - }) - - it('responds with a block', async () => { - const chain = routeTest.node.chain - - const block = await useMinerBlockFixture(chain, 2) - await expect(chain).toAddBlock(block) - - // by hash first - const hash = BlockHashSerdeInstance.serialize(block.header.hash) - let response = await routeTest.client - .request('chain/getBlock', { hash }) - .waitForEnd() - - expect(response.content).toMatchObject({ - timestamp: block.header.timestamp.valueOf(), - blockIdentifier: { - index: Number(block.header.sequence).toString(), - hash: block.header.hash.toString('hex').toUpperCase(), - }, - parentBlockIdentifier: { - index: Number(GENESIS_BLOCK_SEQUENCE).toString(), - hash: block.header.previousBlockHash.toString('hex').toUpperCase(), - }, - metadata: { - size: expect.any(Number), - difficulty: block.header.target.toDifficulty().toString(), - }, - }) - expect(response.content.transactions).toHaveLength(1) - - // now by sequence - response = await routeTest.client - .request('chain/getBlock', { index: 2 }) - .waitForEnd() - expect(response.content.blockIdentifier.hash).toEqual( - block.header.hash.toString('hex').toUpperCase(), - ) - }) -}) diff --git a/ironfish/src/rpc/routes/chain/getBlock.ts b/ironfish/src/rpc/routes/chain/getBlock.ts deleted file mode 100644 index f509011f4c..0000000000 --- a/ironfish/src/rpc/routes/chain/getBlock.ts +++ /dev/null @@ -1,200 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -import * as yup from 'yup' -import { getBlockSize, getTransactionSize } from '../../../network/utils/serializers' -import { GENESIS_BLOCK_SEQUENCE } from '../../../primitives/block' -import { BlockHashSerdeInstance } from '../../../serde' -import { ValidationError } from '../../adapters' -import { ApiNamespace, router } from '../router' - -export type GetBlockRequest = { index?: number; hash?: string } - -interface Operation { - operation_id: { index: number; network_index: number } - type: string -} -interface Note { - commitment: string -} -interface Spend { - nullifier: string -} -interface Transaction { - transaction_id: { hash: string } - operations: Array - metadata: { - size: number - notes: Array - spends: Array - } -} -interface Block { - blockIdentifier: { index: string; hash: string } - parentBlockIdentifier: { index: string; hash: string } - timestamp: number - transactions: Array - metadata: { - size: number - difficulty: string - } -} -export type GetBlockResponse = Block - -export const GetBlockRequestSchema: yup.ObjectSchema = yup - .object({ - index: yup.number().strip(true), - hash: yup.string().strip(true), - }) - .defined() - -const NoteSchema = yup - .object() - .shape({ - commitment: yup.string().defined(), - }) - .defined() - -const SpendSchema = yup - .object() - .shape({ - nullifier: yup.string().defined(), - }) - .defined() - -const OperationSchema = yup - .object() - .shape({ - type: yup.string().defined(), - operation_id: yup - .object() - .shape({ - index: yup.number().defined(), - network_index: yup.number().defined(), - }) - .defined(), - }) - .defined() - -const TransactionSchema = yup - .object() - .shape({ - transaction_id: yup.object({ hash: yup.string().defined() }).defined(), - operations: yup.array().of(OperationSchema).defined(), - metadata: yup - .object({ - notes: yup.array().of(NoteSchema).defined(), - spends: yup.array().of(SpendSchema).defined(), - size: yup.number().defined(), - }) - .defined(), - }) - .defined() - -export const GetBlockResponseSchema: yup.ObjectSchema = yup - .object({ - blockIdentifier: yup - .object({ index: yup.string().defined(), hash: yup.string().defined() }) - .defined(), - parentBlockIdentifier: yup - .object({ index: yup.string().defined(), hash: yup.string().defined() }) - .defined(), - timestamp: yup.number().defined(), - transactions: yup.array().of(TransactionSchema).defined(), - metadata: yup - .object({ - size: yup.number().defined(), - difficulty: yup.string().defined(), - }) - .defined(), - }) - .defined() - -router.register( - `${ApiNamespace.chain}/getBlock`, - GetBlockRequestSchema, - async (request, node): Promise => { - let hashBuffer = null - let sequence = null - - if (request.data.hash) { - hashBuffer = BlockHashSerdeInstance.deserialize(request.data.hash) - } - - if (request.data.index) { - sequence = request.data.index - } - - if (!hashBuffer && !sequence) { - throw new ValidationError(`Missing hash or sequence`) - } - - // Get a block hash for the specific sequence - // You must assume that the block returned will not be idempotent - // Given that a chain reorg event might cause the specific block - // at that sequence can be set to a different one - if (!hashBuffer && sequence) { - hashBuffer = await node.chain.getHashAtSequence(sequence) - } - - if (!hashBuffer) { - throw new ValidationError(`No block found at provided sequence`) - } - - const block = await node.chain.getBlock(hashBuffer) - if (!block) { - throw new ValidationError(`No block found`) - } - - let parentBlock - if (block.header.sequence === GENESIS_BLOCK_SEQUENCE) { - parentBlock = block - } else { - parentBlock = await node.chain.getBlock(block.header.previousBlockHash) - } - - if (!parentBlock) { - throw new ValidationError(`No parent block found`) - } - - const transactions = block.transactions.map((transaction) => { - const notes = transaction.notes.map((note) => ({ - commitment: Buffer.from(note.hash()).toString('hex'), - })) - - const spends = transaction.spends.map((spend) => ({ - nullifier: BlockHashSerdeInstance.serialize(spend.nullifier), - })) - - return { - transaction_id: { - hash: BlockHashSerdeInstance.serialize(transaction.hash()), - }, - operations: [], - metadata: { - notes, - spends, - size: getTransactionSize(transaction), - fee: Number(transaction.fee()), - }, - } - }) - - request.end({ - blockIdentifier: { - index: block.header.sequence.toString(), - hash: BlockHashSerdeInstance.serialize(block.header.hash), - }, - parentBlockIdentifier: { - index: parentBlock.header.sequence.toString(), - hash: BlockHashSerdeInstance.serialize(parentBlock.header.hash), - }, - timestamp: block.header.timestamp.getTime(), - transactions, - metadata: { - size: getBlockSize(block), - difficulty: block.header.target.toDifficulty().toString(), - }, - }) - }, -) diff --git a/ironfish/src/rpc/routes/chain/index.ts b/ironfish/src/rpc/routes/chain/index.ts index cc28d1687d..8a73e61b4f 100644 --- a/ironfish/src/rpc/routes/chain/index.ts +++ b/ironfish/src/rpc/routes/chain/index.ts @@ -5,7 +5,6 @@ export * from './estimateFeeRates' export * from './exportChain' export * from './followChain' -export * from './getBlock' export * from './getBlockInfo' export * from './getChainInfo' export * from './getDifficulty' From 6dd4e85b80cb69694d0e8b2d0b94713cde7635b4 Mon Sep 17 00:00:00 2001 From: wd021 Date: Mon, 13 Feb 2023 17:41:41 +0000 Subject: [PATCH 03/43] fix typos (#3401) --- ironfish-cli/src/utils/transaction.ts | 2 +- ironfish-phase2/src/lib.rs | 2 +- ironfish-rust/src/keys/public_address.rs | 2 +- ironfish-zkp/src/circuits/spend.rs | 2 +- ironfish/src/network/peers/peer.test.ts | 6 +++--- ironfish/src/utils/bench.ts | 6 +++--- ironfish/src/wallet/wallet.test.ts | 10 +++++----- ironfish/src/wallet/wallet.ts | 2 +- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/ironfish-cli/src/utils/transaction.ts b/ironfish-cli/src/utils/transaction.ts index 3134e06d81..a9cba58a94 100644 --- a/ironfish-cli/src/utils/transaction.ts +++ b/ironfish-cli/src/utils/transaction.ts @@ -37,7 +37,7 @@ export async function watchTransaction(options: { const startTime = lastTime if (last.content.transaction == null) { - logger.log(`Tried to watch tranaction ${options.hash} but it's missing.`) + logger.log(`Tried to watch transaction ${options.hash} but it's missing.`) return } diff --git a/ironfish-phase2/src/lib.rs b/ironfish-phase2/src/lib.rs index 6bba15615a..5c12fe1c23 100644 --- a/ironfish-phase2/src/lib.rs +++ b/ironfish-phase2/src/lib.rs @@ -580,7 +580,7 @@ impl MPCParameters { &mut ic, ); - // Evaluate for auxillary variables. + // Evaluate for auxiliary variables. eval( &coeffs_g1, &coeffs_g2, diff --git a/ironfish-rust/src/keys/public_address.rs b/ironfish-rust/src/keys/public_address.rs index 081166c9cd..54d3e8ff52 100644 --- a/ironfish-rust/src/keys/public_address.rs +++ b/ironfish-rust/src/keys/public_address.rs @@ -17,7 +17,7 @@ pub const PUBLIC_ADDRESS_SIZE: usize = 32; /// The address to which funds can be sent, stored as a public /// transmission key. Using the incoming_viewing_key allows -/// the creation of a unqiue public addresses without revealing the viewing key. +/// the creation of a unique public addresses without revealing the viewing key. #[derive(Clone, Copy)] pub struct PublicAddress { /// The transmission key is the result of combining the diversifier with the diff --git a/ironfish-zkp/src/circuits/spend.rs b/ironfish-zkp/src/circuits/spend.rs index 21d7d49a41..19d5e6dcec 100644 --- a/ironfish-zkp/src/circuits/spend.rs +++ b/ironfish-zkp/src/circuits/spend.rs @@ -201,7 +201,7 @@ impl Circuit for Spend { 256 + // asset generator 64 + // value 256 + // pk_d owner - 256 // pk_d sender (this is added to match requirments for `Output` circuit) + 256 // pk_d sender (this is added to match requirements for `Output` circuit) ); // Compute the hash of the note contents diff --git a/ironfish/src/network/peers/peer.test.ts b/ironfish/src/network/peers/peer.test.ts index 72f0196c0e..7a061f53d9 100644 --- a/ironfish/src/network/peers/peer.test.ts +++ b/ironfish/src/network/peers/peer.test.ts @@ -346,10 +346,10 @@ describe('punish', () => { connections: { webSocket: connection }, }) - const onBannedHander = jest.fn() - peer.onBanned.on(onBannedHander) + const onBannedHandler = jest.fn() + peer.onBanned.on(onBannedHandler) peer.punish(BAN_SCORE.MAX, 'TESTING') - expect(onBannedHander).toHaveBeenCalled() + expect(onBannedHandler).toHaveBeenCalled() }) }) diff --git a/ironfish/src/utils/bench.ts b/ironfish/src/utils/bench.ts index 112967e84e..0915a5b78c 100644 --- a/ironfish/src/utils/bench.ts +++ b/ironfish/src/utils/bench.ts @@ -47,7 +47,7 @@ function getSegment(): Segment { if (global.gc) { // Need to mark and sweep multiple times to try to collect all of it. You - // could also just continue to do this until memory stabilizies but this + // could also just continue to do this until memory stabilizes but this // is good enough. for (let i = 0; i < 5; ++i) { global.gc() @@ -77,7 +77,7 @@ function endSegment(start: Segment): SegmentResults { } } -function renderSegment(segment: SegmentResults, title = 'Benchmark', delimeter = ', '): string { +function renderSegment(segment: SegmentResults, title = 'Benchmark', delimiter = ', '): string { const result = [] result.push(`Time: ${TimeUtils.renderSpan(segment.time)}`) @@ -85,7 +85,7 @@ function renderSegment(segment: SegmentResults, title = 'Benchmark', delimeter = result.push(`RSS: ${FileUtils.formatMemorySize(segment.rss)}`) result.push(`Mem: ${FileUtils.formatMemorySize(segment.mem)}`) - let rendered = result.join(delimeter) + let rendered = result.join(delimiter) if (title) { rendered = `${title} - ` + rendered diff --git a/ironfish/src/wallet/wallet.test.ts b/ironfish/src/wallet/wallet.test.ts index 962098c5c3..6e6f4726fe 100644 --- a/ironfish/src/wallet/wallet.test.ts +++ b/ironfish/src/wallet/wallet.test.ts @@ -702,7 +702,7 @@ describe('Accounts', () => { expect(node.wallet.getAccountByName(account.name)).toBeNull() - // It should not be cleand yet + // It should not be cleaned yet await expect( node.wallet.walletDb.loadTransaction(account, tx.hash()), ).resolves.not.toBeUndefined() @@ -1805,9 +1805,9 @@ describe('Accounts', () => { await node.wallet.updateHead() - let accoundAHead = await accountA.getHead() + let accountAHead = await accountA.getHead() - expect(accoundAHead?.hash).toEqualHash(blockA2.header.hash) + expect(accountAHead?.hash).toEqualHash(blockA2.header.hash) await node.chain.db.transaction(async (tx) => { await node.chain.disconnect(blockA2, tx) @@ -1815,9 +1815,9 @@ describe('Accounts', () => { await node.wallet.updateHead() - accoundAHead = await accountA.getHead() + accountAHead = await accountA.getHead() - expect(accoundAHead?.hash).toEqualHash(blockA2.header.previousBlockHash) + expect(accountAHead?.hash).toEqualHash(blockA2.header.previousBlockHash) }) it('should update the account unconfirmed balance', async () => { diff --git a/ironfish/src/wallet/wallet.ts b/ironfish/src/wallet/wallet.ts index 6fd7741623..54aaff4817 100644 --- a/ironfish/src/wallet/wallet.ts +++ b/ironfish/src/wallet/wallet.ts @@ -1019,7 +1019,7 @@ export class Wallet { * Checks if a note is already on the chain when trying to spend it * * This function should be deleted once the wallet is detached from the chain, - * either way. It shouldn't be neccessary. It's just a hold over function to + * either way. It shouldn't be necessary. It's just a hold over function to * sanity check from wallet 1.0. * * @returns true if the note is on the chain already From a2369c51913124a27f1eac511acb0204c0cdc92a Mon Sep 17 00:00:00 2001 From: wd021 Date: Mon, 13 Feb 2023 17:43:33 +0000 Subject: [PATCH 04/43] show asset name in human readable form (#3388) --- ironfish-cli/src/commands/wallet/mint.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ironfish-cli/src/commands/wallet/mint.ts b/ironfish-cli/src/commands/wallet/mint.ts index f08d0105cc..87a67ccbe5 100644 --- a/ironfish-cli/src/commands/wallet/mint.ts +++ b/ironfish-cli/src/commands/wallet/mint.ts @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import { + BufferUtils, CreateTransactionRequest, CreateTransactionResponse, CurrencyUtils, @@ -319,7 +320,7 @@ ${amountString} plus a transaction fee of ${feeString} with the account ${accoun const minted = transaction.mints[0] this.log(` -Minted asset ${minted.asset.name().toString('hex')} from ${account} +Minted asset ${BufferUtils.toHuman(minted.asset.name())} from ${account} Asset Identifier: ${minted.asset.id().toString('hex')} Value: ${CurrencyUtils.renderIron(minted.value, true, minted.asset.id().toString('hex'))} From 17338fa75189ebfe05546ec3fc2965586bfc3b92 Mon Sep 17 00:00:00 2001 From: Jason Spafford Date: Mon, 13 Feb 2023 12:43:49 -0500 Subject: [PATCH 05/43] fixes Test Failure: Keeps spends created by the node when rolling back a fork (#3377) * Demonstrate test crash * fixes failing test and regenerates fixture failing test was creating mismatched fixtures: a transaction with a fee that was not included in the block fixture sets the fee for the transaction to 0 to match the block fixture and teh rest of the test logic --------- Co-authored-by: Hugh Cunningham --- .../__fixtures__/wallet.test.slow.ts.fixture | 60 +++++++++---------- ironfish/src/wallet/wallet.test.slow.ts | 2 +- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/ironfish/src/wallet/__fixtures__/wallet.test.slow.ts.fixture b/ironfish/src/wallet/__fixtures__/wallet.test.slow.ts.fixture index 44e0fec280..ae15a32704 100644 --- a/ironfish/src/wallet/__fixtures__/wallet.test.slow.ts.fixture +++ b/ironfish/src/wallet/__fixtures__/wallet.test.slow.ts.fixture @@ -179,20 +179,20 @@ ], "Accounts Keeps spends created by the node when rolling back a fork": [ { - "id": "684ca211-cecd-43ad-9a6c-b51715b14282", + "id": "9472f2bf-a143-49b0-87d5-12bc8435eade", "name": "testA", - "spendingKey": "a8963163096f42840e61927c826644732c1e94142d2f19379df4941ba3b0d432", - "incomingViewKey": "1e0decb520e8d00b9d8de635e30f474015c52df754c44ac14584a29e2d248707", - "outgoingViewKey": "cf665b6a1d5ae1dac5eee9b68b40186abee15ffa046b139a12acf8845558cdea", - "publicAddress": "2908b57abb8173a1ad3cb7c480d3fc63e1e9109c0f69799c41e1087c15075f8f" + "spendingKey": "1722e116eb82e4de523fb15bc7a58f8741373f018ed552a7299ef90b8333f3fc", + "incomingViewKey": "3b583b87e2515663f2e5bcf5fc33c8b7469c2d0f81ca8d46b7559a76ec0ba600", + "outgoingViewKey": "9005c94c295a3dd585235bb3becfbaf3e77e6ab6f7652e44bda21629c9e06c62", + "publicAddress": "9a87bcb21513d8b0db7cdc66f0fb8d666ddba8afb27752b52a470a0b5aca5ca4" }, { - "id": "5b00cb36-b7ee-4df8-a329-565e4219bcc8", + "id": "9707fc87-1b1f-40c1-a38a-8f20afb0b4dc", "name": "testB", - "spendingKey": "83af65fb5a9c8774149d019848d0705227e731373087a45d6ecaabc85e3040ae", - "incomingViewKey": "22f1ccea7604d93e6d19baf5ad863760fae9ec70dd1c70ead8ce56cdf9d3d200", - "outgoingViewKey": "5b227576bb269c0d09d29aaadbaac230e4eca660deece8acf7c9a9d81c209b3b", - "publicAddress": "c2f56c557c07f993d92ac7e1c8730370c0d0d94cdfc4f5169710d6b3ea28f863" + "spendingKey": "a64cb89f54efc79911ac15db2839c55139d6442f3a9565d68b1224f38305ad15", + "incomingViewKey": "397a36401fd9d8aaf5b1e086711fc6a23f8239600f8f166013e0db9eaddd0907", + "outgoingViewKey": "d11278405078f6a5afa8c31a8244e9cc3b7b52ce8d544ba760b127639e83201a", + "publicAddress": "f58c7ee88beb545f0138425136c58234ac314ac00f26ae23a66123e11d8b0b1b" }, { "header": { @@ -200,15 +200,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:Ir5zIad6P+HLDH82YCkT1EWZZU9ZS+IkxmGT4c3kdmA=" + "data": "base64:WE1o3enLy6XUDLqrVB82gDvC+BoqR9RbzNiiK+i1aik=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:Tdc8sJK9xI69c3FeWj9DuOmx14iHRUeEy9Dm0ek8TIo=" + "data": "base64:JZpe3ZSn6bXJy35Z/p6E++r41nCCqjvEb+2VNsbwnkM=" }, "target": "115792089237316195423570985008687907853269984665640564039457584007913129639935", "randomness": "0", - "timestamp": 1672870270392, + "timestamp": 1676062789830, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -216,25 +216,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAbU6qUG5TQPj5uaM9T54y3Rb+Y1X2+U2nG1OUA8ZF/jGxhtZ7ssMIaoYYUkkvc1xNtm6fmneaN3uYmUgAS0ypkvkiBIfP2UhjsyK1MEa86q+1LjtDWdbijCQOLzKvGoOcIyhvOD3zwOHPzZ+mSVfUGYXrwujhXE5K700pvrAFDgwDkDETk5IL2XcnPw8RcVvn0pdIte5iGILvSaFehZS7gcUIdk38Zb4OtRr4NXbY95KtE4ka7LRhXb2Ln6kBrthfPvlsyCx5+xBMVqNC84EakpfMONjgDC+CF6axuzl9cRs7+ONGsILjFdN33QnfxJ8Gx+3skJBB7k1Zsa8UqlZfODLC6j0yBGNxB3aP2No4GIODrKnBLimjaJns4FMdAQZQU9w9tRL9H6iVZ+QvrZNY76CeL1l9dQC0xBCBbpMVnu5cMrm3RUCZ3sDdHsnGUuii1KB+y/qk4j9i2V5xhkLT+IstxMMIaOWfSBlUJOw1gwayDA+ak2iJ+VZrOvzMsypAuIOx8c6Bl00R1VKzMyUVeBX0ntyjTVJordvMQgQrtw0LQX5UFMhuglVXS2UZTfavzxnlwZ795YGskA5JQrz75Hu9tcQ5O9e8kPCUE83SJkwOSogOk5fGJ0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw6culkLNejfpKfYcuAuA83Icg0Rm/KuoJUnrrFQf2j4DuLuVz750KD3ljW8SdegPm2NH2zrDAfVWXrdgYpBRsAQ==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA9FxUKdmPWhQ26RcjgBlLxt4Yn/tKOht80dfLX4FJu4WtdpSaIc0I9Lq/eWfqfMPkOtll9n+S/LUlmbpYTSKUlq7ClFXxKhrOHwitG++usPSidgVOUdbh7bX4kGuQnWs1WTmjxod3IQfyA0s6/6+fGwXrxWoMQ1bF/PzbGRq4kmoFjLIYny0l+hZegUO54wBTHhgaOs1SWkVKwt9ozE4wHfigoRj93M/8e3ZruECKPiWVY30l32KT+KIvw4WSh4gsyEZa3CHNzuhIM81yYFtZTaWP09jzeLIJHBNERiUhuAxQ4g8iU/9gcMhGqwslCr2jEj6BBtfksg2Z6Mw/+B3kM8GRxgIu8WpK+/tXgldwT6jQALDOonQw15FxiyR1kSA1u19Rm50kihfuRtm8qHiQBvjlWPa/6NI2PulNKFrCSMmZCWdaYJHhBrU56rOkzvsYUXizPHMOUv/ICgNAW64P4PkFmYw8hkNfn2QB4laxfDMMsXQWh47XktuPL8S9BvaAFxzKn4NFkvFpD/LXaMeW/S73wwdhzJmMzAqkAnw0WHPvblSv9PYtDwzdk4uNLyaOuVS5ccLMsz0HaBMbrHTjy6eo64PVVq238vpS3TD4MDUnSYoeQspbRElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwBHWyqtZmu46WW9Cs8UgsguWh2VBAOTeugru9imBjWIfXCcQZW/H/KuTjQOuogo87YaCXYvcJ7egN697q8dcKBw==" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "D41752C8A47105D08E1B266255DA8C956780409330B7EDBFA478D432EB8DD9D9", + "previousBlockHash": "D8ED38D26AAFB10EF33E908DD1BA6E032E975FEC0A47E1FDB79A7D1A42EA2B94", "noteCommitment": { "type": "Buffer", - "data": "base64:HXCstmcsinz6OjYp4FZxGYPaowbcAY0VIgO1azJ4dQM=" + "data": "base64:IiaI48pikkfYRs+tt67a+IGYDApRlgcgsETTZ624IyE=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:QZQ/XiRlAz7WC2Uae8/aX5O3PW9zL78tWsYXwqatp60=" + "data": "base64:xBuJvPQQbbMJYRjT/yGR7ZFfguqVN4KGb38O0OSP0co=" }, "target": "115792089237316195423570985008687907853269984665640564039457584007913129639935", "randomness": "0", - "timestamp": 1672870272448, + "timestamp": 1676062792668, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 7, "work": "0" @@ -242,29 +242,29 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA05fQIloI+byliiqLN6pUCF/jXwKwF3tG4gTvXXD9e2qqglzg4z7tOOOuhUumgGqVRncN5O5YH/ug7eBFw+y46mAnx5BB4pWdTY25DQSVTC2ZdgX8OaTpLUHPX+LJ0D1R2xxu8HVUi74nvsP14w8+c9JbJtD4EFvKXZyj9HP8zUYE+KxvyZG9LSz/nSNg2cqLrO4MToQVjYcyowi5cnNI2CyzHOwo19G0bT/nqAdL16qVFcsPFQp9yuJb09ZAWibN1AIvlJfy/SJ8fr+ItFaYjSIittVEgSLKzSLQcdLBy2zJXzP1T7RE2WhUrt1XMyRhcjqYC6M9jZ5RAp585klkGAzdOAyr/DjBesGcMr8HOuJB1kwZdatDOImSOBfqGKUZ7nDo1AM9E2G4XzUpmDIq4otnsUZBvuglISCZDTDHdOwJgoS3wrpiCZU9wGaEX3VYKWxaZTFI/TSxlLgn2N1JkYhvoHCEvNMnlPUllOsLmsRT+v0xIJUVqr25jJHB8Y87rUtr/2dscdusNVf02zKgPHBn4HS7lP10yobv2N5C5Iiu6BAmMu04fnZC3wK7bghspLeqkZZ5bkgLeqLWZdAzweFPXujMus6sELLo6ANITXqak7O+S+DRRklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwh/3BywZupdQj54vuNKgPuIVygwdg3x3mqJukQMQbWidagMG0fU0L9MkVIDq6cYGFOtOgpBDKY3x6j6YpMTbLAA==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAoZw3x673MNq9tLwhFQDBHbgSGvDqRzFbO9874N50XbCxhDliswM4IpayTgDK68b3+S0FmiidvioddAADvIkjbrPooY1Ji7eNUbDFARe5mRGPzwcn5Zfo/+m0hcsd4qfTGksTeN7yQp5MRpX7XpsYxgquqZx/MDzfS2Ozj2KyoHUHOiJaGJMgPKGwJWu/zPsCucmPRILFj1TsEU5jzsfRqtrxBft2JAaWU3Btu7QdpMiDU9kvdXIRS3EejQftb21JiWBE8/FUNat9QPoaBZFXe5kL4AeGUZ8oKDgtoyx05oco20/7CyLAh2mhBE3i9qx4nhrqXOlXuanFwe48/nZjuuZgfmZNyBdDpwzEBxyvDy6KIb92om6SdohFTDqhzSFGsAj3twBIt9yiy3ALIfbQ4iVpzkZ87OZhSEHdj0h+SIIS/Hpmoal+pdxF72JrlDJv4aKUWLkKt8xbVQ9p1GzxgjzYm1o/t6IjTkPdi5WWl/a2KoSlUOG6KjOpkfQpmULqZAtgeIcAMuCqUKaKSKWasq/vpMl11tkPSoT56rnX+tRjbrMavoWS8GpHcCSULDXFizwSPjv0RWPelH7b5FWE5pjYIE8HE94auQJtGi4bpR2WWnAxbkeZG0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw/wh6B3maG5YXgCwm6j4TJMNucQxgVJrnlf6QRmQTIASyj01c4aOmNKTLevFhYHHLjCjPyFgqZze1HjN1GUR2Dg==" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "D41752C8A47105D08E1B266255DA8C956780409330B7EDBFA478D432EB8DD9D9", + "previousBlockHash": "D8ED38D26AAFB10EF33E908DD1BA6E032E975FEC0A47E1FDB79A7D1A42EA2B94", "noteCommitment": { "type": "Buffer", - "data": "base64:2Iv/2UNo2ZB1PnWj2u1f/zZnpzoGhvYJ9vfUQE8cg1Q=" + "data": "base64:Hr3w0gPTdmYEydTBlMciePP0Mgv9BMBt2Wvdb7O8d2w=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:eCAMwbgvFnT9jbRRYwdb49Szx4qXKZd+nx19zhepDAo=" + "data": "base64:RGpKggIwMjdEeFeEwm0FVH+dB3M+Wyrf+83W6aSIYSI=" }, "target": "115792089237316195423570985008687907853269984665640564039457584007913129639935", "randomness": "0", - "timestamp": 1672870272801, + "timestamp": 1676062793109, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 5, "work": "0" @@ -272,25 +272,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA/FR8NGyv18HJuG0fV1PxFE9kXF2y2tBsCuoOU3Rr6m2Lz1WMR03iQ3gVvrgy2+SCUJ/PFRMn0kOQjc7BBuO5HjXDvp4rOwWpgaBJAwkwbE2C+gvYDitd+dy/Z1shZWHg5phHqBsLguJBBifj1Kxt9SlgeFd9jKhL61Go9uwnm+EEKLP/PkSV2JPh9hGO0H9W854bxsonN6GHMiKiRmDgN3uBWVI2Wy8kZ9aJCNPOJQCxDE57SFSNBUCpJwmwo3B9wdxNkneykIgMq77QK4IcBUufqqqINysDfwkAvwM131eIdy6TeBjdpaqA8jgHbctfn/9sTzgmyHN0LkyKmd6IWCDgAKjzXkPL0JM5+ylhrz0flkPT5HHA2M1MATR+PUhEuonKJ687UjkVIinX7sSnEQ+r5YNuwUUIFWyhLTrBFT80d8ZI435SDf6AY6OFNpKZThKndbs8qaBKD+y6Tdz3JiTiCY/LO/3yeU/wT4ZTQZJOdHa2J5PWwMNrgZRq1zKIdIcTnAVrC4GShcMWSnWclkAq7avxnb/9SibbK9Qn2XV4563tTYe2dcCQWLt7MHaH4txCUA3FRDDojDocSkaevcLdxjjWN5NEyrN1AiaXLeKivlpqCLHzqklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw60ylh1IU0M3lFiZm2wP4Rwekl/7L47k+5O6m+Au5vuBSfJyAcG+IhwmWDJaCTp2rizDbxiEo0Dvx6xJM7Ti3Bg==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAECc8b7Ahn81tcX9O7ZH6TFFed2drPrm6WFVcSo6cqUqkAF09Do84T7peOkCv2h/QMpMFW7ec8TV1mGbT0q2Ilhx4me8f5BVEqBfF6mE5bRyP+3ldt/WWw4VlRq0NyhUdJBw4ck8m/2YSCmOK+j6ctRzYckdKQdNhCrRCb3V3zYoH9bEnE0JN3uEKzEU9XrdFmYGpbi86OyTsLhACVQ+ZcsPksOXutGLWCbUHSvIan0Wl6aYx/PjuJLdUO44rZpNMnEC8uOYmwjc3jiHjUht9JNCXsEGMMkTQYNdwXJ+gtni5JXgNKGqe6df93CX5oAJ126e5kOkJL+YpNnqe0D4huIl6pT1eNOFkLKoD/rLqd2fLTgCdCVDnO7fHjQnbobBV2J8EYacMqJKR+QDAu7E93r67emaKhnR3H+M19QCy6TPf+4AblzuCjesbbS75hkCLT82zxN/MQB5NSGwGAl3lHBY5w0eUC/s0leMJtQifGqkaA/iETvg8ihPvpCZ0X1VLGI9ncGj2fgvmMmzDKuqJjZp3G8zBAfKUU6SvRrFXGoMPAg6xmRvpbzHLPjI57ZbGIFpcnvk8Qg9GA9fHLQBDdOdUZWBmUEFe/QaCO0xN0i7Adi8FACvTC0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwpBSZ2PKVxH56WAaLExqrYPpYUXA/vLxtR+v3FdNeugpDS8Ysa8adzkz6YwxdxIdl4uqHcSdeat0L28a/FxvvAw==" } ] }, { "header": { "sequence": 4, - "previousBlockHash": "D3DA7E63CCF96B8B024097E56BA1A0AD9FCFE966FF9FAF4A10B151814C62A986", + "previousBlockHash": "BF95939CA8A3253C89B4D3DB4F4D1675ADBFAEDCD83DB9B1FA220D6530E43921", "noteCommitment": { "type": "Buffer", - "data": "base64:jsJ76rrrL3DxsrICnk3LSAH7ProFw87xzPMtcG0zPTc=" + "data": "base64:q+nfeTw024tq9a/wsgfG22i/haJIfwp7FsH57DfPlV8=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:8vZTzSyL0Tnw1ky3kvWRJZuZxq3TD0tBY8dTSsNhn2s=" + "data": "base64:mOQapkklBDzYlzHuQPuWZnGd7qMtgXBHx4CNGb4UFPM=" }, "target": "115792089237316195423570985008687907853269984665640564039457584007913129639935", "randomness": "0", - "timestamp": 1672870273186, + "timestamp": 1676062793538, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 6, "work": "0" @@ -298,7 +298,7 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAcqLQSkI9VNlmmMGyKNHJWbXM+wn5u6Uuf+ulOJbZFQ+xC9uFI+GowN1g0NNsmor7SewkOwd5lUWalwN6Kf7H6BL3Zj8lBHrI0ZqngFArtXuztc2Y052sj2SLT6RVpAcj+CoEFUZ2+RsQGtYMrtfisVsxos2bWHAbCfH6SOaglPQQD8vIk6tSLqto5lYfcKWd8bY7qqsp66D9rQm4Mk5BnOqs7ueC68BCjtDHY34tSf2VAHvOzlol/yru/7q17Znq3JUrXfCFqjOynZLWNb853CC0F6ylVLnbktnc65Hxs1A8ARGRbrWASkAMstbzZ6m0QPnotZ5A+zuFc8iPn0lwRu4n4q8A22FwXhS4xXwyFHy86hWbIO+0JkfThmV9KQltRHK1vFQDcNn6XOz9kTrcgYWJNaIFAl5iPwG3RYdF4WJQjQ5IE8BUIVzr++ZdeuX0wJjw81PdxKVl2/kD2ys/8z7mnPl6R5zKTuCd5c23uzSQlL6UUGKWzdLrNdZgZchuKKYZWafKY0evOyEODslMlQYMYICK/Rh3nMoAKxrH0DOtOgfy8XeburIsGShVWRXssjzTwaJe/cgG4/BE+4PuVDICzOgOKT3bql4Z5HIkFhnzAAOIgUXzDklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwzp4wTaPUBO87gVDF7byxwNsw9Xxt/w2WJZ5ohWlBGpJlbomm+M7nJ9vg2eyzHHKjKZDq+DzFWXWLI1K2GYKxAQ==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAN7SKa8eskWCmMKAE99xNk6+VLiZSp410XTstxwy/Ds6p7pPqqPUZVVG7JIKGs513zHaG4fFTvXn5L2ECCp1o9NsIs+t2C1xOH+y3rAtNTbeyOVRUa/nSbVzsfjANjHLibXtsQfPpSx5SmHRv2hwyIZc9CI53F0hJ2udSF7TTAwAUHtLbSpIQJ0RojK633k8uEwZLu+FJ1HfXUsvwczxkI0eh9CAN74ur/atrY9h7M3qHGglzIRfohm8latVJJQiGYlnvbWi7ES800jyEfVJ9yNTX7f6GqiZq1bvWQ8UVRBP3DMJ2iz9MoXfmRqyyvn2VpsMkv92ysRO+XSAX+JCfxt4zx8mCoTPCjoo8S/4RJfnMxA5z5n0hgu51GBtXXG8A/1YiPyzGsSy+A5gSDXV6M/erjlYH24QY+0WXjG++sj783BNFgqTyRjt15DKYZ2A/wIli4NCgK0FzSAPArFUJvcvbpS0L5wC7Zdm8BkMBS96dsYPgWynux+OdIUb5cY14IAhf7UnxRr00bN9l8PdMfptfmushd/Bd19EOa+4tabu/zaFG2+LeVFEXmptjcjSvmz9bQ6MdvCKvC2w21GC6OmIYBlPVf3ETbavyPdDGdb015x9oGUyx1Ulyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwD81lZ27/VheKDXMGuSpvfhvDG+x3Q4uUYfYmiZh5bIfzLuRbuMpOsq176pJn9+w835M4HMwWvo0MxtiU9GtICA==" } ] } diff --git a/ironfish/src/wallet/wallet.test.slow.ts b/ironfish/src/wallet/wallet.test.slow.ts index 8033c7ba0f..7eb300e773 100644 --- a/ironfish/src/wallet/wallet.test.slow.ts +++ b/ironfish/src/wallet/wallet.test.slow.ts @@ -667,7 +667,7 @@ describe('Accounts', () => { [], [], { - fee: 1n, + fee: 0n, expiration: 0, }, ) From 82342499519b58a435a8b0a1286dd429b7495af4 Mon Sep 17 00:00:00 2001 From: lovedret Date: Tue, 14 Feb 2023 02:57:01 +0800 Subject: [PATCH 06/43] Human readable mint desc&error (#3362) --- ironfish-cli/src/commands/wallet/mint.ts | 2 +- ironfish/src/primitives/rawTransaction.test.ts | 4 ++-- ironfish/src/primitives/rawTransaction.ts | 13 +++++++++++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/ironfish-cli/src/commands/wallet/mint.ts b/ironfish-cli/src/commands/wallet/mint.ts index 87a67ccbe5..41fe7f7869 100644 --- a/ironfish-cli/src/commands/wallet/mint.ts +++ b/ironfish-cli/src/commands/wallet/mint.ts @@ -41,7 +41,7 @@ export class Mint extends IronfishCommand { }), amount: IronFlag({ char: 'a', - description: 'Amount of coins to send', + description: 'Amount of coins to mint in IRON', flagName: 'amount', }), assetId: Flags.string({ diff --git a/ironfish/src/primitives/rawTransaction.test.ts b/ironfish/src/primitives/rawTransaction.test.ts index 50c949d822..7e94a2dcd0 100644 --- a/ironfish/src/primitives/rawTransaction.test.ts +++ b/ironfish/src/primitives/rawTransaction.test.ts @@ -118,7 +118,7 @@ describe('RawTransaction', () => { }) expect(() => raw.post(account.spendingKey)).toThrow( - 'Cannot post transaction. Mint value exceededs maximum', + /Cannot post transaction. Mint value *.* exceededs maximum *.*/, ) }) @@ -170,7 +170,7 @@ describe('RawTransaction', () => { }) expect(() => raw.post(account.spendingKey)).toThrow( - 'Cannot post transaction. Burn value exceededs maximum', + /Cannot post transaction. Burn value *.* exceededs maximum *.*/, ) }) }) diff --git a/ironfish/src/primitives/rawTransaction.ts b/ironfish/src/primitives/rawTransaction.ts index 6fa7edd3f9..5a358ae79e 100644 --- a/ironfish/src/primitives/rawTransaction.ts +++ b/ironfish/src/primitives/rawTransaction.ts @@ -13,6 +13,7 @@ import bufio from 'bufio' import { Witness } from '../merkletree' import { NoteHasher } from '../merkletree/hasher' import { Side } from '../merkletree/merkletree' +import { CurrencyUtils } from '../utils/currency' import { BurnDescription } from './burnDescription' import { Note } from './note' import { NoteEncrypted, NoteEncryptedHash, SerializedNoteEncryptedHash } from './noteEncrypted' @@ -60,7 +61,11 @@ export class RawTransaction { for (const mint of this.mints) { if (mint.value > MAX_MINT_OR_BURN_VALUE) { - throw new Error('Cannot post transaction. Mint value exceededs maximum') + throw new Error( + `Cannot post transaction. Mint value ${CurrencyUtils.renderIron( + mint.value, + )} exceededs maximum ${CurrencyUtils.renderIron(MAX_MINT_OR_BURN_VALUE)}. `, + ) } const asset = new Asset(spendingKey, mint.name, mint.metadata) @@ -70,7 +75,11 @@ export class RawTransaction { for (const burn of this.burns) { if (burn.value > MAX_MINT_OR_BURN_VALUE) { - throw new Error('Cannot post transaction. Burn value exceededs maximum') + throw new Error( + `Cannot post transaction. Burn value ${CurrencyUtils.renderIron( + burn.value, + )} exceededs maximum ${CurrencyUtils.renderIron(MAX_MINT_OR_BURN_VALUE)}`, + ) } builder.burn(burn.assetId, burn.value) From 3e829636815394787d0829101d288c81c8af3c46 Mon Sep 17 00:00:00 2001 From: Rohan Jadvani <5459049+rohanjadvani@users.noreply.github.com> Date: Mon, 13 Feb 2023 16:21:09 -0500 Subject: [PATCH 07/43] refactor(cli,ironfish): `getBlockInfo` -> `getBlock` (#3408) --- ironfish-cli/src/commands/blocks/show.ts | 2 +- .../src/commands/service/sync-multi-asset.ts | 4 +- ironfish/src/mining/pool.ts | 2 +- ironfish/src/rpc/clients/client.ts | 13 +- .../__fixtures__/getBlock.test.ts.fixture | 168 +++++++++++++++- .../__fixtures__/getBlockInfo.test.ts.fixture | 188 ------------------ ...{getBlockInfo.test.ts => getBlock.test.ts} | 22 +- .../chain/{getBlockInfo.ts => getBlock.ts} | 16 +- ironfish/src/rpc/routes/chain/index.ts | 2 +- 9 files changed, 191 insertions(+), 226 deletions(-) delete mode 100644 ironfish/src/rpc/routes/chain/__fixtures__/getBlockInfo.test.ts.fixture rename ironfish/src/rpc/routes/chain/{getBlockInfo.test.ts => getBlock.test.ts} (83%) rename ironfish/src/rpc/routes/chain/{getBlockInfo.ts => getBlock.ts} (90%) diff --git a/ironfish-cli/src/commands/blocks/show.ts b/ironfish-cli/src/commands/blocks/show.ts index 41314d9cf6..7abc4df3db 100644 --- a/ironfish-cli/src/commands/blocks/show.ts +++ b/ironfish-cli/src/commands/blocks/show.ts @@ -25,7 +25,7 @@ export default class ShowBlock extends IronfishCommand { const search = args.search as string const client = await this.sdk.connectRpc() - const data = await client.getBlockInfo({ search }) + const data = await client.getBlock({ search }) this.log(JSON.stringify(data.content, undefined, ' ')) } diff --git a/ironfish-cli/src/commands/service/sync-multi-asset.ts b/ironfish-cli/src/commands/service/sync-multi-asset.ts index c7a89d6430..bbdab38927 100644 --- a/ironfish-cli/src/commands/service/sync-multi-asset.ts +++ b/ironfish-cli/src/commands/service/sync-multi-asset.ts @@ -95,8 +95,8 @@ export default class SyncMultiAsset extends IronfishCommand { let lastCountedSequence: number if (head) { - const blockInfo = await client.getBlockInfo({ hash: head }) - lastCountedSequence = blockInfo.content.block.sequence + const block = await client.getBlock({ hash: head }) + lastCountedSequence = block.content.block.sequence } else { lastCountedSequence = GENESIS_BLOCK_SEQUENCE } diff --git a/ironfish/src/mining/pool.ts b/ironfish/src/mining/pool.ts index 5118706db5..8d36ecdb2c 100644 --- a/ironfish/src/mining/pool.ts +++ b/ironfish/src/mining/pool.ts @@ -538,7 +538,7 @@ export class MiningPool { const unconfirmedBlocks = await this.shares.unconfirmedBlocks() for (const block of unconfirmedBlocks) { - const blockInfoResp = await this.rpc.getBlockInfo({ + const blockInfoResp = await this.rpc.getBlock({ hash: block.blockHash, confirmations: this.config.get('confirmations'), }) diff --git a/ironfish/src/rpc/clients/client.ts b/ironfish/src/rpc/clients/client.ts index 84716dc51d..6951981007 100644 --- a/ironfish/src/rpc/clients/client.ts +++ b/ironfish/src/rpc/clients/client.ts @@ -21,8 +21,8 @@ import { GetAssetResponse, GetBalanceRequest, GetBalanceResponse, - GetBlockInfoRequest, - GetBlockInfoResponse, + GetBlockRequest, + GetBlockResponse, GetChainInfoRequest, GetChainInfoResponse, GetConfigRequest, @@ -450,13 +450,8 @@ export abstract class RpcClient { ) } - async getBlockInfo( - params: GetBlockInfoRequest, - ): Promise> { - return this.request( - `${ApiNamespace.chain}/getBlockInfo`, - params, - ).waitForEnd() + async getBlock(params: GetBlockRequest): Promise> { + return this.request(`${ApiNamespace.chain}/getBlock`, params).waitForEnd() } async getDifficulty( diff --git a/ironfish/src/rpc/routes/chain/__fixtures__/getBlock.test.ts.fixture b/ironfish/src/rpc/routes/chain/__fixtures__/getBlock.test.ts.fixture index 2bef165b18..2cf4d19d33 100644 --- a/ironfish/src/rpc/routes/chain/__fixtures__/getBlock.test.ts.fixture +++ b/ironfish/src/rpc/routes/chain/__fixtures__/getBlock.test.ts.fixture @@ -1,20 +1,20 @@ { - "Route chain.getBlock responds with a block": [ + "Route chain/getBlock Processes hash and sequence inputs": [ { "header": { "sequence": 2, "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:1DsvhJ5gJ0Scj8V+BtDE1yNsXGRb5ZVCckHtW3pOcEg=" + "data": "base64:WrvfekEegOH5/XoRADicDmWgHttdTdMI3/3vA2LYSD8=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:O5HQ5yDYjcywnFilFqzwpKfCEnAVuoa1/rf2XsygP2U=" + "data": "base64:RorOFNv7/MOhHOS21QvIArI/hS+y9G2GQ8saesSEpgM=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223331718, + "timestamp": 1672935256225, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -22,7 +22,165 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAEDIbMBlxAl+CgAeaMglkYCQr9J8TffkpzN3I0Wi7ycOlofu4riJXqnZ90ekEGlhAXiOBz6N5p4ynv8GycVO567L7cKMDrItie/2x0tNfhP6YKFkcreOfhxEJZr2O5ypl67BChI2OU/iD+28r3tb5kgcOkZmvHidBnaY9MI0cn5YDVs5JX+w+RhCuoF//V8/ea17HMn8rtPw2eBj3BpFA3TFjpibpK80wHivRkhl8yASxNDqNaNhid+3rIhLlGc+ioSzZqFo6KlUiEzxQ7nkrDtKKmnRl8a6UpfpOWA5I4+6Xg9zmP+6zcrwqnEx1Rcq2vU2zTMnhP7pzFKfukQ9t3LGJopG+wx1p1b0WHe9rViwtlLmU8ceqzNI2cgI6diAsJBEiyL9vMasKfN7IBrfkfIpRu5+h24Y7DMyEJIbHgJBc2fGvVKDhbsMBBA0Zb1qabw4kwXamZkwa0u7jvkKgzLRpW4LxfflO9HqAMz1GqeYwQ7bUrOsD06lpOUNrJ7w3WtSfKOMKFrn8z3H+8BXHxUl7X4zicGiAWxTDVwYabsk1T5WzBrczaj9cw5LEBEdhhaHPPmqWxMQdcnzs50X1x7auchaY/qGTpKrIkbWaNtb798WaCGDQRklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwpI8hfSlO1VQ2civuOt7GXNqeqp/iffTEtA9qg8OWpa2LTFJhBlVIRPwd1UKqIYFYr+OBccfcB+4kVSOYwyflBw==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAlQeVr9LFJRsD2uDtDCgir9oWC0p4Sgj2nN5pm+nqw22QgclKFucBvNTydIvTvGF6fIiO6pIMknYmn5Uch+Gi4+RKwxKZlgxhlnW1Uzy2V3y0fw+v51sYILTsuaE3QGmDPaV84PxebrPcftqo0lwi0Ufio8M+SDO+wKYb6Cl0ihYY14NssKLYhBw/zBaUHWpAR8J62MhQ5KpyIu/p8MkHUVW9wtf2cxEt5cAVsf7srLyXDZeFt550SfiMNiS+45norL287geh+Xv58dXi61cf8FjM5bDp06MVVgmqYL/lQ4s+cqSyrBtbMj6OpZWWwpqd78Z0O6ry19/VxdhN8N4Zjq/SAYW70du7/yCYiNC5X+2SslMwCJGxAvb5b3PZLf9X43OvyHHM1wUmBPAVDZvnHjFnq0NKIhrcX0WWU5hf3AZDNcNNcWvgJ0qd3Vn6DYWC4k8VzC+wmHX7EWsD6JJwu4+rC/Ea3+Urz0/OSf+DjZT8eQHK51TVCGov1BDWWrftC5bByR/RJpoW3/myuakbJA+1hGtlVGGbiojV2W6N5+6Lr2yE5FGR6OZsc/Rr8bTtra7uGzoOKcHwEZg99WR5sPMPBQ7axNqB9lsdATglxJEAIGqQluTEhElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwXIOt+AXHzMaAcBdJoUX0kP0AoMEqzTv+f6HVAYYwQk/3KHRp7qrJaSuD/DAlVAZgzoBegkvYEzX6NWue5HRoAw==" + } + ] + }, + { + "header": { + "sequence": 3, + "previousBlockHash": "701211EC0239846884B1A965E95BA25DE3BD1188F9B969932F9D8450ED39E85F", + "noteCommitment": { + "type": "Buffer", + "data": "base64:otSDkXN6zS1omXSkrs11aD7AcaPmBFLTB8LnlR/EMx0=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:ag98p5FZIcELKJDEH5CA+19fJvxBkoWnkbBkilu8BGE=" + }, + "target": "880842937844725196442695540779332307793253899902937591585455087694081134", + "randomness": "0", + "timestamp": 1672935256635, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 5, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAWsN0/inJVC4nNj0nMhhfHC59e8qwyuHVOjxgIfYw2zmS2/HokT5oROXnYCS3iF3UApA81wRASCfNGxoAP8rACGHn9PHfMvLVDHYQuVik/uWmQ/32pLKZEvthErizMaKRDTv/otILw8DRSffhYc8sMoxElxhDWaO5++9JqSb21zoYlVRpKSQN/djps8aa7SW/9NqtIui0133IHj7N/3xCsUh4t4EtdWJAOqml+aCcsmKObSwYRMrFly06V97eFeSoc9t4KAV0xK4Zc94Y8Rr6MgjfW9DyjlOWICjpDY4Sy/9Z6Na4f1E2Am/V/5mb6m4uUupQRcXqWaj438TKKN1ryJJTUrgAW9Zir3ddUkPhK7yOUoLONqMVUUHrKpFdSeZXC7WT0ky9TKUtAG8hUSnJsk1eHdO9kxfoHf2xqNr9ssRpmDB75nxFP9L2p6COzO1hp5sF/hNCuGZrO5871AogdGGloXaGuY+tKriO0u89VYIt6Jb4CLBGGGshnaCGvZRdZRUS4Pga9zMxu1VsBh43kiNVomQHNPx7XfTkLzj1Q1qW8rsgLEQSQJCHivC/lmHfAaXk3FZgT0i20vv0qKkdyrSZxmm9mQvJn9OPzwLJ8KOCgSHymREdPklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw+lL5pmTwIhAo6gEmm3HmQpE+QzZne+wP0gobBv46qbofMFezavw3lB4p7yb+FFlxTVYJrJnR/4p+dMTbCjbXCA==" + } + ] + } + ], + "Route chain/getBlock Receives transactions from a matched block": [ + { + "id": "9dc1a2a3-b96b-4fca-93f0-b8f9c3c1c4db", + "name": "test", + "spendingKey": "f86c6fe10ce4034552dd3306c0103c2e9af704bd72083cd957f3067540f6ce0c", + "incomingViewKey": "fcc19e310e5314fcd730f526af571ba2fd7ed58ee7c3e5382de633ff361fbf07", + "outgoingViewKey": "75ec6769f9b331779b10473b5552558e532c508d1a49bca2be3e724a0740c86a", + "publicAddress": "f0e3a3c3ee8704b683c9bc467a84388144fb9d231783deeb396ca155e5562b1a" + }, + { + "header": { + "sequence": 2, + "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", + "noteCommitment": { + "type": "Buffer", + "data": "base64:kJb6mGSFiSAR/l5VlQz2BYipimyKi0EomusGE4BJmD8=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:lT0qtNpV/ImfehKxJ3GXf2uAT7sudfwclTj22z2Nih0=" + }, + "target": "883423532389192164791648750371459257913741948437809479060803100646309888", + "randomness": "0", + "timestamp": 1672935257125, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 4, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAArd9W6+nEH5YTIP6v1Y34chohDlfxNp0997tXtidDhQGZvZNksWu6k+uS+hGmjiXrZREwfUfj4h4Zqdqz/SX6J+pRhHJQ9lC1irvLgsjL49qXfMxhW7bNPsNA40cD4mUHbGo47Pyc5zbf5aOGOpqPeun1Qj9RiXMOhw5Ldr6KV5QTRZw1k496YB97j7cY/ZoAFOArCW6gl/rUqg24JqCzf0/Q6Rlcg8pg7AaqGloASu6Pxg4BjTGPLfbPAVj1TXXFEpd93uKKxAilQSlX3Tmn9MuNDBnSrifGgXiMxGo4B2g739nodyTwtmGlBiyQEieFO598pIv4Lj/4Rq0zbViuGCTociwwHZpSK+1yk36PrcSwKMvcZgkMPZwwhf4o22hyl6U1p4bw1RPVXxEyrmzVpMVBx44//SDWzolVCT4dNqyOcEEzBSynaf7MgcCoNlzPsnUifiOhY9lzadx9ynLlKpt6jpnTE6IsPv0wYGiNo7P+NcLkl1jK80nmim87PmGu/5512VRboobJzCk6i380uEztd5jjrUvdaJG8rLo1aeJTz89vns62Ctyq0u9AdRaKTnJwssioiOzTb5azW9wKVdnMidI1k78CHdQiPfLpl3hJlB4UBU1WL0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwArueI5zLwGtGIdbe1m8RnrYWPKHI2YsztY2/SjboojwuaUC7nKID+tJe02tsywKMrJfdaowJqSwK3GTjcGpWAw==" + } + ] + }, + { + "header": { + "sequence": 3, + "previousBlockHash": "007432BBB05C40358BAAED1EE50692CADAA1ADD7537AD2AC833FF32EF1C306FF", + "noteCommitment": { + "type": "Buffer", + "data": "base64:Dthi+sSmBbkHKUxLoIos35iO0tY2QdmU90v6KojiEmg=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:Q7mEWC0x+3SBiQzC462uUe+FAKUqfN/FAUIaEb9A2FY=" + }, + "target": "880842937844725196442695540779332307793253899902937591585455087694081134", + "randomness": "0", + "timestamp": 1672935259381, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 7, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAnfjNzBFviRTJIgjftuVtG30jHtIZARYm5qYiG3HL5HGHEjZGHeu8fl4k+/sUzTqVlrQTqIyrclQ8M/+egjjTgUyfe1IoXXdC93bhcF9q+jGJ+M+a71UHcZp3g37G4+RWSV8ef1cFvJM1+UJ9O3E0Izf4kEyjbz4xog1ZUpVcnokKIOM0+OaswOK0STqRdynydVd3m8X56OMniNCK4B79hYwDIgAZT9oSpa56JgIo+OqzTuBMcus4WP5SwmLs0Gr4d5oUNmCzZ5q9efOhjHKqvC9LmeM9JZI9WB2KptHSENsj41wZgoWaGgAgnq/ATRKa8mMcfeQbk16SnzemJN7LYNCotkCILWuk8snYT3z+oIFkQAJttAqMbsV3uSUYpF8TGVZefcGDlfYkM7B5YDDCeIDO/JsVMltqceuGym6msSt2axmTndqMDT2fbOUURbSh4EgTRwGFoFbLIwCtkLTO0+Gol62a7HDV5gBDNHttohrzseM4aPj5+jPtipMnlJm5xR9+LOf8i9Frdud9rmY4yD1rdqytgpw//OUH8otcgeImWtEJFeh4NxgFDX58iEKwOKNo7Kl4uqTFSPVJHcafznUX3MGQeQd95dlu+8p/q9Mu7+kOjzdmHElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwXLbaUNzDa3gcBySxtydaI7nF/Lt4kjlLsvZtaWkC9APKe65TSwpYNRuMrypnuoyT1prMcvbaIYG0UiORsZ5NAg==" + }, + { + "type": "Buffer", + "data": "base64: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" + } + ] + } + ], + "Route chain/getBlock has block confirmation status": [ + { + "id": "ff30122c-8b51-4331-9197-f8f4e7876e9f", + "name": "test", + "spendingKey": "9b4d67d7f9c087103dac7b168ba38e561273151dd17a3ca5e263aa6465edebc8", + "incomingViewKey": "780ca5b531f2acf8f258264053715009c10ce1e60c86d645f718a99ce3c5ae02", + "outgoingViewKey": "e43c78540f1b66122f88ea17f7431e2d1e4b8dadac6cdba4395a6fb8332223a9", + "publicAddress": "3bb8a761218f07fc3f165f03b47233df4f0f08b82f415ac7eeb3133c223a9db5" + }, + { + "header": { + "sequence": 2, + "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", + "noteCommitment": { + "type": "Buffer", + "data": "base64:7hnys5CpdXfPuJb5Cvpev2q4VlnwbSpwSjzL0ygtZWI=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:nlOk8ONeUi8pKoAgp+/K9rk8QOOk5z9A+VF8LjrYgKc=" + }, + "target": "883423532389192164791648750371459257913741948437809479060803100646309888", + "randomness": "0", + "timestamp": 1675122554221, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 4, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAdXcwWpdd1KwRjU5cR88iejq9IujfHKjFZrIF4SgEptm4c7uLccGu3B1KDsmIca7RosVcdmc+e8TNbLqSgonvrylmQCiXg3akpc8OobPPLUSvF18au17mPmvQoLUPFlX2h9xXAn2OisKzorx859vR0eUa3YKuFilfOHnmohnmgXgB2k5AsTPlZXKHU4JevpOTqfNRp2urU0Uq/QKPXtk84JJx8cV1B8Ta43psZ7zddUChyhczq+Fh6mCwSI97LB/ba0rZYZd45Z1E3XcKTmE2nYgMhyLaWB76sNT4lmWezZJ8niDWEs5yztH5b+/5Hkr2XKTlB5EewE4asM4TbWFlJtqsYDaxSS4tB50eqTaxia50I+d+T5MUZs83Lc6kcdo530zOn6lJBop7zyFlVbvRNLU61quUs49/I/hcTU5z41FamRiG+1V49l+2ZBvo8pdyVbj2318uQ9gQE6oWdCF81mtdrXZbvKRUr2k0hgiUDzcpxTMzKqTlMxAmxJPGsjZfXS+4VYnLOQbMYUcn2I0oMZvmVZrMY5VSCHZcSp3zVdeLdY730fhk9BY2mUKZQ2gsGgoT46JvZYESeiCgjQ642Hd7FbFDeQFyvAx4W0o8/b5Oh4PKd7juaUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw9cSCcU4MfUuWI4ptsyLHodvFrmQu66hqD8wkTpbFvDfu31i/FFc6ChSSuOUQikP1CBjJhO2bRg/CDWIo+uC3BQ==" + } + ] + }, + { + "header": { + "sequence": 3, + "previousBlockHash": "8D955430B63330B3311F25EB449BD06B1D6A2946A5A86A281009E572589E7CB0", + "noteCommitment": { + "type": "Buffer", + "data": "base64:hOGJs0Ww9cZ5FGVxUOQWtRJsJCh+TDsZwoaffwEN0xs=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:H9B0jtb18Y6qRz/TZbPdxQ5Js73Hx5oxi4rM9Sj0Rr4=" + }, + "target": "880842937844725196442695540779332307793253899902937591585455087694081134", + "randomness": "0", + "timestamp": 1675122555770, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 7, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAWYYdd/I719W0W3QDsOoC9AuUOfvdtteZsIOS2v9Lm0a1z2OGkLepx6MqPFIyuLwhMq9DXNf6Zffmf2c+OvaxLIrHsCfAyr52oZ2XbcjgfKemhYWNQGRzvldGrgD54WYAi19jMZNdG2joFqP2gZi+kREEU/iggzNNRNNalFnJvyoPwpjjBhskFmYWjlunbY/72CgxxLkVm6BIdcxZ89fUr/U+ZeQbeB3bNmyiSNVdvcqg1O49or6BRG0h36LMsHzlmL3AGKkUM7aNUH/COXfKnqp4Ypsznr9U1r/yt/seMfVkfNqMAHgHFdYF9NJWw4kWeOkoB6WLgGUN73G9jVXENU/GAeQDtZknp5rvDx/je7PIBO5t5WoDcdGsO4Z8quRhryifipYM+xfDUfXKDEf5NZ5q3UBevX4MDgcOe6ycM5Ub86N9ucT0nVya31uKr3AGT5sWv96tXigYoTD7+jDgf8qrIoEZK46W+J7rc2tkMaNn48ms8hqxUqhhs/cOl+N+LdcsuYn5pkYX5Oci8MkX9D8Bkkykd6PmLNEj5QuFcKU6Y5LCgUPy7TRWSfSCHScURdBOkh7BHD1/K1poy3uY6wvVYX97D2dUcVWZ86SR1qR0c7jwC3Fnzklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwGPgRK7Tr3KvSx6g5LxpOhgzcZEwru6YQwrRoUSwtDMF5iKlm/D6Hfh4onDw+GP4a7VUVYm69wOs6kJhPCrshCQ==" + }, + { + "type": "Buffer", + "data": "base64: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" } ] } diff --git a/ironfish/src/rpc/routes/chain/__fixtures__/getBlockInfo.test.ts.fixture b/ironfish/src/rpc/routes/chain/__fixtures__/getBlockInfo.test.ts.fixture deleted file mode 100644 index 1197918cf3..0000000000 --- a/ironfish/src/rpc/routes/chain/__fixtures__/getBlockInfo.test.ts.fixture +++ /dev/null @@ -1,188 +0,0 @@ -{ - "Route chain/getBlockInfo Processes hash and sequence inputs": [ - { - "header": { - "sequence": 2, - "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", - "noteCommitment": { - "type": "Buffer", - "data": "base64:WrvfekEegOH5/XoRADicDmWgHttdTdMI3/3vA2LYSD8=" - }, - "transactionCommitment": { - "type": "Buffer", - "data": "base64:RorOFNv7/MOhHOS21QvIArI/hS+y9G2GQ8saesSEpgM=" - }, - "target": "883423532389192164791648750371459257913741948437809479060803100646309888", - "randomness": "0", - "timestamp": 1672935256225, - "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", - "noteSize": 4, - "work": "0" - }, - "transactions": [ - { - "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAlQeVr9LFJRsD2uDtDCgir9oWC0p4Sgj2nN5pm+nqw22QgclKFucBvNTydIvTvGF6fIiO6pIMknYmn5Uch+Gi4+RKwxKZlgxhlnW1Uzy2V3y0fw+v51sYILTsuaE3QGmDPaV84PxebrPcftqo0lwi0Ufio8M+SDO+wKYb6Cl0ihYY14NssKLYhBw/zBaUHWpAR8J62MhQ5KpyIu/p8MkHUVW9wtf2cxEt5cAVsf7srLyXDZeFt550SfiMNiS+45norL287geh+Xv58dXi61cf8FjM5bDp06MVVgmqYL/lQ4s+cqSyrBtbMj6OpZWWwpqd78Z0O6ry19/VxdhN8N4Zjq/SAYW70du7/yCYiNC5X+2SslMwCJGxAvb5b3PZLf9X43OvyHHM1wUmBPAVDZvnHjFnq0NKIhrcX0WWU5hf3AZDNcNNcWvgJ0qd3Vn6DYWC4k8VzC+wmHX7EWsD6JJwu4+rC/Ea3+Urz0/OSf+DjZT8eQHK51TVCGov1BDWWrftC5bByR/RJpoW3/myuakbJA+1hGtlVGGbiojV2W6N5+6Lr2yE5FGR6OZsc/Rr8bTtra7uGzoOKcHwEZg99WR5sPMPBQ7axNqB9lsdATglxJEAIGqQluTEhElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwXIOt+AXHzMaAcBdJoUX0kP0AoMEqzTv+f6HVAYYwQk/3KHRp7qrJaSuD/DAlVAZgzoBegkvYEzX6NWue5HRoAw==" - } - ] - }, - { - "header": { - "sequence": 3, - "previousBlockHash": "701211EC0239846884B1A965E95BA25DE3BD1188F9B969932F9D8450ED39E85F", - "noteCommitment": { - "type": "Buffer", - "data": "base64:otSDkXN6zS1omXSkrs11aD7AcaPmBFLTB8LnlR/EMx0=" - }, - "transactionCommitment": { - "type": "Buffer", - "data": "base64:ag98p5FZIcELKJDEH5CA+19fJvxBkoWnkbBkilu8BGE=" - }, - "target": "880842937844725196442695540779332307793253899902937591585455087694081134", - "randomness": "0", - "timestamp": 1672935256635, - "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", - "noteSize": 5, - "work": "0" - }, - "transactions": [ - { - "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAWsN0/inJVC4nNj0nMhhfHC59e8qwyuHVOjxgIfYw2zmS2/HokT5oROXnYCS3iF3UApA81wRASCfNGxoAP8rACGHn9PHfMvLVDHYQuVik/uWmQ/32pLKZEvthErizMaKRDTv/otILw8DRSffhYc8sMoxElxhDWaO5++9JqSb21zoYlVRpKSQN/djps8aa7SW/9NqtIui0133IHj7N/3xCsUh4t4EtdWJAOqml+aCcsmKObSwYRMrFly06V97eFeSoc9t4KAV0xK4Zc94Y8Rr6MgjfW9DyjlOWICjpDY4Sy/9Z6Na4f1E2Am/V/5mb6m4uUupQRcXqWaj438TKKN1ryJJTUrgAW9Zir3ddUkPhK7yOUoLONqMVUUHrKpFdSeZXC7WT0ky9TKUtAG8hUSnJsk1eHdO9kxfoHf2xqNr9ssRpmDB75nxFP9L2p6COzO1hp5sF/hNCuGZrO5871AogdGGloXaGuY+tKriO0u89VYIt6Jb4CLBGGGshnaCGvZRdZRUS4Pga9zMxu1VsBh43kiNVomQHNPx7XfTkLzj1Q1qW8rsgLEQSQJCHivC/lmHfAaXk3FZgT0i20vv0qKkdyrSZxmm9mQvJn9OPzwLJ8KOCgSHymREdPklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw+lL5pmTwIhAo6gEmm3HmQpE+QzZne+wP0gobBv46qbofMFezavw3lB4p7yb+FFlxTVYJrJnR/4p+dMTbCjbXCA==" - } - ] - } - ], - "Route chain/getBlockInfo Receives transactions from a matched block": [ - { - "id": "9dc1a2a3-b96b-4fca-93f0-b8f9c3c1c4db", - "name": "test", - "spendingKey": "f86c6fe10ce4034552dd3306c0103c2e9af704bd72083cd957f3067540f6ce0c", - "incomingViewKey": "fcc19e310e5314fcd730f526af571ba2fd7ed58ee7c3e5382de633ff361fbf07", - "outgoingViewKey": "75ec6769f9b331779b10473b5552558e532c508d1a49bca2be3e724a0740c86a", - "publicAddress": "f0e3a3c3ee8704b683c9bc467a84388144fb9d231783deeb396ca155e5562b1a" - }, - { - "header": { - "sequence": 2, - "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", - "noteCommitment": { - "type": "Buffer", - "data": "base64:kJb6mGSFiSAR/l5VlQz2BYipimyKi0EomusGE4BJmD8=" - }, - "transactionCommitment": { - "type": "Buffer", - "data": "base64:lT0qtNpV/ImfehKxJ3GXf2uAT7sudfwclTj22z2Nih0=" - }, - "target": "883423532389192164791648750371459257913741948437809479060803100646309888", - "randomness": "0", - "timestamp": 1672935257125, - "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", - "noteSize": 4, - "work": "0" - }, - "transactions": [ - { - "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAArd9W6+nEH5YTIP6v1Y34chohDlfxNp0997tXtidDhQGZvZNksWu6k+uS+hGmjiXrZREwfUfj4h4Zqdqz/SX6J+pRhHJQ9lC1irvLgsjL49qXfMxhW7bNPsNA40cD4mUHbGo47Pyc5zbf5aOGOpqPeun1Qj9RiXMOhw5Ldr6KV5QTRZw1k496YB97j7cY/ZoAFOArCW6gl/rUqg24JqCzf0/Q6Rlcg8pg7AaqGloASu6Pxg4BjTGPLfbPAVj1TXXFEpd93uKKxAilQSlX3Tmn9MuNDBnSrifGgXiMxGo4B2g739nodyTwtmGlBiyQEieFO598pIv4Lj/4Rq0zbViuGCTociwwHZpSK+1yk36PrcSwKMvcZgkMPZwwhf4o22hyl6U1p4bw1RPVXxEyrmzVpMVBx44//SDWzolVCT4dNqyOcEEzBSynaf7MgcCoNlzPsnUifiOhY9lzadx9ynLlKpt6jpnTE6IsPv0wYGiNo7P+NcLkl1jK80nmim87PmGu/5512VRboobJzCk6i380uEztd5jjrUvdaJG8rLo1aeJTz89vns62Ctyq0u9AdRaKTnJwssioiOzTb5azW9wKVdnMidI1k78CHdQiPfLpl3hJlB4UBU1WL0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwArueI5zLwGtGIdbe1m8RnrYWPKHI2YsztY2/SjboojwuaUC7nKID+tJe02tsywKMrJfdaowJqSwK3GTjcGpWAw==" - } - ] - }, - { - "header": { - "sequence": 3, - "previousBlockHash": "007432BBB05C40358BAAED1EE50692CADAA1ADD7537AD2AC833FF32EF1C306FF", - "noteCommitment": { - "type": "Buffer", - "data": "base64:Dthi+sSmBbkHKUxLoIos35iO0tY2QdmU90v6KojiEmg=" - }, - "transactionCommitment": { - "type": "Buffer", - "data": "base64:Q7mEWC0x+3SBiQzC462uUe+FAKUqfN/FAUIaEb9A2FY=" - }, - "target": "880842937844725196442695540779332307793253899902937591585455087694081134", - "randomness": "0", - "timestamp": 1672935259381, - "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", - "noteSize": 7, - "work": "0" - }, - "transactions": [ - { - "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAnfjNzBFviRTJIgjftuVtG30jHtIZARYm5qYiG3HL5HGHEjZGHeu8fl4k+/sUzTqVlrQTqIyrclQ8M/+egjjTgUyfe1IoXXdC93bhcF9q+jGJ+M+a71UHcZp3g37G4+RWSV8ef1cFvJM1+UJ9O3E0Izf4kEyjbz4xog1ZUpVcnokKIOM0+OaswOK0STqRdynydVd3m8X56OMniNCK4B79hYwDIgAZT9oSpa56JgIo+OqzTuBMcus4WP5SwmLs0Gr4d5oUNmCzZ5q9efOhjHKqvC9LmeM9JZI9WB2KptHSENsj41wZgoWaGgAgnq/ATRKa8mMcfeQbk16SnzemJN7LYNCotkCILWuk8snYT3z+oIFkQAJttAqMbsV3uSUYpF8TGVZefcGDlfYkM7B5YDDCeIDO/JsVMltqceuGym6msSt2axmTndqMDT2fbOUURbSh4EgTRwGFoFbLIwCtkLTO0+Gol62a7HDV5gBDNHttohrzseM4aPj5+jPtipMnlJm5xR9+LOf8i9Frdud9rmY4yD1rdqytgpw//OUH8otcgeImWtEJFeh4NxgFDX58iEKwOKNo7Kl4uqTFSPVJHcafznUX3MGQeQd95dlu+8p/q9Mu7+kOjzdmHElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwXLbaUNzDa3gcBySxtydaI7nF/Lt4kjlLsvZtaWkC9APKe65TSwpYNRuMrypnuoyT1prMcvbaIYG0UiORsZ5NAg==" - }, - { - "type": "Buffer", - "data": "base64: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" - } - ] - } - ], - "Route chain/getBlockInfo has block confirmation status": [ - { - "id": "ff30122c-8b51-4331-9197-f8f4e7876e9f", - "name": "test", - "spendingKey": "9b4d67d7f9c087103dac7b168ba38e561273151dd17a3ca5e263aa6465edebc8", - "incomingViewKey": "780ca5b531f2acf8f258264053715009c10ce1e60c86d645f718a99ce3c5ae02", - "outgoingViewKey": "e43c78540f1b66122f88ea17f7431e2d1e4b8dadac6cdba4395a6fb8332223a9", - "publicAddress": "3bb8a761218f07fc3f165f03b47233df4f0f08b82f415ac7eeb3133c223a9db5" - }, - { - "header": { - "sequence": 2, - "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", - "noteCommitment": { - "type": "Buffer", - "data": "base64:7hnys5CpdXfPuJb5Cvpev2q4VlnwbSpwSjzL0ygtZWI=" - }, - "transactionCommitment": { - "type": "Buffer", - "data": "base64:nlOk8ONeUi8pKoAgp+/K9rk8QOOk5z9A+VF8LjrYgKc=" - }, - "target": "883423532389192164791648750371459257913741948437809479060803100646309888", - "randomness": "0", - "timestamp": 1675122554221, - "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", - "noteSize": 4, - "work": "0" - }, - "transactions": [ - { - "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAdXcwWpdd1KwRjU5cR88iejq9IujfHKjFZrIF4SgEptm4c7uLccGu3B1KDsmIca7RosVcdmc+e8TNbLqSgonvrylmQCiXg3akpc8OobPPLUSvF18au17mPmvQoLUPFlX2h9xXAn2OisKzorx859vR0eUa3YKuFilfOHnmohnmgXgB2k5AsTPlZXKHU4JevpOTqfNRp2urU0Uq/QKPXtk84JJx8cV1B8Ta43psZ7zddUChyhczq+Fh6mCwSI97LB/ba0rZYZd45Z1E3XcKTmE2nYgMhyLaWB76sNT4lmWezZJ8niDWEs5yztH5b+/5Hkr2XKTlB5EewE4asM4TbWFlJtqsYDaxSS4tB50eqTaxia50I+d+T5MUZs83Lc6kcdo530zOn6lJBop7zyFlVbvRNLU61quUs49/I/hcTU5z41FamRiG+1V49l+2ZBvo8pdyVbj2318uQ9gQE6oWdCF81mtdrXZbvKRUr2k0hgiUDzcpxTMzKqTlMxAmxJPGsjZfXS+4VYnLOQbMYUcn2I0oMZvmVZrMY5VSCHZcSp3zVdeLdY730fhk9BY2mUKZQ2gsGgoT46JvZYESeiCgjQ642Hd7FbFDeQFyvAx4W0o8/b5Oh4PKd7juaUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw9cSCcU4MfUuWI4ptsyLHodvFrmQu66hqD8wkTpbFvDfu31i/FFc6ChSSuOUQikP1CBjJhO2bRg/CDWIo+uC3BQ==" - } - ] - }, - { - "header": { - "sequence": 3, - "previousBlockHash": "8D955430B63330B3311F25EB449BD06B1D6A2946A5A86A281009E572589E7CB0", - "noteCommitment": { - "type": "Buffer", - "data": "base64:hOGJs0Ww9cZ5FGVxUOQWtRJsJCh+TDsZwoaffwEN0xs=" - }, - "transactionCommitment": { - "type": "Buffer", - "data": "base64:H9B0jtb18Y6qRz/TZbPdxQ5Js73Hx5oxi4rM9Sj0Rr4=" - }, - "target": "880842937844725196442695540779332307793253899902937591585455087694081134", - "randomness": "0", - "timestamp": 1675122555770, - "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", - "noteSize": 7, - "work": "0" - }, - "transactions": [ - { - "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAWYYdd/I719W0W3QDsOoC9AuUOfvdtteZsIOS2v9Lm0a1z2OGkLepx6MqPFIyuLwhMq9DXNf6Zffmf2c+OvaxLIrHsCfAyr52oZ2XbcjgfKemhYWNQGRzvldGrgD54WYAi19jMZNdG2joFqP2gZi+kREEU/iggzNNRNNalFnJvyoPwpjjBhskFmYWjlunbY/72CgxxLkVm6BIdcxZ89fUr/U+ZeQbeB3bNmyiSNVdvcqg1O49or6BRG0h36LMsHzlmL3AGKkUM7aNUH/COXfKnqp4Ypsznr9U1r/yt/seMfVkfNqMAHgHFdYF9NJWw4kWeOkoB6WLgGUN73G9jVXENU/GAeQDtZknp5rvDx/je7PIBO5t5WoDcdGsO4Z8quRhryifipYM+xfDUfXKDEf5NZ5q3UBevX4MDgcOe6ycM5Ub86N9ucT0nVya31uKr3AGT5sWv96tXigYoTD7+jDgf8qrIoEZK46W+J7rc2tkMaNn48ms8hqxUqhhs/cOl+N+LdcsuYn5pkYX5Oci8MkX9D8Bkkykd6PmLNEj5QuFcKU6Y5LCgUPy7TRWSfSCHScURdBOkh7BHD1/K1poy3uY6wvVYX97D2dUcVWZ86SR1qR0c7jwC3Fnzklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwGPgRK7Tr3KvSx6g5LxpOhgzcZEwru6YQwrRoUSwtDMF5iKlm/D6Hfh4onDw+GP4a7VUVYm69wOs6kJhPCrshCQ==" - }, - { - "type": "Buffer", - "data": "base64:AQEAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAj9MwT2G1L5f5RZGYD0hnMYVAH6eXU1xPVBzoaz3W/c6nvX+YIyFsh3LK6dWw2T1E9wZQMajkdD7tt+iEuiEKLlhOx4nrs8HsA/525AKVPV2zC4neauDkSu0gcJ6acoBaCvtxX0kJa2dH/JUJAzk0OnAsf5/rAp09k0MJ9XH9LNwOAKhbRRS4BCxtq3RU2sUhZFy2avt2E640aDtHkMZAgb2hQ0dl8x3Ammw4tfLP2Q+B0PS35ScoJpLAU1o8a3K/EVVpinxdBCOd3RCdj/WeQst0W2WFrcSCqO2tL9KinvRiYayhCtwLjauKHxlW9KjCWD9zTc21RyUDnGFSmYk9i+4Z8rOQqXV3z7iW+Qr6Xr9quFZZ8G0qcEo8y9MoLWViBAAAALssiIPYBekPZp5DnZ2o8by6kgmfLtH2ErOIdmfXImU9IKY7RRoN8762gmNP2pG0c0+2lnBJZdo8DMVCgKG8wq97KeZREs4p2A/Ov18M9hzgIrpGpdPFmnD0UzQdkj/YALFxFDgSA7EhXzBG9kpoGQfglHAv/UNF0Hla6vh/0TKNh8uGgfSD/juNhDOb9miULYAAAfXv+mX+Y0+pcQOqONjpTYgTXekHyYVP8Aieq7AwssYzV7cFtKQlS7Dq6gHm+QMuYmpfaYzqF88StLX2UDLNoOCFV0IRUTNOIWaMOMpqug8uUaRr2f1yfdwEE+AsHpDN7d0V61zR9X+A0CyKQUMfH05XmqKe0S6uQwYKJSzc5uDMKIXKWtZjgfKsg55xGPYmNVIs96GlvmleSfV46eFs1giDZY41hD1y+rPkxyhyync5InqAxfXJZT9rPnuYpzrQ87ZKQGPQafHVh1bMtDzMhQSW9tgt6DoqP64UCGcofS0OzC0kNFBzNTngAd7sQfRoxzvK+oleJyrwgr17j0z5e+UMyBGXNIgtuC5n+2TdUa8oUI/orxnZV73bWk96oZP7iZkx15s2vSVpOyTTvTWZkQZqvurXSUE+QL9e3ebbYB+m2tCtou2WUvUAoDWCwGALrLB1MwiOSOjYKbfZ5M2tzUumJr8nAt9VHC3r8BiDcRtRVMTN0wEzXxFFulO8aN74GWWorvrqeMnLkaHIV67Aci6icthyi0DGtKiHSvWRNGFYuNqlkHZOvIzxSiWshZhO8g6y2ZUqMqTAA/k3G4Pd6b39QxtmJY+3CHrGJO7XgiKKte1t1TyT/tZcGNM+ExCjROlhuMNy3p1Cr+JOfywEX6BlJ9tfLAZBNNdttusSTrjhXg0vj2q517qAYc/jq+pbkl8I/dF9M/m0k24vwUnNVIlrAmMIz9ai4PUxr46M/czkdJKnvDULL7d64pCGgJUlu96HfYrKVkshvwCon5JrmMhz8yzXL2A5vjvAE439OB30xLWcyy6VB8Ew1EVBSSzvW8hA7vETtngyJp4xrZRV2Z5LKikVvglN/EI6YA9RvQ75lvb9t0jGQkfB8mam+pcbIj1yeNmiOaQm+PZsQhFjyaJzpt2PDwkAQJ1vcRRd87JYikiqB3HxGsnBkiS1snaKtRQWoqsoVqq1y2R2NbLCHNAp8KISFIs/Z0agexqMhPTKG0jqbeO1wXPAyMaNwO7ifl/0nfDXKF/ZYH7JpurfA4Q1iNOvX+V05pdCJfVsyT7FbKTmOSXwyyxs7JV70RoFb7zm3HoZGjhaOvmdxvcLNK2pd+Cnhcv6yvyj1TTHFdjxYEVa7temNSTyS7pN1rNvJVrTcV4NLSjalZm4HisQkbATWCUqsEOLT9v/d7Vy4wBUwH789mMUD/MKDbarkHgPuYSVKt5Ir458cRShti3ZegQcmUuhjfPyu8kbVBdcDYK+LEdR9SLEaPXrQlokWvAwsE8CNmgCLxGUvqOjeR4Z2l8rgBojK0mBpKrLnlRD7whrRJR4fD/NBfbS2x2pWkaypaoy6sJZl3LoVhoEPzubJUqERhSd027qy6PplZN2o0QTO2OWYy5fX/X1tXASDQ==" - } - ] - } - ] -} \ No newline at end of file diff --git a/ironfish/src/rpc/routes/chain/getBlockInfo.test.ts b/ironfish/src/rpc/routes/chain/getBlock.test.ts similarity index 83% rename from ironfish/src/rpc/routes/chain/getBlockInfo.test.ts rename to ironfish/src/rpc/routes/chain/getBlock.test.ts index 5d3e530f85..a6c4c6a09c 100644 --- a/ironfish/src/rpc/routes/chain/getBlockInfo.test.ts +++ b/ironfish/src/rpc/routes/chain/getBlock.test.ts @@ -5,9 +5,9 @@ import { useBlockWithTx, useMinerBlockFixture } from '../../../testUtilities' import { createRouteTest } from '../../../testUtilities/routeTest' import { ERROR_CODES } from '../../adapters' import { RpcRequestError } from '../../clients/errors' -import { GetBlockInfoResponse } from './getBlockInfo' +import { GetBlockResponse } from './getBlock' -describe('Route chain/getBlockInfo', () => { +describe('Route chain/getBlock', () => { const routeTest = createRouteTest() it('Processes hash and sequence inputs', async () => { @@ -27,7 +27,7 @@ describe('Route chain/getBlockInfo', () => { // Find block matching hash let response = await routeTest.client - .request('chain/getBlockInfo', { search: hash2 }) + .request('chain/getBlock', { search: hash2 }) .waitForEnd() expect(response.content).toMatchObject({ @@ -40,7 +40,7 @@ describe('Route chain/getBlockInfo', () => { // Now miss on a hash check try { await routeTest.client - .request('chain/getBlockInfo', { + .request('chain/getBlock', { search: '123405c7492bd000d6a8312f7592737e869967c890aac22247ede00678d4a2b2', }) .waitForEnd() @@ -55,7 +55,7 @@ describe('Route chain/getBlockInfo', () => { // Find block matching sequence response = await routeTest.client - .request('chain/getBlockInfo', { search: '2' }) + .request('chain/getBlock', { search: '2' }) .waitForEnd() expect(response.content).toMatchObject({ @@ -67,7 +67,7 @@ describe('Route chain/getBlockInfo', () => { // Find block matching sequence response = await routeTest.client - .request('chain/getBlockInfo', { search: '-1' }) + .request('chain/getBlock', { search: '-1' }) .waitForEnd() expect(response.content).toMatchObject({ @@ -80,7 +80,7 @@ describe('Route chain/getBlockInfo', () => { // Now miss on a sequence check try { await routeTest.client - .request('chain/getBlockInfo', { search: '1234' }) + .request('chain/getBlock', { search: '1234' }) .waitForEnd() } catch (e: unknown) { if (!(e instanceof RpcRequestError)) { @@ -96,7 +96,7 @@ describe('Route chain/getBlockInfo', () => { try { await routeTest.client - .request('chain/getBlockInfo', { search: hash0 }) + .request('chain/getBlock', { search: hash0 }) .waitForEnd() } catch (e: unknown) { if (!(e instanceof RpcRequestError)) { @@ -117,7 +117,7 @@ describe('Route chain/getBlockInfo', () => { const hash = block.header.hash.toString('hex') const response = await routeTest.client - .request('chain/getBlockInfo', { search: '3' }) + .request('chain/getBlock', { search: '3' }) .waitForEnd() expect(response.content).toMatchObject({ @@ -138,7 +138,7 @@ describe('Route chain/getBlockInfo', () => { const hash = block.header.hash.toString('hex') const response = await routeTest.client - .request('chain/getBlockInfo', { search: '3' }) + .request('chain/getBlock', { search: '3' }) .waitForEnd() expect(response.content).toMatchObject({ @@ -152,7 +152,7 @@ describe('Route chain/getBlockInfo', () => { }) const unconfirmedResponse = await routeTest.client - .request('chain/getBlockInfo', { search: '3', confirmations: 10 }) + .request('chain/getBlock', { search: '3', confirmations: 10 }) .waitForEnd() expect(unconfirmedResponse.content).toMatchObject({ diff --git a/ironfish/src/rpc/routes/chain/getBlockInfo.ts b/ironfish/src/rpc/routes/chain/getBlock.ts similarity index 90% rename from ironfish/src/rpc/routes/chain/getBlockInfo.ts rename to ironfish/src/rpc/routes/chain/getBlock.ts index 8b80fa9a2d..64762b09de 100644 --- a/ironfish/src/rpc/routes/chain/getBlockInfo.ts +++ b/ironfish/src/rpc/routes/chain/getBlock.ts @@ -8,14 +8,14 @@ import { BufferUtils } from '../../../utils' import { ValidationError } from '../../adapters' import { ApiNamespace, router } from '../router' -export type GetBlockInfoRequest = { +export type GetBlockRequest = { search?: string hash?: string sequence?: number confirmations?: number } -export type GetBlockInfoResponse = { +export type GetBlockResponse = { block: { graffiti: string difficulty: string @@ -37,7 +37,7 @@ export type GetBlockInfoResponse = { } } -export const GetBlockInfoRequestSchema: yup.ObjectSchema = yup +export const GetBlockRequestSchema: yup.ObjectSchema = yup .object() .shape({ search: yup.string(), @@ -47,7 +47,7 @@ export const GetBlockInfoRequestSchema: yup.ObjectSchema = }) .defined() -export const GetBlockInfoResponseSchema: yup.ObjectSchema = yup +export const GetBlockResponseSchema: yup.ObjectSchema = yup .object({ block: yup .object({ @@ -81,9 +81,9 @@ export const GetBlockInfoResponseSchema: yup.ObjectSchema }) .defined() -router.register( - `${ApiNamespace.chain}/getBlockInfo`, - GetBlockInfoRequestSchema, +router.register( + `${ApiNamespace.chain}/getBlock`, + GetBlockRequestSchema, async (request, node): Promise => { let header: BlockHeader | null = null let error = '' @@ -129,7 +129,7 @@ router.register( throw new ValidationError(`No block with header ${header.hash.toString('hex')}`) } - const transactions: GetBlockInfoResponse['block']['transactions'] = [] + const transactions: GetBlockResponse['block']['transactions'] = [] for (const tx of block.transactions) { const fee = tx.fee() diff --git a/ironfish/src/rpc/routes/chain/index.ts b/ironfish/src/rpc/routes/chain/index.ts index 8a73e61b4f..44707006cc 100644 --- a/ironfish/src/rpc/routes/chain/index.ts +++ b/ironfish/src/rpc/routes/chain/index.ts @@ -5,7 +5,7 @@ export * from './estimateFeeRates' export * from './exportChain' export * from './followChain' -export * from './getBlockInfo' +export * from './getBlock' export * from './getChainInfo' export * from './getDifficulty' export * from './getNetworkHashPower' From 18d9ba6fada6d74a6b736cabc7935b020d8cab7f Mon Sep 17 00:00:00 2001 From: Jason Spafford Date: Mon, 13 Feb 2023 16:25:30 -0500 Subject: [PATCH 08/43] Move unsubscriptions to stratumServer (#3409) --- ironfish/src/mining/stratum/stratumServer.ts | 2 ++ ironfish/src/mining/stratum/stratumServerClient.ts | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ironfish/src/mining/stratum/stratumServer.ts b/ironfish/src/mining/stratum/stratumServer.ts index d6183c773c..cf4f441b71 100644 --- a/ironfish/src/mining/stratum/stratumServer.ts +++ b/ironfish/src/mining/stratum/stratumServer.ts @@ -184,6 +184,8 @@ export class StratumServer { this.clients.delete(client.id) this.peers.removeConnectionCount(client) client.close() + client.socket.removeAllListeners('close') + client.socket.removeAllListeners('error') } private async onData(client: StratumServerClient, data: Buffer): Promise { diff --git a/ironfish/src/mining/stratum/stratumServerClient.ts b/ironfish/src/mining/stratum/stratumServerClient.ts index a821562726..38bedf06da 100644 --- a/ironfish/src/mining/stratum/stratumServerClient.ts +++ b/ironfish/src/mining/stratum/stratumServerClient.ts @@ -37,7 +37,6 @@ export class StratumServerClient { this.messageBuffer = '' this.connected = false - this.socket.removeAllListeners() this.socket.destroy(error) } } From 6ce1f5dabef86dfe43d551e506cd8ebba18f3f85 Mon Sep 17 00:00:00 2001 From: Derek Guenther Date: Tue, 14 Feb 2023 09:01:10 -0800 Subject: [PATCH 09/43] Fix 'Already have a WebSocket connection' message (#3410) * Move peerCandidateMap to PeerCandidates * Add tests for peerCandidates * Fix tests --- ironfish/src/network/messages/peerList.ts | 2 +- ironfish/src/network/peers/peer.ts | 5 + ironfish/src/network/peers/peerCandidates.ts | 94 ++++++++++ .../peers/peerConnectionManager.test.ts | 55 ++---- .../network/peers/peerConnectionManager.ts | 9 +- .../src/network/peers/peerManager.test.ts | 169 +++++++++--------- ironfish/src/network/peers/peerManager.ts | 80 ++------- ironfish/src/network/testUtilities/helpers.ts | 21 +-- 8 files changed, 224 insertions(+), 211 deletions(-) create mode 100644 ironfish/src/network/peers/peerCandidates.ts diff --git a/ironfish/src/network/messages/peerList.ts b/ironfish/src/network/messages/peerList.ts index 35c07d2086..9f96fe7bad 100644 --- a/ironfish/src/network/messages/peerList.ts +++ b/ironfish/src/network/messages/peerList.ts @@ -7,7 +7,7 @@ import { identityLength } from '../identity' import { NetworkMessageType } from '../types' import { NetworkMessage } from './networkMessage' -interface Peer { +export interface Peer { identity: Buffer name?: string address: string | null diff --git a/ironfish/src/network/peers/peer.ts b/ironfish/src/network/peers/peer.ts index 714edb571a..8b32d2ea13 100644 --- a/ironfish/src/network/peers/peer.ts +++ b/ironfish/src/network/peers/peer.ts @@ -171,6 +171,11 @@ export class Peer { /** how many outbound connections does the peer have */ pendingRPC = 0 + /** + * True if the peer is a known honest peer. + */ + isWhitelisted = false + shouldLogMessages = false loggedMessages: Array = [] diff --git a/ironfish/src/network/peers/peerCandidates.ts b/ironfish/src/network/peers/peerCandidates.ts new file mode 100644 index 0000000000..ae2845a44b --- /dev/null +++ b/ironfish/src/network/peers/peerCandidates.ts @@ -0,0 +1,94 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +import { ArrayUtils } from '../../utils/array' +import { Identity } from '../identity' +import { Peer as PeerListPeer } from '../messages/peerList' +import { ConnectionRetry } from './connectionRetry' +import { Peer } from './peer' + +export type PeerCandidate = { + name?: string + address: string | null + port: number | null + neighbors: Set + webRtcRetry: ConnectionRetry + websocketRetry: ConnectionRetry + /** + * UTC timestamp. If set, the peer manager should not initiate connections to the + * Peer until after the timestamp. + */ + peerRequestedDisconnectUntil: number | null + /** + * UTC timestamp. If set, the peer manager should not accept connections from the + * Peer until after the timestamp. + */ + localRequestedDisconnectUntil: number | null +} + +export class PeerCandidates { + private readonly map: Map = new Map() + + get size(): number { + return this.map.size + } + + addFromPeer(peer: Peer, neighbors = new Set()): void { + const address = peer.getWebSocketAddress() + const addressPeerCandidate = this.map.get(address) + const newPeerCandidate = { + address: peer.address, + port: peer.port, + neighbors, + webRtcRetry: new ConnectionRetry(peer.isWhitelisted), + websocketRetry: new ConnectionRetry(peer.isWhitelisted), + localRequestedDisconnectUntil: null, + peerRequestedDisconnectUntil: null, + } + + if (peer.state.identity !== null) { + if (addressPeerCandidate) { + this.map.delete(address) + } + + if (!this.map.has(peer.state.identity)) { + this.map.set(peer.state.identity, addressPeerCandidate ?? newPeerCandidate) + } + } else if (!addressPeerCandidate) { + this.map.set(address, newPeerCandidate) + } + } + + addFromPeerList(sendingPeerIdentity: Identity, peer: PeerListPeer): void { + const peerIdentity = peer.identity.toString('base64') + const peerCandidateValue = this.map.get(peerIdentity) + + if (peerCandidateValue) { + peerCandidateValue.neighbors.add(sendingPeerIdentity) + } else { + const tempPeer = new Peer(peerIdentity) + tempPeer.setWebSocketAddress(peer.address, peer.port) + this.addFromPeer(tempPeer, new Set([sendingPeerIdentity])) + } + } + + shufflePeerCandidates(): string[] { + return ArrayUtils.shuffle([...this.map.keys()]) + } + + get(identity: Identity): PeerCandidate | undefined { + return this.map.get(identity) + } + + has(identity: Identity): boolean { + return this.map.has(identity) + } + + private set(identity: Identity, value: PeerCandidate): void { + this.map.set(identity, value) + } + + clear(): void { + this.map.clear() + } +} diff --git a/ironfish/src/network/peers/peerConnectionManager.test.ts b/ironfish/src/network/peers/peerConnectionManager.test.ts index cd558400dc..de3da1723c 100644 --- a/ironfish/src/network/peers/peerConnectionManager.test.ts +++ b/ironfish/src/network/peers/peerConnectionManager.test.ts @@ -14,7 +14,6 @@ import { webRtcCanInitiateIdentity, webRtcLocalIdentity, } from '../testUtilities' -import { ConnectionRetry } from './connectionRetry' import { ConnectionDirection, ConnectionType, @@ -46,15 +45,7 @@ describe('connectToDisconnectedPeers', () => { peer.setWebSocketAddress('testuri.com', 9033) pm['tryDisposePeer'](peer) - pm.peerCandidateMap.set(peer.getWebSocketAddress(), { - address: 'testuri.com', - port: 9033, - neighbors: new Set(), - webRtcRetry: new ConnectionRetry(), - websocketRetry: new ConnectionRetry(), - localRequestedDisconnectUntil: null, - peerRequestedDisconnectUntil: null, - }) + pm.peerCandidates.addFromPeer(peer) const pcm = new PeerConnectionManager(pm, createRootLogger(), { maxPeers: 50 }) pcm.start() @@ -72,15 +63,11 @@ describe('connectToDisconnectedPeers', () => { const pm = new PeerManager(mockLocalPeer(), mockHostsStore()) const identity = mockIdentity('peer') - pm.peerCandidateMap.set(identity, { - address: 'testuri.com', - port: 9033, - neighbors: new Set(), - webRtcRetry: new ConnectionRetry(), - websocketRetry: new ConnectionRetry(), - localRequestedDisconnectUntil: null, - peerRequestedDisconnectUntil: null, - }) + const peer = pm.getOrCreatePeer(identity) + peer.setWebSocketAddress('testuri.com', 9033) + pm['tryDisposePeer'](peer) + + pm.peerCandidates.addFromPeer(peer) // We want to test websocket only const retry = pm.getConnectionRetry( @@ -106,15 +93,11 @@ describe('connectToDisconnectedPeers', () => { const peers = new PeerManager(mockLocalPeer(), mockHostsStore()) const identity = mockIdentity('peer') - peers.peerCandidateMap.set(identity, { - address: 'testuri.com', - port: 9033, - neighbors: new Set(), - webRtcRetry: new ConnectionRetry(), - websocketRetry: new ConnectionRetry(), - localRequestedDisconnectUntil: null, - peerRequestedDisconnectUntil: null, - }) + const createdPeer = peers.getOrCreatePeer(identity) + createdPeer.setWebSocketAddress('testuri.com', 9033) + peers['tryDisposePeer'](createdPeer) + + peers.peerCandidates.addFromPeer(createdPeer) const peerConnections = new PeerConnectionManager(peers, createRootLogger(), { maxPeers: 50, @@ -141,23 +124,15 @@ describe('connectToDisconnectedPeers', () => { ) const { peer: brokeringPeer } = getConnectedPeer(pm, 'brokering') // Link the peers - pm.peerCandidateMap.set(brokeringPeer.getIdentityOrThrow(), { + pm.peerCandidates.addFromPeerList(brokeringPeer.getIdentityOrThrow(), { address: null, port: null, - neighbors: new Set([peerIdentity]), - webRtcRetry: new ConnectionRetry(), - websocketRetry: new ConnectionRetry(), - localRequestedDisconnectUntil: null, - peerRequestedDisconnectUntil: null, + identity: Buffer.from(peerIdentity, 'base64'), }) - pm.peerCandidateMap.set(peerIdentity, { + pm.peerCandidates.addFromPeerList(peerIdentity, { address: null, port: null, - neighbors: new Set([brokeringPeer.getIdentityOrThrow()]), - webRtcRetry: new ConnectionRetry(), - websocketRetry: new ConnectionRetry(), - localRequestedDisconnectUntil: null, - peerRequestedDisconnectUntil: null, + identity: Buffer.from(brokeringPeer.getIdentityOrThrow(), 'base64'), }) const pcm = new PeerConnectionManager(pm, createRootLogger(), { maxPeers: 50 }) diff --git a/ironfish/src/network/peers/peerConnectionManager.ts b/ironfish/src/network/peers/peerConnectionManager.ts index 093ef61546..0145f86676 100644 --- a/ironfish/src/network/peers/peerConnectionManager.ts +++ b/ironfish/src/network/peers/peerConnectionManager.ts @@ -4,7 +4,7 @@ import type { Peer } from './peer' import { createRootLogger, Logger } from '../../logger' -import { ArrayUtils, SetTimeoutToken } from '../../utils' +import { SetTimeoutToken } from '../../utils' import { PeerManager } from './peerManager' /** @@ -83,17 +83,14 @@ export class PeerConnectionManager { } let connectAttempts = 0 - const shuffledPeerCandidates = ArrayUtils.shuffle([ - ...this.peerManager.peerCandidateMap.keys(), - ]) - for (const peerCandidateIdentity of shuffledPeerCandidates) { + for (const peerCandidateIdentity of this.peerManager.peerCandidates.shufflePeerCandidates()) { if (connectAttempts >= CONNECT_ATTEMPTS_MAX) { break } if (!this.peerManager.identifiedPeers.has(peerCandidateIdentity)) { - const val = this.peerManager.peerCandidateMap.get(peerCandidateIdentity) + const val = this.peerManager.peerCandidates.get(peerCandidateIdentity) if (val) { const peer = this.peerManager.getOrCreatePeer(peerCandidateIdentity) peer.name = val.name ?? null diff --git a/ironfish/src/network/peers/peerManager.test.ts b/ironfish/src/network/peers/peerManager.test.ts index 7f6db72dac..1563306a9d 100644 --- a/ironfish/src/network/peers/peerManager.test.ts +++ b/ironfish/src/network/peers/peerManager.test.ts @@ -28,7 +28,6 @@ import { } from '../testUtilities' import { NetworkMessageType } from '../types' import { VERSION_PROTOCOL, VERSION_PROTOCOL_MIN } from '../version' -import { ConnectionRetry } from './connectionRetry' import { ConnectionDirection, ConnectionType, @@ -158,6 +157,59 @@ describe('PeerManager', () => { // peerIn2's was never set to connected, so it was never merged into peerOut. }) + describe('Should remove peer candidates without identity when identity is found', () => { + it('When peer becomes CONNECTED', () => { + const peers = new PeerManager(mockLocalPeer(), mockHostsStore()) + + const peerIdentity = mockIdentity('peer') + const peer = peers.connectToWebSocketAddress('testuri:9033') + expect(peers.peerCandidates.get(peer.getWebSocketAddress())).not.toBeUndefined() + if (peer.state.type === 'DISCONNECTED') { + throw new Error('Peer should not be disconnected') + } + + const connection = peer.state.connections.webSocket + Assert.isNotUndefined(connection) + + connection.setState({ type: 'CONNECTED', identity: peerIdentity }) + + expect(peers.peerCandidates.size).toBe(1) + const pc = peers.peerCandidates.get(peerIdentity) + expect(pc).not.toBeUndefined() + }) + + it('When receiving a peer list with a matching address', () => { + const peers = new PeerManager(mockLocalPeer(), mockHostsStore()) + + // Create a websocket peer + const peerIdentity = mockIdentity('peer') + const connectedPeerIdentity = mockIdentity('connected') + const peer = peers.connectToWebSocketAddress('testuri:9033') + expect(peers.peerCandidates.get(peer.getWebSocketAddress())).not.toBeUndefined() + peer.close() + + // Create a connected peer + const { peer: connectedPeer, connection } = getConnectedPeer(peers, connectedPeerIdentity) + + connectedPeer.onMessage.emit( + new PeerListMessage([ + { + address: 'testuri', + port: 9033, + identity: Buffer.from(peerIdentity, 'base64'), + }, + ]), + connection, + ) + + expect(peers.peerCandidates.size).toBe(2) + const peerCandidate = peers.peerCandidates.get(peerIdentity) + const connectedPeerCandidate = peers.peerCandidates.get(connectedPeerIdentity) + expect(peerCandidate).not.toBeUndefined() + expect(connectedPeerCandidate).not.toBeUndefined() + }) + }) + it('Sends identity when a connection is successfully made', () => { const localIdentity = mockPrivateIdentity('local') const pm = new PeerManager(mockLocalPeer({ identity: localIdentity }), mockHostsStore()) @@ -308,23 +360,15 @@ describe('PeerManager', () => { const peer2 = pm.getOrCreatePeer(peer2Identity) // Link the peers - pm.peerCandidateMap.set(peer1Identity, { + pm.peerCandidates.addFromPeerList(peer2Identity, { address: null, port: null, - neighbors: new Set([peer2Identity]), - webRtcRetry: new ConnectionRetry(), - websocketRetry: new ConnectionRetry(), - localRequestedDisconnectUntil: null, - peerRequestedDisconnectUntil: null, + identity: Buffer.from(peer1Identity, 'base64'), }) - pm.peerCandidateMap.set(peer2Identity, { + pm.peerCandidates.addFromPeerList(peer1Identity, { address: null, port: null, - neighbors: new Set([peer1Identity]), - webRtcRetry: new ConnectionRetry(), - websocketRetry: new ConnectionRetry(), - localRequestedDisconnectUntil: null, - peerRequestedDisconnectUntil: null, + identity: Buffer.from(peer2Identity, 'base64'), }) // Verify peer2 is not connected @@ -355,23 +399,15 @@ describe('PeerManager', () => { expect(targetPeer.state.type).toEqual('DISCONNECTED') // Link the peers - peers.peerCandidateMap.set(brokeringPeer.getIdentityOrThrow(), { + peers.peerCandidates.addFromPeerList(targetPeer.getIdentityOrThrow(), { address: null, port: null, - neighbors: new Set([targetPeer.getIdentityOrThrow()]), - webRtcRetry: new ConnectionRetry(), - websocketRetry: new ConnectionRetry(), - localRequestedDisconnectUntil: null, - peerRequestedDisconnectUntil: null, + identity: Buffer.from(brokeringPeer.getIdentityOrThrow(), 'base64'), }) - peers.peerCandidateMap.set(targetPeer.getIdentityOrThrow(), { + peers.peerCandidates.addFromPeerList(brokeringPeer.getIdentityOrThrow(), { address: null, port: null, - neighbors: new Set([brokeringPeer.getIdentityOrThrow()]), - webRtcRetry: new ConnectionRetry(), - websocketRetry: new ConnectionRetry(), - localRequestedDisconnectUntil: null, - peerRequestedDisconnectUntil: null, + identity: Buffer.from(targetPeer.getIdentityOrThrow(), 'base64'), }) peers.connectToWebRTC(targetPeer) @@ -448,23 +484,15 @@ describe('PeerManager', () => { expect(targetPeer.state.type).toEqual('DISCONNECTED') // Link the peers - peers.peerCandidateMap.set(brokeringPeer.getIdentityOrThrow(), { + peers.peerCandidates.addFromPeerList(targetPeer.getIdentityOrThrow(), { address: null, port: null, - neighbors: new Set([targetPeer.getIdentityOrThrow()]), - webRtcRetry: new ConnectionRetry(), - websocketRetry: new ConnectionRetry(), - localRequestedDisconnectUntil: null, - peerRequestedDisconnectUntil: null, + identity: Buffer.from(brokeringPeer.getIdentityOrThrow(), 'base64'), }) - peers.peerCandidateMap.set(targetPeer.getIdentityOrThrow(), { + peers.peerCandidates.addFromPeerList(brokeringPeer.getIdentityOrThrow(), { address: null, port: null, - neighbors: new Set([brokeringPeer.getIdentityOrThrow()]), - webRtcRetry: new ConnectionRetry(), - websocketRetry: new ConnectionRetry(), - localRequestedDisconnectUntil: null, - peerRequestedDisconnectUntil: null, + identity: Buffer.from(targetPeer.getIdentityOrThrow(), 'base64'), }) peers.connectToWebRTC(targetPeer) @@ -501,15 +529,11 @@ describe('PeerManager', () => { // Set disconnectUntil and verify that we can't create a connection Assert.isNotNull(peer.state.identity) - pm.peerCandidateMap.set(peer.state.identity, { - address: null, - port: null, - neighbors: new Set(), - webRtcRetry: new ConnectionRetry(), - websocketRetry: new ConnectionRetry(), - peerRequestedDisconnectUntil: Number.MAX_SAFE_INTEGER, - localRequestedDisconnectUntil: null, - }) + pm.peerCandidates.addFromPeer(peer) + const candidate = pm.peerCandidates.get(peer.getIdentityOrThrow()) + Assert.isNotUndefined(candidate) + candidate.peerRequestedDisconnectUntil = Number.MAX_SAFE_INTEGER + pm.connectToWebSocket(peer) expect(peer.state.type).toBe('DISCONNECTED') }) @@ -519,24 +543,15 @@ describe('PeerManager', () => { const { peer } = getConnectedPeer(pm, 'peer') peer.close() - // Try websockets first - pm.peerCandidateMap.set(peer.getIdentityOrThrow(), { - address: null, - port: null, - neighbors: new Set(), - webRtcRetry: new ConnectionRetry(), - websocketRetry: new ConnectionRetry(), - localRequestedDisconnectUntil: null, - peerRequestedDisconnectUntil: 1, - }) + pm.peerCandidates.addFromPeer(peer) + const candidate = pm.peerCandidates.get(peer.getIdentityOrThrow()) + Assert.isNotUndefined(candidate) + candidate.peerRequestedDisconnectUntil = 1 pm.connectToWebSocket(peer) expect(peer.state.type).toBe('CONNECTING') - const candidate = pm.peerCandidateMap.get(peer.getIdentityOrThrow()) - Assert.isNotUndefined(candidate) expect(candidate.peerRequestedDisconnectUntil).toBeNull() - // Try websockets first candidate.peerRequestedDisconnectUntil = 1 pm.connectToWebRTC(peer) expect(peer.state.type).toBe('CONNECTING') @@ -937,15 +952,10 @@ describe('PeerManager', () => { peer.close() expect(peer.state).toEqual({ type: 'DISCONNECTED', identity: peerIdentity }) - pm.peerCandidateMap.set(peerIdentity, { - address: null, - port: null, - neighbors: new Set(), - webRtcRetry: new ConnectionRetry(), - websocketRetry: new ConnectionRetry(), - localRequestedDisconnectUntil: Number.MAX_SAFE_INTEGER, - peerRequestedDisconnectUntil: null, - }) + pm.peerCandidates.addFromPeer(peer) + const candidate = pm.peerCandidates.get(peerIdentity) + Assert.isNotUndefined(candidate) + candidate.localRequestedDisconnectUntil = Number.MAX_SAFE_INTEGER const { connection } = getWaitingForIdentityPeer(pm) @@ -964,7 +974,7 @@ describe('PeerManager', () => { connection.onMessage.emit(id) const localRequestedDisconnectUntil = - pm.peerCandidateMap.get(peerIdentity)?.localRequestedDisconnectUntil + pm.peerCandidates.get(peerIdentity)?.localRequestedDisconnectUntil Assert.isNotUndefined(localRequestedDisconnectUntil) Assert.isNotNull(localRequestedDisconnectUntil) @@ -1437,7 +1447,7 @@ describe('PeerManager', () => { }, ]) peer.onMessage.emit(peerList, connection) - expect(pm.peerCandidateMap.has(privateIdentityToIdentity(localIdentity))).toBe(false) + expect(pm.peerCandidates.has(privateIdentityToIdentity(localIdentity))).toBe(false) }) it('Links peers when adding a new known peer', () => { @@ -1450,7 +1460,6 @@ describe('PeerManager', () => { expect(pm.peers.length).toBe(1) expect(pm.identifiedPeers.size).toBe(1) - expect(pm.peerCandidateMap.get(peer.getIdentityOrThrow())).toBeUndefined() const peerList = new PeerListMessage([ { @@ -1466,8 +1475,8 @@ describe('PeerManager', () => { expect(pm.identifiedPeers.get(peerIdentity)).toBe(peer) expect(pm.identifiedPeers.get(newPeerIdentity)).toBeUndefined() - expect(pm.peerCandidateMap.get(newPeerIdentity)?.neighbors.size).toBe(1) - expect(pm.peerCandidateMap.get(newPeerIdentity)?.neighbors.has(peerIdentity)).toBe(true) + expect(pm.peerCandidates.get(newPeerIdentity)?.neighbors.size).toBe(1) + expect(pm.peerCandidates.get(newPeerIdentity)?.neighbors.has(peerIdentity)).toBe(true) }) }) @@ -1520,7 +1529,7 @@ describe('PeerManager', () => { expect(peer.state.type).toEqual('DISCONNECTED') expect( - pm.peerCandidateMap.get(webRtcCanInitiateIdentity())?.peerRequestedDisconnectUntil, + pm.peerCandidates.get(webRtcCanInitiateIdentity())?.peerRequestedDisconnectUntil, ).toEqual(Number.MAX_SAFE_INTEGER) expect(brokeringPeer.state.type).toEqual('CONNECTED') }) @@ -1532,15 +1541,7 @@ describe('PeerManager', () => { const { peer, connection } = getConnectedPeer(pm, peerIdentity) Assert.isNotNull(peer.state.identity) - pm.peerCandidateMap.set(peer.state.identity, { - address: null, - port: null, - neighbors: new Set(), - webRtcRetry: new ConnectionRetry(), - websocketRetry: new ConnectionRetry(), - peerRequestedDisconnectUntil: null, - localRequestedDisconnectUntil: null, - }) + pm.peerCandidates.addFromPeer(peer) const disconnectMessage = new DisconnectingMessage({ sourceIdentity: peerIdentity, @@ -1551,7 +1552,7 @@ describe('PeerManager', () => { connection.onMessage.emit(disconnectMessage) - const peerRequestedDisconnectUntil = pm.peerCandidateMap.get( + const peerRequestedDisconnectUntil = pm.peerCandidates.get( peer.state.identity, )?.peerRequestedDisconnectUntil diff --git a/ironfish/src/network/peers/peerManager.ts b/ironfish/src/network/peers/peerManager.ts index 89e0860858..fd19ac4514 100644 --- a/ironfish/src/network/peers/peerManager.ts +++ b/ironfish/src/network/peers/peerManager.ts @@ -40,6 +40,7 @@ import { } from './connections' import { LocalPeer } from './localPeer' import { Peer } from './peer' +import { PeerCandidates } from './peerCandidates' /** * The maximum number of attempts the client will make to find a brokering peer @@ -74,27 +75,7 @@ export class PeerManager { */ peers: Array = [] - peerCandidateMap: Map< - string, - { - name?: string - address: string | null - port: number | null - neighbors: Set - webRtcRetry: ConnectionRetry - websocketRetry: ConnectionRetry - /** - * UTC timestamp. If set, the peer manager should not initiate connections to the - * Peer until after the timestamp. - */ - peerRequestedDisconnectUntil: number | null - /** - * UTC timestamp. If set, the peer manager should not accept connections from the - * Peer until after the timestamp. - */ - localRequestedDisconnectUntil: number | null - } - > = new Map() + peerCandidates: PeerCandidates = new PeerCandidates() addressManager: AddressManager @@ -189,20 +170,9 @@ export class PeerManager { const peer = this.getOrCreatePeer(null) peer.setWebSocketAddress(url.hostname, url.port) + peer.isWhitelisted = isWhitelisted - const address = peer.getWebSocketAddress() - const peerCandidate = this.peerCandidateMap.get(address) - if (!peerCandidate) { - this.peerCandidateMap.set(address, { - address: url.hostname, - port: url.port, - neighbors: new Set(), - webRtcRetry: new ConnectionRetry(isWhitelisted), - websocketRetry: new ConnectionRetry(isWhitelisted), - localRequestedDisconnectUntil: null, - peerRequestedDisconnectUntil: null, - }) - } + this.peerCandidates.addFromPeer(peer) this.connectToWebSocket(peer) return peer @@ -218,7 +188,7 @@ export class PeerManager { const alternateIdentity = peer.state.identity ?? peer.getWebSocketAddress() - const candidate = this.peerCandidateMap.get(alternateIdentity) + const candidate = this.peerCandidates.get(alternateIdentity) if (candidate) { // If we're trying to connect to the peer, we don't care about limiting the peer's connections to us candidate.localRequestedDisconnectUntil = null @@ -263,7 +233,7 @@ export class PeerManager { return false } - const candidate = this.peerCandidateMap.get(peer.state.identity) + const candidate = this.peerCandidates.get(peer.state.identity) if (candidate) { // If we're trying to connect to the peer, we don't care about limiting the peer's connections to us candidate.localRequestedDisconnectUntil = null @@ -492,7 +462,7 @@ export class PeerManager { peer.state.type !== 'DISCONNECTED' || this.canCreateNewConnections() const peerRequestedDisconnectUntil = - this.peerCandidateMap.get(alternateIdentity)?.peerRequestedDisconnectUntil ?? null + this.peerCandidates.get(alternateIdentity)?.peerRequestedDisconnectUntil ?? null const disconnectOk = peerRequestedDisconnectUntil === null || now >= peerRequestedDisconnectUntil @@ -529,7 +499,7 @@ export class PeerManager { peer.state.type !== 'DISCONNECTED' || this.canCreateNewConnections() const peerRequestedDisconnectUntil = - this.peerCandidateMap.get(peer.state.identity)?.peerRequestedDisconnectUntil ?? null + this.peerCandidates.get(peer.state.identity)?.peerRequestedDisconnectUntil ?? null const disconnectOk = peerRequestedDisconnectUntil === null || now >= peerRequestedDisconnectUntil @@ -563,7 +533,7 @@ export class PeerManager { */ disconnect(peer: Peer, reason: DisconnectingReason, until: number): void { if (peer.state.identity) { - const candidate = this.peerCandidateMap.get(peer.state.identity) + const candidate = this.peerCandidates.get(peer.state.identity) if (candidate) { candidate.localRequestedDisconnectUntil = until } @@ -641,7 +611,7 @@ export class PeerManager { const candidates = [] // The peer candidate map tracks any brokering peer candidates - const val = this.peerCandidateMap.get(peer.state.identity) + const val = this.peerCandidates.get(peer.state.identity) if (!val) { return null } @@ -768,6 +738,7 @@ export class PeerManager { peer.onStateChanged.on(({ prevState }) => { if (prevState.type !== 'CONNECTED' && peer.state.type === 'CONNECTED') { + this.peerCandidates.addFromPeer(peer) this.onConnect.emit(peer) this.onConnectedPeersChanged.emit() } @@ -892,7 +863,7 @@ export class PeerManager { return null } - const candidate = this.peerCandidateMap.get(identity) + const candidate = this.peerCandidates.get(identity) if (type === ConnectionType.WebRtc) { return candidate?.webRtcRetry ?? null @@ -1013,7 +984,7 @@ export class PeerManager { } if (disconnectingPeer.state.identity) { - const candidate = this.peerCandidateMap.get(disconnectingPeer.state.identity) + const candidate = this.peerCandidates.get(disconnectingPeer.state.identity) if (candidate) { candidate.peerRequestedDisconnectUntil = message.disconnectUntil } @@ -1184,7 +1155,7 @@ export class PeerManager { originalPeer.address !== null ) { peer.setWebSocketAddress(originalPeer.address, originalPeer.port) - const candidate = this.peerCandidateMap.get(identity) + const candidate = this.peerCandidates.get(identity) if (candidate) { candidate.address = originalPeer.address candidate.port = originalPeer.port @@ -1264,7 +1235,7 @@ export class PeerManager { // If we've told the peer to stay disconnected, repeat // the disconnection time before closing the connection const localRequestedDisconnectUntil = - this.peerCandidateMap.get(identity)?.localRequestedDisconnectUntil ?? null + this.peerCandidates.get(identity)?.localRequestedDisconnectUntil ?? null if (localRequestedDisconnectUntil !== null && Date.now() < localRequestedDisconnectUntil) { const disconnectMessage = new DisconnectingMessage({ @@ -1342,7 +1313,7 @@ export class PeerManager { } if (messageSender.state.identity !== null) { - this.peerCandidateMap + this.peerCandidates .get(message.sourceIdentity) ?.neighbors.add(messageSender.state.identity) } @@ -1434,7 +1405,7 @@ export class PeerManager { } if (messageSender.state.identity !== null) { - this.peerCandidateMap + this.peerCandidates .get(message.sourceIdentity) ?.neighbors.add(messageSender.state.identity) } @@ -1565,22 +1536,7 @@ export class PeerManager { continue } - const peerCandidateValue = this.peerCandidateMap.get(identity) - - if (peerCandidateValue) { - peerCandidateValue.neighbors.add(peer.state.identity) - } else { - this.peerCandidateMap.set(identity, { - name: connectedPeer.name, - address: connectedPeer.address, - port: connectedPeer.port, - neighbors: new Set([peer.state.identity]), - webRtcRetry: new ConnectionRetry(), - websocketRetry: new ConnectionRetry(), - peerRequestedDisconnectUntil: null, - localRequestedDisconnectUntil: null, - }) - } + this.peerCandidates.addFromPeerList(peer.state.identity, connectedPeer) } } } diff --git a/ironfish/src/network/testUtilities/helpers.ts b/ironfish/src/network/testUtilities/helpers.ts index 7a1f5c8baa..de7a683bfe 100644 --- a/ironfish/src/network/testUtilities/helpers.ts +++ b/ironfish/src/network/testUtilities/helpers.ts @@ -8,7 +8,6 @@ import { Identity, isIdentity } from '../identity' import { GetBlockTransactionsResponse } from '../messages/getBlockTransactions' import { GetCompactBlockResponse } from '../messages/getCompactBlock' import { IncomingPeerMessage, NetworkMessage } from '../messages/networkMessage' -import { ConnectionRetry } from '../peers/connectionRetry' import { Connection, ConnectionDirection, @@ -154,27 +153,13 @@ export function getSignalingWebRtcPeer( // We don't expect this function to be called multiple times, so make sure // we're not resetting pre-existing peer candidate data. - Assert.isFalse(pm.peerCandidateMap.has(brokeringPeerIdentity)) - Assert.isFalse(pm.peerCandidateMap.has(peerIdentity)) + Assert.isFalse(pm.peerCandidates.has(peerIdentity)) // Link the peers - pm.peerCandidateMap.set(brokeringPeerIdentity, { - address: brokeringPeer.address, - port: brokeringPeer.port, - neighbors: new Set([peerIdentity]), - webRtcRetry: new ConnectionRetry(), - websocketRetry: new ConnectionRetry(), - peerRequestedDisconnectUntil: null, - localRequestedDisconnectUntil: null, - }) - pm.peerCandidateMap.set(peerIdentity, { + pm.peerCandidates.addFromPeerList(brokeringPeerIdentity, { address: peer.address, port: peer.port, - neighbors: new Set([brokeringPeerIdentity]), - webRtcRetry: new ConnectionRetry(), - websocketRetry: new ConnectionRetry(), - peerRequestedDisconnectUntil: null, - localRequestedDisconnectUntil: null, + identity: Buffer.from(peerIdentity, 'base64'), }) // Verify peer2 is not connected From ff00897c541005e34468b763c296e9f4c310456e Mon Sep 17 00:00:00 2001 From: mat-if <97762857+mat-if@users.noreply.github.com> Date: Tue, 14 Feb 2023 11:53:31 -0700 Subject: [PATCH 10/43] feat(ironfish): Introduce new `GetBlockHeaders` network message (#3412) This message will replace `GetBlockHashes` as the message used for syncing in a follow-up change. It also includes a `skip` and `reverse` flag, for more flexible future usage. --- .../__fixtures__/peerNetwork.test.ts.fixture | 450 ++++++++++++++++++ ironfish/src/network/messageRegistry.ts | 5 + .../getBlockHeaders.test.ts.fixture | 110 +++++ .../network/messages/getBlockHeaders.test.ts | 42 ++ .../src/network/messages/getBlockHeaders.ts | 93 ++++ ironfish/src/network/peerNetwork.test.ts | 141 ++++++ ironfish/src/network/peerNetwork.ts | 91 ++++ ironfish/src/network/testUtilities/helpers.ts | 15 + ironfish/src/network/types.ts | 2 + 9 files changed, 949 insertions(+) create mode 100644 ironfish/src/network/messages/__fixtures__/getBlockHeaders.test.ts.fixture create mode 100644 ironfish/src/network/messages/getBlockHeaders.test.ts create mode 100644 ironfish/src/network/messages/getBlockHeaders.ts diff --git a/ironfish/src/network/__fixtures__/peerNetwork.test.ts.fixture b/ironfish/src/network/__fixtures__/peerNetwork.test.ts.fixture index ac63492513..0556d710f5 100644 --- a/ironfish/src/network/__fixtures__/peerNetwork.test.ts.fixture +++ b/ironfish/src/network/__fixtures__/peerNetwork.test.ts.fixture @@ -1324,5 +1324,455 @@ } ] } + ], + "PeerNetwork handles requests for block headers should respond to GetBlockHeadersRequest": [ + { + "header": { + "sequence": 2, + "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", + "noteCommitment": { + "type": "Buffer", + "data": "base64:RIqunNumNtATvUUZ+4VXjidberNWzeZG5LDDk/O5dCI=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:ZfTJDY0arUqztIsc0aJDnO1yWNgMEtoYd5ZE722NhIc=" + }, + "target": "883423532389192164791648750371459257913741948437809479060803100646309888", + "randomness": "0", + "timestamp": 1676325609945, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 4, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA9EN6QZHMrABAp6NR+yIXSRvQMyJvsH8OVj7d23NxPcyHD3oep0d1nLQUVo8lEz6u/HH/4kpjDEL7R0n68CPwEYL+bwLSxq5FPpP/7vQsmYOMFiShhz6XBOu5g9VlieiY62Wqkl7tm8GbJxVwiWw1A5BRycePo1zkB7uQqfhA8Y8Xp7eZONvYe2GiUCSaDWb3b9QotAL2hPwaXKcv7O2/suBnImTk1iMDwv1IjgnpvqKhhnaSPo3uzc2ga0yEnLty1cNOiH+iqgP1Rydbx/JDyCaFohgTH2Mpi4MpWaQyicgiYFdlRqYAWzmflzUZ8VsDTNxB9mwhrxtlwFkhu+j8iQq+BBMOKLc+QgqlweFrKcsIvtomNoVLrvoLOrahBRAUDbGKTq6w2Xx34hIZKhpgrkPsMkAIFD24qLVT2PXKxRctBDfZ5uRc1Gr9GiYbYCn6X98lL6oozSpVALWyIfN70HKkS+oEgmBVMRy3W85nyxrxvpsFv7npgaWchwyDN6ffu2t3xlFgR21WcU1x9lJTWcXOseD4Ve3MJarTUb5hV4T1cAjQjVx/qXZtsIlrhtlKFXPcJNckjSWgzGuvzsPTxL/bRgXIKg/6efbISSGT9X63A4Launguf0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw5VbvtoqqqpKKZ24+LnpwEMrtp3tPClyX2BLc2VQa1SWav9E5YARkm98bDzlkda9j22M2Oad/5ZjtdS0Db1EMDQ==" + } + ] + }, + { + "header": { + "sequence": 3, + "previousBlockHash": "681163D68772F09CB6B971DF14E966F2B6BD0DCE8DAAF07D58D2ADF369898744", + "noteCommitment": { + "type": "Buffer", + "data": "base64:6kzjjfnKbHUmh6mAQL24L/bXyxdqLcJ32sLWoJKhc1U=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:MNkFMYlx0qa/OoAgG27pW5VBnqJO4Nfe3PjFR+TAxvI=" + }, + "target": "880842937844725196442695540779332307793253899902937591585455087694081134", + "randomness": "0", + "timestamp": 1676325610248, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 5, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAoC6JO2XV+ovMzUSb04Oqioj9XLoQMqWPVW5hk5G57524tA7jrD3KJhC615GdWdqDN3m2EmlRzs8uAuDUikKNXkEJfvajtyqGH1AxNj1wHZuwjKuuT6JlDuo0ZbL504MDtvHnBh/mgtekwglAMpV5XAeSeKjCAGQOvT1xtKDvigkN+JqQI+7828O4ppNbgJ33MAoDjv7PenNBg1ITLv4MOilE/uenhqU9+aKS2NcP/Y65U5gwfZeKFdR89wlZGrjXmFyFLj8rkfL3V9jW9zwHwg/mA926z5XSimQPsjjGYBc4CKRHGFgyzdIma7IQ/TQkvoOk0rVePILDgC1gc5lECYCxx5RFlWJhsDrZtJfO48RZgkRDo2mPeHIWcpmEcyBOEz9FePanTlr9Iq3sug4QY3x3/gNAS6AXiv7aSN7f2Ftb3D3ksSmnYwPfdlgqV5p09VvsDEsDf+9H1gI/sO4q5Gzcg6xkCvrR+O1X7XXh9WLDzmpW5MJN6APwcDnmq9KzVw+MyAFsTHNAOxkxZbvb+Nbvgzljpk53VwPLwlJTz9C01zVirI58l4+FIklUbXf4kA9viCw1WBRtV/YB5pZy8ffkR15gJEDfZ54lmYgnc7Ntx1kt21Pq1Elyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw4cSVrBDbH+GL9jEu7fGfYhLwdPUAqPQ2feVs6KfeX8oN8COHBhYpDzEw0Fo61hqwWvyDp7pi4MYQNMScyRRuCg==" + } + ] + }, + { + "header": { + "sequence": 4, + "previousBlockHash": "5ACDDC347D42FEF5B93EB10D2361107AEA1D3AB65009BE961BE991D0F1CF9B3F", + "noteCommitment": { + "type": "Buffer", + "data": "base64:KYnnsa/vp/AMeJXurHKfPwBieEkribf13qigXOyk3Qw=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:O4Xa56cvBVfgubVe/8q4yxsUx3Af8FRWxV5colfDt6A=" + }, + "target": "878277375889837647326843029495509009809390053592540685978895509768758568", + "randomness": "0", + "timestamp": 1676325610528, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 6, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAY24X7DfF+oYGuJhhVvBvdfovbs/QP+R1HjaiIR/qPVqVQXfFu2AZZu13tEkt4JBgqYpIkTvm2TwKg8JN3jxTUksU5w6PBIHpYYq68NONF2CY1wyRWjDJFpOVKs+MLXqEBzXyo7yhGctl1JEC7ZWB0qpYjjUSwnxQkcOH+pByo64A3SA9wqsxBB8cxLYhldPR1j/dVWPVTI8ebgoGOBPZqKEsip57AQpLWY+Yl+r3seipjQSQk7I9IglFWuA4uMNiM/RzbT2KSmMToLTdQuO4vUXE5ZgZvjWbz06UiuUhhRheA+198kMfIoDj3d7aDacdE1jRyaR43ugS0uhcFOlx257Caa/8aRC0U2DzcUEA5SorhPneRaiFSLJ15YE0FhdJROoLIxWxVwYf+MNX/BrmnII1xOhU6C230EmFr7kbIfK1zlbmkVd8mjULPNbJCqvvrvWwKO0VUoaXreGizuss+ruV+fAZOberCuzZwkv9pLULMBOGmn6xGutl/NWURmp0b7zCnu/9okenyIkUoc/mNgb7P7S/1X4fTTQwn7pj9ByWWqoRvZXs44CkqUICBdd33M7sPILurpkdP6PtXFaQuYnSR2tG4xzNEM+UAapN2k6FYo1UHmHjj0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw9Pxeeg6g+Rtox3jB+rgMS8jZOcMYf3nFagZnoK41DuW64Wi2wVGQ3dB3RI1anAWxbbmchhAe+0cYGO72cWuIDQ==" + } + ] + }, + { + "header": { + "sequence": 5, + "previousBlockHash": "E81B109E9172FA6FC18FE08BEABFB6EDD4FC34F00C4CCE00E47D8F11F647B1E4", + "noteCommitment": { + "type": "Buffer", + "data": "base64:YyRD+Q0XYXfgVBkBJr2A1ss3ak94THqNhlhvzxYlZGY=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:IzXukrx+13gPmxyN4CSa0u95Y6NeiFEkJSHb9RGyvLI=" + }, + "target": "875726715553274711274586950997458160797358911132930209640137826778142618", + "randomness": "0", + "timestamp": 1676325610809, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 7, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAd+5ADsQoZgp4r6nQPWVI46royQ6wNpQmsBJJHJyl1Iampuarb0Z3lozmM7xq9Qx1smYsj3XCOoG76Kr0lM1N4IXh5EBTjUCNlGMlq5wFtJu2GG2CYmotl4/sWj9EGnGbbvC06SgHYP8JAb2lhM09OKfMn0seJd6zgGSFORoi9kEE4bDDaqPRpSXm2H00/+fNtn9Ba0ghu/LsUqQF9fJ9aQrZ3bo3w/cr1QjjCOm3HYavC1mFyTLMR6AGEaIyVV7HSMi1XmUWIButbVOvv5J3oY+RWE7CQjjTMyc3mjTBNHPGjpX/gVeuoL4B4ilpi+6Fq09bfsyw1wk4DquZ9/VrgIHBK9ALfJMvR6VM4nIBmyHTgnwP7chMr3pSM/98qvFToYqIzRxyg4q5RH514O551d1uBMsuNAVnM/T7geTkCW8EpS2n4Ik4zezO9XuQIQ/FPDyeqQ+eWJezZJYDj2VgcRchh0AZ56WYjTE2SyjmoUL9Du0kZO2CQH3/8xtlSFHEuZcniEjhIlEDG3K7rw2PnJk2aWKxhMy4AaMzId+cIFiRHfCKCD9Frh6Tnp2ZLplxk7D3glnl3o5VGsDj7YcFhGYFf2be55w7nWmwcbNHVFmxohAt5yQXTElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw66z5VO2NCPz4PcAEdIQXL+a9cRMSov46MQydIfUTWvDubkv3Y1LyoAmWYm1S20NGSgRbUa3cEMeLDydyHGKrCg==" + } + ] + } + ], + "PeerNetwork handles requests for block headers should respond to GetBlockHeadersRequest with skip": [ + { + "header": { + "sequence": 2, + "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", + "noteCommitment": { + "type": "Buffer", + "data": "base64:CY/Vg3Hp5CmdMcScOpZ/9dSS4GdMEuFgMUIXmdqoqmw=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:/c5IXaK8aejg4vD6xFwZyvRPhCPVV1QpzyVzafln/DY=" + }, + "target": "883423532389192164791648750371459257913741948437809479060803100646309888", + "randomness": "0", + "timestamp": 1676325611120, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 4, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAnjFF3jqtgNOY3ZNIPqDHK7CVByphfH8QhcqyNN3uMIu37b7wECAf/5XwpahcExWUOhqQdsAB1Utt6XPkktbZgz/171d0jSXkN/AzluZCJlGIltnt+bANJ38iFDl7A+mER/ZJOBMN1eYGjIhrWIoHu8v/fKGrJyQJ3W6SvLxAYBkUl9ktZ1PCofEcYLmuNcIHACUH1xd1Fy75bEDZBifJQbd/I32I5d2p9RDUEKfd/euSYKv4Svh5wBDobcFmrjDV8WlUsDma4ND3n9+TG/a2UAkQ4NzzCkosP58MxtkPtru6eHgidBzvs9VT4z61NwefNYvqLIPt0JLNok8Akm5OAJK1sAlGJtWTVgZhLQueme/cAzgH4jmBV4b3eUUqjaIqE3B0Xk1q5ixl+VZ7kc+NUBuloDuLENRZLFN9ClsCt0ywE6ROrP95BW4pWUPG4BhzLV4HKpF/Si6Tirge3GNE/p4abNWxrKKqnK9y6tHLM/OFkj0OXNo8IOlIkH2V2XxIF67x/sKBJ7Y6dovE3U/8vDHSa5r6sUtRbTxFhh+WjV4lCIDh7E0suUIPqpRbas339vvPE0GDxfzBNg1bhAgNVSJhtnHXRxWrZvo6T+55wVy8yX6EDZjwVElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwtnWX5vKBsIiWnQtPA/JqHPBiPvV+BCJ6oizeNCDZKKCECGjTtnpzud8bMcPi9dsr0bnM5AcsGwVBU8Ewyw3FBg==" + } + ] + }, + { + "header": { + "sequence": 3, + "previousBlockHash": "6BAADA2EB1864C4EBC9E27B1CA74638B866317103DFB1D37098EDFB985CC3B64", + "noteCommitment": { + "type": "Buffer", + "data": "base64:JgANHrxyquT4/Cj1Yr6RT5ZmZMk1EZeuLzIdshvXBzo=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:MEbdTY8LbdtqeRrU+kZ1Ly/RtAUVFXUMwE9ObFWO3Bs=" + }, + "target": "880842937844725196442695540779332307793253899902937591585455087694081134", + "randomness": "0", + "timestamp": 1676325611416, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 5, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAsLDQxv0geZj+R2U+WYrOTI8PH1vOPLP6FvDqS4CCTZWJv/KkGyJ+J7PLHB6pw7jx4Ky8Zfegu55fv2jtp2M5CL0T3rWz36t0nknCZlmulJWD+OpyM85IrxhD049o8AbsogaGDQchb3RUSHggJXx4IDYv4zonFoXBVbSqIgLK85UM6DshnI+v8jHK0j/vZDkT4PK5YERSnuFD2wTovxFK6UXyOFGHTQcgv8gYtw2XgjiHyRa3gM3/wEBY30X8IDgnqwdTFkrwL2i/HAopjj/8oQa5M690q5DccZ5+iUntNMBeL6Bt0M54jfamtnG6XU4u5A2ry8CwfFSe/+3wTtjFlMtr4sjsB63juG7dQcBOuU7S/nt4rpj2VbKKOHTr5lwPjXY7rT7NucFguz1i6iPMClNkuoXMIvrPSVsYcV5NFzmc01iBR8Ny1NLP/aiYhArXdfpDuKCI/7mR7/CBHJnR2y9aPAWjU5MDkOpKSff8bN3EmKjuClmOEVl43qdd7SFFSBSUN6Cofs41INZqXTKFVVrBXZ4TcgmUTfd6JU+cNwxKNtEHSAUJe5GVP+RiMqnhKS9EGGi+rvJHUggtjTEW+JycDNKySOX1oHgu6O9ect+ky3xpfdYJ4Ulyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwcokU5wdGUhG5CQHogBFlcKql+FaxV3DKZRBoYZeTFsssE/o2je9ai+fYcc62xMUk5zFo5eAPUXuCVkQiUfgzDg==" + } + ] + }, + { + "header": { + "sequence": 4, + "previousBlockHash": "130D527D673847148C95E41114D0FC31784C545E3597E8FEF0AEB01DAEB12908", + "noteCommitment": { + "type": "Buffer", + "data": "base64:2LkxWCrb5R8WuLa4kGlH2P9s1PQ+N2lBdmKH7hWP8z4=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:j9u8jmNEOUPPwxhPD0tVC/FFh2IhpGhKB2vhtGfbzqc=" + }, + "target": "878277375889837647326843029495509009809390053592540685978895509768758568", + "randomness": "0", + "timestamp": 1676325611691, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 6, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAJMzIiCFtw9Jcdbe+E6qHMeQxDqxhTmnf2L9rlzkSWQCRXvGcMqyXwQgj5C9YeX5igf/L/+DhKDDNG+P/gMiDO3KnRL/52Ml5boysK2+yYrKkLxHAOwAfcuRwmMp1AKl01eEy9cuQF9YwLF9iia1RDAneO7rfVohu4WIe6nd71VwEmGyee/uv9b+ap0S3mixx6btnXXL+zmCvceXGy3PDs5c7fYOlojGW7oJyJEjps+yAy4sFBKonAsM1c2u4OIS8YzcW9d72vB+VqNnAH/WehDYIpjMAv5Agr7pDwZLdMij/M1j8sJVaJri5PLVkezRfVc+gepTWYhXThLWXVmXsJKqiFeG0X5x5yUhOX2zcGQhw462oiNLtxER1f+EOUQc6XjEV7hvSL5NyXZ/oMKz20ki0iQuEItxbEI4fx5GzlAc65LAkhUuRYJnsapC/im6a7nvvFAXKWVjbJYAY0OVcSF/u5Lr7ktAOT6HWwHDkxtAVO03+plf4nkXpBGuPkSjJCiXH3+VoHCrp5mY8YhgkWENnpI3ssgJ/a7Sj2qRAlidTxG/Xx6h9OW/0a1IpMi5JRd2qJc+SB+gGwK7wbrdNb/LhgR5OkMnqh9mPBTLKt6ox1I0B4n8vN0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwUEFYAiDpcVA63Cx341zRPNZbNVgTdF6KheCybbd4hpphCgKuqksUwvGFMgk9IrX5emr3c0yHzJaVh0R7iWk8Cg==" + } + ] + }, + { + "header": { + "sequence": 5, + "previousBlockHash": "A65EE9F181B11306249C194391337A8F469EB135F25879833BED7840804719D1", + "noteCommitment": { + "type": "Buffer", + "data": "base64:X4EBcjeDWazpZHPmrXKT8h1bUqXr0DUnJLKzRMX/swg=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:QNlj0NEbLMuR1gi5W6XHq/e68QitHkXP1ywJMWeEuGg=" + }, + "target": "875726715553274711274586950997458160797358911132930209640137826778142618", + "randomness": "0", + "timestamp": 1676325611972, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 7, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAQ5zkFtMPSxUMPSrU1RRkknkDaS6zOQ0Ep7Bp+qFI7qSXXz90xUmxS1c71ZyNyjfDc0avOvMhq3rSDaL/yijmN+x25jnI8FWLqtTOHj0PhMOk81ybFQWIHW759X5pYjKCdIQz25WXbIQmTYbrFq+JSgfueETYjBijOUn8EiYhRigT5ZAxO9uzggdiIq25vsNFM77Ka+5t4sN0cWHqVlj9nDLW2E4GsqRhvMZsAV+h+Naq9k+vD8V5bouV7BsCCPpRoeGD9s9FtDlOJaibxYpUX1RsMTHp+iL2L1EpTZPAFPEx+vP7j15igXGO53ts1vYZczfTX6BJyi3gZQfYOERZRm7SOnnEows3ZKT/ByEcpOQjOB/+Nva9tMrmOM8ZVWIFr8dDolru3SIMzJWS5s3rkvDeXk8CNPYB37HqZ9Au45WVIZOuaKPE+n0iCCg4i1MmPFy9kPivNGbtXSYB4KhjpHGrCkOCZfec/2mKFcmDl/sjSo6sYdZDrFEV8zSMjw9tZqz3OAVF+rQG+WmH9+FPc9muDMVV/FmNGyXK4gLmgBv97BJFaRxjH1cOniwrEHEDVBomORCPMq7rDtnC7b2ve4XfLgVFB/j+URju/J/pwuStEY5VnS63Lklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwvkfd8ImVVkNeK+gvr37HGut9Va4tDB0waBv+u+/aOd8QFPFMvumRThbPMZ0v+bbk2a7a7CVnbVrRVCqaZAHlDQ==" + } + ] + }, + { + "header": { + "sequence": 6, + "previousBlockHash": "B2D774B1009ECF2B9AC7CEA66DB0EAE0673A4FA508933D4304C1E8471D2A96A4", + "noteCommitment": { + "type": "Buffer", + "data": "base64:dLn0jmAQ5/NZnzR7iELkKtnX0AqZmkMOu316L+dnfzg=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:NIxlIg1GNhXWNeH3bce4oUCeBTaKWC7CVqZQmyLmLHM=" + }, + "target": "873190827380823143577845869093025366895436057143163037218399975928398962", + "randomness": "0", + "timestamp": 1676325612243, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 8, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA6Bu5NmbLPovkelnYDnOMhMARYPwCNXp/1UKR/AZ51rSj5eMQaQH/f9ZeCuQ4CHhBCMu2hEaR1Mk8WwCvTgCg3xcw7b1/sm6Lo55RkgQ9o4WEKGfW0XcPCLE3Q/gfUo55wals1JyeDGlznRZjGNENEmihTAGjYAG3w3iG+DWBMAcZv8iyt6yrUDGYqNaSPOgI9qV3DcGuScJgyIklXsmn5YE5l2lDMnagsnirVxhw/+qV3FpXhSpKydjlZGZ50hNGvpjpS2DPD/R0HkkodqBuI8LQ8yb15cvN9A1gfB2wCokOCOSlmeA8LVAea7q1cmlYSI5GqK7Qv3Ky4x9WfFDmyj5rN6606xB7yc9Z89q0Aq7pkVx7SCb+LQsUtBwjRehtWhlguFmv2CQZr0Wcu76ZEf6hzxkJVbiVl4LmLtOMDwEDLc2pl/Kvf4OlKKZ8bBIJIiDD9+70+5DGs2v5onUVhuqFnfD1j9YVSou6IZ64eOxAAfRJTHmHEN5ZoROi7/vkHQpbEzB2r4sOkL0ypkaVdRDJCd/4K2gl3R5G0d2zl1D0y9yYOMzOvj6eHvWOS3X1S9+F5V1g75Bcg5pJ5wpChp/CXSPn+LO/lO854+5tqpLnz8B9DbQ0gElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAY8w1+9LEnMIXdJXVBO3yuWeI2UqfSp4sQkaeqDfLU4Uwyadz+YyTWItYKLbzR31Dn9VYsnuBN//I6jhTGB8BQ==" + } + ] + }, + { + "header": { + "sequence": 7, + "previousBlockHash": "4F49F43ECCC9094087748A57D5CEDB05F77F08F8ECE7C45D496FD20103454C41", + "noteCommitment": { + "type": "Buffer", + "data": "base64:QC3190h9ygtImwy5tISZhHg8V8W5gHx3LNLo02GygmM=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:1cjvr93XZ6Ik4JF7sJIDl9yrquTNYa4l9b9aRBAd7t8=" + }, + "target": "870669583413409794751345832897376592977547406352566801307278513052763546", + "randomness": "0", + "timestamp": 1676325612523, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 9, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAPIapfEHPe/OY2eFG02lyQG5/Jf10XscVBBY37pPaeGWr9hBMjbaO+LbnI5dniPD+yJGboTe4DKzRpidnU/v00Dn9k1GLxs4UAAbE9I4Vkc6xAcrtwoOItyhcwVV3MF9jtjUHB8HS9d8v2xL8oudukS/X9mJ6t/QS0ExyT6fp0kUUUGEic2Q3B27WGXn1aU1w6pTiwp/YD+BjWs1ziW07XqZpPu2/nsgD3PoFq+reC9CDAEVbrIcQL+3IdMdK76zMediPmoymiGyiwOkl2ieXsmv+Yghu3h3Pc3yP0jTJcBoUoXtHfMvTtB5lP5Fq1HO/YwJnIXPk8BpmvADucZVznOKInHfj5c9wrpxVrwgeacFtqXuXmEp0vaC4T0BaJXsxgbm5oEPTBC5PvjkA0XwV0WnpyJSYqDSXTCvGXgdDm1LzvwhVlxuTnQy8gHAEBxZ0p+PJyKlpoyLzZjPpm+LAVyVfUVmA8n2QWfdsPAd6l0uMIij1+pRcir/Dmv2d/N7KRsSKp4VnxqBs23TXWJRfA1SXsykxzHx00MVxBKVkj8mHYWxljKP3x1cmDSLSNB4miwNC2kwZx8xwKTv3u+MAzcxYmkd5y4tNbF1Q+Q8QIvIM6yTkxtD+PElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwEboSZ1jXOoJr88oehJ3Tf5Ayub1F38uF/Ezma0lbfS0D7Jb+Wi3hqXK7Ahb7SFgPNTxuRDiVDYpOGLwLSdnrAg==" + } + ] + }, + { + "header": { + "sequence": 8, + "previousBlockHash": "7C21DD136165DC7A9BEF0E82647C56B8CD04EEF9BB9BDCD140556C976179863E", + "noteCommitment": { + "type": "Buffer", + "data": "base64:rrNSHbD4h/h+2nEMBCgqyem94nOpxz2bUCji0P8NwyQ=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:+N+E800t3X9Pt5osWPnTV6ET1P834mDTROoEdss1m20=" + }, + "target": "868162857165578480563002226852566487623485369674008547560712452074684573", + "randomness": "0", + "timestamp": 1676325612817, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 10, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAKEHtJ+nuSWwBdmSz+C/Qv9OTEtntIzla3u9K8+8hre6lTuPloIG6fBS0Zh+XKIJ3k3H4mk7XvDrasZFL9FE+/UWdTPs++3/ZER0bkjewEBqs+ubob9Q9U3Rsukl3J7QOSyNwUlkk8zBDOGXfIrt4xe4c/ExcSxmx0nkGPUK9jeMZno0dgGHr5tnLnnX0/UuupdRVOXzqjIPw5vfcsYGwS10nrJg00m+4qhNeDwKARB23L4EXRvlFfz+n/DmX7TAFXrWnIpFJWOR1yKlLIOuw30HfN8CpnxLwjHPbpCzUUk6P4rvK4+zpdia+uHb/f/lYy9Kw77r0zrxZh3bavqAUBdh2V01dhRr1cbFAM98vnwrdr8bOGJu2/MzrCEbXUwEmNf4Ib4s7KDmIW0xrP8VNxTnTmVSGFmtUODWlutk0/e8z0DanRA/0CSn0t1QYgJ7HD8mvKOkT0BWSDHS1ogFQOOF6LCVVHBMenUtMSmRCRX9xRXazdJz1R2xMgiebGEjFH+A6fc5cOAvcDG2ynKcPMU7OEbr8v6BP2wOJ5+eNJNzoIaKIBvHNRRUlKdFyZc0rpL7NkSUbxA2+4ZX5QUTIN4iPdInEoBFzkcN359HKJ3lIXHZelsd1QUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw4mYfHsp6ZQ7Es3WjZEoFEcZwFzD5ugtFTYxdUfcbTV97W0AQao/4BPhCIXsGvWswg2Y10FMPY6+GPNj4p8PZCg==" + } + ] + } + ], + "PeerNetwork handles requests for block headers should respond to GetBlockHeadersRequest with reverse": [ + { + "header": { + "sequence": 2, + "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", + "noteCommitment": { + "type": "Buffer", + "data": "base64:4HjH82db3xKVx2XcOGdq5AQ5zp0tR9a52FuvjExozA8=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:MtpPHh1cnQnEVhuUgdU3B9V2R1I7DQpEl+4dH/u5cvI=" + }, + "target": "883423532389192164791648750371459257913741948437809479060803100646309888", + "randomness": "0", + "timestamp": 1676325613120, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 4, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAVyINRA4/9UaYFbqm5kE8FgTr3oMaGaQP6LbXFNsYzYq1Mhzn/rArl9r9Apyda8v2bWD0x3AVXaiD/l59rF/R9t3pkp2hqC/EsMCFZ+7h55ilquvbd4CnnlWqNZIBW43X+ldbjNzuCrxm04uSJ4rQiX/og8gA/MFZLT9dvxpS4VsEgepQe7xzytT/GdsXvRjx68DY02ajta21UMJdmpgaSCAiK/8p8RLpl84/qwKe8GaVa5lA4uOZXDnOK3lI8C1f75fEoVgFSQqim6HSL+KNJY3OBnwYl9oAWfitCMBZ/m+Fq30SmDldvj7hQ2r5EDukEyWgHoL1oaEsx6O72YiyIxkxYTxaOj4lVXYi1HaVPlT9/B5Ztv8GhV1LDSunJkpumfWvU1QUbe8BO+vU7curjGazudSUnKNfB13EQSdc0iZj8FN+AyB7sJUrZEd5JXAx4Izocddzx3veT/YQ36UttYm1j5dtiqoU4DvGPhTNedzIRZmFCfvJ7vNoRVJ1sf4RC1Wu/0WwLPG3+znihtQNn948y0vh4aGPURyclGBnzQ1F4frMjNIlEUbICf4BIE468MG81oxrU0mo3sDmlxTz5OsYG+ctYN09g4s/VWH7kcWShG+YDvlQHUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwibgBM/jZigMBtvQEyD5sNlpoVorOOPkEd9A84LtxPMoeR8lLBeGw/AQvKriLJOvGhO6kk0/czMJ8J40tCXeqCA==" + } + ] + }, + { + "header": { + "sequence": 3, + "previousBlockHash": "0FCFA7268BE1E80D78E7103F57CCC398174EC39A9857ED03D7CF63F3B16AC0CF", + "noteCommitment": { + "type": "Buffer", + "data": "base64:oIp7EtmE73he8sR6VdRHvVrgVrDLcauhW63xM4lC6Cw=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:X8F9C5XNcxFqa9rDruCV8hsdTSF8HyRIQ3u39WKOhf4=" + }, + "target": "880842937844725196442695540779332307793253899902937591585455087694081134", + "randomness": "0", + "timestamp": 1676325613398, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 5, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAARnqE461d1EUhTrrkktCvCw1BmPejB4iAQbvKmOF+G4WS33APkwYkUvlOBTAkJrz1bzwsZc2tJn3mYvg0BZcpYKrMUjCcHRWZB3K5ZcSJaVKYY4EBEdmgQZ7EghCTrPuCXLJsqVrue2f3oEBA2MFM04a1MB/bsUqelPZop6r20vUDiZ0BGUY5qvf3mg1Q5vz7rEdgesFh0bLIUS8C5HmYIW6hIG9yFRWux8saL3/DHOCXeImi5o/m/WudriJo/8iYNDCczUn6j0bY85xXlSgiTKR8qTX+ubHbpg6GuijtlO6bBoL3YZEycJVfxoqW+AnGVRbTiQZgzT6dVzy1E5ES6nU6czDNHuY7B1xM/aDAdb8dz/rQdQ7jAnfFjkO2p88RFhu5JWtCOdiULDT9iiUHAB2mueG+uXVzFTpPWd1pjfKbqTm8x1cfUS3fCwO94KvrJGL3QCELMHMHbXmFuzo4asvtoYIpTjaqzJ8v1+1iJvgnnU+KjR0yYjE7vywKBjMmPxoJQdrW7zeaMf+7xjJq/K6sYNtkJtX/jP4EIRhz5FUSy3mH4I+8IWarWSjqhZVPy77lTcedFgq4ghKW1ogw0Th8jD7cGWOmesP+TnCvBR29Wi7llIvMMUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwJ6OyXquMAzNbuLTmStmL5q2t3GkEawO+76JBE4uBc5W+sr1w5UWKVQq163xMWDEX7NlXVh7EHDys6/O/CzxECQ==" + } + ] + }, + { + "header": { + "sequence": 4, + "previousBlockHash": "AAC355D47BB23BBF812F53E536E35B8CC5BECD32BC610046EB10049B89BC79F1", + "noteCommitment": { + "type": "Buffer", + "data": "base64:VMlXm4pD6xNSbU3qGsR808yh3RxQYpTK4r0JcIF0CGg=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:/NeotLXXBJwCxeb0enHGVYj917cnWyKKJ/iX4AJmmlQ=" + }, + "target": "878277375889837647326843029495509009809390053592540685978895509768758568", + "randomness": "0", + "timestamp": 1676325613691, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 6, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAADtAPbvoU/VKjq3DeLt2lTVt8CvCxzyxQH2chV7QWf72sayEo4AKo0vxhhRnd9ClbAzWba4kD3qj9NOq2Opu8Rttvdc3kBG/iX90jQcyxJfiQL1lue6iu6lseWanvUe3f87tSkq4CJ1qC6QDmCdYirJ7+215j0n9sck1NSrf9EqgAlnfYNR5Lekc0XkZt4FMULeoa+iuFR2/oqw85IDmpqQjU7t40B9a/1b2uB5Ja3CaQ2M6eyE46LqXL3BSztMyVsL4T42L07aqWhSo42QMIFH1l9ZQdvi56sLMcCgkvVGfORV8PZDRtMKnG5+F+Ij69VlESYTlU+Za4X/yfEd39S8h9ZuqHoYFvYbasAIWEeIfUV0ngE0mSxVAD3BY4Z1A6cLlFQrqiQhfWY1ojHyvWBeWl16wrIxfia4TGXgJOdrDtevWmyPBM1HLl7W+Ekzb4iEAK2lNevw55Mvov690IrgiwrTEMj8G0jpK9L95yWLZKX0EbwduNniv7aubD7u0w66dqk/asKJmjJ/RejGkyb6w1IWm2wL9Nz2M5tinWGn1oe7Ws1BLYLYueY3N3RQDcPMcDj9v1DfCldoPwXZ0X0y76V+keIfuRNOKkvS2fdkBR6rKkV92mj0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDj0ibBFbLrLy/yEIEDxbZ7YCWbbCgjBh5/ABF85JLdJoBR6n1MR8cEhsGd2Xs03g2UtRnopGp7C9aGTK+HhBCQ==" + } + ] + } + ], + "PeerNetwork handles requests for block headers should respond to GetBlockHeadersRequest with reverse and skip": [ + { + "header": { + "sequence": 2, + "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", + "noteCommitment": { + "type": "Buffer", + "data": "base64:ikH+lCwcW/To1lkwH54LeKtbyuA6Gv8/bOVCbIhcumc=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:lNfm6YkuiiA1Z8YzSJwcCzDXRFQ0XyO1SFwjwXVadYs=" + }, + "target": "883423532389192164791648750371459257913741948437809479060803100646309888", + "randomness": "0", + "timestamp": 1676325614005, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 4, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAQmZvGf8jnVzIt17kXPFHZ193qmy7PVCJdXHyWeUk8OKBLl6dH3rnRSEKQyJhQgzGwhOINwXQmJ1p09mQ9DjGAnB+KY2w6hRUIBdeVvK1eEWJ2S/qVi6vOgTKtQJ/fJ/Y/6H+ET+0Y4ILf51rv5QzGZmHbSbB6QTyupIPj3pCI3kNtl3u46kOLRTJq2lFysf1l8MuP3bZi5gMa1HH+0VMye1sFN+87QhAMjUSXyEA/hOoqnIk7ygEwIM9sIAqPaQMtkK66zYmaDBa75/QMYMR8VsmksOYDFwSG1gBVyfvg7Nf8aD8Ga3s79lGbC5OKnPHrh99+98mJ58T64aTiqcsL+PnDQ7//a1j6aqREIvgolefcD3wszcvx6uq7oa8qU4Jgeg7I4XfOvEJQfza/W/BhxeFEkpmM/L3Xp7Lp3zyWxIABLhmDIHzGjSOjYDwO7AJoyoSILkx150EG/C5dIHxmA1MZcCmrDDaMLyTMmfq84Fzfb4nUiC24fT5TsUqPyT17Q/iUgGXfWbFOvrwxNqcNpGzu06JdHKhBY86V67TQM3GpNITMxDq63UtNSoLzNAgy/QopSHqaTPr6YxmCqGDbUA+B2Qp+r0t1NaS2GCxxYDENDT5tvNvQ0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw6EKGXhmMn32g5dSIvbfsQjpA0BOsuS+QL9o7LAYr40l8d1/77JfLexn2O726m2I8lPTMa7eT2LRNP7NQOpoRBg==" + } + ] + }, + { + "header": { + "sequence": 3, + "previousBlockHash": "9D9BCAA157BF070B6DFEF0801DE591BD4617BC6E06C606F3B97E42F0A473C7AD", + "noteCommitment": { + "type": "Buffer", + "data": "base64:CVbI0xuAWLrXIbza2qFRExX0aDXoI49aOKR3qE826gY=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:Umtz6yU+WR06Aoy7lQIWEX/Id7PI7/aRM4U5rt4cgcc=" + }, + "target": "880842937844725196442695540779332307793253899902937591585455087694081134", + "randomness": "0", + "timestamp": 1676325614306, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 5, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAAfn95g4+7AAsuQ6VHV5XN+P2MHUCi49QtfeQbVMhdFuqiJA31LVMyYV9YrArOy0LanrhapBY81sNQZ97fI4WWi0N9mdCz4NiTaJOQ4H+Kb2rEZ0x6HohxDZF25qivQWucSK75Bzl4qtpG14GC09G+jXxz2ND2TYhxgySZluCZyYUsqDiySFewpV6lM0oJt2M/p1PbVt7R6jZGUY9ocuyPZae0dgLKkhYOHAAYDgK/wWNuIZufinl2pwAUKBB+W697Q+SuBEuHEwMw124mGrEoqr2rqEtuv0sCdYWM+iA/+QUaZVGIvH+eRO5+32SYy86lROEGjxqIv0jmqsmcHP/RsmDSH0FEU88yL8o7dP7gIlBhuWOIPrzptBK6dSUaABnqNsR5Ztyb/+ucs8zzTdqbP9Xsan5TgzCYje9Iu4FSq5QCOUkztaDNhX+1RbS+R+MJ4MEvEpJFL2SqYRf+UoTFWp1Tp6iC7IA32q91XnjICaMARFYFqxFNlZyc9toiez9R/IInu+cwjrCJFko6NM4plb8bGLCNrZeuVXHhol6yz5oGObwpT1h0D7DUtMsGa4Kid5sRnezLYEar/LLNHxpGWV1CNcMNeMzRvl9GZyMxBOTFAFMGFDvgElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwmDxrsvL3N3iIErk68z4AsIJmCJfYxAX1Npx38AWAvZ9T9xe+B3qauxpytZPgQeBxm2RzeYWdxkpzIKfdgCxVDg==" + } + ] + }, + { + "header": { + "sequence": 4, + "previousBlockHash": "26200F9C2E317FC52E9AFC7CFF09065ABAD8BAE89C897ABAF0A8C988DD32FD0F", + "noteCommitment": { + "type": "Buffer", + "data": "base64:GLym8epLj4ZZzCr3lB4mk6jbutZRYv+TQaMPX5SGzQ8=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:tygn1GYUllq3TDE8vUxNVaDBRTm2AszFlejicxPFHEo=" + }, + "target": "878277375889837647326843029495509009809390053592540685978895509768758568", + "randomness": "0", + "timestamp": 1676325614591, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 6, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA/GhYHJgsQ3LGOHG7Khk0nl2OoOQ2qIoTeVyTXOtnaY6EtbEHUA+ZDx9QrVIpzBQY82TFkNa7gmgBKauWAoYQDfb6iDAbTC1J78XpFPLu/T2Vf70TtaKdUWjgI5x5ZBFAVAirRMnjojcmrhX/UGTSKHJ+4gGYaD4sRzvY+usMCLgMc9/dBoCrYBHRcGBpwro6aQUk5TDwfHjI+CAFUBK343aD2pOf38fRhFpTjP6Cep6vsl044frbKT99mlVPsdWFM9nshnZp2bUlmIMcof6JFaDQ5kVwf6WIyfvn1EbUJ5srPN88AZNAwXItl3NsmU2Zn5OW9Pz6c81vvCmxkafALNOTkS/3Bvjo9zWkZd4GdAQQOEBLyCbR0BhURaDHaNcdwTvk1pd4lbIhBb5ArFtqqTbETQR9ZNNN4xV5nZP5gyz0LLoO/BPG2Uq2Qu5ugS8m9zOj76DTrtJUG3NBX2BezIe40c0le4m13T4StBOf9CyKpGZ5k4131ejZtcNpAfeKoonurxlD4EyV/f8rTvlDAEha93tGnV9g/LOFgocRsHB0eBhdWc7lpXHfOz5l0BzCIPj8q5kpUh2MIM8GJe5ELFsqQrfkt4FlaJBw579zRomx0DV0Bnx43Elyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw4ZIaFqx/QhIPwpcshZbwXp639mSTihRxzGO6bQJWJuuB19wyxqKHrVJpAXzcjx06qcpOuvxkGzGQYBJN0LpUAg==" + } + ] + } ] } \ No newline at end of file diff --git a/ironfish/src/network/messageRegistry.ts b/ironfish/src/network/messageRegistry.ts index 31d19db3c2..f66e2db53c 100644 --- a/ironfish/src/network/messageRegistry.ts +++ b/ironfish/src/network/messageRegistry.ts @@ -5,6 +5,7 @@ import { CannotSatisfyRequest } from './messages/cannotSatisfyRequest' import { DisconnectingMessage } from './messages/disconnecting' import { GetBlockHashesRequest, GetBlockHashesResponse } from './messages/getBlockHashes' +import { GetBlockHeadersRequest, GetBlockHeadersResponse } from './messages/getBlockHeaders' import { GetBlocksRequest, GetBlocksResponse } from './messages/getBlocks' import { GetBlockTransactionsRequest, @@ -83,6 +84,10 @@ const parseRpcNetworkMessage = ( return GetCompactBlockRequest.deserialize(body, rpcId) case NetworkMessageType.GetCompactBlockResponse: return GetCompactBlockResponse.deserialize(body, rpcId) + case NetworkMessageType.GetBlockHeadersRequest: + return GetBlockHeadersRequest.deserialize(body, rpcId) + case NetworkMessageType.GetBlockHeadersResponse: + return GetBlockHeadersResponse.deserialize(body, rpcId) default: throw new Error(`Unknown RPC network message type: ${type}`) } diff --git a/ironfish/src/network/messages/__fixtures__/getBlockHeaders.test.ts.fixture b/ironfish/src/network/messages/__fixtures__/getBlockHeaders.test.ts.fixture new file mode 100644 index 0000000000..05ebbe6809 --- /dev/null +++ b/ironfish/src/network/messages/__fixtures__/getBlockHeaders.test.ts.fixture @@ -0,0 +1,110 @@ +{ + "GetBlockHeadersResponse serializes the object into a buffer and deserializes to the original object": [ + { + "header": { + "sequence": 2, + "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", + "noteCommitment": { + "type": "Buffer", + "data": "base64:BCtBfMP/skq71PETYlxXxm0dq9VoL3muPjQpozTyfgE=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:3T039xk7I0BT8gt5QzW0+8okUhHfWQLX/vL3rtgD69Q=" + }, + "target": "883423532389192164791648750371459257913741948437809479060803100646309888", + "randomness": "0", + "timestamp": 1676313126608, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 4, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA1egmBgkkqNHc4UmiF58aB8LNByWr++3x/52jivAvUhaC/fZ0Yxwn3sR+Kj73uiSbhZv6fmwpBd8Sw7J5/po9oXU19qQpiYDwWWA+Xq8PjbOCjsh2btvG7llSlJBme3ICuhGhxgN3hX4ODBpmYmhAufwDYxtEyq82MVOhGk1wBdAN96Ndc7HDAwXnrAwEW6nsw1ggJ0k5PW4/k8SQZQnfEKhUyYT7GkbkbV+pTljjDWaulcQv9ip/9nH8csPvdIPm/DWaXJdwFMyY4El7dIRGdiMlSwmSK2VqZ1klQMg5GrB/+fvKnhQQgLFZ6ZnvAifJWuVDUe+cOlA6oBLD7ky1AYxpS8WVmFpvhaJNa0fpG3HOnhvrYZY5DLv2zoky/zYa2jOCyt6DxSE22+f/n7SmwHmZ+rZVVBK77RMg02BasCbVksHoww929j9A+V+pjETyjSx/Pwh3H1QFD8/v7zyV7uPfdZMQD4O0FieqH6cOXAcSoacYvcqHiu53NyLFkioXLOZqkk3xbOmWm90qSQH/1oBCl51lkoYQEwh4aPW1WN9Z+SidpRqYBTPgdiLipDPSqPVUm2xrYRYwPm6H++Bdhg2gGCGYnmeOMQtjlD10V11l0YTcp3YPdklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwd/bDxDj3vlDYuEfnJzdxWyh9HZHAPLBRDYdQssBjD0X93YdriM3qcRi2GZi27ca4ss248sGLQocB1BK0TQi/AA==" + } + ] + }, + { + "header": { + "sequence": 2, + "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", + "noteCommitment": { + "type": "Buffer", + "data": "base64:ssOjjeK+j8GW2G5JbRGxKi1F4gZTD7pbwVOCHJoY7Sk=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:AdF0iy65u+AzW1wRqkSZm7j8ayLSojl6UN9pzt+7id4=" + }, + "target": "883423532389192164791648750371459257913741948437809479060803100646309888", + "randomness": "0", + "timestamp": 1676313126896, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 4, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA/Hyg4kaK0A9UZ7jlxueS2g10dn65Av5UryiXPf8sCJ+tKmC5t/dVoiscOqfvbvVYPWEhBeevey5qe1e1aBrW7VNTphhIuXNARFceVsF3HF6oj96ncaNkL1b19N1KF7uVXTFV8jpIKH+SASR/UEjWCiunjTeexGB/kagZg799t1UQ4S7zX4AtZnitvRfryx838xBkr+U3VadYDx4Frp1jKigGd3cnbhXZ8G0PmlgBJMuo6pS3fmWoL/zp8NgF8PlQCRFD8outq6MjO3wvzIfgvTciQvkTTeWbMc0HOteToKh3SNIQSBO2reB5l6u0JM0ojwhTRjspL3pMVu7gtBkb0lviiXk8Cp7FWxMR2k9KxMZG6zyRXEMB8/JXT7Ixe7Fzb1oMPyLo9LjAw7bBF2l+/DWIPUfVs+mhulnUY19JdkdHMdRb22Fa1drMGrdT2odZzNiC9swQT+c9PWuQrUm9TgHLXcbdgaCMze+XCaMoU9VnUCerz4vQYyshgp9SR6uIxtaupo76z5hGC8lUvubcEXMOuFn4Z76ATt8LrGmkZWJyo5urgdluA8P1vNPVecV5gvXno2hAKd0LnQHdRWDgxobEORErGq+2YtTTrEnSZ9v16uEYRYSo8Ulyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwrZPms/ty/jx50fFsh+yPyDwvFeiOlpOQLL3DZFx+OEAtCiGc+gBpNRAIrtF/ItU4X8mMO7nw5wKOk6XLA5h/Aw==" + } + ] + } + ], + "GetBlockHeadersResponse throws if the given length does not match the number of hashes": [ + { + "header": { + "sequence": 2, + "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", + "noteCommitment": { + "type": "Buffer", + "data": "base64:vreARwgeIDL0iJUK3KSxm7TgdyhFCC5jZCMrUxIpPiU=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:neYh0TXTqT4/5zldCz5yPxDitLyATh9ao70KqivUxCA=" + }, + "target": "883423532389192164791648750371459257913741948437809479060803100646309888", + "randomness": "0", + "timestamp": 1676313127208, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 4, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAoL+N1CfYxnqsJL7zc/xoTrMQppWjH8gLjGQOYwvq/ruZEkKd9KxfW1qgVX+4T62bDVFzixwvcT9EsWhhOkiq8lDz+N05UuUq1DlhnO4HtVi2RdIqbLl2xiurySFZLcsxSBZYhQlXgE6U1WM3Kzh8aEmiVlZFwKJm2/D+25NPU5YIcXvGyCUhlIRwTTPdlrzH+0vPf8crQgpM5108HdFNtCNLChMpY/rlWDU+L5O6XFOrKma9cKuqLNalCe35Vb5tsNqLP/k/XTqrYkBachKMCw7JsYP9xcLmDrsRLbO+ZmFDHX/PeQlhj5zvw3bsTkHYVNx6ofHOqaA3/L4cLfizQSINpvUvuIqV3eRqeeGGiwq3EXzleUbHL5IG6JSi4mwkwfDdGvE0EXY3BPVWiwYxJXVF4wTIMcK3eBvhN8XB2BlbMz7ZQhicFlCn+YvIOhxJlU2pSRdstL8oLLNezjft6OGcG2sBqjmH1J/YrDLHeTFOpRXSxViDINjnvwq67rFdzVrDmkzRNnaHvPrUW74AS9vO2ffLy+r5984JxhLAYpmwshc8+xA27fgoV01EliM6aD6PTyF4NiacD6Gg2iPyv+sIEz+EYrwoDSSSt9ucEIRaa4mntCpfBUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwnd2ft+05imPSAivoKDTu6xOxVsSOOhqNanvS1wiuTmGa69cWyGl6dR9eHOWpxkE6XaTL3DcKGsIF4xh/JrpTAg==" + } + ] + }, + { + "header": { + "sequence": 2, + "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", + "noteCommitment": { + "type": "Buffer", + "data": "base64:9dTzfhdu7VRWF3HrIXhM12CwWsxeevDW/gd5eViPlDU=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:vFDY4nHca+eqLsCVR5egKKE8wGj/GkDeSGebhmqbcKg=" + }, + "target": "883423532389192164791648750371459257913741948437809479060803100646309888", + "randomness": "0", + "timestamp": 1676313127505, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 4, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA6JbW9PkeYJrgJl7mh9OAcg1o85gnLClx39sKZIHYWcC0aDXm22l/Ti4aKROnQ3wNvmpvWHExn4BhO1c+5molqbxRmHrGhuSpSGlAJc8asnmRZeY8v3G9hKlzIy99Hg0EKIgG+MS4Ivt2IGWwtoxZVI5MD9Do7WgLjpEfCRxC2SURsPr8KHhpdosQ/7sVRUCzJG59w+AVHyVVdX02zlW2QYvMGluJN9VQ7gv0qO+zJLyUFH4fSoD+z6AfPPjoAbRz6ayyrxmRZG/riU+egf5zP41AbDrsHwMiyfdM7i4yY4/hvFZPF2IYwBVe/ruv/pszUrAXCAYlok7b76p/Y9MRG/UymEk19BYzaLkWFEpvONw3dtGDAQbRwlu1aRqFkaciHbXARZENcH/zg7qwne0x0O2x8e6H3yzioIG3EJBzbh4pEyV3e4tDHT0wRRRtn2HfFvGBVGxTU6+aFeKTObe1MmyXe5VJYnFCJMjAToSrZ+pDk85wp7DC7bn31FE8XtCczSxm+4h7xopXYk7Lb3BvBH2jw35LS0tW/L5WT70LYrTtrGqz2h34x+pWBfOXC3EUrepgk6+GcU/RSxP5oHKYePj9Sq4MRMzY94NG6b5UH7LkuvcGIcwct0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwtYDrNZ8yjybYLGJLanUid4Wa23ekxEVay3vB8hbdyI+e+MTBfYqKD9MRdNRtdR7kAkrzFQaCBlc2ExOiuegECg==" + } + ] + } + ] +} \ No newline at end of file diff --git a/ironfish/src/network/messages/getBlockHeaders.test.ts b/ironfish/src/network/messages/getBlockHeaders.test.ts new file mode 100644 index 0000000000..86310c60d5 --- /dev/null +++ b/ironfish/src/network/messages/getBlockHeaders.test.ts @@ -0,0 +1,42 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +import { createNodeTest, useMinerBlockFixture } from '../../testUtilities' +import { expectGetBlockHeadersResponseToMatch } from '../testUtilities' +import { GetBlockHeadersRequest, GetBlockHeadersResponse } from './getBlockHeaders' + +describe('GetBlockHeadersRequest', () => { + it('serializes the object into a buffer and deserializes to the original object', () => { + const rpcId = 0 + const message = new GetBlockHeadersRequest(1, 10, 0, false, rpcId) + const buffer = message.serialize() + const deserializedMessage = GetBlockHeadersRequest.deserialize(buffer, rpcId) + expect(deserializedMessage).toEqual(message) + }) +}) + +describe('GetBlockHeadersResponse', () => { + const nodeTest = createNodeTest() + + it('serializes the object into a buffer and deserializes to the original object', async () => { + const block1 = await useMinerBlockFixture(nodeTest.chain, 1) + const block2 = await useMinerBlockFixture(nodeTest.chain, 2) + + const rpcId = 0 + const message = new GetBlockHeadersResponse([block1.header, block2.header], rpcId) + const buffer = message.serialize() + const deserializedMessage = GetBlockHeadersResponse.deserialize(buffer, rpcId) + expectGetBlockHeadersResponseToMatch(deserializedMessage, message) + }) + + it('throws if the given length does not match the number of hashes', async () => { + const block1 = await useMinerBlockFixture(nodeTest.chain, 1) + const block2 = await useMinerBlockFixture(nodeTest.chain, 2) + + const rpcId = 0 + const message = new GetBlockHeadersResponse([block1.header, block2.header], rpcId) + const buffer = message.serialize() + buffer.writeUInt16LE(3, 0) + expect(() => GetBlockHeadersResponse.deserialize(buffer, rpcId)).toThrow() + }) +}) diff --git a/ironfish/src/network/messages/getBlockHeaders.ts b/ironfish/src/network/messages/getBlockHeaders.ts new file mode 100644 index 0000000000..ce39659aa3 --- /dev/null +++ b/ironfish/src/network/messages/getBlockHeaders.ts @@ -0,0 +1,93 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +import bufio from 'bufio' +import { BlockHeader } from '../../primitives' +import { NetworkMessageType } from '../types' +import { getBlockHeaderSize, readBlockHeader, writeBlockHeader } from '../utils/serializers' +import { Direction, RpcNetworkMessage } from './rpcNetworkMessage' + +export class GetBlockHeadersRequest extends RpcNetworkMessage { + readonly start: number + readonly limit: number + readonly skip: number + readonly reverse: boolean + + constructor(start: number, limit: number, skip: number, reverse: boolean, rpcId?: number) { + super(NetworkMessageType.GetBlockHeadersRequest, Direction.Request, rpcId) + this.start = start + this.limit = limit + this.skip = skip + this.reverse = reverse + } + + serialize(): Buffer { + const bw = bufio.write(this.getSize()) + bw.writeU32(this.start) + bw.writeU16(this.limit) + bw.writeU16(this.skip) + bw.writeU8(Number(this.reverse)) + return bw.render() + } + + static deserialize(buffer: Buffer, rpcId: number): GetBlockHeadersRequest { + const reader = bufio.read(buffer, true) + const start = reader.readU32() + const limit = reader.readU16() + const skip = reader.readU16() + const reverse = Boolean(reader.readU8()) + return new GetBlockHeadersRequest(start, limit, skip, reverse, rpcId) + } + + getSize(): number { + let size = 0 + size += 4 // start + size += 2 // limit + size += 2 // skip + size += 1 // reverse + return size + } +} + +export class GetBlockHeadersResponse extends RpcNetworkMessage { + readonly headers: BlockHeader[] + + constructor(headers: BlockHeader[], rpcId: number) { + super(NetworkMessageType.GetBlockHeadersResponse, Direction.Response, rpcId) + this.headers = headers + } + + serialize(): Buffer { + const bw = bufio.write(this.getSize()) + + bw.writeU16(this.headers.length) + + for (const header of this.headers) { + writeBlockHeader(bw, header) + } + + return bw.render() + } + + static deserialize(buffer: Buffer, rpcId: number): GetBlockHeadersResponse { + const reader = bufio.read(buffer, true) + const headers = [] + + const headersLength = reader.readU16() + for (let i = 0; i < headersLength; i++) { + const header = readBlockHeader(reader) + headers.push(header) + } + + return new GetBlockHeadersResponse(headers, rpcId) + } + + getSize(): number { + let size = 0 + size += 2 // headers length + size += getBlockHeaderSize() * this.headers.length + + return size + } +} diff --git a/ironfish/src/network/peerNetwork.test.ts b/ironfish/src/network/peerNetwork.test.ts index e8023c8d88..dd29af3494 100644 --- a/ironfish/src/network/peerNetwork.test.ts +++ b/ironfish/src/network/peerNetwork.test.ts @@ -24,6 +24,7 @@ import { createNodeTest } from '../testUtilities/nodeTest' import { parseNetworkMessage } from './messageRegistry' import { CannotSatisfyRequest } from './messages/cannotSatisfyRequest' import { DisconnectingMessage, DisconnectingReason } from './messages/disconnecting' +import { GetBlockHeadersRequest, GetBlockHeadersResponse } from './messages/getBlockHeaders' import { GetBlockTransactionsRequest, GetBlockTransactionsResponse, @@ -40,6 +41,7 @@ import { } from './messages/pooledTransactions' import { PeerNetwork } from './peerNetwork' import { + expectGetBlockHeadersResponseToMatch, expectGetBlockTransactionsResponseToMatch, expectGetCompactBlockResponseToMatch, getConnectedPeer, @@ -376,6 +378,145 @@ describe('PeerNetwork', () => { }) }) + describe('handles requests for block headers', () => { + const nodeTest = createNodeTest() + + it('should respond to GetBlockHeadersRequest', async () => { + const { node, peerNetwork } = nodeTest + const block2 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block2) + const block3 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block3) + const block4 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block4) + const block5 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block5) + + const { peer } = getConnectedPeer(peerNetwork.peerManager) + const peerIdentity = peer.getIdentityOrThrow() + + const sendSpy = jest.spyOn(peer, 'send') + + const rpcId = 432 + const message = new GetBlockHeadersRequest(2, 3, 0, false, rpcId) + const response = new GetBlockHeadersResponse( + [block2.header, block3.header, block4.header], + rpcId, + ) + + await peerNetwork.peerManager.onMessage.emitAsync(peer, { peerIdentity, message }) + + expect(sendSpy.mock.calls[0][0]).toBeInstanceOf(GetBlockHeadersResponse) + expectGetBlockHeadersResponseToMatch( + sendSpy.mock.calls[0][0] as GetBlockHeadersResponse, + response, + ) + + expect(true).toBe(true) + }) + + it('should respond to GetBlockHeadersRequest with skip', async () => { + const { node, peerNetwork } = nodeTest + const block2 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block2) + const block3 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block3) + const block4 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block4) + const block5 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block5) + const block6 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block6) + const block7 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block7) + const block8 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block8) + + const { peer } = getConnectedPeer(peerNetwork.peerManager) + const peerIdentity = peer.getIdentityOrThrow() + + const sendSpy = jest.spyOn(peer, 'send') + + const rpcId = 432 + const message = new GetBlockHeadersRequest(2, 3, 2, false, rpcId) + const response = new GetBlockHeadersResponse( + [block2.header, block5.header, block8.header], + rpcId, + ) + + await peerNetwork.peerManager.onMessage.emitAsync(peer, { peerIdentity, message }) + + expect(sendSpy.mock.calls[0][0]).toBeInstanceOf(GetBlockHeadersResponse) + expectGetBlockHeadersResponseToMatch( + sendSpy.mock.calls[0][0] as GetBlockHeadersResponse, + response, + ) + + expect(true).toBe(true) + }) + + it('should respond to GetBlockHeadersRequest with reverse', async () => { + const { node, peerNetwork } = nodeTest + const block2 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block2) + const block3 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block3) + const block4 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block4) + + const { peer } = getConnectedPeer(peerNetwork.peerManager) + const peerIdentity = peer.getIdentityOrThrow() + + const sendSpy = jest.spyOn(peer, 'send') + + const rpcId = 432 + const message = new GetBlockHeadersRequest(4, 3, 0, true, rpcId) + const response = new GetBlockHeadersResponse( + [block4.header, block3.header, block2.header], + rpcId, + ) + + await peerNetwork.peerManager.onMessage.emitAsync(peer, { peerIdentity, message }) + + expect(sendSpy.mock.calls[0][0]).toBeInstanceOf(GetBlockHeadersResponse) + expectGetBlockHeadersResponseToMatch( + sendSpy.mock.calls[0][0] as GetBlockHeadersResponse, + response, + ) + + expect(true).toBe(true) + }) + + it('should respond to GetBlockHeadersRequest with reverse and skip', async () => { + const { node, peerNetwork } = nodeTest + const block2 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block2) + const block3 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block3) + const block4 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block4) + + const { peer } = getConnectedPeer(peerNetwork.peerManager) + const peerIdentity = peer.getIdentityOrThrow() + + const sendSpy = jest.spyOn(peer, 'send') + + const rpcId = 432 + const message = new GetBlockHeadersRequest(4, 2, 1, true, rpcId) + const response = new GetBlockHeadersResponse([block4.header, block2.header], rpcId) + + await peerNetwork.peerManager.onMessage.emitAsync(peer, { peerIdentity, message }) + + expect(sendSpy.mock.calls[0][0]).toBeInstanceOf(GetBlockHeadersResponse) + expectGetBlockHeadersResponseToMatch( + sendSpy.mock.calls[0][0] as GetBlockHeadersResponse, + response, + ) + + expect(true).toBe(true) + }) + }) + describe('when enable syncing is true', () => { const nodeTest = createNodeTest() diff --git a/ironfish/src/network/peerNetwork.ts b/ironfish/src/network/peerNetwork.ts index ff19024e77..ecd7b84c2a 100644 --- a/ironfish/src/network/peerNetwork.ts +++ b/ironfish/src/network/peerNetwork.ts @@ -27,6 +27,7 @@ import { Identity, PrivateIdentity } from './identity' import { CannotSatisfyRequest } from './messages/cannotSatisfyRequest' import { DisconnectingMessage, DisconnectingReason } from './messages/disconnecting' import { GetBlockHashesRequest, GetBlockHashesResponse } from './messages/getBlockHashes' +import { GetBlockHeadersRequest, GetBlockHeadersResponse } from './messages/getBlockHeaders' import { GetBlocksRequest, GetBlocksResponse } from './messages/getBlocks' import { GetBlockTransactionsRequest, @@ -583,6 +584,28 @@ export class PeerNetwork { return { hashes: response.message.hashes, time: BenchUtils.end(begin) } } + async getBlockHeaders( + peer: Peer, + start: number, + limit: number, + skip = 0, + reverse = false, + ): Promise<{ headers: BlockHeader[]; time: number }> { + const begin = BenchUtils.start() + + const message = new GetBlockHeadersRequest(start, limit, skip, reverse) + const response = await this.requestFrom(peer, message) + + if (!(response.message instanceof GetBlockHeadersResponse)) { + // TODO jspafford: disconnect peer, or handle it more properly + throw new Error( + `Invalid GetBlockHeadersResponse: ${displayNetworkMessageType(message.type)}`, + ) + } + + return { headers: response.message.headers, time: BenchUtils.end(begin) } + } + async getBlocks( peer: Peer, start: Buffer, @@ -650,6 +673,11 @@ export class PeerNetwork { peerIdentity, message: rpcMessage, }) + } else if (rpcMessage instanceof GetBlockHeadersRequest) { + responseMessage = await this.onGetBlockHeadersRequest({ + peerIdentity, + message: rpcMessage, + }) } else if (rpcMessage instanceof GetBlocksRequest) { responseMessage = await this.onGetBlocksRequest({ peerIdentity, message: rpcMessage }) } else if (rpcMessage instanceof PooledTransactionsRequest) { @@ -993,6 +1021,69 @@ export class PeerNetwork { return await this.chain.getHeaderAtSequence(start) } + private async onGetBlockHeadersRequest( + request: IncomingPeerMessage, + ): Promise { + const peer = this.peerManager.getPeerOrThrow(request.peerIdentity) + const rpcId = request.message.rpcId + + if (request.message.limit === 0) { + peer.punish( + BAN_SCORE.LOW, + `Peer sent GetBlockHeaders with limit of ${request.message.limit}`, + ) + return new GetBlockHeadersResponse([], rpcId) + } + + if (request.message.limit > MAX_REQUESTED_BLOCKS) { + peer.punish( + BAN_SCORE.MAX, + `Peer sent GetBlockHeaders with limit of ${request.message.limit}`, + ) + const error = new CannotSatisfyRequestError(`Requested more than ${MAX_REQUESTED_BLOCKS}`) + throw error + } + + const message = request.message + const start = message.start + const limit = message.limit + const skip = message.skip + const reverse = message.reverse + + const from = await this.resolveSequenceOrHash(start) + if (!from) { + return new GetBlockHeadersResponse([], rpcId) + } + + const headers = [] + let skipCounter = skip + + // If `reverse` is true, we iterate in descending order, using `start` as the + // highest sequence. Otherwise, we iterate in ascending order, using + // `start` as the lowest sequence. + const iterationFunction = reverse + ? (from: BlockHeader) => this.chain.iterateFrom(from) + : (from: BlockHeader) => this.chain.iterateTo(from) + + for await (const header of iterationFunction(from)) { + if (skip) { + if (skipCounter < skip) { + skipCounter += 1 + continue + } else if (skipCounter === skip) { + skipCounter = 0 + } + } + + headers.push(header) + if (headers.length === limit) { + break + } + } + + return new GetBlockHeadersResponse(headers, rpcId) + } + private async onGetBlockHashesRequest( request: IncomingPeerMessage, ): Promise { diff --git a/ironfish/src/network/testUtilities/helpers.ts b/ironfish/src/network/testUtilities/helpers.ts index de7a683bfe..2cab925133 100644 --- a/ironfish/src/network/testUtilities/helpers.ts +++ b/ironfish/src/network/testUtilities/helpers.ts @@ -5,6 +5,7 @@ import ws from 'ws' import { Assert } from '../../assert' import { Identity, isIdentity } from '../identity' +import { GetBlockHeadersResponse } from '../messages/getBlockHeaders' import { GetBlockTransactionsResponse } from '../messages/getBlockTransactions' import { GetCompactBlockResponse } from '../messages/getCompactBlock' import { IncomingPeerMessage, NetworkMessage } from '../messages/networkMessage' @@ -233,3 +234,17 @@ export function expectGetBlockTransactionsResponseToMatch( expect({ ...a, transactions: undefined }).toMatchObject({ ...b, transactions: undefined }) } + +export function expectGetBlockHeadersResponseToMatch( + a: GetBlockHeadersResponse, + b: GetBlockHeadersResponse, +): void { + expect(a.headers.length).toEqual(b.headers.length) + a.headers.forEach((headerA, headerIndexA) => { + const headerB = b.headers[headerIndexA] + + expect(headerA.hash).toEqual(headerB.hash) + }) + + expect({ ...a, headers: undefined }).toMatchObject({ ...b, headers: undefined }) +} diff --git a/ironfish/src/network/types.ts b/ironfish/src/network/types.ts index ba3ed7f2f4..b5d1c96d50 100644 --- a/ironfish/src/network/types.ts +++ b/ironfish/src/network/types.ts @@ -26,6 +26,8 @@ export enum NetworkMessageType { GetBlockTransactionsResponse = 18, GetCompactBlockRequest = 19, GetCompactBlockResponse = 20, + GetBlockHeadersRequest = 21, + GetBlockHeadersResponse = 22, } export type IsomorphicWebSocketConstructor = typeof WebSocket | typeof WSWebSocket From 695ed79f27020e73c3456328498bfd46d90a0521 Mon Sep 17 00:00:00 2001 From: Jason Spafford Date: Tue, 14 Feb 2023 17:18:54 -0500 Subject: [PATCH 11/43] Clean up sendTransaction RPC (#3421) * Clean up sendTransaction RPC * Revert fee change --- ironfish-cli/src/commands/service/faucet.ts | 2 +- ironfish/src/mining/poolShares.ts | 2 +- .../rpc/routes/wallet/sendTransaction.test.ts | 8 +- .../src/rpc/routes/wallet/sendTransaction.ts | 90 +++++++------------ 4 files changed, 37 insertions(+), 65 deletions(-) diff --git a/ironfish-cli/src/commands/service/faucet.ts b/ironfish-cli/src/commands/service/faucet.ts index fe63564887..e6836190da 100644 --- a/ironfish-cli/src/commands/service/faucet.ts +++ b/ironfish-cli/src/commands/service/faucet.ts @@ -195,7 +195,7 @@ export default class Faucet extends IronfishCommand { }) const tx = await client.sendTransaction({ - fromAccountName: account, + account, outputs, fee: BigInt(faucetTransactions.length * FAUCET_FEE).toString(), }) diff --git a/ironfish/src/mining/poolShares.ts b/ironfish/src/mining/poolShares.ts index 384cbed8ce..84dcf4388a 100644 --- a/ironfish/src/mining/poolShares.ts +++ b/ironfish/src/mining/poolShares.ts @@ -278,7 +278,7 @@ export class MiningPoolShares { }[], ): Promise { const transaction = await this.rpc.sendTransaction({ - fromAccountName: this.accountName, + account: this.accountName, outputs, fee: outputs.length.toString(), expirationDelta: this.config.get('transactionExpirationDelta'), diff --git a/ironfish/src/rpc/routes/wallet/sendTransaction.test.ts b/ironfish/src/rpc/routes/wallet/sendTransaction.test.ts index 00da790e34..1aa5ef02e1 100644 --- a/ironfish/src/rpc/routes/wallet/sendTransaction.test.ts +++ b/ironfish/src/rpc/routes/wallet/sendTransaction.test.ts @@ -9,7 +9,7 @@ import { NotEnoughFundsError } from '../../../wallet/errors' import { ERROR_CODES } from '../../adapters' const TEST_PARAMS = { - fromAccountName: 'existingAccount', + account: 'existingAccount', outputs: [ { publicAddress: 'test2', @@ -22,7 +22,7 @@ const TEST_PARAMS = { } const TEST_PARAMS_MULTI = { - fromAccountName: 'existingAccount', + account: 'existingAccount', outputs: [ { publicAddress: 'test2', @@ -51,9 +51,9 @@ describe('Transactions sendTransaction', () => { await expect( routeTest.client.sendTransaction({ ...TEST_PARAMS, - fromAccountName: 'AccountDoesNotExist', + account: 'AccountDoesNotExist', }), - ).rejects.toThrow('No account found with name AccountDoesNotExist') + ).rejects.toThrow('No account with name AccountDoesNotExist') }) it('throws if not connected to network', async () => { diff --git a/ironfish/src/rpc/routes/wallet/sendTransaction.ts b/ironfish/src/rpc/routes/wallet/sendTransaction.ts index dd610b6c22..4ab5cd3286 100644 --- a/ironfish/src/rpc/routes/wallet/sendTransaction.ts +++ b/ironfish/src/rpc/routes/wallet/sendTransaction.ts @@ -8,9 +8,10 @@ import { CurrencyUtils } from '../../../utils' import { NotEnoughFundsError } from '../../../wallet/errors' import { ERROR_CODES, ValidationError } from '../../adapters/errors' import { ApiNamespace, router } from '../router' +import { getAccount } from './utils' export type SendTransactionRequest = { - fromAccountName: string + account: string outputs: { publicAddress: string amount: string @@ -24,19 +25,14 @@ export type SendTransactionRequest = { } export type SendTransactionResponse = { - outputs: { - publicAddress: string - amount: string - memo: string - assetId?: string - }[] - fromAccountName: string + account: string hash: string + transaction: string } export const SendTransactionRequestSchema: yup.ObjectSchema = yup .object({ - fromAccountName: yup.string().defined(), + account: yup.string().defined(), outputs: yup .array( yup @@ -58,20 +54,9 @@ export const SendTransactionRequestSchema: yup.ObjectSchema = yup .object({ - outputs: yup - .array( - yup - .object({ - publicAddress: yup.string().defined(), - amount: yup.string().defined(), - memo: yup.string().defined(), - assetId: yup.string().optional(), - }) - .defined(), - ) - .defined(), - fromAccountName: yup.string().defined(), + account: yup.string().defined(), hash: yup.string().defined(), + transaction: yup.string().defined(), }) .defined() @@ -79,15 +64,8 @@ router.register( `${ApiNamespace.wallet}/sendTransaction`, SendTransactionRequestSchema, async (request, node): Promise => { - const transaction = request.data - - const account = node.wallet.getAccountByName(transaction.fromAccountName) + const account = getAccount(node, request.data.account) - if (!account) { - throw new ValidationError(`No account found with name ${transaction.fromAccountName}`) - } - - // The node must be connected to the network first if (!node.peerNetwork.isReady) { throw new ValidationError( `Your node must be connected to the Iron Fish network to send a transaction`, @@ -100,38 +78,32 @@ router.register( ) } - const outputs = transaction.outputs.map((output) => { - let assetId = Asset.nativeId() - if (output.assetId) { - assetId = Buffer.from(output.assetId, 'hex') - } - - return { - publicAddress: output.publicAddress, - amount: CurrencyUtils.decode(output.amount), - memo: output.memo, - assetId, - } - }) + const outputs = request.data.outputs.map((output) => ({ + publicAddress: output.publicAddress, + amount: CurrencyUtils.decode(output.amount), + memo: output.memo, + assetId: output.assetId ? Buffer.from(output.assetId, 'hex') : Asset.nativeId(), + })) - const fee = CurrencyUtils.decode(transaction.fee) + const fee = CurrencyUtils.decode(request.data.fee) if (fee < 1n) { - throw new ValidationError(`Invalid transaction fee, ${transaction.fee}`) + throw new ValidationError(`Invalid transaction fee, ${request.data.fee}`) } - const totalByAssetIdentifier = new BufferMap() - totalByAssetIdentifier.set(Asset.nativeId(), fee) + const totalByAssetId = new BufferMap() + totalByAssetId.set(Asset.nativeId(), fee) + for (const { assetId, amount } of outputs) { if (amount < 0) { throw new ValidationError(`Invalid transaction amount ${amount}.`) } - const sum = totalByAssetIdentifier.get(assetId) ?? BigInt(0) - totalByAssetIdentifier.set(assetId, sum + amount) + const sum = totalByAssetId.get(assetId) ?? 0n + totalByAssetId.set(assetId, sum + amount) } - // Check that the node account is updated - for (const [assetId, sum] of totalByAssetIdentifier) { + // Check that the node has enough balance + for (const [assetId, sum] of totalByAssetId) { const balance = await node.wallet.getBalance(account, assetId) if (balance.confirmed < sum) { @@ -144,20 +116,20 @@ router.register( } try { - const transactionPosted = await node.wallet.send( + const transaction = await node.wallet.send( node.memPool, account, outputs, - BigInt(transaction.fee), - transaction.expirationDelta ?? node.config.get('transactionExpirationDelta'), - transaction.expiration, - transaction.confirmations, + fee, + request.data.expirationDelta ?? node.config.get('transactionExpirationDelta'), + request.data.expiration, + request.data.confirmations, ) request.end({ - outputs: transaction.outputs, - fromAccountName: account.name, - hash: transactionPosted.hash().toString('hex'), + account: account.name, + transaction: transaction.serialize().toString('hex'), + hash: transaction.hash().toString('hex'), }) } catch (e) { if (e instanceof NotEnoughFundsError) { From 65f10a469a3b87eefd961d9c29b9f7f595dbf870 Mon Sep 17 00:00:00 2001 From: ygao76 <4500784+ygao76@users.noreply.github.com> Date: Tue, 14 Feb 2023 14:26:31 -0800 Subject: [PATCH 12/43] wallet prune (#3413) * Create wallet:prune * Remove db open * Close db --- ironfish-cli/src/commands/wallet/prune.ts | 40 +++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 ironfish-cli/src/commands/wallet/prune.ts diff --git a/ironfish-cli/src/commands/wallet/prune.ts b/ironfish-cli/src/commands/wallet/prune.ts new file mode 100644 index 0000000000..7fb0bf89a6 --- /dev/null +++ b/ironfish-cli/src/commands/wallet/prune.ts @@ -0,0 +1,40 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +import { NodeUtils } from '@ironfish/sdk' +import { CliUx, Flags } from '@oclif/core' +import { IronfishCommand } from '../../command' +import { LocalFlags } from '../../flags' + +export default class PruneCommand extends IronfishCommand { + static description = 'Removes expired transactions from the wallet' + + static hidden = false + + static flags = { + ...LocalFlags, + compact: Flags.boolean({ + char: 'c', + default: true, + allowNo: true, + description: 'Compact the database', + }), + } + + async start(): Promise { + const { flags } = await this.parse(PruneCommand) + + CliUx.ux.action.start(`Opening node`) + const node = await this.sdk.node() + await NodeUtils.waitForOpen(node) + CliUx.ux.action.stop('Done.') + + if (flags.compact) { + CliUx.ux.action.start(`Compacting wallet database`) + await node.wallet.walletDb.db.compact() + CliUx.ux.action.stop() + } + + await node.closeDB() + } +} From 49f44ee2be2136c8002c447ab153a74c8a317c00 Mon Sep 17 00:00:00 2001 From: Jason Spafford Date: Tue, 14 Feb 2023 17:59:12 -0500 Subject: [PATCH 13/43] Add currency yup validator (#3424) * Add currency yup validator And remove the need for validating this in all the RPCS. * Fixed tests --- .../src/rpc/routes/wallet/burnAsset.test.ts | 4 +-- ironfish/src/rpc/routes/wallet/burnAsset.ts | 13 +++------- .../rpc/routes/wallet/createTransaction.ts | 25 ++++++------------- .../src/rpc/routes/wallet/mintAsset.test.ts | 4 +-- ironfish/src/rpc/routes/wallet/mintAsset.ts | 13 +++------- .../src/rpc/routes/wallet/sendTransaction.ts | 13 +++------- ironfish/src/utils/currency.ts | 5 ++++ ironfish/src/utils/yup.test.ts | 8 ++++++ ironfish/src/utils/yup.ts | 24 ++++++++++++++++++ 9 files changed, 57 insertions(+), 52 deletions(-) diff --git a/ironfish/src/rpc/routes/wallet/burnAsset.test.ts b/ironfish/src/rpc/routes/wallet/burnAsset.test.ts index c754f3d7a5..d30a719b8e 100644 --- a/ironfish/src/rpc/routes/wallet/burnAsset.test.ts +++ b/ironfish/src/rpc/routes/wallet/burnAsset.test.ts @@ -39,7 +39,7 @@ describe('burnAsset', () => { fee: '0', value: '100', }), - ).rejects.toThrow('Invalid transaction fee') + ).rejects.toThrow('value must be equal to or greater than 1') }) }) @@ -52,7 +52,7 @@ describe('burnAsset', () => { fee: '1', value: '-1', }), - ).rejects.toThrow('Invalid burn amount') + ).rejects.toThrow('value must be equal to or greater than 1') }) }) diff --git a/ironfish/src/rpc/routes/wallet/burnAsset.ts b/ironfish/src/rpc/routes/wallet/burnAsset.ts index 54cc23e660..a3de429653 100644 --- a/ironfish/src/rpc/routes/wallet/burnAsset.ts +++ b/ironfish/src/rpc/routes/wallet/burnAsset.ts @@ -3,7 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import * as yup from 'yup' import { Assert } from '../../../assert' -import { CurrencyUtils } from '../../../utils' +import { CurrencyUtils, YupUtils } from '../../../utils' import { ValidationError } from '../../adapters' import { ApiNamespace, router } from '../router' @@ -28,8 +28,8 @@ export const BurnAssetRequestSchema: yup.ObjectSchema = yup .object({ account: yup.string().required(), assetId: yup.string().required(), - fee: yup.string().required(), - value: yup.string().required(), + fee: YupUtils.currency({ min: 1n }).defined(), + value: YupUtils.currency({ min: 1n }).defined(), expiration: yup.number().optional(), expirationDelta: yup.number().optional(), confirmations: yup.number().optional(), @@ -55,14 +55,7 @@ router.register( } const fee = CurrencyUtils.decode(request.data.fee) - if (fee < 1n) { - throw new ValidationError(`Invalid transaction fee, ${fee}`) - } - const value = CurrencyUtils.decode(request.data.value) - if (value <= 0) { - throw new ValidationError('Invalid burn amount') - } const assetId = Buffer.from(request.data.assetId, 'hex') const asset = await node.chain.getAssetById(assetId) diff --git a/ironfish/src/rpc/routes/wallet/createTransaction.ts b/ironfish/src/rpc/routes/wallet/createTransaction.ts index d4bbb11c21..9f60d0df05 100644 --- a/ironfish/src/rpc/routes/wallet/createTransaction.ts +++ b/ironfish/src/rpc/routes/wallet/createTransaction.ts @@ -6,7 +6,7 @@ import { BufferMap } from 'buffer-map' import * as yup from 'yup' import { BurnDescription } from '../../../primitives/burnDescription' import { MintData, RawTransactionSerde } from '../../../primitives/rawTransaction' -import { CurrencyUtils } from '../../../utils' +import { CurrencyUtils, YupUtils } from '../../../utils' import { NotEnoughFundsError } from '../../../wallet/errors' import { ERROR_CODES, ValidationError } from '../../adapters/errors' import { ApiNamespace, router } from '../router' @@ -48,7 +48,7 @@ export const CreateTransactionRequestSchema: yup.ObjectSchema() - if (data.fee) { + if (data.fee != null) { const fee = CurrencyUtils.decode(data.fee) - if (fee < 1n) { - throw new ValidationError(`Invalid transaction fee, ${data.fee}`) - } - totalByAssetIdentifier.set(Asset.nativeId(), fee) } @@ -133,9 +129,6 @@ router.register { name: 'fake-coin', value: '100', }), - ).rejects.toThrow('Invalid transaction fee') + ).rejects.toThrow('value must be equal to or greater than 1') }) }) @@ -51,7 +51,7 @@ describe('mint', () => { name: 'fake-coin', value: '-1', }), - ).rejects.toThrow('Invalid mint amount') + ).rejects.toThrow('value must be equal to or greater than 1') }) }) diff --git a/ironfish/src/rpc/routes/wallet/mintAsset.ts b/ironfish/src/rpc/routes/wallet/mintAsset.ts index b385df1f97..a7cdcb71f1 100644 --- a/ironfish/src/rpc/routes/wallet/mintAsset.ts +++ b/ironfish/src/rpc/routes/wallet/mintAsset.ts @@ -3,7 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import * as yup from 'yup' import { Assert } from '../../../assert' -import { CurrencyUtils } from '../../../utils' +import { CurrencyUtils, YupUtils } from '../../../utils' import { MintAssetOptions } from '../../../wallet/interfaces/mintAssetOptions' import { ValidationError } from '../../adapters' import { ApiNamespace, router } from '../router' @@ -30,8 +30,8 @@ export interface MintAssetResponse { export const MintAssetRequestSchema: yup.ObjectSchema = yup .object({ account: yup.string().required(), - fee: yup.string().required(), - value: yup.string().required(), + fee: YupUtils.currency({ min: 1n }).defined(), + value: YupUtils.currency({ min: 1n }).defined(), assetId: yup.string().optional(), expiration: yup.number().optional(), expirationDelta: yup.number().optional(), @@ -60,14 +60,7 @@ router.register( } const fee = CurrencyUtils.decode(request.data.fee) - if (fee < 1n) { - throw new ValidationError(`Invalid transaction fee, ${fee}`) - } - const value = CurrencyUtils.decode(request.data.value) - if (value <= 0) { - throw new ValidationError('Invalid mint amount') - } const expirationDelta = request.data.expirationDelta ?? node.config.get('transactionExpirationDelta') diff --git a/ironfish/src/rpc/routes/wallet/sendTransaction.ts b/ironfish/src/rpc/routes/wallet/sendTransaction.ts index 4ab5cd3286..d191a91400 100644 --- a/ironfish/src/rpc/routes/wallet/sendTransaction.ts +++ b/ironfish/src/rpc/routes/wallet/sendTransaction.ts @@ -4,7 +4,7 @@ import { Asset } from '@ironfish/rust-nodejs' import { BufferMap } from 'buffer-map' import * as yup from 'yup' -import { CurrencyUtils } from '../../../utils' +import { CurrencyUtils, YupUtils } from '../../../utils' import { NotEnoughFundsError } from '../../../wallet/errors' import { ERROR_CODES, ValidationError } from '../../adapters/errors' import { ApiNamespace, router } from '../router' @@ -38,14 +38,14 @@ export const SendTransactionRequestSchema: yup.ObjectSchema( })) const fee = CurrencyUtils.decode(request.data.fee) - if (fee < 1n) { - throw new ValidationError(`Invalid transaction fee, ${request.data.fee}`) - } const totalByAssetId = new BufferMap() totalByAssetId.set(Asset.nativeId(), fee) for (const { assetId, amount } of outputs) { - if (amount < 0) { - throw new ValidationError(`Invalid transaction amount ${amount}.`) - } - const sum = totalByAssetId.get(assetId) ?? 0n totalByAssetId.set(assetId, sum + amount) } diff --git a/ironfish/src/utils/currency.ts b/ironfish/src/utils/currency.ts index 89fb6ba1ea..8ee71ffc44 100644 --- a/ironfish/src/utils/currency.ts +++ b/ironfish/src/utils/currency.ts @@ -4,6 +4,7 @@ import { formatFixed, parseFixed } from '@ethersproject/bignumber' import { isNativeIdentifier } from './asset' +import { BigIntUtils } from './bigint' import { FixedNumberUtils } from './fixedNumber' export class CurrencyUtils { @@ -30,6 +31,10 @@ export class CurrencyUtils { return BigInt(amount) } + static decodeTry(amount: string): [bigint, null] | [null, Error] { + return BigIntUtils.tryParse(amount) + } + /** * Serialize ore into a string */ diff --git a/ironfish/src/utils/yup.test.ts b/ironfish/src/utils/yup.test.ts index e9ba237abc..da8833f291 100644 --- a/ironfish/src/utils/yup.test.ts +++ b/ironfish/src/utils/yup.test.ts @@ -1,6 +1,7 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +import { CurrencyUtils } from './currency' import { YupUtils } from './yup' describe('YupUtils', () => { @@ -30,5 +31,12 @@ describe('YupUtils', () => { expect(YupUtils.isPort.isValidSync(65535)).toBe(true) expect(YupUtils.isPort.isValidSync(-1)).toBe(false) }) + + it('currency', () => { + expect(YupUtils.currency().isValidSync(CurrencyUtils.encode(6n))).toBe(true) + expect(YupUtils.currency({ min: 0n }).isValidSync(CurrencyUtils.encode(-1n))).toBe(false) + expect(YupUtils.currency().isValidSync('hello world')).toBe(false) + expect(YupUtils.currency().isValidSync(0.00046)).toBe(false) + }) }) }) diff --git a/ironfish/src/utils/yup.ts b/ironfish/src/utils/yup.ts index c1d7396ad3..b04113e692 100644 --- a/ironfish/src/utils/yup.ts +++ b/ironfish/src/utils/yup.ts @@ -3,6 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import * as yup from 'yup' +import { CurrencyUtils } from './currency' import { UnwrapPromise } from './types' export type YupSchema = yup.Schema @@ -21,6 +22,29 @@ export class YupUtils { static isPercent = yup.number().min(0).max(100) static isUrl = yup.string().url() + static currency = (options?: { min?: bigint }): yup.StringSchema => { + let schema = yup.string().test('currency', `Must be encoded currency`, (val) => { + if (val == null) { + return true + } + + const [value] = CurrencyUtils.decodeTry(val) + return value != null + }) + + if (options?.min != null) { + const min = options?.min + + schema = schema.test( + `min`, + `value must be equal to or greater than ${min.toString()}`, + (val) => val == null || CurrencyUtils.decode(val) >= min, + ) + } + + return schema + } + static async tryValidate( schema: S, value: unknown, From 121d05bd1873f306f8d0ad77064e3d02b424edcb Mon Sep 17 00:00:00 2001 From: mat-if <97762857+mat-if@users.noreply.github.com> Date: Wed, 15 Feb 2023 10:51:01 -0700 Subject: [PATCH 14/43] feat(ironfish): GetBlockHeaders can take sequence or hash for start (#3418) * feat(ironfish): GetBlockHeaders can take sequence or hash for start * remove initial test asserts * fix: add GetBlockHeaders to rpc network message type * fix: allow typescript to figure out type narrowing --- .../__fixtures__/peerNetwork.test.ts.fixture | 80 +++++++++++++++++++ ironfish/src/network/messageRegistry.ts | 2 + .../network/messages/getBlockHeaders.test.ts | 24 ++++-- .../src/network/messages/getBlockHeaders.ts | 34 ++++++-- ironfish/src/network/peerNetwork.test.ts | 33 ++++++-- ironfish/src/network/peerNetwork.ts | 2 +- 6 files changed, 156 insertions(+), 19 deletions(-) diff --git a/ironfish/src/network/__fixtures__/peerNetwork.test.ts.fixture b/ironfish/src/network/__fixtures__/peerNetwork.test.ts.fixture index 0556d710f5..ed8b6aa775 100644 --- a/ironfish/src/network/__fixtures__/peerNetwork.test.ts.fixture +++ b/ironfish/src/network/__fixtures__/peerNetwork.test.ts.fixture @@ -1774,5 +1774,85 @@ } ] } + ], + "PeerNetwork handles requests for block headers should respond to GetBlockHeadersRequest with reverse, skip and start as buffer": [ + { + "header": { + "sequence": 2, + "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", + "noteCommitment": { + "type": "Buffer", + "data": "base64:TWXHygwbRD/Iw/b82JdIWQTO4/kaqpSlnhcUHPK8LQQ=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:b1MeRDFhhmJm3F2+EkGHjIRvYTlmpxfz1i+mGucTGVw=" + }, + "target": "883423532389192164791648750371459257913741948437809479060803100646309888", + "randomness": "0", + "timestamp": 1676400725049, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 4, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA4KMZ/K/CWIPPJu2KMCLHEvhR240BQ4QfTrtSHeu6viqMCFYZDqZ2dJ0LjSB6KpU/9G1ZkhlCohREobAz0GOVK51IbbFwT0JS4HrbpgbKwFCAtTwI6MEIEyRgBmYlF68nEqZH0ne8NT3yPtyRKP8UjZaKGidhvVZcOcTqxr5ZjmIOa97xsWXd4sRHA68CE6KA4F9S2eM8ArgvHwbAibU+6GdHNJE8ylqtsQfQlsvnFyyig184CEpG8e0RAKQah0/CV98d6LJ3aaHU3Doz1acQmAG8RjCVXreiOR6WJG8nqNr/DY7rLCd/t6H0+7Pyf6rOxl8a+ax18LXbvV72Qxfnip0zDKNRxvIwFjC8rRSX+1sF/qpbMBp3XBNTB6X5glBDzoBkGy1uKLhTA8zIMk/TZ4oDgCv3+2sDW98uYa6935tp54gQxAVzypodq8voq6MdenT2hqj+IhevrGOSmpByycwVUI8SlQ9J0HHmScVazcs/0Gscsm9ZOQrEMXh1Y4JRkFu8lUvNiHg6V05fIfJXWGu3cUfO1pRcV2mq4QG3eRz2Z+76F3LFBXcp6+fPFGvyahdgZOMgaAbSpA9rjWMUMlJhWQF0wbxmY1FEkmf1jAvUymar8OFesklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw/R5IEYW0jL+4zpxE9pgEqrH+lgPD+Rb7QUi6dujIh99M2KepyVxszecH025PL219N50FXJ2Ojo6Q2gTdg//HDA==" + } + ] + }, + { + "header": { + "sequence": 3, + "previousBlockHash": "9699F512C5C3D4BE1E29D3C98EDB5DD3FF981D65F6BA5FF709203E3E9C9B21AC", + "noteCommitment": { + "type": "Buffer", + "data": "base64:F+8OR5JhGuNF7VbNi/Kd4wTyVKPrrlrhI++2YLzai0A=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:4uQQjTVNCnMY/EXAWA8Kh9nvpxssAW4rknafxIDFqRg=" + }, + "target": "880842937844725196442695540779332307793253899902937591585455087694081134", + "randomness": "0", + "timestamp": 1676400725414, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 5, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA7X2FkN/Z1S+iMgtM8KkxvfZTgwaYHXWAbreAHvB7jwqh1lALV6elk98OOQtepMucClvm8JghNQrFFJslz4KLhvE/jZo86T1SXHVkrpLhX2q44LAJDTCDkpQqpum5UMGpZwz6zS0Sr5BLaWDasMnjJAmIZlktdJJb+OKqkr6WnIsAKxfMgbXBCoOk2XTQ7zlomnRUCqz9/licdoP1c42raT0K3w/HwPCRADT/XGaaguiScA4tgUEaOJk4riwOD3R7q4WdNL7vaBb9nuy+Ck4mgB7SQ5HAYfFGsizKM80XalA5pVMHNd+HNS5GEdSZM2hlR/R65NwdvXGNJFDhBYT8zzdd6zc2w1qLVoiPq/je6ezSIlwVjz8bf1rkCzaqGiRMHxTXmUJmdf31yW/n+cnVvGWQaDRTAdy5LiO+yuYhhr3MUGDW6os7Epqz20PhrbLNG6UJ2kdNarmZE/5iStcHq9Asg87IXF4rVSgxgz75kEALmBOEIMKbndavnOpfUcaIjv9fAdGmvw52i3YtndvQ9fQIgyOrTl5kH6If/MqVXvVOrvnSEN0Vg8mNz3q6in3FjhjwxUNEcerBVQEbPVZwgiUt6a41T667EzO9Pep4uYaKP5DRF6TZ7Ulyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwENXrLL42DSD3bgUdb5a3PIs9bIqnZ+XXryJAd7GQk2ZGrQgoc3rrSR1mR/QOLrXKLmHDiP+5Fs2E4QW4oQFxBQ==" + } + ] + }, + { + "header": { + "sequence": 4, + "previousBlockHash": "3C105165F61358A2140A28471BB36FD3BD2504E995786BCB5E99EEC38469A598", + "noteCommitment": { + "type": "Buffer", + "data": "base64:xTJuZz74tp8UiNp3ZNmMTwcAAytUZbmjBwVNnF3NuxQ=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:T13tpiMF8lGneiwIOjeKniPU9avDvVcDa6IdvW3IwyI=" + }, + "target": "878277375889837647326843029495509009809390053592540685978895509768758568", + "randomness": "0", + "timestamp": 1676400725717, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 6, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAoQxZH1M29VITnZpJ33wfT0UJ6UtxVfrNh2nOZvmkmCC0/bQfJZyIOXNRapo8TtqG3f0t6lFUWBTXqsxfUkqAPsUyMzOZJxFDl00UqHnHt/aUcgfP4S+TdBwS/VUk0AL+SbcM8XaojeLRJW3jtMkKfUnt+qU7BuYp+3Az/nWuY+AOj0Q3YiwSXJNb4amXAmK2y30aUBt7ech/BgDXII9mwXuRk+46M746uifqYd65WSyAAjiqe7iW06p87uvWqUkJWwYxwKP9JqzokJcRvivUmEzNdJ3FE0NH4fFQIxQtcRGLA8B9o/3Xc75FWeLHCOUFxDIH0O4W3cp1UiGkySVGszcGKOIGu/79RcE/VqFaJsVjwr/4ZC6hRc6ajFeS1XdBMXqA0SY8Ig6XjQLXjmVWmlnOY3np5eqCAWmOco4f9Jfd5rludujb4usIyjNasjpfzMoW18+4z958H/m2LM3LyS5ilfGi6cy8OUQv6JIdE0dfFPBQItQfB1emKX4a4Yz0Z85MDcukbnEKqV0UsS1GoI+S9sq0bTc/aArOTfwXw6cSCAgBOTBlu4FHm7t2FOWUIgrMJhy9I7Mfu49vXvx4mHvTdqNP1p187uS1uu+PKVV4pHhM0a+Vlklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAww/zZXWHflqFg0dceQwQwoNLJILaXjdzuqMKiBGkxAwVBG+CD05RqnLX+Fpp0OzQJSykbJrIVkFi/VOlYkb0eAw==" + } + ] + } ] } \ No newline at end of file diff --git a/ironfish/src/network/messageRegistry.ts b/ironfish/src/network/messageRegistry.ts index f66e2db53c..4133ed9e0d 100644 --- a/ironfish/src/network/messageRegistry.ts +++ b/ironfish/src/network/messageRegistry.ts @@ -52,6 +52,8 @@ export const isRpcNetworkMessageType = (type: NetworkMessageType): boolean => { NetworkMessageType.GetBlockTransactionsResponse, NetworkMessageType.GetCompactBlockRequest, NetworkMessageType.GetCompactBlockResponse, + NetworkMessageType.GetBlockHeadersRequest, + NetworkMessageType.GetBlockHeadersResponse, ].includes(type) } diff --git a/ironfish/src/network/messages/getBlockHeaders.test.ts b/ironfish/src/network/messages/getBlockHeaders.test.ts index 86310c60d5..546b71ff2f 100644 --- a/ironfish/src/network/messages/getBlockHeaders.test.ts +++ b/ironfish/src/network/messages/getBlockHeaders.test.ts @@ -6,12 +6,24 @@ import { expectGetBlockHeadersResponseToMatch } from '../testUtilities' import { GetBlockHeadersRequest, GetBlockHeadersResponse } from './getBlockHeaders' describe('GetBlockHeadersRequest', () => { - it('serializes the object into a buffer and deserializes to the original object', () => { - const rpcId = 0 - const message = new GetBlockHeadersRequest(1, 10, 0, false, rpcId) - const buffer = message.serialize() - const deserializedMessage = GetBlockHeadersRequest.deserialize(buffer, rpcId) - expect(deserializedMessage).toEqual(message) + describe('start as sequence', () => { + it('serializes the object into a buffer and deserializes to the original object', () => { + const rpcId = 0 + const message = new GetBlockHeadersRequest(1, 10, 0, false, rpcId) + const buffer = message.serialize() + const deserializedMessage = GetBlockHeadersRequest.deserialize(buffer, rpcId) + expect(deserializedMessage).toEqual(message) + }) + }) + + describe('start as block hash', () => { + it('serializes the object into a buffer and deserializes to the original object', () => { + const rpcId = 0 + const message = new GetBlockHeadersRequest(Buffer.alloc(32, 1), 10, 0, false, rpcId) + const buffer = message.serialize() + const deserializedMessage = GetBlockHeadersRequest.deserialize(buffer, rpcId) + expect(deserializedMessage).toEqual(message) + }) }) }) diff --git a/ironfish/src/network/messages/getBlockHeaders.ts b/ironfish/src/network/messages/getBlockHeaders.ts index ce39659aa3..5a507a62df 100644 --- a/ironfish/src/network/messages/getBlockHeaders.ts +++ b/ironfish/src/network/messages/getBlockHeaders.ts @@ -9,12 +9,18 @@ import { getBlockHeaderSize, readBlockHeader, writeBlockHeader } from '../utils/ import { Direction, RpcNetworkMessage } from './rpcNetworkMessage' export class GetBlockHeadersRequest extends RpcNetworkMessage { - readonly start: number + readonly start: number | Buffer readonly limit: number readonly skip: number readonly reverse: boolean - constructor(start: number, limit: number, skip: number, reverse: boolean, rpcId?: number) { + constructor( + start: number | Buffer, + limit: number, + skip: number, + reverse: boolean, + rpcId?: number, + ) { super(NetworkMessageType.GetBlockHeadersRequest, Direction.Request, rpcId) this.start = start this.limit = limit @@ -24,7 +30,15 @@ export class GetBlockHeadersRequest extends RpcNetworkMessage { serialize(): Buffer { const bw = bufio.write(this.getSize()) - bw.writeU32(this.start) + + if (Buffer.isBuffer(this.start)) { + bw.writeU8(1) + bw.writeHash(this.start) + } else { + bw.writeU8(0) + bw.writeU32(this.start) + } + bw.writeU16(this.limit) bw.writeU16(this.skip) bw.writeU8(Number(this.reverse)) @@ -33,7 +47,10 @@ export class GetBlockHeadersRequest extends RpcNetworkMessage { static deserialize(buffer: Buffer, rpcId: number): GetBlockHeadersRequest { const reader = bufio.read(buffer, true) - const start = reader.readU32() + + const isBuffer = Boolean(reader.readU8()) + const start = isBuffer ? reader.readHash() : reader.readU32() + const limit = reader.readU16() const skip = reader.readU16() const reverse = Boolean(reader.readU8()) @@ -42,7 +59,14 @@ export class GetBlockHeadersRequest extends RpcNetworkMessage { getSize(): number { let size = 0 - size += 4 // start + size += 1 // is buffer flag + + if (Buffer.isBuffer(this.start)) { + size += 32 // start as hash + } else { + size += 4 // start as number + } + size += 2 // limit size += 2 // skip size += 1 // reverse diff --git a/ironfish/src/network/peerNetwork.test.ts b/ironfish/src/network/peerNetwork.test.ts index dd29af3494..445eabce6b 100644 --- a/ironfish/src/network/peerNetwork.test.ts +++ b/ironfish/src/network/peerNetwork.test.ts @@ -411,8 +411,6 @@ describe('PeerNetwork', () => { sendSpy.mock.calls[0][0] as GetBlockHeadersResponse, response, ) - - expect(true).toBe(true) }) it('should respond to GetBlockHeadersRequest with skip', async () => { @@ -451,8 +449,6 @@ describe('PeerNetwork', () => { sendSpy.mock.calls[0][0] as GetBlockHeadersResponse, response, ) - - expect(true).toBe(true) }) it('should respond to GetBlockHeadersRequest with reverse', async () => { @@ -483,8 +479,6 @@ describe('PeerNetwork', () => { sendSpy.mock.calls[0][0] as GetBlockHeadersResponse, response, ) - - expect(true).toBe(true) }) it('should respond to GetBlockHeadersRequest with reverse and skip', async () => { @@ -512,8 +506,33 @@ describe('PeerNetwork', () => { sendSpy.mock.calls[0][0] as GetBlockHeadersResponse, response, ) + }) + + it('should respond to GetBlockHeadersRequest with reverse, skip and start as buffer', async () => { + const { node, peerNetwork } = nodeTest + const block2 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block2) + const block3 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block3) + const block4 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block4) - expect(true).toBe(true) + const { peer } = getConnectedPeer(peerNetwork.peerManager) + const peerIdentity = peer.getIdentityOrThrow() + + const sendSpy = jest.spyOn(peer, 'send') + + const rpcId = 432 + const message = new GetBlockHeadersRequest(block4.header.hash, 2, 1, true, rpcId) + const response = new GetBlockHeadersResponse([block4.header, block2.header], rpcId) + + await peerNetwork.peerManager.onMessage.emitAsync(peer, { peerIdentity, message }) + + expect(sendSpy.mock.calls[0][0]).toBeInstanceOf(GetBlockHeadersResponse) + expectGetBlockHeadersResponseToMatch( + sendSpy.mock.calls[0][0] as GetBlockHeadersResponse, + response, + ) }) }) diff --git a/ironfish/src/network/peerNetwork.ts b/ironfish/src/network/peerNetwork.ts index ecd7b84c2a..7583436018 100644 --- a/ironfish/src/network/peerNetwork.ts +++ b/ironfish/src/network/peerNetwork.ts @@ -586,7 +586,7 @@ export class PeerNetwork { async getBlockHeaders( peer: Peer, - start: number, + start: number | Buffer, limit: number, skip = 0, reverse = false, From f320ce4c7d894c46cac22a41927cef146e4ae92f Mon Sep 17 00:00:00 2001 From: jowparks Date: Wed, 15 Feb 2023 10:00:02 -0800 Subject: [PATCH 15/43] feat: type wrapper ViewKey (#3423) --- ironfish-rust/src/errors.rs | 2 + ironfish-rust/src/keys/mod.rs | 15 +++--- ironfish-rust/src/keys/view_keys.rs | 79 ++++++++++++++++++++++++++--- ironfish-rust/src/lib.rs | 2 +- 4 files changed, 81 insertions(+), 17 deletions(-) diff --git a/ironfish-rust/src/errors.rs b/ironfish-rust/src/errors.rs index a7b6750a55..ba2b31995f 100644 --- a/ironfish-rust/src/errors.rs +++ b/ironfish-rust/src/errors.rs @@ -21,6 +21,7 @@ pub enum IronfishError { IllegalValue, InconsistentWitness, InvalidAssetIdentifier, + InvalidAuthorizingKey, InvalidBalance, InvalidCommitment, InvalidData, @@ -31,6 +32,7 @@ pub enum IronfishError { InvalidMinersFeeTransaction, InvalidMnemonicString, InvalidNonceLength, + InvalidNullifierDerivingKey, InvalidPaymentAddress, InvalidPublicAddress, InvalidSigningKey, diff --git a/ironfish-rust/src/keys/mod.rs b/ironfish-rust/src/keys/mod.rs index f19a858b1d..c15742d8a0 100644 --- a/ironfish-rust/src/keys/mod.rs +++ b/ironfish-rust/src/keys/mod.rs @@ -210,15 +210,8 @@ impl SaplingKey { &self.incoming_viewing_key } - /// Retrieve both the view keys. These would normally used for third-party audits + /// Retrieve the sapling_representation of the ViewKey. These would normally used for third-party audits /// or for light clients. - pub fn view_keys(&self) -> ViewKeys { - ViewKeys { - incoming: self.incoming_view_key().clone(), - outgoing: self.outgoing_view_key().clone(), - } - } - /// Adapter to convert this key to a viewing key for use in sapling /// functions. pub(crate) fn sapling_viewing_key(&self) -> ViewingKey { @@ -227,6 +220,12 @@ impl SaplingKey { nk: self.nullifier_deriving_key, } } + pub fn view_key(&self) -> ViewKey { + ViewKey { + authorizing_key: self.authorizing_key, + nullifier_deriving_key: self.nullifier_deriving_key, + } + } /// Adapter to convert this key to a proof generation key for use in /// sapling functions diff --git a/ironfish-rust/src/keys/view_keys.rs b/ironfish-rust/src/keys/view_keys.rs index ffa2618bbc..e06bfc37ee 100644 --- a/ironfish-rust/src/keys/view_keys.rs +++ b/ironfish-rust/src/keys/view_keys.rs @@ -92,6 +92,53 @@ impl IncomingViewKey { } } +/// Contains two keys that are required (along with outgoing view key) +/// to have full view access to an account. +/// Referred to as `ViewingKey` in the literature. +#[derive(Clone)] +pub struct ViewKey { + pub authorizing_key: jubjub::SubgroupPoint, + pub nullifier_deriving_key: jubjub::SubgroupPoint, +} + +impl ViewKey { + /// Load a key from a string of hexadecimal digits + pub fn from_hex(value: &str) -> Result { + let bytes = hex_to_bytes(value)?; + if bytes.len() != 64 { + return Err(IronfishError::InvalidViewingKey); + } + let mut authorizing_key_bytes = [0; 32]; + let mut nullifier_deriving_key_bytes = [0; 32]; + + authorizing_key_bytes.clone_from_slice(&bytes[..32]); + nullifier_deriving_key_bytes.clone_from_slice(&bytes[32..]); + + let authorizing_key = Option::from(SubgroupPoint::from_bytes(&authorizing_key_bytes)) + .ok_or(IronfishError::InvalidAuthorizingKey)?; + let nullifier_deriving_key = + Option::from(SubgroupPoint::from_bytes(&nullifier_deriving_key_bytes)) + .ok_or(IronfishError::InvalidNullifierDerivingKey)?; + + Ok(Self { + authorizing_key, + nullifier_deriving_key, + }) + } + + /// Viewing key as hexadecimal, for readability. + pub fn hex_key(&self) -> String { + bytes_to_hex(&self.to_bytes()) + } + + pub fn to_bytes(&self) -> [u8; 64] { + let mut result = [0; 64]; + result[..32].copy_from_slice(&self.authorizing_key.to_bytes()); + result[32..].copy_from_slice(&self.nullifier_deriving_key.to_bytes()); + result + } +} + /// Key that allows someone to view a transaction that you have spent. /// /// Referred to as `ovk` in the literature. @@ -143,14 +190,6 @@ impl OutgoingViewKey { } } -/// Pair of outgoing and incoming view keys for a complete audit -/// of spends and outputs -#[derive(Clone)] -pub struct ViewKeys { - pub incoming: IncomingViewKey, - pub outgoing: OutgoingViewKey, -} - /// Derive a shared secret key from a secret key and the other person's public /// key. /// @@ -194,3 +233,27 @@ pub(crate) fn shared_secret( hash_result[..].clone_from_slice(hasher.finalize().as_ref()); hash_result } + +#[cfg(test)] +mod test { + use crate::{SaplingKey, ViewKey}; + + #[test] + fn test_view_key() { + let key = SaplingKey::from_hex( + "d96dc74bbca05dffb14a5631024588364b0cc9f583b5c11908b6ea98a2b778f7", + ) + .expect("Key should be generated"); + let view_key = key.view_key(); + let view_key_hex = view_key.hex_key(); + assert_eq!(view_key_hex, "498b5103a72c41237c3f2bca96f20100f5a3a8a17c6b8366a485fd16e8931a5d2ff2eb8f991032c815414ff0ae2d8bc3ea3b56bffc481db3f28e800050244463"); + + let recreated_key = + ViewKey::from_hex(&view_key_hex).expect("Key should be created from hex"); + assert_eq!(view_key.authorizing_key, recreated_key.authorizing_key); + assert_eq!( + view_key.nullifier_deriving_key, + recreated_key.nullifier_deriving_key + ); + } +} diff --git a/ironfish-rust/src/lib.rs b/ironfish-rust/src/lib.rs index c807f296a1..d0e79f054f 100644 --- a/ironfish-rust/src/lib.rs +++ b/ironfish-rust/src/lib.rs @@ -19,7 +19,7 @@ pub mod transaction; pub mod util; pub mod witness; pub use { - keys::{IncomingViewKey, OutgoingViewKey, PublicAddress, SaplingKey, ViewKeys}, + keys::{IncomingViewKey, OutgoingViewKey, PublicAddress, SaplingKey, ViewKey}, merkle_note::MerkleNote, merkle_note_hash::MerkleNoteHash, note::Note, From 1b80012dad047045feb7d4dd8b73f33a9bfda8d2 Mon Sep 17 00:00:00 2001 From: mat-if <97762857+mat-if@users.noreply.github.com> Date: Wed, 15 Feb 2023 11:08:44 -0700 Subject: [PATCH 16/43] feat(ironfish): use GetBlockHeaders if peer has the appropriate version (#3425) This allows us to use the new GetBlockHeaders message without requiring a minimum version bump, as syncing from a peer on an older version will default to the previously expected behavior of using GetBlockHashes. --- ironfish/src/network/version.ts | 2 +- ironfish/src/syncer.ts | 35 ++++++++++++++++++++++++++------- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/ironfish/src/network/version.ts b/ironfish/src/network/version.ts index d3e624bda5..d82f7a21db 100644 --- a/ironfish/src/network/version.ts +++ b/ironfish/src/network/version.ts @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -export const VERSION_PROTOCOL = 19 +export const VERSION_PROTOCOL = 20 export const VERSION_PROTOCOL_MIN = 19 export const MAX_REQUESTED_BLOCKS = 50 diff --git a/ironfish/src/syncer.ts b/ironfish/src/syncer.ts index fdd4430966..49a872d8af 100644 --- a/ironfish/src/syncer.ts +++ b/ironfish/src/syncer.ts @@ -19,6 +19,7 @@ import { ArrayUtils } from './utils/array' const SYNCER_TICK_MS = 10 * 1000 const LINEAR_ANCESTOR_SEARCH = 3 const REQUEST_BLOCKS_PER_MESSAGE = 20 +const BLOCK_HEADERS_MIN_VERSION = 20 class AbortSyncingError extends Error { name = this.constructor.name @@ -258,12 +259,22 @@ export class Syncer { requests++ const needle = start - i * 2 - const { hashes } = await this.peerNetwork.getBlockHashes(peer, needle, 1) - if (!hashes.length) { - continue + + let hash + if (peer.version && peer.version >= BLOCK_HEADERS_MIN_VERSION) { + const { headers } = await this.peerNetwork.getBlockHeaders(peer, needle, 1) + if (!headers.length) { + continue + } + hash = headers[0].hash + } else { + const { hashes } = await this.peerNetwork.getBlockHashes(peer, needle, 1) + if (!hashes.length) { + continue + } + hash = hashes[0] } - const hash = hashes[0] const { found, local } = await hasHash(hash) if (!found) { @@ -300,8 +311,18 @@ export class Syncer { requests++ const needle = Math.floor((lower + upper) / 2) - const { hashes, time } = await this.peerNetwork.getBlockHashes(peer, needle, 1) - const remote = hashes.length === 1 ? hashes[0] : null + + let remote + let reportedTime + if (peer.version && peer.version >= BLOCK_HEADERS_MIN_VERSION) { + const { headers, time } = await this.peerNetwork.getBlockHeaders(peer, needle, 1) + remote = headers.length === 1 ? headers[0].hash : null + reportedTime = time + } else { + const { hashes, time } = await this.peerNetwork.getBlockHashes(peer, needle, 1) + remote = hashes.length === 1 ? hashes[0] : null + reportedTime = time + } const { found, local } = await hasHash(remote) @@ -310,7 +331,7 @@ export class Syncer { peer.displayName }, needle: ${needle}, lower: ${lower}, upper: ${upper}, hash: ${HashUtils.renderHash( remote, - )}, time: ${time.toFixed(2)}ms: ${found ? 'HIT' : 'MISS'}`, + )}, time: ${reportedTime.toFixed(2)}ms: ${found ? 'HIT' : 'MISS'}`, ) if (!found) { From 63e07459f2d1c2eef7a27f9f63a3a451c36a8534 Mon Sep 17 00:00:00 2001 From: ygao76 <4500784+ygao76@users.noreply.github.com> Date: Wed, 15 Feb 2023 12:07:55 -0800 Subject: [PATCH 17/43] Remove expired transaction (#3419) * Create wallet:prune * Remove expired transactions * Add logs * Resolve conflict * Remove logs * Check status --- ironfish-cli/src/commands/wallet/prune.ts | 38 ++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/ironfish-cli/src/commands/wallet/prune.ts b/ironfish-cli/src/commands/wallet/prune.ts index 7fb0bf89a6..38fbcebc1f 100644 --- a/ironfish-cli/src/commands/wallet/prune.ts +++ b/ironfish-cli/src/commands/wallet/prune.ts @@ -1,7 +1,7 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -import { NodeUtils } from '@ironfish/sdk' +import { NodeUtils, TransactionStatus } from '@ironfish/sdk' import { CliUx, Flags } from '@oclif/core' import { IronfishCommand } from '../../command' import { LocalFlags } from '../../flags' @@ -13,6 +13,16 @@ export default class PruneCommand extends IronfishCommand { static flags = { ...LocalFlags, + dryrun: Flags.boolean({ + default: false, + description: 'Dry run prune first', + }), + expire: Flags.boolean({ + char: 'e', + default: true, + allowNo: true, + description: 'Delete expired transactions from the wallet', + }), compact: Flags.boolean({ char: 'c', default: true, @@ -29,6 +39,32 @@ export default class PruneCommand extends IronfishCommand { await NodeUtils.waitForOpen(node) CliUx.ux.action.stop('Done.') + if (flags.expire) { + for (const account of node.wallet.listAccounts()) { + const head = await account.getHead() + + if (head !== null) { + this.log(`Process Account ${account.displayName}.`) + + let count = 0 + + for await (const transactionValue of account.getTransactions()) { + const status = await node.wallet.getTransactionStatus(account, transactionValue) + + if (status === TransactionStatus.EXPIRED) { + count = +1 + + if (flags.dryrun === false) { + await account.deleteTransaction(transactionValue.transaction) + } + } + } + + this.log(`Account ${account.displayName} has ${count} expired transactions`) + } + } + } + if (flags.compact) { CliUx.ux.action.start(`Compacting wallet database`) await node.wallet.walletDb.db.compact() From 38baaf41ac4f6708ccdf2f380f91b962bfa295d7 Mon Sep 17 00:00:00 2001 From: Jason Spafford Date: Wed, 15 Feb 2023 15:20:07 -0500 Subject: [PATCH 18/43] Make account uniform and use getAccount() (#3428) This standardizes on the name "account" for passing in an account as the context for all wallet operations. --- ironfish-cli/src/commands/faucet.ts | 2 +- ironfish-cli/src/commands/wallet/burn.ts | 6 +- ironfish-cli/src/commands/wallet/delete.ts | 14 +-- ironfish-cli/src/commands/wallet/mint.ts | 6 +- ironfish-cli/src/commands/wallet/post.ts | 2 +- ironfish-cli/src/commands/wallet/send.ts | 6 +- ironfish-cli/src/commands/wallet/use.ts | 6 +- .../src/rpc/routes/faucet/getFunds.test.ts | 114 ++++++++---------- ironfish/src/rpc/routes/faucet/getFunds.ts | 12 +- .../src/rpc/routes/wallet/burnAsset.test.ts | 13 -- ironfish/src/rpc/routes/wallet/burnAsset.ts | 7 +- .../wallet/createTransaction.test.slow.ts | 2 +- .../routes/wallet/createTransaction.test.ts | 16 +-- .../rpc/routes/wallet/createTransaction.ts | 11 +- .../src/rpc/routes/wallet/exportAccount.ts | 3 +- .../src/rpc/routes/wallet/mintAsset.test.ts | 14 --- ironfish/src/rpc/routes/wallet/mintAsset.ts | 7 +- .../rpc/routes/wallet/postTransaction.test.ts | 6 +- .../src/rpc/routes/wallet/postTransaction.ts | 6 +- .../src/rpc/routes/wallet/removeAccount.ts | 21 +--- ironfish/src/rpc/routes/wallet/useAccount.ts | 20 +-- 21 files changed, 109 insertions(+), 185 deletions(-) diff --git a/ironfish-cli/src/commands/faucet.ts b/ironfish-cli/src/commands/faucet.ts index 1ad79098d9..4468d23d04 100644 --- a/ironfish-cli/src/commands/faucet.ts +++ b/ironfish-cli/src/commands/faucet.ts @@ -70,7 +70,7 @@ export class FaucetCommand extends IronfishCommand { try { await client.getFunds({ - accountName, + account: accountName, email, }) } catch (error: unknown) { diff --git a/ironfish-cli/src/commands/wallet/burn.ts b/ironfish-cli/src/commands/wallet/burn.ts index 5fd1f4c535..6102bfaeee 100644 --- a/ironfish-cli/src/commands/wallet/burn.ts +++ b/ironfish-cli/src/commands/wallet/burn.ts @@ -133,7 +133,7 @@ export class Burn extends IronfishCommand { if (flags.fee) { fee = CurrencyUtils.encode(flags.fee) const createResponse = await client.createTransaction({ - sender: account, + account, outputs: [], burns: [ { @@ -159,7 +159,7 @@ export class Burn extends IronfishCommand { const feeRateOptions: { value: number; name: string }[] = [] const createTransactionRequest: CreateTransactionRequest = { - sender: account, + account, outputs: [], burns: [ { @@ -265,7 +265,7 @@ ${CurrencyUtils.renderIron( try { const result = await client.postTransaction({ transaction: rawTransactionResponse, - sender: account, + account, }) stopProgressBar() diff --git a/ironfish-cli/src/commands/wallet/delete.ts b/ironfish-cli/src/commands/wallet/delete.ts index e876c3cf0a..99af4d2e03 100644 --- a/ironfish-cli/src/commands/wallet/delete.ts +++ b/ironfish-cli/src/commands/wallet/delete.ts @@ -28,23 +28,23 @@ export class DeleteCommand extends IronfishCommand { async start(): Promise { const { args, flags } = await this.parse(DeleteCommand) const confirm = flags.confirm - const name = args.account as string + const account = args.account as string const client = await this.sdk.connectRpc() - const response = await client.removeAccount({ name, confirm }) + const response = await client.removeAccount({ account, confirm }) if (response.content.needsConfirm) { - const value = await CliUx.ux.prompt(`Are you sure? Type ${name} to confirm`) + const value = await CliUx.ux.prompt(`Are you sure? Type ${account} to confirm`) - if (value !== name) { - this.log(`Aborting: ${value} did not match ${name}`) + if (value !== account) { + this.log(`Aborting: ${value} did not match ${account}`) this.exit(1) } - await client.removeAccount({ name, confirm: true }) + await client.removeAccount({ account, confirm: true }) } - this.log(`Account '${name}' successfully deleted.`) + this.log(`Account '${account}' successfully deleted.`) } } diff --git a/ironfish-cli/src/commands/wallet/mint.ts b/ironfish-cli/src/commands/wallet/mint.ts index 41fe7f7869..620a5862e0 100644 --- a/ironfish-cli/src/commands/wallet/mint.ts +++ b/ironfish-cli/src/commands/wallet/mint.ts @@ -176,7 +176,7 @@ export class Mint extends IronfishCommand { fee = flags.fee const createResponse = await client.createTransaction({ - sender: account, + account, outputs: [], mints: [ { @@ -204,7 +204,7 @@ export class Mint extends IronfishCommand { const feeRateOptions: { value: number; name: string }[] = [] const createTransactionRequest: CreateTransactionRequest = { - sender: account, + account, outputs: [], mints: [ { @@ -309,7 +309,7 @@ ${amountString} plus a transaction fee of ${feeString} with the account ${accoun try { const result = await client.postTransaction({ transaction: rawTransactionResponse, - sender: account, + account, }) stopProgressBar() diff --git a/ironfish-cli/src/commands/wallet/post.ts b/ironfish-cli/src/commands/wallet/post.ts index 050305e3a0..b586979108 100644 --- a/ironfish-cli/src/commands/wallet/post.ts +++ b/ironfish-cli/src/commands/wallet/post.ts @@ -96,7 +96,7 @@ export class PostCommand extends IronfishCommand { const response = await client.postTransaction({ transaction, - sender: flags.account, + account: flags.account, offline: flags.offline, }) diff --git a/ironfish-cli/src/commands/wallet/send.ts b/ironfish-cli/src/commands/wallet/send.ts index 87fcb4919c..4750de695d 100644 --- a/ironfish-cli/src/commands/wallet/send.ts +++ b/ironfish-cli/src/commands/wallet/send.ts @@ -201,7 +201,7 @@ export class Send extends IronfishCommand { const feeRateOptions: { value: number; name: string }[] = [] const createTransactionRequest: CreateTransactionRequest = { - sender: from, + account: from, outputs: [ { publicAddress: to, @@ -247,7 +247,7 @@ export class Send extends IronfishCommand { rawTransactionResponse = createResponses[input.selection].content.transaction } else { const createResponse = await client.createTransaction({ - sender: from, + account: from, outputs: [ { publicAddress: to, @@ -326,7 +326,7 @@ ${CurrencyUtils.renderIron( try { const result = await client.postTransaction({ transaction: rawTransactionResponse, - sender: from, + account: from, }) stopProgressBar() diff --git a/ironfish-cli/src/commands/wallet/use.ts b/ironfish-cli/src/commands/wallet/use.ts index 5961a67f88..18e35b3255 100644 --- a/ironfish-cli/src/commands/wallet/use.ts +++ b/ironfish-cli/src/commands/wallet/use.ts @@ -22,10 +22,10 @@ export class UseCommand extends IronfishCommand { async start(): Promise { const { args } = await this.parse(UseCommand) - const name = args.account as string + const account = args.account as string const client = await this.sdk.connectRpc() - await client.useAccount({ name }) - this.log(`The default account is now: ${name}`) + await client.useAccount({ account }) + this.log(`The default account is now: ${account}`) } } diff --git a/ironfish/src/rpc/routes/faucet/getFunds.test.ts b/ironfish/src/rpc/routes/faucet/getFunds.test.ts index 2834155466..48b3eaa666 100644 --- a/ironfish/src/rpc/routes/faucet/getFunds.test.ts +++ b/ironfish/src/rpc/routes/faucet/getFunds.test.ts @@ -10,82 +10,68 @@ jest.mock('axios') describe('Route faucet.getFunds', () => { const routeTest = createRouteTest() - describe('if the account does not exist in the DB', () => { - it('should fail', async () => { - await expect( - routeTest.client - .request('faucet/getFunds', { accountName: 'test-notfound' }) - .waitForEnd(), - ).rejects.toThrow('Account test-notfound could not be found') - }) - }) - - describe('With a default account and the db', () => { - let accountName = 'test' + Math.random().toString() - const email = 'test@test.com' - let publicAddress = '' + let accountName = 'test' + Math.random().toString() + const email = 'test@test.com' + let publicAddress = '' - beforeEach(async () => { - accountName = 'test' + Math.random().toString() - const account = await routeTest.node.wallet.createAccount(accountName, true) - publicAddress = account.publicAddress - }) + beforeEach(async () => { + accountName = 'test' + Math.random().toString() + const account = await routeTest.node.wallet.createAccount(accountName, true) + publicAddress = account.publicAddress + }) - describe('when the API request succeeds', () => { - it('returns a 200 status code', async () => { - routeTest.node.config.set('getFundsApi', 'foo.com') + describe('when the API request succeeds', () => { + it('returns a 200 status code', async () => { + routeTest.node.config.set('getFundsApi', 'foo.com') - axios.post = jest - .fn() - .mockImplementationOnce(() => Promise.resolve({ data: { id: 5 } })) + axios.post = jest.fn().mockImplementationOnce(() => Promise.resolve({ data: { id: 5 } })) - const response = await routeTest.client - .request('faucet/getFunds', { - accountName, - email, - }) - .waitForEnd() + const response = await routeTest.client + .request('faucet/getFunds', { + accountName, + email, + }) + .waitForEnd() - // Response gives back string for ID - expect(response).toMatchObject({ status: 200, content: { id: '5' } }) + // Response gives back string for ID + expect(response).toMatchObject({ status: 200, content: { id: '5' } }) - expect(axios.post).toHaveBeenCalledWith( - 'foo.com', - { - email, - public_key: publicAddress, - }, - expect.anything(), - ) - }) + expect(axios.post).toHaveBeenCalledWith( + 'foo.com', + { + email, + public_key: publicAddress, + }, + expect.anything(), + ) }) + }) - describe('when too many faucet requests have been made', () => { - it('throws an error', async () => { - axios.post = jest.fn().mockImplementationOnce(() => { - throw { - response: { - data: { - code: 'faucet_max_requests_reached', - message: 'Too many faucet requests', - }, + describe('when too many faucet requests have been made', () => { + it('throws an error', async () => { + axios.post = jest.fn().mockImplementationOnce(() => { + throw { + response: { + data: { + code: 'faucet_max_requests_reached', + message: 'Too many faucet requests', }, - } - }) - await expect( - routeTest.client.request('faucet/getFunds', { accountName, email }).waitForEnd(), - ).rejects.toThrow(RpcRequestError) + }, + } }) + await expect( + routeTest.client.request('faucet/getFunds', { accountName, email }).waitForEnd(), + ).rejects.toThrow(RpcRequestError) }) + }) - describe('when the API request fails', () => { - it('throws an error', async () => { - const apiResponse = new Error('API failure') as AxiosError - axios.post = jest.fn().mockRejectedValueOnce(apiResponse) - await expect( - routeTest.client.request('faucet/getFunds', { accountName, email }).waitForEnd(), - ).rejects.toThrow('API failure') - }) + describe('when the API request fails', () => { + it('throws an error', async () => { + const apiResponse = new Error('API failure') as AxiosError + axios.post = jest.fn().mockRejectedValueOnce(apiResponse) + await expect( + routeTest.client.request('faucet/getFunds', { accountName, email }).waitForEnd(), + ).rejects.toThrow('API failure') }) }) }) diff --git a/ironfish/src/rpc/routes/faucet/getFunds.ts b/ironfish/src/rpc/routes/faucet/getFunds.ts index 27daaeb362..29ce8ad986 100644 --- a/ironfish/src/rpc/routes/faucet/getFunds.ts +++ b/ironfish/src/rpc/routes/faucet/getFunds.ts @@ -5,15 +5,16 @@ import { AxiosError } from 'axios' import * as yup from 'yup' import { Assert } from '../../../assert' import { WebApi } from '../../../webApi' -import { ERROR_CODES, ResponseError, ValidationError } from '../../adapters' +import { ERROR_CODES, ResponseError } from '../../adapters' import { ApiNamespace, router } from '../router' +import { getAccount } from '../wallet/utils' -export type GetFundsRequest = { accountName: string; email?: string } +export type GetFundsRequest = { account?: string; email?: string } export type GetFundsResponse = { id: string } export const GetFundsRequestSchema: yup.ObjectSchema = yup .object({ - accountName: yup.string().required(), + account: yup.string(), email: yup.string().strip(true), }) .defined() @@ -28,10 +29,7 @@ router.register( `${ApiNamespace.faucet}/getFunds`, GetFundsRequestSchema, async (request, node): Promise => { - const account = node.wallet.getAccountByName(request.data.accountName) - if (!account) { - throw new ValidationError(`Account ${request.data.accountName} could not be found`) - } + const account = getAccount(node, request.data.account) const api = new WebApi({ getFundsEndpoint: node.config.get('getFundsApi'), diff --git a/ironfish/src/rpc/routes/wallet/burnAsset.test.ts b/ironfish/src/rpc/routes/wallet/burnAsset.test.ts index d30a719b8e..da97790260 100644 --- a/ironfish/src/rpc/routes/wallet/burnAsset.test.ts +++ b/ironfish/src/rpc/routes/wallet/burnAsset.test.ts @@ -17,19 +17,6 @@ describe('burnAsset', () => { await routeTest.node.wallet.createAccount('account', true) }) - describe('with no default account', () => { - it('throws a validation error', async () => { - await expect( - routeTest.client.burnAsset({ - account: 'fake-account', - assetId: '{ url: hello }', - fee: '1', - value: '1', - }), - ).rejects.toThrow('No account found with name fake-account') - }) - }) - describe('with an invalid fee', () => { it('throws a validation error', async () => { await expect( diff --git a/ironfish/src/rpc/routes/wallet/burnAsset.ts b/ironfish/src/rpc/routes/wallet/burnAsset.ts index a3de429653..b087e3f65d 100644 --- a/ironfish/src/rpc/routes/wallet/burnAsset.ts +++ b/ironfish/src/rpc/routes/wallet/burnAsset.ts @@ -4,8 +4,8 @@ import * as yup from 'yup' import { Assert } from '../../../assert' import { CurrencyUtils, YupUtils } from '../../../utils' -import { ValidationError } from '../../adapters' import { ApiNamespace, router } from '../router' +import { getAccount } from './utils' export interface BurnAssetRequest { account: string @@ -49,10 +49,7 @@ router.register( `${ApiNamespace.wallet}/burnAsset`, BurnAssetRequestSchema, async (request, node): Promise => { - const account = node.wallet.getAccountByName(request.data.account) - if (!account) { - throw new ValidationError(`No account found with name ${request.data.account}`) - } + const account = getAccount(node, request.data.account) const fee = CurrencyUtils.decode(request.data.fee) const value = CurrencyUtils.decode(request.data.value) diff --git a/ironfish/src/rpc/routes/wallet/createTransaction.test.slow.ts b/ironfish/src/rpc/routes/wallet/createTransaction.test.slow.ts index c7c33e2831..a5b6eae414 100644 --- a/ironfish/src/rpc/routes/wallet/createTransaction.test.slow.ts +++ b/ironfish/src/rpc/routes/wallet/createTransaction.test.slow.ts @@ -56,7 +56,7 @@ describe('Route wallet/createTransaction', () => { } const response = await routeTest.client.createTransaction({ - sender: 'existingAccount', + account: 'existingAccount', outputs: [ { publicAddress: '0d804ea639b2547d1cd612682bf99f7cad7aad6d59fd5457f61272defcd4bf5b', diff --git a/ironfish/src/rpc/routes/wallet/createTransaction.test.ts b/ironfish/src/rpc/routes/wallet/createTransaction.test.ts index e6948af928..ebaab1439a 100644 --- a/ironfish/src/rpc/routes/wallet/createTransaction.test.ts +++ b/ironfish/src/rpc/routes/wallet/createTransaction.test.ts @@ -10,7 +10,7 @@ import { Account } from '../../../wallet' import { ERROR_CODES } from '../../adapters/errors' const REQUEST_PARAMS = { - sender: 'existingAccount', + account: 'existingAccount', outputs: [ { publicAddress: '0d804ea639b2547d1cd612682bf99f7cad7aad6d59fd5457f61272defcd4bf5b', @@ -23,7 +23,7 @@ const REQUEST_PARAMS = { } const REQUEST_PARAMS_WITH_MULTIPLE_RECIPIENTS = { - sender: 'existingAccount', + account: 'existingAccount', outputs: [ { publicAddress: '0d804ea639b2547d1cd612682bf99f7cad7aad6d59fd5457f61272defcd4bf5b', @@ -168,7 +168,7 @@ describe('Route wallet/createTransaction', () => { } const response = await routeTest.client.createTransaction({ - sender: 'existingAccount', + account: 'existingAccount', outputs: [ { publicAddress: '0d804ea639b2547d1cd612682bf99f7cad7aad6d59fd5457f61272defcd4bf5b', @@ -213,7 +213,7 @@ describe('Route wallet/createTransaction', () => { } const response = await routeTest.client.createTransaction({ - sender: 'existingAccount', + account: 'existingAccount', outputs: [ { publicAddress: '0d804ea639b2547d1cd612682bf99f7cad7aad6d59fd5457f61272defcd4bf5b', @@ -259,7 +259,7 @@ describe('Route wallet/createTransaction', () => { const asset = new Asset(sender.spendingKey, 'mint-asset', 'metadata') const response = await routeTest.client.createTransaction({ - sender: 'existingAccount', + account: 'existingAccount', outputs: [ { publicAddress: '0d804ea639b2547d1cd612682bf99f7cad7aad6d59fd5457f61272defcd4bf5b', @@ -314,7 +314,7 @@ describe('Route wallet/createTransaction', () => { await expect( routeTest.client.createTransaction({ - sender: 'existingAccount', + account: 'existingAccount', outputs: [ { publicAddress: '0d804ea639b2547d1cd612682bf99f7cad7aad6d59fd5457f61272defcd4bf5b', @@ -355,7 +355,7 @@ describe('Route wallet/createTransaction', () => { await expect( routeTest.client.createTransaction({ - sender: 'existingAccount', + account: 'existingAccount', outputs: [ { publicAddress: '0d804ea639b2547d1cd612682bf99f7cad7aad6d59fd5457f61272defcd4bf5b', @@ -392,7 +392,7 @@ describe('Route wallet/createTransaction', () => { await expect( routeTest.client.createTransaction({ - sender: 'existingAccount', + account: 'existingAccount', outputs: [ { publicAddress: '0d804ea639b2547d1cd612682bf99f7cad7aad6d59fd5457f61272defcd4bf5b', diff --git a/ironfish/src/rpc/routes/wallet/createTransaction.ts b/ironfish/src/rpc/routes/wallet/createTransaction.ts index 9f60d0df05..97b56e4932 100644 --- a/ironfish/src/rpc/routes/wallet/createTransaction.ts +++ b/ironfish/src/rpc/routes/wallet/createTransaction.ts @@ -10,9 +10,10 @@ import { CurrencyUtils, YupUtils } from '../../../utils' import { NotEnoughFundsError } from '../../../wallet/errors' import { ERROR_CODES, ValidationError } from '../../adapters/errors' import { ApiNamespace, router } from '../router' +import { getAccount } from './utils' export type CreateTransactionRequest = { - sender: string + account: string outputs: { publicAddress: string amount: string @@ -42,7 +43,7 @@ export type CreateTransactionResponse = { export const CreateTransactionRequestSchema: yup.ObjectSchema = yup .object({ - sender: yup.string().defined(), + account: yup.string().defined(), outputs: yup .array( yup @@ -97,11 +98,7 @@ router.register => { const data = request.data - const account = node.wallet.getAccountByName(data.sender) - - if (!account) { - throw new ValidationError(`No account found with name ${data.sender}`) - } + const account = getAccount(node, request.data.account) // The node must be connected to the network first if (!node.peerNetwork.isReady) { diff --git a/ironfish/src/rpc/routes/wallet/exportAccount.ts b/ironfish/src/rpc/routes/wallet/exportAccount.ts index dfd688a2af..5953efe408 100644 --- a/ironfish/src/rpc/routes/wallet/exportAccount.ts +++ b/ironfish/src/rpc/routes/wallet/exportAccount.ts @@ -41,8 +41,7 @@ router.register( ExportAccountRequestSchema, (request, node): void => { const account = getAccount(node, request.data.account) - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { id, ...accountInfo } = account.serialize() + const { id: _, ...accountInfo } = account.serialize() request.end({ account: accountInfo }) }, ) diff --git a/ironfish/src/rpc/routes/wallet/mintAsset.test.ts b/ironfish/src/rpc/routes/wallet/mintAsset.test.ts index 669c35f7fd..88163a54c5 100644 --- a/ironfish/src/rpc/routes/wallet/mintAsset.test.ts +++ b/ironfish/src/rpc/routes/wallet/mintAsset.test.ts @@ -13,20 +13,6 @@ describe('mint', () => { await routeTest.node.wallet.createAccount('account', true) }) - describe('with no default account', () => { - it('throws a validation error', async () => { - await expect( - routeTest.client.mintAsset({ - account: 'fake-account', - fee: '1', - metadata: '{ url: hello }', - name: 'fake-coin', - value: '1', - }), - ).rejects.toThrow('No account found with name fake-account') - }) - }) - describe('with an invalid fee', () => { it('throws a validation error', async () => { await expect( diff --git a/ironfish/src/rpc/routes/wallet/mintAsset.ts b/ironfish/src/rpc/routes/wallet/mintAsset.ts index a7cdcb71f1..0cc038164c 100644 --- a/ironfish/src/rpc/routes/wallet/mintAsset.ts +++ b/ironfish/src/rpc/routes/wallet/mintAsset.ts @@ -5,8 +5,8 @@ import * as yup from 'yup' import { Assert } from '../../../assert' import { CurrencyUtils, YupUtils } from '../../../utils' import { MintAssetOptions } from '../../../wallet/interfaces/mintAssetOptions' -import { ValidationError } from '../../adapters' import { ApiNamespace, router } from '../router' +import { getAccount } from './utils' export interface MintAssetRequest { account: string @@ -54,10 +54,7 @@ router.register( `${ApiNamespace.wallet}/mintAsset`, MintAssetRequestSchema, async (request, node): Promise => { - const account = node.wallet.getAccountByName(request.data.account) - if (!account) { - throw new ValidationError(`No account found with name ${request.data.account}`) - } + const account = getAccount(node, request.data.account) const fee = CurrencyUtils.decode(request.data.fee) const value = CurrencyUtils.decode(request.data.value) diff --git a/ironfish/src/rpc/routes/wallet/postTransaction.test.ts b/ironfish/src/rpc/routes/wallet/postTransaction.test.ts index 03448b7ab6..a286026fdd 100644 --- a/ironfish/src/rpc/routes/wallet/postTransaction.test.ts +++ b/ironfish/src/rpc/routes/wallet/postTransaction.test.ts @@ -21,7 +21,7 @@ describe('Route wallet/postTransaction', () => { const rawTransaction = await createRawTransaction(options) const response = await routeTest.client.postTransaction({ transaction: RawTransactionSerde.serialize(rawTransaction).toString('hex'), - sender: account.name, + account: account.name, offline: true, }) @@ -41,7 +41,7 @@ describe('Route wallet/postTransaction', () => { const rawTransaction = await createRawTransaction(options) const response = await routeTest.client.postTransaction({ transaction: RawTransactionSerde.serialize(rawTransaction).toString('hex'), - sender: account.name, + account: account.name, }) expect(addSpy).toHaveBeenCalledTimes(1) @@ -55,7 +55,7 @@ describe('Route wallet/postTransaction', () => { await expect( routeTest.client.postTransaction({ transaction: '0xdeadbeef', - sender: account.name, + account: account.name, }), ).rejects.toThrow('Out of bounds read (offset=0).') }) diff --git a/ironfish/src/rpc/routes/wallet/postTransaction.ts b/ironfish/src/rpc/routes/wallet/postTransaction.ts index 3580869479..2e592c691d 100644 --- a/ironfish/src/rpc/routes/wallet/postTransaction.ts +++ b/ironfish/src/rpc/routes/wallet/postTransaction.ts @@ -8,7 +8,7 @@ import { ApiNamespace, router } from '../router' import { getAccount } from './utils' export type PostTransactionRequest = { - sender?: string + account?: string transaction: string offline?: boolean } @@ -19,7 +19,7 @@ export type PostTransactionResponse = { export const PostTransactionRequestSchema: yup.ObjectSchema = yup .object({ - sender: yup.string().strip(true), + account: yup.string().strip(true), transaction: yup.string().defined(), offline: yup.boolean().optional(), }) @@ -35,7 +35,7 @@ router.register( `${ApiNamespace.wallet}/postTransaction`, PostTransactionRequestSchema, async (request, node): Promise => { - const account = getAccount(node, request.data.sender) + const account = getAccount(node, request.data.account) const rawTransactionBytes = Buffer.from(request.data.transaction, 'hex') const rawTransaction = RawTransactionSerde.deserialize(rawTransactionBytes) diff --git a/ironfish/src/rpc/routes/wallet/removeAccount.ts b/ironfish/src/rpc/routes/wallet/removeAccount.ts index 0028d74a05..a0da1965c2 100644 --- a/ironfish/src/rpc/routes/wallet/removeAccount.ts +++ b/ironfish/src/rpc/routes/wallet/removeAccount.ts @@ -2,15 +2,15 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import * as yup from 'yup' -import { ValidationError } from '../../adapters' import { ApiNamespace, router } from '../router' +import { getAccount } from './utils' -export type RemoveAccountRequest = { name: string; confirm?: boolean } +export type RemoveAccountRequest = { account: string; confirm?: boolean } export type RemoveAccountResponse = { needsConfirm?: boolean } export const RemoveAccountRequestSchema: yup.ObjectSchema = yup .object({ - name: yup.string().defined(), + account: yup.string().defined(), confirm: yup.boolean().optional(), }) .defined() @@ -25,24 +25,13 @@ router.register( `${ApiNamespace.wallet}/remove`, RemoveAccountRequestSchema, async (request, node): Promise => { - const name = request.data.name - const account = node.wallet.getAccountByName(name) - - if (!account) { - throw new ValidationError( - `There is no account with the name ${name}. Options are:\n` + - node.wallet - .listAccounts() - .map((a) => a.name) - .join('\n'), - ) - } + const account = getAccount(node, request.data.account) if (!request.data.confirm) { const balances = await account.getUnconfirmedBalances() for (const [_, { unconfirmed }] of balances) { - if (unconfirmed !== BigInt(0)) { + if (unconfirmed !== 0n) { request.end({ needsConfirm: true }) return } diff --git a/ironfish/src/rpc/routes/wallet/useAccount.ts b/ironfish/src/rpc/routes/wallet/useAccount.ts index fa7992796c..772d9b8f7b 100644 --- a/ironfish/src/rpc/routes/wallet/useAccount.ts +++ b/ironfish/src/rpc/routes/wallet/useAccount.ts @@ -2,15 +2,15 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import * as yup from 'yup' -import { ValidationError } from '../../adapters' import { ApiNamespace, router } from '../router' +import { getAccount } from './utils' -export type UseAccountRequest = { name: string } +export type UseAccountRequest = { account: string } export type UseAccountResponse = undefined export const UseAccountRequestSchema: yup.ObjectSchema = yup .object({ - name: yup.string().defined(), + account: yup.string().defined(), }) .defined() @@ -22,19 +22,7 @@ router.register( `${ApiNamespace.wallet}/use`, UseAccountRequestSchema, async (request, node): Promise => { - const name = request.data.name - const account = node.wallet.getAccountByName(name) - - if (!account) { - throw new ValidationError( - `There is no account with the name ${name}. Options are:\n` + - node.wallet - .listAccounts() - .map((a) => a.name) - .join('\n'), - ) - } - + const account = getAccount(node, request.data.account) await node.wallet.setDefaultAccount(account.name) request.end() }, From 5d8be03f6a14c2c0d224cc4a7904ac28c8b1cd13 Mon Sep 17 00:00:00 2001 From: Jason Spafford Date: Wed, 15 Feb 2023 15:30:48 -0500 Subject: [PATCH 19/43] Convert wallet.createTransaction() to use options (#3432) Also simplified the code by moving the size calculation into rawTransaction() --- ironfish/src/primitives/rawTransaction.ts | 23 +++- .../src/primitives/transaction.test.slow.ts | 32 ++--- .../wallet/createTransaction.test.slow.ts | 4 +- .../rpc/routes/wallet/createTransaction.ts | 12 +- .../src/rpc/routes/wallet/mintAsset.test.ts | 4 +- ironfish/src/testUtilities/fixtures/blocks.ts | 36 +++--- .../testUtilities/fixtures/transactions.ts | 18 ++- .../src/testUtilities/helpers/transaction.ts | 18 ++- ironfish/src/wallet/account.ts | 1 + ironfish/src/wallet/wallet.test.slow.ts | 64 ++++------ ironfish/src/wallet/wallet.test.ts | 34 +++--- ironfish/src/wallet/wallet.ts | 112 +++++++++--------- 12 files changed, 171 insertions(+), 187 deletions(-) diff --git a/ironfish/src/primitives/rawTransaction.ts b/ironfish/src/primitives/rawTransaction.ts index 5a358ae79e..b8ec4c06d9 100644 --- a/ironfish/src/primitives/rawTransaction.ts +++ b/ironfish/src/primitives/rawTransaction.ts @@ -4,6 +4,7 @@ import { AMOUNT_VALUE_LENGTH, + ASSET_LENGTH, Transaction as NativeTransaction, TRANSACTION_EXPIRATION_LENGTH, TRANSACTION_FEE_LENGTH, @@ -16,7 +17,13 @@ import { Side } from '../merkletree/merkletree' import { CurrencyUtils } from '../utils/currency' import { BurnDescription } from './burnDescription' import { Note } from './note' -import { NoteEncrypted, NoteEncryptedHash, SerializedNoteEncryptedHash } from './noteEncrypted' +import { + NOTE_ENCRYPTED_SERIALIZED_SIZE_IN_BYTE, + NoteEncrypted, + NoteEncryptedHash, + SerializedNoteEncryptedHash, +} from './noteEncrypted' +import { SPEND_SERIALIZED_SIZE_IN_BYTE } from './spend' import { Transaction } from './transaction' // Needed for constructing a witness when creating transactions @@ -46,6 +53,20 @@ export class RawTransaction { > }[] = [] + size(): number { + let size = 0 + size += 8 // spends length + size += 8 // notes length + size += 8 // fee + size += 4 // expiration + size += 64 // signature + size += this.outputs.length * NOTE_ENCRYPTED_SERIALIZED_SIZE_IN_BYTE + size += this.mints.length * (ASSET_LENGTH + 8) + size += this.burns.length * (ASSET_ID_LENGTH + 8) + size += this.spends.length * SPEND_SERIALIZED_SIZE_IN_BYTE + return size + } + post(spendingKey: string): Transaction { const builder = new NativeTransaction(spendingKey) diff --git a/ironfish/src/primitives/transaction.test.slow.ts b/ironfish/src/primitives/transaction.test.slow.ts index a4c3ff5993..cad14514c2 100644 --- a/ironfish/src/primitives/transaction.test.slow.ts +++ b/ironfish/src/primitives/transaction.test.slow.ts @@ -65,9 +65,9 @@ describe('Accounts', () => { headhash[0] = 0 await accountA.updateHead({ hash: headhash, sequence: 2 }) - const response = nodeA.wallet.createTransaction( - accountA, - [ + const response = nodeA.wallet.createTransaction({ + account: accountA, + outputs: [ { publicAddress: accountB.publicAddress, amount: BigInt(1), @@ -75,13 +75,9 @@ describe('Accounts', () => { assetId: Asset.nativeId(), }, ], - [], - [], - { - fee: 1n, - expiration: 0, - }, - ) + fee: 1n, + expiration: 0, + }) await expect(response).rejects.toThrow(Error) }) @@ -97,9 +93,9 @@ describe('Accounts', () => { await nodeA.chain.addBlock(block1) await nodeA.wallet.updateHead() - const raw = await nodeA.wallet.createTransaction( - accountA, - [ + const raw = await nodeA.wallet.createTransaction({ + account: accountA, + outputs: [ { publicAddress: accountB.publicAddress, amount: BigInt(1), @@ -107,13 +103,9 @@ describe('Accounts', () => { assetId: Asset.nativeId(), }, ], - [], - [], - { - fee: 1n, - expiration: 0, - }, - ) + fee: 1n, + expiration: 0, + }) const transaction = await nodeA.wallet.post(raw, nodeA.memPool, accountA.spendingKey) diff --git a/ironfish/src/rpc/routes/wallet/createTransaction.test.slow.ts b/ironfish/src/rpc/routes/wallet/createTransaction.test.slow.ts index a5b6eae414..4dbb848a3d 100644 --- a/ironfish/src/rpc/routes/wallet/createTransaction.test.slow.ts +++ b/ironfish/src/rpc/routes/wallet/createTransaction.test.slow.ts @@ -32,7 +32,9 @@ describe('Route wallet/createTransaction', () => { sender, sender, async () => { - const raw = await routeTest.node.wallet.createTransaction(sender, [], [mintData], [], { + const raw = await routeTest.node.wallet.createTransaction({ + account: sender, + mints: [mintData], fee: 0n, expiration: 0, }) diff --git a/ironfish/src/rpc/routes/wallet/createTransaction.ts b/ironfish/src/rpc/routes/wallet/createTransaction.ts index 97b56e4932..925b9a2847 100644 --- a/ironfish/src/rpc/routes/wallet/createTransaction.ts +++ b/ironfish/src/rpc/routes/wallet/createTransaction.ts @@ -201,7 +201,11 @@ router.register { } const mintTransaction = await useTxFixture(wallet, account, account, async () => { - const raw = await wallet.createTransaction(account, [], [mintData], [], { + const raw = await wallet.createTransaction({ + account, + mints: [mintData], fee: 0n, expiration: 0, }) diff --git a/ironfish/src/testUtilities/fixtures/blocks.ts b/ironfish/src/testUtilities/fixtures/blocks.ts index 9d550ea6b0..0968f2248d 100644 --- a/ironfish/src/testUtilities/fixtures/blocks.ts +++ b/ironfish/src/testUtilities/fixtures/blocks.ts @@ -239,9 +239,9 @@ export async function useBlockWithTx( Assert.isNotUndefined(from) Assert.isNotUndefined(to) - const raw = await node.wallet.createTransaction( - from, - [ + const raw = await node.wallet.createTransaction({ + account: from, + outputs: [ { publicAddress: to.publicAddress, amount: BigInt(1), @@ -249,14 +249,10 @@ export async function useBlockWithTx( assetId: Asset.nativeId(), }, ], - [], - [], - { - fee: BigInt(options.fee ?? 1n), - expiration: options.expiration ?? 0, - expirationDelta: 0, - }, - ) + fee: BigInt(options.fee ?? 1n), + expiration: options.expiration ?? 0, + expirationDelta: 0, + }) const transaction = await node.wallet.post(raw, node.memPool, from.spendingKey) @@ -299,9 +295,9 @@ export async function useBlockWithTxs( for (let i = 0; i < numTransactions; i++) { Assert.isNotUndefined(from) - const raw = await node.wallet.createTransaction( - from, - [ + const raw = await node.wallet.createTransaction({ + account: from, + outputs: [ { publicAddress: to.publicAddress, amount: BigInt(1), @@ -309,14 +305,10 @@ export async function useBlockWithTxs( assetId: Asset.nativeId(), }, ], - [], - [], - { - fee: 1n, - expiration: 0, - expirationDelta: 0, - }, - ) + fee: 1n, + expiration: 0, + expirationDelta: 0, + }) const transaction = await node.wallet.post(raw, node.memPool, from.spendingKey) diff --git a/ironfish/src/testUtilities/fixtures/transactions.ts b/ironfish/src/testUtilities/fixtures/transactions.ts index 5799b76ff0..7bacb43fd7 100644 --- a/ironfish/src/testUtilities/fixtures/transactions.ts +++ b/ironfish/src/testUtilities/fixtures/transactions.ts @@ -64,9 +64,9 @@ export async function useTxFixture( generate = generate || (async () => { - const raw = await wallet.createTransaction( - from, - [ + const raw = await wallet.createTransaction({ + account: from, + outputs: [ { publicAddress: to.publicAddress, amount: BigInt(1), @@ -74,14 +74,10 @@ export async function useTxFixture( assetId: Asset.nativeId(), }, ], - [], - [], - { - fee: fee ?? 0n, - expiration: expiration ?? 0, - expirationDelta: 0, - }, - ) + fee: fee ?? 0n, + expiration: expiration ?? 0, + expirationDelta: 0, + }) return await wallet.workerPool.postTransaction(raw, from.spendingKey) }) diff --git a/ironfish/src/testUtilities/helpers/transaction.ts b/ironfish/src/testUtilities/helpers/transaction.ts index 5b43350250..e68db43046 100644 --- a/ironfish/src/testUtilities/helpers/transaction.ts +++ b/ironfish/src/testUtilities/helpers/transaction.ts @@ -52,15 +52,13 @@ export async function createRawTransaction(options: { }) } - return await options.wallet.createTransaction( - options.from, + return await options.wallet.createTransaction({ + account: options.from, outputs, - options.mints ?? [], - options.burns ?? [], - { - fee: options.fee ?? 0n, - expiration: options.expiration ?? 0, - expirationDelta: 0, - }, - ) + mints: options.mints, + burns: options.burns, + fee: options.fee ?? 0n, + expiration: options.expiration ?? 0, + expirationDelta: 0, + }) } diff --git a/ironfish/src/wallet/account.ts b/ironfish/src/wallet/account.ts index 5a6819f95b..7e9eb5f8c3 100644 --- a/ironfish/src/wallet/account.ts +++ b/ironfish/src/wallet/account.ts @@ -588,6 +588,7 @@ export class Account { // expiring transaction deletes output notes and sets spent notes to unspent await this.expireTransaction(transaction, tx) + await this.walletDb.deleteTransaction(this, transaction.hash(), tx) }) } diff --git a/ironfish/src/wallet/wallet.test.slow.ts b/ironfish/src/wallet/wallet.test.slow.ts index 7eb300e773..f510af57af 100644 --- a/ironfish/src/wallet/wallet.test.slow.ts +++ b/ironfish/src/wallet/wallet.test.slow.ts @@ -506,9 +506,9 @@ describe('Accounts', () => { const block2 = await useBlockFixture(nodeA.chain, async () => { // Generate a transaction from account A to account B - const raw = await nodeA.wallet.createTransaction( - accountA, - [ + const raw = await nodeA.wallet.createTransaction({ + account: accountA, + outputs: [ { publicAddress: accountB.publicAddress, amount: BigInt(1), @@ -516,13 +516,9 @@ describe('Accounts', () => { assetId: Asset.nativeId(), }, ], - [], - [], - { - fee: 1n, - expiration: 0, - }, - ) + fee: 1n, + expiration: 0, + }) const transaction = await nodeA.wallet.post(raw, nodeA.memPool, accountA.spendingKey) @@ -539,9 +535,9 @@ describe('Accounts', () => { // Attempting to create another transaction for account A // to account C should not throw an error await expect( - nodeA.wallet.createTransaction( - accountA, - [ + nodeA.wallet.createTransaction({ + account: accountA, + outputs: [ { publicAddress: accountC.publicAddress, amount: BigInt(1), @@ -549,13 +545,9 @@ describe('Accounts', () => { assetId: Asset.nativeId(), }, ], - [], - [], - { - fee: 1n, - expiration: 0, - }, - ), + fee: 1n, + expiration: 0, + }), ).resolves.toBeTruthy() }) @@ -654,9 +646,9 @@ describe('Accounts', () => { nodeA.chain, async () => { // Generate a transaction from account A to account B - const raw = await nodeA.wallet.createTransaction( - accountA, - [ + const raw = await nodeA.wallet.createTransaction({ + account: accountA, + outputs: [ { publicAddress: accountB.publicAddress, amount: BigInt(2), @@ -664,13 +656,9 @@ describe('Accounts', () => { assetId: Asset.nativeId(), }, ], - [], - [], - { - fee: 0n, - expiration: 0, - }, - ) + fee: 0n, + expiration: 0, + }) const transaction = await nodeA.wallet.post(raw, nodeA.memPool, accountA.spendingKey) @@ -768,9 +756,9 @@ describe('Accounts', () => { nodeB.chain, async () => { // Generate a transaction from account A to account B - const raw = await nodeB.wallet.createTransaction( - accountANodeB, - [ + const raw = await nodeB.wallet.createTransaction({ + account: accountANodeB, + outputs: [ { publicAddress: accountB.publicAddress, amount: BigInt(2), @@ -778,13 +766,9 @@ describe('Accounts', () => { assetId: Asset.nativeId(), }, ], - [], - [], - { - fee: 0n, - expiration: 0, - }, - ) + fee: 0n, + expiration: 0, + }) const transaction = await nodeB.wallet.post( raw, diff --git a/ironfish/src/wallet/wallet.test.ts b/ironfish/src/wallet/wallet.test.ts index 6e6f4726fe..ad8001cf2a 100644 --- a/ironfish/src/wallet/wallet.test.ts +++ b/ironfish/src/wallet/wallet.test.ts @@ -733,9 +733,9 @@ describe('Accounts', () => { Assert.isNotUndefined(transactionValue) Assert.isNotNull(transactionValue.sequence) - const rawTransaction = node.wallet.createTransaction( - accountA, - [ + const rawTransaction = node.wallet.createTransaction({ + account: accountA, + outputs: [ { publicAddress: '0d804ea639b2547d1cd612682bf99f7cad7aad6d59fd5457f61272defcd4bf5b', amount: 10n, @@ -743,12 +743,8 @@ describe('Accounts', () => { assetId: Asset.nativeId(), }, ], - [], - [], - { - expiration: 0, - }, - ) + expiration: 0, + }) await expect(rawTransaction).rejects.toThrow( 'Fee or FeeRate is required to create a transaction', @@ -771,9 +767,9 @@ describe('Accounts', () => { Assert.isNotUndefined(transactionValue) Assert.isNotNull(transactionValue.sequence) - const rawTransaction = await node.wallet.createTransaction( - accountA, - [ + const rawTransaction = await node.wallet.createTransaction({ + account: accountA, + outputs: [ { publicAddress: '0d804ea639b2547d1cd612682bf99f7cad7aad6d59fd5457f61272defcd4bf5b', amount: 10n, @@ -781,13 +777,9 @@ describe('Accounts', () => { assetId: Asset.nativeId(), }, ], - [], - [], - { - expiration: 0, - feeRate: 200n, - }, - ) + expiration: 0, + feeRate: 200n, + }) expect(rawTransaction.outputs.length).toBe(1) expect(rawTransaction.expiration).toBeDefined() @@ -1224,7 +1216,9 @@ describe('Accounts', () => { // Mint some coins const blockB = await useBlockFixture(node.chain, async () => { - const raw = await node.wallet.createTransaction(account, [], [mintData], [], { + const raw = await node.wallet.createTransaction({ + account, + mints: [mintData], fee: 0n, expiration: 0, }) diff --git a/ironfish/src/wallet/wallet.ts b/ironfish/src/wallet/wallet.ts index 54aaff4817..3d1ed6af29 100644 --- a/ironfish/src/wallet/wallet.ts +++ b/ironfish/src/wallet/wallet.ts @@ -3,8 +3,6 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import { Asset, - ASSET_ID_LENGTH, - ASSET_LENGTH, generateKey, generateKeyFromPrivateKey, Note as NativeNote, @@ -26,9 +24,7 @@ import { Mutex } from '../mutex' import { BlockHeader } from '../primitives/blockheader' import { BurnDescription } from '../primitives/burnDescription' import { Note } from '../primitives/note' -import { NOTE_ENCRYPTED_SERIALIZED_SIZE_IN_BYTE } from '../primitives/noteEncrypted' import { MintData, RawTransaction } from '../primitives/rawTransaction' -import { SPEND_SERIALIZED_SIZE_IN_BYTE } from '../primitives/spend' import { Transaction } from '../primitives/transaction' import { IDatabaseTransaction } from '../storage/database/transaction' import { @@ -672,7 +668,7 @@ export class Wallet { async send( memPool: MemPool, - sender: Account, + account: Account, outputs: { publicAddress: string amount: bigint @@ -684,14 +680,16 @@ export class Wallet { expiration?: number | null, confirmations?: number | null, ): Promise { - const raw = await this.createTransaction(sender, outputs, [], [], { + const raw = await this.createTransaction({ + account, + outputs, fee, expirationDelta, expiration: expiration ?? undefined, confirmations: confirmations ?? undefined, }) - return this.post(raw, memPool, sender.spendingKey) + return this.post(raw, memPool, account.spendingKey) } async mint( @@ -722,7 +720,9 @@ export class Wallet { } } - const raw = await this.createTransaction(account, [], [mintData], [], { + const raw = await this.createTransaction({ + account, + mints: [mintData], fee: options.fee, expirationDelta: options.expirationDelta, expiration: options.expiration, @@ -742,34 +742,34 @@ export class Wallet { expiration?: number, confirmations?: number, ): Promise { - const raw = await this.createTransaction(account, [], [], [{ assetId, value }], { - fee: fee, - expirationDelta: expirationDelta, - expiration: expiration, - confirmations: confirmations, + const raw = await this.createTransaction({ + account, + burns: [{ assetId, value }], + fee, + expirationDelta, + expiration, + confirmations, }) return this.post(raw, memPool, account.spendingKey) } - async createTransaction( - sender: Account, - outputs: { + async createTransaction(options: { + account: Account + outputs?: { publicAddress: string amount: bigint memo: string assetId: Buffer - }[], - mints: MintData[], - burns: BurnDescription[], - options: { - fee?: bigint - feeRate?: bigint - expiration?: number - expirationDelta?: number - confirmations?: number - }, - ): Promise { + }[] + mints?: MintData[] + burns?: BurnDescription[] + fee?: bigint + feeRate?: bigint + expiration?: number + expirationDelta?: number + confirmations?: number + }): Promise { const heaviestHead = this.chain.head if (heaviestHead === null) { throw new Error('You must have a genesis block to create a transaction') @@ -793,64 +793,58 @@ export class Wallet { const unlock = await this.createTransactionMutex.lock() try { - this.assertHasAccount(sender) + this.assertHasAccount(options.account) - if (!(await this.isAccountUpToDate(sender))) { + if (!(await this.isAccountUpToDate(options.account))) { throw new Error('Your account must finish scanning before sending a transaction.') } const raw = new RawTransaction() raw.expiration = expiration - raw.mints = mints - raw.burns = burns - - for (const output of outputs) { - const note = new NativeNote( - output.publicAddress, - output.amount, - output.memo, - output.assetId, - sender.publicAddress, - ) - raw.outputs.push({ note: new Note(note.serialize()) }) + if (options.mints) { + raw.mints = options.mints } - if (options.fee) { - raw.fee = options.fee + if (options.burns) { + raw.burns = options.burns } - let size = 0 - if (options.feeRate) { - size += 8 // spends length - size += 8 // notes length - size += 8 // fee - size += 4 // expiration - size += 64 // signature - - size += raw.outputs.length * NOTE_ENCRYPTED_SERIALIZED_SIZE_IN_BYTE + if (options.outputs) { + for (const output of options.outputs) { + const note = new NativeNote( + output.publicAddress, + output.amount, + output.memo, + output.assetId, + options.account.publicAddress, + ) - size += raw.mints.length * (ASSET_LENGTH + 8) + raw.outputs.push({ note: new Note(note.serialize()) }) + } + } - size += raw.burns.length * (ASSET_ID_LENGTH + 8) + if (options.fee != null) { + raw.fee = options.fee + } - raw.fee = getFee(options.feeRate, size) + if (options.feeRate) { + raw.fee = getFee(options.feeRate, raw.size()) } await this.fund(raw, { fee: raw.fee, - account: sender, + account: options.account, confirmations: confirmations, }) if (options.feeRate) { - size += raw.spends.length * SPEND_SERIALIZED_SIZE_IN_BYTE - raw.fee = getFee(options.feeRate, size) + raw.fee = getFee(options.feeRate, raw.size()) raw.spends = [] await this.fund(raw, { fee: raw.fee, - account: sender, + account: options.account, confirmations: confirmations, }) } From 7b1254468c528521344ea7390ad349f810c05952 Mon Sep 17 00:00:00 2001 From: Evan Richard <5766842+EvanJRichard@users.noreply.github.com> Date: Wed, 15 Feb 2023 17:05:58 -0500 Subject: [PATCH 20/43] Account Version for both account import and export (#3251) Review: https://github.com/iron-fish/ironfish/pull/3251 --- ironfish-cli/src/commands/wallet/import.ts | 14 +- .../data/021-add-version-to-accounts.ts | 122 ++++++++++++++++++ ironfish/src/migrations/data/index.ts | 2 + .../src/rpc/routes/wallet/exportAccount.ts | 2 + .../src/rpc/routes/wallet/importAccount.ts | 1 + ironfish/src/wallet/account.ts | 17 ++- ironfish/src/wallet/wallet.ts | 4 +- .../src/wallet/walletdb/accountValue.test.ts | 1 + ironfish/src/wallet/walletdb/accountValue.ts | 6 + ironfish/src/wallet/walletdb/walletdb.ts | 4 +- 10 files changed, 166 insertions(+), 7 deletions(-) create mode 100644 ironfish/src/migrations/data/021-add-version-to-accounts.ts diff --git a/ironfish-cli/src/commands/wallet/import.ts b/ironfish-cli/src/commands/wallet/import.ts index d8d6ee856f..1c99fe7c88 100644 --- a/ironfish-cli/src/commands/wallet/import.ts +++ b/ironfish-cli/src/commands/wallet/import.ts @@ -2,7 +2,13 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import { generateKeyFromPrivateKey, wordsToSpendingKey } from '@ironfish/rust-nodejs' -import { AccountImport, Bech32m, JSONUtils, PromiseUtils } from '@ironfish/sdk' +import { + ACCOUNT_SCHEMA_VERSION, + AccountImport, + Bech32m, + JSONUtils, + PromiseUtils, +} from '@ironfish/sdk' import { CliUx, Flags } from '@oclif/core' import { IronfishCommand } from '../../command' import { RemoteFlags } from '../../flags' @@ -52,6 +58,10 @@ export class ImportCommand extends IronfishCommand { CliUx.ux.error(`Invalid import type`) } + if (!account.version) { + account.version = ACCOUNT_SCHEMA_VERSION as number + } + const result = await client.importAccount({ account, rescan: flags.rescan, @@ -110,7 +120,7 @@ export class ImportCommand extends IronfishCommand { const name = await CliUx.ux.prompt('Enter a new account name', { required: true, }) - return { name, spendingKey } + return { name, spendingKey, version: ACCOUNT_SCHEMA_VERSION as number } } // raw json diff --git a/ironfish/src/migrations/data/021-add-version-to-accounts.ts b/ironfish/src/migrations/data/021-add-version-to-accounts.ts new file mode 100644 index 0000000000..ccce58d913 --- /dev/null +++ b/ironfish/src/migrations/data/021-add-version-to-accounts.ts @@ -0,0 +1,122 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +import { KEY_LENGTH, PUBLIC_ADDRESS_LENGTH } from '@ironfish/rust-nodejs' +import bufio from 'bufio' +import { Logger } from '../../logger' +import { IronfishNode } from '../../node' +import { IDatabaseEncoding, IDatabaseStore, StringEncoding } from '../../storage' +import { IDatabase, IDatabaseTransaction } from '../../storage' +import { Account } from '../../wallet' +import { Migration } from '../migration' + +export class Migration021 extends Migration { + path = __filename + + prepare(node: IronfishNode): IDatabase { + return node.wallet.walletDb.db + } + + async forward( + node: IronfishNode, + db: IDatabase, + tx: IDatabaseTransaction | undefined, + logger: Logger, + ): Promise { + logger.debug(`Loading accounts from wallet db...`) + const accounts: Account[] = [] + + const oldAccountStore = this.getOldAccountStore(db) + logger.info(`Gathering accounts for migration`) + for await (const accountValue of oldAccountStore.getAllValuesIter(tx)) { + accounts.push( + new Account({ + ...accountValue, + walletDb: node.wallet.walletDb, + version: 1, // this migration was applied at version 1, use literal 1, not ACCOUNT_SCHEMA_VERSION + }), + ) + } + + logger.debug(`Saving updated accounts to wallet db...`) + await node.wallet.walletDb.db.transaction(async (tx) => { + for (const account of accounts) { + logger.info('') + logger.info(` Migrating account ${account.name}`) + // reserialization of existing wallet will occur in here + await node.wallet.walletDb.setAccount(account, tx) + logger.info(` Completed migration for account ${account.name}`) + } + }) + + await oldAccountStore.clear(tx) + } + + // eslint-disable-next-line @typescript-eslint/no-empty-function + async backward(): Promise {} + + getOldAccountStore( + db: IDatabase, + ): IDatabaseStore<{ key: string; value: PreMigrationAccountValue }> { + return db.addStore({ + name: 'a', + keyEncoding: new StringEncoding(), + valueEncoding: new PreMigrationAccountValueEncoding(), + }) + } +} + +interface PreMigrationAccountValue { + id: string + name: string + spendingKey: string + incomingViewKey: string + outgoingViewKey: string + publicAddress: string +} + +class PreMigrationAccountValueEncoding implements IDatabaseEncoding { + serialize(value: PreMigrationAccountValue): Buffer { + const bw = bufio.write(this.getSize(value)) + bw.writeVarString(value.id, 'utf8') + bw.writeVarString(value.name, 'utf8') + bw.writeBytes(Buffer.from(value.spendingKey, 'hex')) + bw.writeBytes(Buffer.from(value.incomingViewKey, 'hex')) + bw.writeBytes(Buffer.from(value.outgoingViewKey, 'hex')) + bw.writeBytes(Buffer.from(value.publicAddress, 'hex')) + + return bw.render() + } + + deserialize(buffer: Buffer): PreMigrationAccountValue { + const reader = bufio.read(buffer, true) + const id = reader.readVarString('utf8') + const name = reader.readVarString('utf8') + const spendingKey = reader.readBytes(KEY_LENGTH).toString('hex') + const incomingViewKey = reader.readBytes(KEY_LENGTH).toString('hex') + const outgoingViewKey = reader.readBytes(KEY_LENGTH).toString('hex') + const publicAddress = reader.readBytes(PUBLIC_ADDRESS_LENGTH).toString('hex') + + return { + id, + name, + spendingKey, + incomingViewKey, + outgoingViewKey, + publicAddress, + } + } + + getSize(value: PreMigrationAccountValue): number { + let size = 0 + size += bufio.sizeVarString(value.id, 'utf8') + size += bufio.sizeVarString(value.name, 'utf8') + size += KEY_LENGTH + size += KEY_LENGTH + size += KEY_LENGTH + size += PUBLIC_ADDRESS_LENGTH + + return size + } +} diff --git a/ironfish/src/migrations/data/index.ts b/ironfish/src/migrations/data/index.ts index 3e068442bb..9376e80a12 100644 --- a/ironfish/src/migrations/data/index.ts +++ b/ironfish/src/migrations/data/index.ts @@ -9,6 +9,7 @@ import { Migration017 } from './017-sequence-encoding' import { Migration018 } from './018-backfill-wallet-assets' import { Migration019 } from './019-backfill-wallet-assets-from-chain' import { Migration020 } from './020-backfill-null-asset-supplies' +import { Migration021 } from './021-add-version-to-accounts' export const MIGRATIONS = [ Migration014, @@ -18,4 +19,5 @@ export const MIGRATIONS = [ Migration018, Migration019, Migration020, + Migration021, ] diff --git a/ironfish/src/rpc/routes/wallet/exportAccount.ts b/ironfish/src/rpc/routes/wallet/exportAccount.ts index 5953efe408..78c115f802 100644 --- a/ironfish/src/rpc/routes/wallet/exportAccount.ts +++ b/ironfish/src/rpc/routes/wallet/exportAccount.ts @@ -13,6 +13,7 @@ export type ExportAccountResponse = { incomingViewKey: string outgoingViewKey: string publicAddress: string + version: number } } @@ -31,6 +32,7 @@ export const ExportAccountResponseSchema: yup.ObjectSchema .object({ name: yup.string().defined(), spendingKey: yup.string().defined(), + version: yup.number().defined(), }) .defined(), }) diff --git a/ironfish/src/wallet/account.ts b/ironfish/src/wallet/account.ts index 7e9eb5f8c3..55a65754bf 100644 --- a/ironfish/src/wallet/account.ts +++ b/ironfish/src/wallet/account.ts @@ -22,7 +22,9 @@ import { WalletDB } from './walletdb/walletdb' export const ACCOUNT_KEY_LENGTH = 32 -export type AccountImport = { name: string; spendingKey: string } +export const ACCOUNT_SCHEMA_VERSION = 1 + +export type AccountImport = { name: string; spendingKey: string; version: number } export class Account { private readonly walletDb: WalletDB @@ -33,6 +35,7 @@ export class Account { readonly spendingKey: string readonly incomingViewKey: string readonly outgoingViewKey: string + readonly version: number publicAddress: string readonly prefix: Buffer readonly prefixRange: DatabaseKeyRange @@ -45,8 +48,16 @@ export class Account { outgoingViewKey, publicAddress, walletDb, - }: AccountValue & { + version, + }: { + id: string + name: string + spendingKey: string + incomingViewKey: string + outgoingViewKey: string + publicAddress: string walletDb: WalletDB + version: number | undefined }) { this.id = id this.name = name @@ -61,10 +72,12 @@ export class Account { this.displayName = `${name} (${id.slice(0, 7)})` this.walletDb = walletDb + this.version = version ?? 1 } serialize(): AccountValue { return { + version: this.version, id: this.id, name: this.name, spendingKey: this.spendingKey, diff --git a/ironfish/src/wallet/wallet.ts b/ironfish/src/wallet/wallet.ts index 3d1ed6af29..2f6f6218ef 100644 --- a/ironfish/src/wallet/wallet.ts +++ b/ironfish/src/wallet/wallet.ts @@ -36,7 +36,7 @@ import { } from '../utils' import { WorkerPool } from '../workerPool' import { DecryptedNote, DecryptNoteOptions } from '../workerPool/tasks/decryptNotes' -import { Account, AccountImport } from './account' +import { Account, ACCOUNT_SCHEMA_VERSION, AccountImport } from './account' import { AssetBalances } from './assetBalances' import { NotEnoughFundsError } from './errors' import { MintAssetOptions } from './interfaces/mintAssetOptions' @@ -1250,6 +1250,7 @@ export class Wallet { const key = generateKey() const account = new Account({ + version: ACCOUNT_SCHEMA_VERSION, id: uuid(), name, incomingViewKey: key.incoming_view_key, @@ -1297,6 +1298,7 @@ export class Wallet { const accountValue: AccountValue = { ...toImport, + version: ACCOUNT_SCHEMA_VERSION, id: uuid(), incomingViewKey: key.incoming_view_key, outgoingViewKey: key.outgoing_view_key, diff --git a/ironfish/src/wallet/walletdb/accountValue.test.ts b/ironfish/src/wallet/walletdb/accountValue.test.ts index 4f5b02b2d7..52b71dce37 100644 --- a/ironfish/src/wallet/walletdb/accountValue.test.ts +++ b/ironfish/src/wallet/walletdb/accountValue.test.ts @@ -16,6 +16,7 @@ describe('AccountValueEncoding', () => { outgoingViewKey: key.outgoing_view_key, publicAddress: key.public_address, spendingKey: key.spending_key, + version: 1, } const buffer = encoder.serialize(value) const deserializedValue = encoder.deserialize(buffer) diff --git a/ironfish/src/wallet/walletdb/accountValue.ts b/ironfish/src/wallet/walletdb/accountValue.ts index 192d68c1aa..68d3c188b7 100644 --- a/ironfish/src/wallet/walletdb/accountValue.ts +++ b/ironfish/src/wallet/walletdb/accountValue.ts @@ -6,8 +6,10 @@ import bufio from 'bufio' import { IDatabaseEncoding } from '../../storage' const KEY_LENGTH = 32 +const VERSION_LENGTH = 2 export interface AccountValue { + version: number id: string name: string spendingKey: string @@ -19,6 +21,7 @@ export interface AccountValue { export class AccountValueEncoding implements IDatabaseEncoding { serialize(value: AccountValue): Buffer { const bw = bufio.write(this.getSize(value)) + bw.writeU16(value.version) bw.writeVarString(value.id, 'utf8') bw.writeVarString(value.name, 'utf8') bw.writeBytes(Buffer.from(value.spendingKey, 'hex')) @@ -31,6 +34,7 @@ export class AccountValueEncoding implements IDatabaseEncoding { deserialize(buffer: Buffer): AccountValue { const reader = bufio.read(buffer, true) + const version = reader.readU16() const id = reader.readVarString('utf8') const name = reader.readVarString('utf8') const spendingKey = reader.readBytes(KEY_LENGTH).toString('hex') @@ -39,6 +43,7 @@ export class AccountValueEncoding implements IDatabaseEncoding { const publicAddress = reader.readBytes(PUBLIC_ADDRESS_LENGTH).toString('hex') return { + version, id, name, spendingKey, @@ -50,6 +55,7 @@ export class AccountValueEncoding implements IDatabaseEncoding { getSize(value: AccountValue): number { let size = 0 + size += VERSION_LENGTH size += bufio.sizeVarString(value.id, 'utf8') size += bufio.sizeVarString(value.name, 'utf8') size += KEY_LENGTH diff --git a/ironfish/src/wallet/walletdb/walletdb.ts b/ironfish/src/wallet/walletdb/walletdb.ts index 1e378879b4..96a37368f3 100644 --- a/ironfish/src/wallet/walletdb/walletdb.ts +++ b/ironfish/src/wallet/walletdb/walletdb.ts @@ -34,7 +34,7 @@ import { HeadValue, NullableHeadValueEncoding } from './headValue' import { AccountsDBMeta, MetaValue, MetaValueEncoding } from './metaValue' import { TransactionValue, TransactionValueEncoding } from './transactionValue' -export const VERSION_DATABASE_ACCOUNTS = 20 +export const VERSION_DATABASE_ACCOUNTS = 21 const getAccountsDBMetaDefaults = (): AccountsDBMeta => ({ defaultAccountId: null, @@ -143,7 +143,7 @@ export class WalletDB { }) this.accounts = this.db.addStore({ - name: 'a', + name: 'a' + VERSION_DATABASE_ACCOUNTS.toString(), keyEncoding: new StringEncoding(), valueEncoding: new AccountValueEncoding(), }) From b5db3060b656ba0015c507c2508f098fc3ebacf0 Mon Sep 17 00:00:00 2001 From: Jason Spafford Date: Wed, 15 Feb 2023 17:33:01 -0500 Subject: [PATCH 21/43] Simplify createTransaction route (#3435) * Simplify createTransaction route Reduced the code down a lot and made it fairly linear * Rename record to asset * Rename record -> asset again --- .../routes/wallet/createTransaction.test.ts | 56 +----- .../rpc/routes/wallet/createTransaction.ts | 180 ++++++------------ .../src/rpc/routes/wallet/sendTransaction.ts | 6 +- ironfish/src/wallet/wallet.ts | 22 ++- 4 files changed, 74 insertions(+), 190 deletions(-) diff --git a/ironfish/src/rpc/routes/wallet/createTransaction.test.ts b/ironfish/src/rpc/routes/wallet/createTransaction.test.ts index ebaab1439a..48a90e69ae 100644 --- a/ironfish/src/rpc/routes/wallet/createTransaction.test.ts +++ b/ironfish/src/rpc/routes/wallet/createTransaction.test.ts @@ -49,32 +49,10 @@ describe('Route wallet/createTransaction', () => { sender = await useAccountFixture(routeTest.node.wallet, 'existingAccount') }) - it('throws if not connected to network', async () => { - routeTest.node.peerNetwork['_isReady'] = false - - await expect(routeTest.client.createTransaction(REQUEST_PARAMS)).rejects.toThrow( - 'Your node must be connected to the Iron Fish network to send a transaction', - ) - }) - - it('throws if the chain is outdated', async () => { - routeTest.node.peerNetwork['_isReady'] = true - routeTest.chain.synced = false - - await expect(routeTest.client.createTransaction(REQUEST_PARAMS)).rejects.toThrow( - 'Your node must be synced with the Iron Fish network to send a transaction. Please try again later', - ) - }) - it('throws if not enough funds', async () => { - routeTest.node.peerNetwork['_isReady'] = true - routeTest.chain.synced = true - await expect(routeTest.client.createTransaction(REQUEST_PARAMS)).rejects.toThrow( expect.objectContaining({ - message: expect.stringContaining( - `Your balance is too low. Add funds to your account first`, - ), + message: expect.any(String), status: 400, code: ERROR_CODES.INSUFFICIENT_BALANCE, }), @@ -82,9 +60,6 @@ describe('Route wallet/createTransaction', () => { }) it('should generate a valid transaction', async () => { - routeTest.node.peerNetwork['_isReady'] = true - routeTest.chain.synced = true - for (let i = 0; i < 3; ++i) { const block = await useMinerBlockFixture( routeTest.chain, @@ -116,9 +91,6 @@ describe('Route wallet/createTransaction', () => { }) it('should generate a valid transaction with multiple outputs', async () => { - routeTest.node.peerNetwork['_isReady'] = true - routeTest.chain.synced = true - for (let i = 0; i < 3; ++i) { const block = await useMinerBlockFixture( routeTest.chain, @@ -151,9 +123,6 @@ describe('Route wallet/createTransaction', () => { }) it('should generate a valid transaction with fee rate', async () => { - routeTest.node.peerNetwork['_isReady'] = true - routeTest.chain.synced = true - for (let i = 0; i < 3; ++i) { const block = await useMinerBlockFixture( routeTest.chain, @@ -196,9 +165,6 @@ describe('Route wallet/createTransaction', () => { }) it('should create transaction if fee and fee rate are empty', async () => { - routeTest.node.peerNetwork['_isReady'] = true - routeTest.chain.synced = true - for (let i = 0; i < 3; ++i) { const block = await useMinerBlockFixture( routeTest.chain, @@ -240,9 +206,6 @@ describe('Route wallet/createTransaction', () => { }) it('should create transaction to mint new asset', async () => { - routeTest.node.peerNetwork['_isReady'] = true - routeTest.chain.synced = true - for (let i = 0; i < 3; ++i) { const block = await useMinerBlockFixture( routeTest.chain, @@ -294,9 +257,6 @@ describe('Route wallet/createTransaction', () => { }) it('throw error when create transaction to mint unknown asset', async () => { - routeTest.node.peerNetwork['_isReady'] = true - routeTest.chain.synced = true - const asset = new Asset(sender.spendingKey, 'unknown-asset', 'metadata') for (let i = 0; i < 3; ++i) { @@ -331,15 +291,10 @@ describe('Route wallet/createTransaction', () => { ], fee: BigInt(1).toString(), }), - ).rejects.toThrow( - `Asset not found. Cannot mint for identifier '${asset.id().toString('hex')}'`, - ) + ).rejects.toThrow(`${asset.id().toString('hex')} not found`) }) it('throw error when create transaction without mint asset', async () => { - routeTest.node.peerNetwork['_isReady'] = true - routeTest.chain.synced = true - for (let i = 0; i < 3; ++i) { const block = await useMinerBlockFixture( routeTest.chain, @@ -375,9 +330,6 @@ describe('Route wallet/createTransaction', () => { }) it('should throw an error when attempting to create a transaction with no valid confirmations', async () => { - routeTest.node.peerNetwork['_isReady'] = true - routeTest.chain.synced = true - const block = await useMinerBlockFixture( routeTest.chain, undefined, @@ -413,9 +365,7 @@ describe('Route wallet/createTransaction', () => { }), ).rejects.toThrow( expect.objectContaining({ - message: expect.stringContaining( - `Not enough unspent notes available to fund the transaction.`, - ), + message: expect.any(String), status: 400, code: ERROR_CODES.INSUFFICIENT_BALANCE, }), diff --git a/ironfish/src/rpc/routes/wallet/createTransaction.ts b/ironfish/src/rpc/routes/wallet/createTransaction.ts index 925b9a2847..59dd6ed084 100644 --- a/ironfish/src/rpc/routes/wallet/createTransaction.ts +++ b/ironfish/src/rpc/routes/wallet/createTransaction.ts @@ -2,11 +2,11 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import { Asset } from '@ironfish/rust-nodejs' -import { BufferMap } from 'buffer-map' import * as yup from 'yup' -import { BurnDescription } from '../../../primitives/burnDescription' -import { MintData, RawTransactionSerde } from '../../../primitives/rawTransaction' +import { Assert } from '../../../assert' +import { RawTransactionSerde } from '../../../primitives/rawTransaction' import { CurrencyUtils, YupUtils } from '../../../utils' +import { Wallet } from '../../../wallet' import { NotEnoughFundsError } from '../../../wallet/errors' import { ERROR_CODES, ValidationError } from '../../adapters/errors' import { ApiNamespace, router } from '../router' @@ -96,155 +96,91 @@ router.register => { - const data = request.data - const account = getAccount(node, request.data.account) - // The node must be connected to the network first - if (!node.peerNetwork.isReady) { - throw new ValidationError( - `Your node must be connected to the Iron Fish network to send a transaction`, - ) - } - - if (!node.chain.synced) { - throw new ValidationError( - `Your node must be synced with the Iron Fish network to send a transaction. Please try again later`, - ) + const params: Parameters[0] = { + account: account, + confirmations: request.data.confirmations, + expiration: request.data.expiration, + expirationDelta: request.data.expirationDelta, } - const totalByAssetIdentifier = new BufferMap() - if (data.fee != null) { - const fee = CurrencyUtils.decode(data.fee) - totalByAssetIdentifier.set(Asset.nativeId(), fee) - } + if (request.data.outputs) { + params.outputs = [] - const outputs = data.outputs.map((output) => { - let assetId = Asset.nativeId() - if (output.assetId) { - assetId = Buffer.from(output.assetId, 'hex') + for (const output of request.data.outputs) { + params.outputs.push({ + publicAddress: output.publicAddress, + amount: CurrencyUtils.decode(output.amount), + memo: output.memo, + assetId: output.assetId ? Buffer.from(output.assetId, 'hex') : Asset.nativeId(), + }) } + } - const amount = CurrencyUtils.decode(output.amount) + if (request.data.mints) { + params.mints = [] - const sum = totalByAssetIdentifier.get(assetId) ?? 0n - totalByAssetIdentifier.set(assetId, sum + amount) + for (const mint of request.data.mints) { + if (mint.assetId == null && mint.name == null) { + throw new ValidationError('Must provide name or identifier to mint') + } - return { - publicAddress: output.publicAddress, - amount: amount, - memo: output.memo, - assetId, - } - }) + let name = mint.name + let metadata = mint.metadata ?? '' - const mints: MintData[] = [] - if (data.mints) { - for (const mint of data.mints) { - let mintData: MintData if (mint.assetId) { - const record = await node.chain.getAssetById(Buffer.from(mint.assetId, 'hex')) - if (!record) { - throw new ValidationError( - `Asset not found. Cannot mint for identifier '${mint.assetId}'`, - ) - } + const assetId = Buffer.from(mint.assetId, 'hex') + const asset = await account.getAsset(assetId) - mintData = { - name: record.name.toString('utf8'), - metadata: record.metadata.toString('utf8'), - value: CurrencyUtils.decode(mint.value), - } - } else { - if (mint.name === undefined) { - throw new ValidationError('Must provide name or identifier to mint') - } - mintData = { - name: mint.name, - metadata: mint.metadata ?? '', - value: CurrencyUtils.decode(mint.value), + if (!asset) { + throw new ValidationError(`Error minting: Asset ${mint.assetId} not found.`) } + + name = asset.name.toString('utf8') + metadata = asset.metadata.toString('utf8') } - mints.push(mintData) - } - } + Assert.isNotUndefined(name) + Assert.isNotUndefined(metadata) - const burns: BurnDescription[] = [] - if (data.burns) { - data.burns.map((burn) => { - let assetId = Asset.nativeId() - if (burn.assetId) { - assetId = Buffer.from(burn.assetId, 'hex') - } - burns.push({ - assetId: assetId, - value: CurrencyUtils.decode(burn.value), + params.mints.push({ + name, + metadata, + value: CurrencyUtils.decode(mint.value), }) - }) + } } - // Check that the node account is updated - for (const [assetId, sum] of totalByAssetIdentifier) { - const balance = await node.wallet.getBalance(account, assetId) + if (request.data.burns) { + params.burns = [] - if (balance.confirmed < sum) { - throw new ValidationError( - `Your balance is too low. Add funds to your account first`, - undefined, - ERROR_CODES.INSUFFICIENT_BALANCE, - ) + for (const burn of request.data.burns) { + params.burns.push({ + assetId: burn.assetId ? Buffer.from(burn.assetId, 'hex') : Asset.nativeId(), + value: CurrencyUtils.decode(burn.value), + }) } } - let rawTransaction + if (request.data.fee) { + params.fee = CurrencyUtils.decode(request.data.fee) + } else if (request.data.feeRate) { + params.feeRate = CurrencyUtils.decode(request.data.feeRate) + } else { + params.feeRate = node.memPool.feeEstimator.estimateFeeRate('medium') + } try { - if (data.fee) { - rawTransaction = await node.wallet.createTransaction({ - account, - outputs, - mints, - burns, - fee: CurrencyUtils.decode(data.fee), - expirationDelta: - data.expirationDelta ?? node.config.get('transactionExpirationDelta'), - expiration: data.expiration, - confirmations: data.confirmations, - }) - } else { - let feeRate - - if (data.feeRate) { - feeRate = CurrencyUtils.decode(data.feeRate) - } else { - feeRate = node.memPool.feeEstimator.estimateFeeRate('medium') - } - - rawTransaction = await node.wallet.createTransaction({ - account, - outputs, - mints, - burns, - expirationDelta: - data.expirationDelta ?? node.config.get('transactionExpirationDelta'), - expiration: data.expiration, - confirmations: data.confirmations, - feeRate: feeRate, - }) - } + const transaction = await node.wallet.createTransaction(params) + const serialized = RawTransactionSerde.serialize(transaction) - const rawTransactionBytes = RawTransactionSerde.serialize(rawTransaction) request.end({ - transaction: rawTransactionBytes.toString('hex'), + transaction: serialized.toString('hex'), }) } catch (e) { if (e instanceof NotEnoughFundsError) { - throw new ValidationError( - `Not enough unspent notes available to fund the transaction. Please wait for any pending transactions to be confirmed.`, - 400, - ERROR_CODES.INSUFFICIENT_BALANCE, - ) + throw new ValidationError(e.message, 400, ERROR_CODES.INSUFFICIENT_BALANCE) } throw e } diff --git a/ironfish/src/rpc/routes/wallet/sendTransaction.ts b/ironfish/src/rpc/routes/wallet/sendTransaction.ts index d191a91400..7c2f406981 100644 --- a/ironfish/src/rpc/routes/wallet/sendTransaction.ts +++ b/ironfish/src/rpc/routes/wallet/sendTransaction.ts @@ -126,11 +126,7 @@ router.register( }) } catch (e) { if (e instanceof NotEnoughFundsError) { - throw new ValidationError( - `Not enough unspent notes available to fund the transaction. Please wait for any pending transactions to be confirmed.`, - 400, - ERROR_CODES.INSUFFICIENT_BALANCE, - ) + throw new ValidationError(e.message, 400, ERROR_CODES.INSUFFICIENT_BALANCE) } throw e } diff --git a/ironfish/src/wallet/wallet.ts b/ironfish/src/wallet/wallet.ts index 2f6f6218ef..eabf0f8765 100644 --- a/ironfish/src/wallet/wallet.ts +++ b/ironfish/src/wallet/wallet.ts @@ -700,16 +700,16 @@ export class Wallet { let mintData: MintData if ('assetId' in options) { - const record = await this.chain.getAssetById(options.assetId) - if (!record) { + const asset = await this.chain.getAssetById(options.assetId) + if (!asset) { throw new Error( `Asset not found. Cannot mint for identifier '${options.assetId.toString('hex')}'`, ) } mintData = { - name: record.name.toString('utf8'), - metadata: record.metadata.toString('utf8'), + name: asset.name.toString('utf8'), + metadata: asset.metadata.toString('utf8'), value: options.value, } } else { @@ -781,13 +781,15 @@ export class Wallet { const confirmations = options.confirmations ?? this.config.get('confirmations') - let expiration = options.expiration - if (expiration === undefined && options.expirationDelta) { - expiration = heaviestHead.sequence + options.expirationDelta - } + const expirationDelta = + options.expirationDelta ?? this.config.get('transactionExpirationDelta') - if (expiration === undefined || isExpiredSequence(expiration, this.chain.head.sequence)) { - throw new Error('Invalid expiration sequence for transaction') + const expiration = options.expiration ?? heaviestHead.sequence + expirationDelta + + if (isExpiredSequence(expiration, this.chain.head.sequence)) { + throw new Error( + `Invalid expiration sequence for transaction ${expiration} vs ${this.chain.head.sequence}`, + ) } const unlock = await this.createTransactionMutex.lock() From 14f8f53d6fbec74729f465f0b2f57b4ee4a59c5e Mon Sep 17 00:00:00 2001 From: Jason Spafford Date: Wed, 15 Feb 2023 17:33:10 -0500 Subject: [PATCH 22/43] Remove promise-all usage in createTransaction.test (#3437) --- .../routes/wallet/createTransaction.test.ts | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/ironfish/src/rpc/routes/wallet/createTransaction.test.ts b/ironfish/src/rpc/routes/wallet/createTransaction.test.ts index 48a90e69ae..329f4143e9 100644 --- a/ironfish/src/rpc/routes/wallet/createTransaction.test.ts +++ b/ironfish/src/rpc/routes/wallet/createTransaction.test.ts @@ -70,9 +70,9 @@ describe('Route wallet/createTransaction', () => { block.transactions[0].notes[0].decryptNoteForOwner(sender.incomingViewKey) - await Promise.all([expect(routeTest.node.chain).toAddBlock(block)]) + await expect(routeTest.node.chain).toAddBlock(block) - await Promise.all([routeTest.node.wallet.updateHead()]) + await routeTest.node.wallet.updateHead() } const response = await routeTest.client.createTransaction(REQUEST_PARAMS) @@ -99,9 +99,9 @@ describe('Route wallet/createTransaction', () => { routeTest.node.wallet, ) - await Promise.all([expect(routeTest.node.chain).toAddBlock(block)]) + await expect(routeTest.node.chain).toAddBlock(block) - await Promise.all([routeTest.node.wallet.updateHead()]) + await routeTest.node.wallet.updateHead() } const response = await routeTest.client.createTransaction( @@ -131,9 +131,9 @@ describe('Route wallet/createTransaction', () => { routeTest.node.wallet, ) - await Promise.all([expect(routeTest.node.chain).toAddBlock(block)]) + await expect(routeTest.node.chain).toAddBlock(block) - await Promise.all([routeTest.node.wallet.updateHead()]) + await routeTest.node.wallet.updateHead() } const response = await routeTest.client.createTransaction({ @@ -173,9 +173,9 @@ describe('Route wallet/createTransaction', () => { routeTest.node.wallet, ) - await Promise.all([expect(routeTest.node.chain).toAddBlock(block)]) + await expect(routeTest.node.chain).toAddBlock(block) - await Promise.all([routeTest.node.wallet.updateHead()]) + await routeTest.node.wallet.updateHead() } const response = await routeTest.client.createTransaction({ @@ -214,9 +214,9 @@ describe('Route wallet/createTransaction', () => { routeTest.node.wallet, ) - await Promise.all([expect(routeTest.node.chain).toAddBlock(block)]) + await expect(routeTest.node.chain).toAddBlock(block) - await Promise.all([routeTest.node.wallet.updateHead()]) + await routeTest.node.wallet.updateHead() } const asset = new Asset(sender.spendingKey, 'mint-asset', 'metadata') @@ -267,9 +267,9 @@ describe('Route wallet/createTransaction', () => { routeTest.node.wallet, ) - await Promise.all([expect(routeTest.node.chain).toAddBlock(block)]) + await expect(routeTest.node.chain).toAddBlock(block) - await Promise.all([routeTest.node.wallet.updateHead()]) + await routeTest.node.wallet.updateHead() } await expect( @@ -303,9 +303,9 @@ describe('Route wallet/createTransaction', () => { routeTest.node.wallet, ) - await Promise.all([expect(routeTest.node.chain).toAddBlock(block)]) + await expect(routeTest.node.chain).toAddBlock(block) - await Promise.all([routeTest.node.wallet.updateHead()]) + await routeTest.node.wallet.updateHead() } await expect( From 3078e049153b553b007f11403eabe87e0c8f9b18 Mon Sep 17 00:00:00 2001 From: jowparks Date: Thu, 16 Feb 2023 08:41:06 -0800 Subject: [PATCH 23/43] feat: SaplingKey.view_key update (PR 2) (#3429) * feat: type wrapper ViewKey * feat: add ViewKey to SaplingKey --- ironfish-rust/src/keys/mod.rs | 43 ++++++++---------------- ironfish-rust/src/keys/view_keys.rs | 13 ++++--- ironfish-rust/src/note.rs | 2 +- ironfish-rust/src/transaction/mints.rs | 8 ++--- ironfish-rust/src/transaction/mod.rs | 10 +++--- ironfish-rust/src/transaction/outputs.rs | 15 +++++---- ironfish-rust/src/transaction/spends.rs | 4 +-- 7 files changed, 45 insertions(+), 50 deletions(-) diff --git a/ironfish-rust/src/keys/mod.rs b/ironfish-rust/src/keys/mod.rs index c15742d8a0..5b17f1cee4 100644 --- a/ironfish-rust/src/keys/mod.rs +++ b/ironfish-rust/src/keys/mod.rs @@ -13,7 +13,7 @@ use group::GroupEncoding; use ironfish_zkp::constants::{ CRH_IVK_PERSONALIZATION, PROOF_GENERATION_KEY_GENERATOR, SPENDING_KEY_GENERATOR, }; -use ironfish_zkp::{ProofGenerationKey, ViewingKey}; +use ironfish_zkp::ProofGenerationKey; use jubjub::SubgroupPoint; use rand::prelude::*; @@ -62,21 +62,15 @@ pub struct SaplingKey { /// keys needed to decrypt the note's contents. pub(crate) outgoing_viewing_key: OutgoingViewKey, - /// Part of the full viewing key. Generally referred to as - /// `ak` in the literature. Derived from spend_authorizing_key using scalar - /// multiplication in Sapling. Used to construct incoming viewing key. - pub(crate) authorizing_key: SubgroupPoint, - - /// Part of the full viewing key. Generally referred to as - /// `nk` in the literature. Derived from proof_authorizing_key using scalar - /// multiplication. Used to construct incoming viewing key. - pub(crate) nullifier_deriving_key: SubgroupPoint, + /// Part of the full viewing key. Contains ak/nk from literature, used for deriving nullifiers + /// and therefore spends + pub(crate) view_key: ViewKey, /// Part of the payment_address. Generally referred to as /// `ivk` in the literature. Derived from authorizing key and /// nullifier deriving key. Used to construct payment address and /// transmission key. This key allows the receiver of a note to decrypt its - /// contents. + /// contents. Derived from view_key contents, this is materialized for convenience pub(crate) incoming_viewing_key: IncomingViewKey, } @@ -101,6 +95,10 @@ impl SaplingKey { }; let authorizing_key = SPENDING_KEY_GENERATOR * spend_authorizing_key; let nullifier_deriving_key = PROOF_GENERATION_KEY_GENERATOR * proof_authorizing_key; + let view_key = ViewKey { + authorizing_key, + nullifier_deriving_key, + }; let incoming_viewing_key = IncomingViewKey { view_key: Self::hash_viewing_key(&authorizing_key, &nullifier_deriving_key)?, }; @@ -110,8 +108,7 @@ impl SaplingKey { spend_authorizing_key, proof_authorizing_key, outgoing_viewing_key, - authorizing_key, - nullifier_deriving_key, + view_key, incoming_viewing_key, }) } @@ -210,28 +207,16 @@ impl SaplingKey { &self.incoming_viewing_key } - /// Retrieve the sapling_representation of the ViewKey. These would normally used for third-party audits - /// or for light clients. - /// Adapter to convert this key to a viewing key for use in sapling - /// functions. - pub(crate) fn sapling_viewing_key(&self) -> ViewingKey { - ViewingKey { - ak: self.authorizing_key, - nk: self.nullifier_deriving_key, - } - } - pub fn view_key(&self) -> ViewKey { - ViewKey { - authorizing_key: self.authorizing_key, - nullifier_deriving_key: self.nullifier_deriving_key, - } + /// Retrieve the publicly visible view key + pub fn view_key(&self) -> &ViewKey { + &self.view_key } /// Adapter to convert this key to a proof generation key for use in /// sapling functions pub(crate) fn sapling_proof_generation_key(&self) -> ProofGenerationKey { ProofGenerationKey { - ak: self.authorizing_key, + ak: self.view_key.authorizing_key, nsk: self.proof_authorizing_key, } } diff --git a/ironfish-rust/src/keys/view_keys.rs b/ironfish-rust/src/keys/view_keys.rs index e06bfc37ee..b413def8a6 100644 --- a/ironfish-rust/src/keys/view_keys.rs +++ b/ironfish-rust/src/keys/view_keys.rs @@ -97,7 +97,13 @@ impl IncomingViewKey { /// Referred to as `ViewingKey` in the literature. #[derive(Clone)] pub struct ViewKey { + /// Part of the full viewing key. Generally referred to as + /// `ak` in the literature. Derived from spend_authorizing_key using scalar + /// multiplication in Sapling. Used to construct incoming viewing key. pub authorizing_key: jubjub::SubgroupPoint, + /// Part of the full viewing key. Generally referred to as + /// `nk` in the literature. Derived from proof_authorizing_key using scalar + /// multiplication. Used to construct incoming viewing key. pub nullifier_deriving_key: jubjub::SubgroupPoint, } @@ -244,15 +250,14 @@ mod test { "d96dc74bbca05dffb14a5631024588364b0cc9f583b5c11908b6ea98a2b778f7", ) .expect("Key should be generated"); - let view_key = key.view_key(); - let view_key_hex = view_key.hex_key(); + let view_key_hex = key.view_key.hex_key(); assert_eq!(view_key_hex, "498b5103a72c41237c3f2bca96f20100f5a3a8a17c6b8366a485fd16e8931a5d2ff2eb8f991032c815414ff0ae2d8bc3ea3b56bffc481db3f28e800050244463"); let recreated_key = ViewKey::from_hex(&view_key_hex).expect("Key should be created from hex"); - assert_eq!(view_key.authorizing_key, recreated_key.authorizing_key); + assert_eq!(key.view_key.authorizing_key, recreated_key.authorizing_key); assert_eq!( - view_key.nullifier_deriving_key, + key.view_key.nullifier_deriving_key, recreated_key.nullifier_deriving_key ); } diff --git a/ironfish-rust/src/note.rs b/ironfish-rust/src/note.rs index 9c00e6ca2e..5c3bde5c2e 100644 --- a/ironfish-rust/src/note.rs +++ b/ironfish-rust/src/note.rs @@ -298,7 +298,7 @@ impl<'a> Note { .hash_length(32) .personal(PRF_NF_PERSONALIZATION) .to_state() - .update(&private_key.sapling_viewing_key().nk.to_bytes()) + .update(&private_key.view_key.nullifier_deriving_key.to_bytes()) .update(&rho.to_bytes()) .finalize() .as_bytes(), diff --git a/ironfish-rust/src/transaction/mints.rs b/ironfish-rust/src/transaction/mints.rs index e728d87863..4c161a085b 100644 --- a/ironfish-rust/src/transaction/mints.rs +++ b/ironfish-rust/src/transaction/mints.rs @@ -98,7 +98,7 @@ impl UnsignedMintDescription { redjubjub::PublicKey::from_private(&randomized_private_key, SPENDING_KEY_GENERATOR); let transaction_randomized_public_key = - redjubjub::PublicKey(spender_key.authorizing_key.into()) + redjubjub::PublicKey(spender_key.view_key.authorizing_key.into()) .randomize(self.public_key_randomness, SPENDING_KEY_GENERATOR); if randomized_public_key.0 != transaction_randomized_public_key.0 { @@ -247,7 +247,7 @@ mod test { let value = 5; let public_key_randomness = jubjub::Fr::random(thread_rng()); - let randomized_public_key = redjubjub::PublicKey(key.authorizing_key.into()) + let randomized_public_key = redjubjub::PublicKey(key.view_key.authorizing_key.into()) .randomize(public_key_randomness, SPENDING_KEY_GENERATOR); let mint = MintBuilder::new(asset, value); @@ -277,7 +277,7 @@ mod test { .verify_signature(&other_sig_hash, &randomized_public_key) .is_err()); - let other_randomized_public_key = redjubjub::PublicKey(key.authorizing_key.into()) + let other_randomized_public_key = redjubjub::PublicKey(key.view_key.authorizing_key.into()) .randomize(jubjub::Fr::random(thread_rng()), SPENDING_KEY_GENERATOR); assert!(description .verify_signature(&sig_hash, &other_randomized_public_key) @@ -296,7 +296,7 @@ mod test { let value = 5; let public_key_randomness = jubjub::Fr::random(thread_rng()); - let randomized_public_key = redjubjub::PublicKey(key.authorizing_key.into()) + let randomized_public_key = redjubjub::PublicKey(key.view_key.authorizing_key.into()) .randomize(public_key_randomness, SPENDING_KEY_GENERATOR); let mint = MintBuilder::new(asset, value); diff --git a/ironfish-rust/src/transaction/mod.rs b/ironfish-rust/src/transaction/mod.rs index e018be6c95..240816ba8b 100644 --- a/ironfish-rust/src/transaction/mod.rs +++ b/ironfish-rust/src/transaction/mod.rs @@ -262,8 +262,9 @@ impl ProposedTransaction { // The public key after randomization has been applied. This is used // during signature verification. Referred to as `rk` in the literature // Calculated from the authorizing key and the public_key_randomness. - let randomized_public_key = redjubjub::PublicKey(self.spender_key.authorizing_key.into()) - .randomize(self.public_key_randomness, SPENDING_KEY_GENERATOR); + let randomized_public_key = + redjubjub::PublicKey(self.spender_key.view_key.authorizing_key.into()) + .randomize(self.public_key_randomness, SPENDING_KEY_GENERATOR); // Build descriptions let mut unsigned_spends = Vec::with_capacity(self.spends.len()); @@ -365,8 +366,9 @@ impl ProposedTransaction { .write_i64::(*self.value_balances.fee()) .unwrap(); - let randomized_public_key = redjubjub::PublicKey(self.spender_key.authorizing_key.into()) - .randomize(self.public_key_randomness, SPENDING_KEY_GENERATOR); + let randomized_public_key = + redjubjub::PublicKey(self.spender_key.view_key.authorizing_key.into()) + .randomize(self.public_key_randomness, SPENDING_KEY_GENERATOR); hasher .write_all(&randomized_public_key.0.to_bytes()) diff --git a/ironfish-rust/src/transaction/outputs.rs b/ironfish-rust/src/transaction/outputs.rs index b02dd2db67..412d790879 100644 --- a/ironfish-rust/src/transaction/outputs.rs +++ b/ironfish-rust/src/transaction/outputs.rs @@ -234,8 +234,9 @@ mod test { fn test_output_miners_fee() { let spender_key = SaplingKey::generate_key(); let public_key_randomness = jubjub::Fr::random(thread_rng()); - let randomized_public_key = redjubjub::PublicKey(spender_key.authorizing_key.into()) - .randomize(public_key_randomness, SPENDING_KEY_GENERATOR); + let randomized_public_key = + redjubjub::PublicKey(spender_key.view_key.authorizing_key.into()) + .randomize(public_key_randomness, SPENDING_KEY_GENERATOR); let note = Note::new( spender_key.public_address(), @@ -263,8 +264,9 @@ mod test { let spender_key = SaplingKey::generate_key(); let receiver_key = SaplingKey::generate_key(); let public_key_randomness = jubjub::Fr::random(thread_rng()); - let randomized_public_key = redjubjub::PublicKey(spender_key.authorizing_key.into()) - .randomize(public_key_randomness, SPENDING_KEY_GENERATOR); + let randomized_public_key = + redjubjub::PublicKey(spender_key.view_key.authorizing_key.into()) + .randomize(public_key_randomness, SPENDING_KEY_GENERATOR); let note = Note::new( receiver_key.public_address(), @@ -290,8 +292,9 @@ mod test { let spender_key = SaplingKey::generate_key(); let receiver_key = SaplingKey::generate_key(); let public_key_randomness = jubjub::Fr::random(thread_rng()); - let randomized_public_key = redjubjub::PublicKey(spender_key.authorizing_key.into()) - .randomize(public_key_randomness, SPENDING_KEY_GENERATOR); + let randomized_public_key = + redjubjub::PublicKey(spender_key.view_key.authorizing_key.into()) + .randomize(public_key_randomness, SPENDING_KEY_GENERATOR); let note = Note::new( receiver_key.public_address(), diff --git a/ironfish-rust/src/transaction/spends.rs b/ironfish-rust/src/transaction/spends.rs index 3fb411972d..5ced6d52e2 100644 --- a/ironfish-rust/src/transaction/spends.rs +++ b/ironfish-rust/src/transaction/spends.rs @@ -165,7 +165,7 @@ impl UnsignedSpendDescription { redjubjub::PublicKey::from_private(&randomized_private_key, SPENDING_KEY_GENERATOR); let transaction_randomized_public_key = - redjubjub::PublicKey(spender_key.authorizing_key.into()) + redjubjub::PublicKey(spender_key.view_key.authorizing_key.into()) .randomize(self.public_key_randomness, SPENDING_KEY_GENERATOR); if randomized_public_key.0 != transaction_randomized_public_key.0 { @@ -402,7 +402,7 @@ mod test { let spend = SpendBuilder::new(note, &witness); let public_key_randomness = jubjub::Fr::random(thread_rng()); - let randomized_public_key = redjubjub::PublicKey(key.authorizing_key.into()) + let randomized_public_key = redjubjub::PublicKey(key.view_key.authorizing_key.into()) .randomize(public_key_randomness, SPENDING_KEY_GENERATOR); // signature comes from transaction, normally From 3d16e75d2ab876d1d0c17dc1a1756da44a74796c Mon Sep 17 00:00:00 2001 From: jowparks Date: Thu, 16 Feb 2023 09:56:30 -0800 Subject: [PATCH 24/43] feat: nullifier from view key (PR 3) (#3433) * feat: type wrapper ViewKey * feat: add ViewKey to SaplingKey * feat: add ViewKey to SaplingKey * feat: nullifier from view_key instead of private_key --- ironfish-rust-nodejs/src/structs/note.rs | 2 +- ironfish-rust/src/note.rs | 10 +++++----- ironfish-rust/src/transaction/spends.rs | 4 +++- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/ironfish-rust-nodejs/src/structs/note.rs b/ironfish-rust-nodejs/src/structs/note.rs index daa5568ef6..cd974395e2 100644 --- a/ironfish-rust-nodejs/src/structs/note.rs +++ b/ironfish-rust-nodejs/src/structs/note.rs @@ -150,7 +150,7 @@ impl NativeNote { let private_key = SaplingKey::from_hex(&owner_private_key).map_err(to_napi_err)?; - let nullifier: &[u8] = &self.note.nullifier(&private_key, position_u64).0; + let nullifier: &[u8] = &self.note.nullifier(private_key.view_key(), position_u64).0; Ok(Buffer::from(nullifier)) } diff --git a/ironfish-rust/src/note.rs b/ironfish-rust/src/note.rs index 5c3bde5c2e..9764176d3d 100644 --- a/ironfish-rust/src/note.rs +++ b/ironfish-rust/src/note.rs @@ -4,11 +4,11 @@ use crate::{ assets::asset::AssetIdentifier, errors::IronfishError, keys::PUBLIC_ADDRESS_SIZE, - serializing::read_point, util::str_to_array, + serializing::read_point, util::str_to_array, ViewKey, }; use super::{ - keys::{IncomingViewKey, PublicAddress, SaplingKey}, + keys::{IncomingViewKey, PublicAddress}, serializing::{aead, read_scalar}, }; use blake2s_simd::Params as Blake2sParams; @@ -282,12 +282,12 @@ impl<'a> Note { ) } - /// Compute the nullifier for this note, given the private key of its owner. + /// Compute the nullifier for this note, given the ViewKey of its owner. /// /// The nullifier is a series of bytes that is published by the note owner /// only at the time the note is spent. This key is collected in a massive /// 'nullifier set', preventing double-spend. - pub fn nullifier(&self, private_key: &SaplingKey, position: u64) -> Nullifier { + pub fn nullifier(&self, view_key: &ViewKey, position: u64) -> Nullifier { // Compute rho = cm + position.G let rho = self.commitment_full_point() + (NULLIFIER_POSITION_GENERATOR * jubjub::Fr::from(position)); @@ -298,7 +298,7 @@ impl<'a> Note { .hash_length(32) .personal(PRF_NF_PERSONALIZATION) .to_state() - .update(&private_key.view_key.nullifier_deriving_key.to_bytes()) + .update(&view_key.nullifier_deriving_key.to_bytes()) .update(&rho.to_bytes()) .finalize() .as_bytes(), diff --git a/ironfish-rust/src/transaction/spends.rs b/ironfish-rust/src/transaction/spends.rs index 5ced6d52e2..7203da6bd8 100644 --- a/ironfish-rust/src/transaction/spends.rs +++ b/ironfish-rust/src/transaction/spends.rs @@ -115,7 +115,9 @@ impl SpendBuilder { // Bytes to be placed into the nullifier set to verify whether this note // has been previously spent. - let nullifier = self.note.nullifier(spender_key, self.witness_position); + let nullifier = self + .note + .nullifier(&spender_key.view_key, self.witness_position); let blank_signature = { let buf = [0u8; 64]; From 3cd7c6135acaa9d76cadf1a665fe282874104e50 Mon Sep 17 00:00:00 2001 From: jowparks Date: Thu, 16 Feb 2023 09:57:29 -0800 Subject: [PATCH 25/43] feat: ViewKey rust nodejs (PR 4) (#3436) * feat: type wrapper ViewKey * feat: add ViewKey to SaplingKey * feat: expose view_key in rust-nodejs layer --- ironfish-rust-nodejs/index.d.ts | 1 + ironfish-rust-nodejs/src/lib.rs | 4 ++++ ironfish-rust-nodejs/tests/demo.test.slow.ts | 7 +++++++ 3 files changed, 12 insertions(+) diff --git a/ironfish-rust-nodejs/index.d.ts b/ironfish-rust-nodejs/index.d.ts index 2f81614d53..7ef2b9ee96 100644 --- a/ironfish-rust-nodejs/index.d.ts +++ b/ironfish-rust-nodejs/index.d.ts @@ -53,6 +53,7 @@ export const enum LanguageCode { } export interface Key { spending_key: string + view_key: string incoming_view_key: string outgoing_view_key: string public_address: string diff --git a/ironfish-rust-nodejs/src/lib.rs b/ironfish-rust-nodejs/src/lib.rs index f6f06bf479..b4a31da816 100644 --- a/ironfish-rust-nodejs/src/lib.rs +++ b/ironfish-rust-nodejs/src/lib.rs @@ -57,6 +57,8 @@ impl From for Language { pub struct Key { #[napi(js_name = "spending_key")] pub spending_key: String, + #[napi(js_name = "view_key")] + pub view_key: String, #[napi(js_name = "incoming_view_key")] pub incoming_view_key: String, #[napi(js_name = "outgoing_view_key")] @@ -71,6 +73,7 @@ pub fn generate_key() -> Key { Key { spending_key: sapling_key.hex_spending_key(), + view_key: sapling_key.view_key().hex_key(), incoming_view_key: sapling_key.incoming_view_key().hex_key(), outgoing_view_key: sapling_key.outgoing_view_key().hex_key(), public_address: sapling_key.public_address().hex_public_address(), @@ -96,6 +99,7 @@ pub fn generate_key_from_private_key(private_key: String) -> Result { Ok(Key { spending_key: sapling_key.hex_spending_key(), + view_key: sapling_key.view_key().hex_key(), incoming_view_key: sapling_key.incoming_view_key().hex_key(), outgoing_view_key: sapling_key.outgoing_view_key().hex_key(), public_address: sapling_key.public_address().hex_public_address(), diff --git a/ironfish-rust-nodejs/tests/demo.test.slow.ts b/ironfish-rust-nodejs/tests/demo.test.slow.ts index 413d634c86..9ebc128edd 100644 --- a/ironfish-rust-nodejs/tests/demo.test.slow.ts +++ b/ironfish-rust-nodejs/tests/demo.test.slow.ts @@ -38,6 +38,13 @@ describe('Demonstrate the Sapling API', () => { expect(hexKeyGenerated).toEqual(hexKey) }) + it('ViewKey concatenated key should be generated from spending key deterministically', () => { + const hexSpendingKey = 'd96dc74bbca05dffb14a5631024588364b0cc9f583b5c11908b6ea98a2b778f7' + const key = generateKeyFromPrivateKey(hexSpendingKey) + // concatenated bytes of authorizing_key and nullifier_deriving_key + expect(key.view_key).toEqual('498b5103a72c41237c3f2bca96f20100f5a3a8a17c6b8366a485fd16e8931a5d2ff2eb8f991032c815414ff0ae2d8bc3ea3b56bffc481db3f28e800050244463') + }) + it('Should generate a new public address given a spending key', () => { const key = generateKey() const newKey = generateKeyFromPrivateKey(key.spending_key) From 81a649c6d9f21d7a1969c433e91c4d2acf9f37a0 Mon Sep 17 00:00:00 2001 From: Jason Spafford Date: Thu, 16 Feb 2023 14:45:10 -0500 Subject: [PATCH 26/43] Change chain:power to follow the new CLI ux guide (#3448) * Change chain:power to follow the new CLI ux guide * Remove flag variable --- ironfish-cli/src/commands/chain/power.ts | 37 +++++++++++------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/ironfish-cli/src/commands/chain/power.ts b/ironfish-cli/src/commands/chain/power.ts index 60d8afc631..a2711ac8fa 100644 --- a/ironfish-cli/src/commands/chain/power.ts +++ b/ironfish-cli/src/commands/chain/power.ts @@ -2,50 +2,47 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import { FileUtils } from '@ironfish/sdk' +import { Flags } from '@oclif/core' import { parseNumber } from '../../args' import { IronfishCommand } from '../../command' import { LocalFlags } from '../../flags' export default class Power extends IronfishCommand { - static description = "Show the network's hash power (hash/s)" + static description = "Show the network's hash power per second" static flags = { ...LocalFlags, + history: Flags.integer({ + required: false, + description: + 'The number of blocks to look back to calculate the network hashes per second', + }), } static args = [ { - name: 'blocks', - parse: (input: string): Promise => Promise.resolve(parseNumber(input)), - required: false, - description: - 'The number of blocks to look back to calculate the power. This value must be > 0', - }, - { - name: 'sequence', + name: 'block', parse: (input: string): Promise => Promise.resolve(parseNumber(input)), required: false, - description: 'The sequence of the latest block from when to estimate network speed ', + description: 'The sequence of the block to estimate network speed for', }, ] async start(): Promise { - const { args } = await this.parse(Power) - const inputBlocks = args.blocks as number | null | undefined - const inputSequence = args.sequence as number | null | undefined + const { flags, args } = await this.parse(Power) + const block = args.block as number | null | undefined - await this.sdk.client.connect() + const client = await this.sdk.connectRpc() - const data = await this.sdk.client.getNetworkHashPower({ - blocks: inputBlocks, - sequence: inputSequence, + const data = await client.getNetworkHashPower({ + sequence: block, + blocks: flags.history, }) - const { hashesPerSecond, blocks, sequence } = data.content - const formattedHashesPerSecond = FileUtils.formatHashRate(hashesPerSecond) + const formattedHashesPerSecond = FileUtils.formatHashRate(data.content.hashesPerSecond) this.log( - `The network power for block ${sequence} was ${formattedHashesPerSecond} averaged over ${blocks} previous blocks.`, + `The network power for block ${data.content.sequence} was ${formattedHashesPerSecond} averaged over ${data.content.blocks} previous blocks.`, ) } } From 1a931ac1aa8cfb9cdbc189f0d1508fdbc10104db Mon Sep 17 00:00:00 2001 From: Jason Spafford Date: Thu, 16 Feb 2023 15:59:24 -0500 Subject: [PATCH 27/43] Add start of a CLI style guide (#3445) * Add start of a CLI style guide * Update ironfish-cli/STYLE_GUIDE.md Co-authored-by: mat-if <97762857+mat-if@users.noreply.github.com> * Fixed example: * Update ironfish-cli/STYLE_GUIDE.md Co-authored-by: mat-if <97762857+mat-if@users.noreply.github.com> * Feedback --------- Co-authored-by: mat-if <97762857+mat-if@users.noreply.github.com> --- ironfish-cli/STYLE_GUIDE.md | 68 +++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 ironfish-cli/STYLE_GUIDE.md diff --git a/ironfish-cli/STYLE_GUIDE.md b/ironfish-cli/STYLE_GUIDE.md new file mode 100644 index 0000000000..e6b7ed2165 --- /dev/null +++ b/ironfish-cli/STYLE_GUIDE.md @@ -0,0 +1,68 @@ +# CLI UX Guide + +The Iron Fish CLI is for humans before machines. The primary goal of anyone developing CLI plugins should always be usability. Input and output should be consistent across commands to allow the user to easily learn how to interact with new commands. + +Based on https://devcenter.heroku.com/articles/cli-style-guide + +## Naming the command +The CLI is made up of topics and commands. For the command `ironfish migrations:start`, migrations is the topic and start is the command. + +Generally topics are plural nouns and commands are verbs. + +Topic and command names should always be a single, lowercase word without spaces, hyphens, underscores, or other word delimiters. Colons, however, are allowed as this is how to define subcommands (such as `ironfish wallet:transactions:add`). If there is no obvious way to avoid having multiple words, separate with kebab-case: `ironfish service:estimate-fee-rates` + +Because topics are generally nouns, the root command of a topic usually lists those nouns. So in the case of `ironfish migrations`, it will list all the migrations. Never create a *:list command such as `ironfish migrations:list`. + +## Command Description +Topic and command descriptions should be provided for all topics and commands. They should fit on 80 character width screens, begin with a lowercase character, and should not end in a period. + +## Input +Input to commands is typically provided by flags and args. Stdin can also be used in cases where it is useful to stream files or information in (such as with heroku run). + +### Flags + +Flags are preferred to args when there are many inputs, particularly inputs of the same type. They involve a bit more typing, but make the use of the CLI clearer. For example, `ironfish wallet:send` used to accept an argument for the account to use, as well as --to flag to specify the account to send to. + +So using `ironfish wallet:send` used to work like this: + +```bash +$ ironfish wallet:send source_account --to dest_account +``` + +This is confusing to the user since it isnโ€™t clear which account they are sending from and which one they are sending to. By switching to required flags, we instead expect input in this form: + +```bash +ironfish wallet:send --from source_account --to dest_account +``` + +This also allows the user to specify the flags in any order, and gives them the confidence that they are running the command correctly. It also allows us to show better error messages. + +Ensure that descriptions are provided for all flags, that the descriptions are in lowercase, that they are concise (so as to fit on narrow screens), and that they do not end in a period to match other flag descriptions. + + +### Arguments +Arguments are the basic way to provide input for a command. While flags are generally preferred, they are sometimes unnecessary in cases where there is only 1 argument, or the arguments are obvious and in an obvious order. + +In the case of `ironfish chain:power`, we can specify the block sequence we want to determine the network mining power with an argument. We can also specify how many blocks back to look to average the mining power with a flag. + +```bash +ironfish chain:power 5432 --history 20 +``` + +If this was done with only arguments, it wouldnโ€™t be clear if the sequence should go before or after the number of blocks to use to sample the network mining power. Using a required flag instead allows the user to specify it either way. + +### Prompting +Prompting for missing input provides a nice way to show complicated options in the CLI. For example, `ironfish wallet:use` shows the following if no account is specified as an arg. + +``` +$ ironfish wallet:use + +? Which wallet would you like to use? (Use arrow keys) +โฏ vitalik + satoshi + jason +``` + +> โ„น๏ธ Use [inquirer](https://github.com/sboudrias/Inquirer.js) to show prompts like this. + +However, if prompting is required to complete a command, this means the user will not be able to script the command. Ensure that args or flags can always be provided to bypass the prompt. In this case, `ironfish wallet:use` can take in an argument for the account to set as default to skip the prompt. From 37fca93066ac35f0e6bf39c28f6495b9f40da51f Mon Sep 17 00:00:00 2001 From: mat-if <97762857+mat-if@users.noreply.github.com> Date: Thu, 16 Feb 2023 15:43:56 -0700 Subject: [PATCH 28/43] refactor(ironfish): move `resolveSequenceOrHash` fn (#3453) Move and rename this function out of `PeerNetwork` class. It is really a blockchain utility function, so moving it to `BlockchainUtils` makes sense. --- ironfish/src/network/peerNetwork.ts | 16 +- .../__fixtures__/blockutil.test.ts.fixture | 58 +++++ ironfish/src/utils/blockchain.ts | 16 +- ironfish/src/utils/blockutil.test.ts | 199 ++++++++++-------- 4 files changed, 192 insertions(+), 97 deletions(-) create mode 100644 ironfish/src/utils/__fixtures__/blockutil.test.ts.fixture diff --git a/ironfish/src/network/peerNetwork.ts b/ironfish/src/network/peerNetwork.ts index 7583436018..422a0bf579 100644 --- a/ironfish/src/network/peerNetwork.ts +++ b/ironfish/src/network/peerNetwork.ts @@ -21,7 +21,7 @@ import { Block, CompactBlock } from '../primitives/block' import { BlockHash, BlockHeader } from '../primitives/blockheader' import { TransactionHash } from '../primitives/transaction' import { Telemetry } from '../telemetry' -import { ArrayUtils, BenchUtils, HRTime } from '../utils' +import { ArrayUtils, BenchUtils, BlockchainUtils, HRTime } from '../utils' import { BlockFetcher } from './blockFetcher' import { Identity, PrivateIdentity } from './identity' import { CannotSatisfyRequest } from './messages/cannotSatisfyRequest' @@ -1013,14 +1013,6 @@ export class PeerNetwork { } } - private async resolveSequenceOrHash(start: Buffer | number): Promise { - if (Buffer.isBuffer(start)) { - return await this.chain.getHeader(start) - } - - return await this.chain.getHeaderAtSequence(start) - } - private async onGetBlockHeadersRequest( request: IncomingPeerMessage, ): Promise { @@ -1050,7 +1042,7 @@ export class PeerNetwork { const skip = message.skip const reverse = message.reverse - const from = await this.resolveSequenceOrHash(start) + const from = await BlockchainUtils.blockHeaderBySequenceOrHash(this.chain, start) if (!from) { return new GetBlockHeadersResponse([], rpcId) } @@ -1111,7 +1103,7 @@ export class PeerNetwork { const start = message.start const limit = message.limit - const from = await this.resolveSequenceOrHash(start) + const from = await BlockchainUtils.blockHeaderBySequenceOrHash(this.chain, start) if (!from) { return new GetBlockHashesResponse([], rpcId) } @@ -1149,7 +1141,7 @@ export class PeerNetwork { const start = message.start const limit = message.limit - const from = await this.resolveSequenceOrHash(start) + const from = await BlockchainUtils.blockHeaderBySequenceOrHash(this.chain, start) if (!from) { return new GetBlocksResponse([], rpcId) } diff --git a/ironfish/src/utils/__fixtures__/blockutil.test.ts.fixture b/ironfish/src/utils/__fixtures__/blockutil.test.ts.fixture new file mode 100644 index 0000000000..3428d8c8c5 --- /dev/null +++ b/ironfish/src/utils/__fixtures__/blockutil.test.ts.fixture @@ -0,0 +1,58 @@ +{ + "BlockchainUtils blockHeaderBySequenceOrHash gets block header by sequence": [ + { + "header": { + "sequence": 2, + "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", + "noteCommitment": { + "type": "Buffer", + "data": "base64:KzPEJPLgCnPELGMpREExQ7ROCFMiYo+ldIVpV/P1oCk=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:dtKD1ObaO3NarBS8NlGysx0iGPmlFTp7H1ImMjv0FYQ=" + }, + "target": "883423532389192164791648750371459257913741948437809479060803100646309888", + "randomness": "0", + "timestamp": 1676586569216, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 4, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAABImcnr0LaejxQDHnCDKIbl40zpA5M6vyCwEZt1Otg6uvNCYUxEYrVm7P8/uukVicp41Y1OQrw1PEg5PogrXEvcv9l43vh0bgefMzkXSjpJapSeXkFu6mj2m5IErigiyIlgwPUpRrRqeEZ7wN7rRPKCoQ2Rs3DG6boEUFWUyPR2QLCGzrjcK8GWGrgbWDnf/baC7AW6+hl3V+1kTEHrVu3sdAgUp+JGAbEFl5uiIJU/S4iSKpTtHlM+xtyvZGNADWxjyqrbdoSrQAaBD0qZ7NYkcRjS9aTIBud1ESf8haKgChgBDGigNkBGCboypUmc0H0No/pzEG4zd0p6SAHeZjLv8ExNg94ubYb0hpSGnjgyBHHs+R/b2qLJR1OW2+EiMOsxtdaZrb/5WYdb7WJhhyj4Bz9ZQ1RmDiusG1XqjSjLf1CIW14pH6A4JjgQtct1kp/Lm1bSknAJD6ofTNnm3ySVWXMuYFm+oSUaYQdi+m5xe9myXAgtE489cOfTR50b784UHeYtkTxBTiC7FItRpUR3OFdVD4CoNAaqJ9y9oRd65c5KOWrN8THAD9xhzcDOH4EtvQBsrmga87gBo393ydH3QXTW+Qbe/+PUHbPCwoN164Ip7VqLWsH0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwV4lG16ZQbtsI+WIUZX52KOrV/xRx9U8cmwFXsDu0Dg3R4w7pST8MIQXiTdz8Wb4YeWs9a5KqYjc+3V2G26MXCQ==" + } + ] + } + ], + "BlockchainUtils blockHeaderBySequenceOrHash gets block header by hash": [ + { + "header": { + "sequence": 2, + "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", + "noteCommitment": { + "type": "Buffer", + "data": "base64:274dGQylL9VXiiiF8JddKdLctp6hkp1gya1wkBlqFFw=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:ma0zYPdbSOO5fJT0/xYTyUp4sG+8jmdxGbdrcYMOofg=" + }, + "target": "883423532389192164791648750371459257913741948437809479060803100646309888", + "randomness": "0", + "timestamp": 1676586570132, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 4, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAq/sACl1n2pCBGLIzorJ1yLIQCNrRMT9FR5LriYNuT8qjkn1cAqRdMol6jnJuE4n7vIvvcj6OvlBmSrgn09YAogJbbYbBjgHasRT6Cpewvy6q4fjEAlSbGfYgxktuccNK/4r72NWPxUd5vos0Yl6MhYaueh3NSbjykHUaYyx8MyAVSlbxJYorqlvyFBWV+JFKDquDh2sCpDuX7V/6S6d6aXAUkURkMhIvDsGTobba3JCAJvarEhYI3dkiM7mFqtltoyuaK7kSn4EqqQcx0QZWh4xQlX56vWBfWWmxD27sAAREwRK1xPXujbLjFhMq3OR1qwVH11oKf79ogJaT32nsQDQZFOZacm+oziWprEIewoZ3/ZBlWfXgj86CJvqaTg4tLSxWKn38+nK51BQLz8oiZBoBTLIgN/net7hllha+3T1bbQ9b5X0wXMyvHzHfIz7kka7zGetAzjvbR2SsPi/EsCTREctqjNB3QzGB3BxVpfEqf1b/o1TdmhO0QoeBtJ3ehNno6LqYQcA9of1KO2PaA67uIirBhKNGWxPIdsTqESanskJnhpEh4HOGLZ71axlVb0Xs+LtIevAvB6cHf7CFqrpCCva4bH5Bg3cmhFm2OWO8CHH76lxthUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwCNBfpDBEjc7uzJzUKTCv+5V6ayEhDI5IErtzVKeBpBA6G7djUzmmt4UCylqZB1DOEnbDGi556J0N31gdP0HKCQ==" + } + ] + } + ] +} \ No newline at end of file diff --git a/ironfish/src/utils/blockchain.ts b/ironfish/src/utils/blockchain.ts index 9e4e45a371..9bb3358db0 100644 --- a/ironfish/src/utils/blockchain.ts +++ b/ironfish/src/utils/blockchain.ts @@ -3,7 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import { Blockchain } from '../blockchain' -import { Block } from '../primitives' +import { Block, BlockHeader } from '../primitives' import { GENESIS_BLOCK_SEQUENCE } from '../primitives/block' import { isTransactionMine } from '../testUtilities/helpers/transaction' import { Account } from '../wallet' @@ -44,4 +44,16 @@ export function isBlockMine(block: Block, account: Account): boolean { return isTransactionMine(block.minersFee, account) } -export const BlockchainUtils = { isBlockMine, getBlockRange } +// Returns the block header at the given sequence or hash +async function blockHeaderBySequenceOrHash( + chain: Blockchain, + start: Buffer | number, +): Promise { + if (Buffer.isBuffer(start)) { + return await chain.getHeader(start) + } + + return await chain.getHeaderAtSequence(start) +} + +export const BlockchainUtils = { isBlockMine, getBlockRange, blockHeaderBySequenceOrHash } diff --git a/ironfish/src/utils/blockutil.test.ts b/ironfish/src/utils/blockutil.test.ts index 7c1729bc52..3e98a9068c 100644 --- a/ironfish/src/utils/blockutil.test.ts +++ b/ironfish/src/utils/blockutil.test.ts @@ -1,91 +1,124 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +import { useMinerBlockFixture } from '../testUtilities' import { createNodeTest } from '../testUtilities/nodeTest' -import { getBlockRange } from './blockchain' - -// Strategy for testing: -// Consider a line of numbers to pick for the input parameters -// <-----N1---N2----0G---P1---P2---H---X1---X2-----> -// N1, N2 are negative (count backward from height) -// G is the genesis block (1) -// P1 and P2 are positive numbers in the range of blocks -// H is the height of the chain -// X1 and X2 exceed the height of the chain -describe('getBlockRange', () => { - const nodeTest = createNodeTest() - - it.each([ - // P1, P2 cases - [{ start: 9000, stop: 900 }, 9000, 9000], - [{ start: 900, stop: 9000 }, 900, 9000], - - // N1, N2 cases - [{ start: -9000, stop: -8000 }, 1000, 2000], - [{ start: -8000, stop: -9000 }, 2000, 2000], - - // N, P cases - [{ start: -9000, stop: 3000 }, 1000, 3000], - [{ start: 3000, stop: -9000 }, 3000, 3000], - [{ start: 1000, stop: -7000 }, 1000, 3000], - [{ start: -7000, stop: 1000 }, 3000, 3000], - - // N, 0 cases - [{ start: -9000, stop: 0 }, 1000, 10000], - [{ start: 0, stop: -9000 }, 1, 1000], - - // P, 0 cases - [{ start: 40, stop: 0 }, 40, 10000], - [{ start: 0, stop: 40 }, 1, 40], - - // H, 0 cases - [{ start: 10000, stop: 0 }, 10000, 10000], - [{ start: 0, stop: 10000 }, 1, 10000], - - // P, H cases - [{ start: 100, stop: 10000 }, 100, 10000], - [{ start: 10000, stop: 100 }, 10000, 10000], - - // X1, X2 cases - [{ start: 11000, stop: 12000 }, 10000, 10000], - [{ start: 12000, stop: 11000 }, 10000, 10000], - - // N, H cases - [{ start: -9000, stop: 10000 }, 1000, 10000], - [{ start: 10000, stop: -9000 }, 10000, 10000], - - // N1, N2 cases: |N1| > H - [{ start: -17000, stop: -8000 }, 1, 2000], - [{ start: -8000, stop: -17000 }, 2000, 2000], - - // N1, N2 cases: |N1| > H, |N2| > H - [{ start: -17000, stop: -18000 }, 1, 1], - [{ start: -18000, stop: -17000 }, 1, 1], - - // Fractional cases - [{ start: 3.14, stop: 6.28 }, 3, 6], - [{ start: 6.28, stop: 3.14 }, 6, 6], - ])('%o returns %d %d', (param, expectedStart, expectedStop) => { - nodeTest.chain.latest.sequence = 10000 - - const { start, stop } = getBlockRange(nodeTest.chain, param) - expect(start).toEqual(expectedStart) - expect(stop).toEqual(expectedStop) +import { BlockchainUtils, getBlockRange } from './blockchain' + +describe('BlockchainUtils', () => { + // Strategy for testing: + // Consider a line of numbers to pick for the input parameters + // <-----N1---N2----0G---P1---P2---H---X1---X2-----> + // N1, N2 are negative (count backward from height) + // G is the genesis block (1) + // P1 and P2 are positive numbers in the range of blocks + // H is the height of the chain + // X1 and X2 exceed the height of the chain + describe('getBlockRange', () => { + const nodeTest = createNodeTest() + + it.each([ + // P1, P2 cases + [{ start: 9000, stop: 900 }, 9000, 9000], + [{ start: 900, stop: 9000 }, 900, 9000], + + // N1, N2 cases + [{ start: -9000, stop: -8000 }, 1000, 2000], + [{ start: -8000, stop: -9000 }, 2000, 2000], + + // N, P cases + [{ start: -9000, stop: 3000 }, 1000, 3000], + [{ start: 3000, stop: -9000 }, 3000, 3000], + [{ start: 1000, stop: -7000 }, 1000, 3000], + [{ start: -7000, stop: 1000 }, 3000, 3000], + + // N, 0 cases + [{ start: -9000, stop: 0 }, 1000, 10000], + [{ start: 0, stop: -9000 }, 1, 1000], + + // P, 0 cases + [{ start: 40, stop: 0 }, 40, 10000], + [{ start: 0, stop: 40 }, 1, 40], + + // H, 0 cases + [{ start: 10000, stop: 0 }, 10000, 10000], + [{ start: 0, stop: 10000 }, 1, 10000], + + // P, H cases + [{ start: 100, stop: 10000 }, 100, 10000], + [{ start: 10000, stop: 100 }, 10000, 10000], + + // X1, X2 cases + [{ start: 11000, stop: 12000 }, 10000, 10000], + [{ start: 12000, stop: 11000 }, 10000, 10000], + + // N, H cases + [{ start: -9000, stop: 10000 }, 1000, 10000], + [{ start: 10000, stop: -9000 }, 10000, 10000], + + // N1, N2 cases: |N1| > H + [{ start: -17000, stop: -8000 }, 1, 2000], + [{ start: -8000, stop: -17000 }, 2000, 2000], + + // N1, N2 cases: |N1| > H, |N2| > H + [{ start: -17000, stop: -18000 }, 1, 1], + [{ start: -18000, stop: -17000 }, 1, 1], + + // Fractional cases + [{ start: 3.14, stop: 6.28 }, 3, 6], + [{ start: 6.28, stop: 3.14 }, 6, 6], + ])('%o returns %d %d', (param, expectedStart, expectedStop) => { + nodeTest.chain.latest.sequence = 10000 + + const { start, stop } = getBlockRange(nodeTest.chain, param) + expect(start).toEqual(expectedStart) + expect(stop).toEqual(expectedStop) + }) + + it('{ start: null, stop: 6000 } returns 1 6000', () => { + nodeTest.chain.latest.sequence = 10000 + + const { start, stop } = getBlockRange(nodeTest.chain, { start: null, stop: 6000 }) + expect(start).toEqual(1) + expect(stop).toEqual(6000) + }) + + it('{ start: 6000, stop: null } returns 6000 10000', () => { + nodeTest.chain.latest.sequence = 10000 + + const { start, stop } = getBlockRange(nodeTest.chain, { start: 6000, stop: null }) + expect(start).toEqual(6000) + expect(stop).toEqual(10000) + }) }) - it('{ start: null, stop: 6000 } returns 1 6000', () => { - nodeTest.chain.latest.sequence = 10000 - - const { start, stop } = getBlockRange(nodeTest.chain, { start: null, stop: 6000 }) - expect(start).toEqual(1) - expect(stop).toEqual(6000) - }) - - it('{ start: 6000, stop: null } returns 6000 10000', () => { - nodeTest.chain.latest.sequence = 10000 - - const { start, stop } = getBlockRange(nodeTest.chain, { start: 6000, stop: null }) - expect(start).toEqual(6000) - expect(stop).toEqual(10000) + describe('blockHeaderBySequenceOrHash', () => { + const nodeTest = createNodeTest() + + it('gets block header by sequence', async () => { + const { chain } = nodeTest.node + const block2 = await useMinerBlockFixture(chain) + await expect(chain).toAddBlock(block2) + + await expect( + BlockchainUtils.blockHeaderBySequenceOrHash(chain, block2.header.sequence), + ).resolves.toMatchObject({ + sequence: block2.header.sequence, + hash: block2.header.hash, + }) + }) + + it('gets block header by hash', async () => { + const { chain } = nodeTest.node + const block2 = await useMinerBlockFixture(chain) + await expect(chain).toAddBlock(block2) + + await expect( + BlockchainUtils.blockHeaderBySequenceOrHash(chain, block2.header.hash), + ).resolves.toMatchObject({ + sequence: block2.header.sequence, + hash: block2.header.hash, + }) + }) }) }) From 0f2c913b1af54d07599dec340efbba982a855027 Mon Sep 17 00:00:00 2001 From: jowparks Date: Thu, 16 Feb 2023 15:29:34 -0800 Subject: [PATCH 29/43] feat: Add viewKey to Account (#3446) * feat: type wrapper ViewKey * feat: add ViewKey to SaplingKey * feat: add viewKey migration for wallet db * Fix migrations so they are future proof * Add VIEW_KEY_LENGTH * Fix schemas --------- Co-authored-by: Jason Spafford --- .../__fixtures__/memPool.test.ts.fixture | 794 ++++++++++-------- .../data/021-add-version-to-accounts.ts | 117 +-- .../021-add-version-to-accounts/schemaNew.ts | 83 ++ .../021-add-version-to-accounts/schemaOld.ts | 77 ++ .../data/022-add-view-key-account.ts | 64 ++ .../022-add-view-key-account/schemaNew.ts | 88 ++ .../022-add-view-key-account/schemaOld.ts | 83 ++ ironfish/src/migrations/data/index.ts | 2 + .../__fixtures__/blockFetcher.test.ts.fixture | 436 +++++----- .../__fixtures__/note.test.ts.fixture | 20 +- .../rawTransaction.test.ts.fixture | 104 +-- ironfish/src/wallet/account.ts | 5 + ironfish/src/wallet/wallet.ts | 2 + .../src/wallet/walletdb/accountValue.test.ts | 1 + ironfish/src/wallet/walletdb/accountValue.ts | 7 +- ironfish/src/wallet/walletdb/walletdb.ts | 4 +- 16 files changed, 1155 insertions(+), 732 deletions(-) create mode 100644 ironfish/src/migrations/data/021-add-version-to-accounts/schemaNew.ts create mode 100644 ironfish/src/migrations/data/021-add-version-to-accounts/schemaOld.ts create mode 100644 ironfish/src/migrations/data/022-add-view-key-account.ts create mode 100644 ironfish/src/migrations/data/022-add-view-key-account/schemaNew.ts create mode 100644 ironfish/src/migrations/data/022-add-view-key-account/schemaOld.ts diff --git a/ironfish/src/memPool/__fixtures__/memPool.test.ts.fixture b/ironfish/src/memPool/__fixtures__/memPool.test.ts.fixture index 8612fe9885..fde01e5680 100644 --- a/ironfish/src/memPool/__fixtures__/memPool.test.ts.fixture +++ b/ironfish/src/memPool/__fixtures__/memPool.test.ts.fixture @@ -1,20 +1,24 @@ { "MemPool size returns the number of transactions in the node": [ { - "id": "883d1f80-0cba-497d-8f48-cffe5d430cd8", + "version": 1, + "id": "2ab6f7bd-82a1-4e4f-a86b-6ad4308474df", "name": "accountA", - "spendingKey": "3166b46f21dc123cc2ac1ccd0e42937f3653fcb6cee530930a4e17c9da7fc753", - "incomingViewKey": "8c6880b2322df338c308104024d9948f8b71a51ef81d2a3cdcf248e71d3c6b06", - "outgoingViewKey": "b9681cc05065135a1ead0705312953a1e1190dfb95af6afec375221dbd4c35a1", - "publicAddress": "a4c951c1b2b6c2508e9ef942b8b9cde5d7c39b7cdcff1e8572585ef232618195" + "spendingKey": "da68d91a71c603539bf27661a91b62abe3b2ffc77f9056e2b482070e2bdf8584", + "viewKey": "f8b89d1d8f13143dcc4dc52a25927f216bed82309d16dd21d3ee54a64c7ea76a6260d58437798f4ab2c0cca4cc22655f4dedb970a051534bc5105aec2b659e82", + "incomingViewKey": "aae24b551a875ef5027224f06802277d5e33c837fd0994493546b1ee48ebb903", + "outgoingViewKey": "1077ac0f8aa32fe89ac573ff33f6ff83af35b9bce31cd69cc2dbb709da6e8566", + "publicAddress": "478a0970672660f514761549e821e8dd051b81af18777df910622ac4d823df1c" }, { - "id": "15ac3a5d-ecac-43b7-a3f9-578ab4e3bd35", + "version": 1, + "id": "257f31c4-b03b-447c-bfd5-616f59544bd0", "name": "accountB", - "spendingKey": "9ed994d37e4e24aac7de7b1b04a2d78d98cf9d1ba83eaf5ddaf32efa2f7abd06", - "incomingViewKey": "f38d8d82335d9364c4faea258ddbf7283ae568df2ee9f50cb9e90fea3bb2f107", - "outgoingViewKey": "ad0cf160f2f7ee8b105aea278fd3e5da1f88a8b1479143cf1a0ecbc1cf9a7410", - "publicAddress": "f29b2c87b36a70f3bfd797b5cd3bf718329f69618f3fabd18d5a7965a7fbccb9" + "spendingKey": "de7a5950225f5889def1e11ef77f253d7640b5cf614d5fe43dba28806db41373", + "viewKey": "3ed6f40a775859b3544c94dd00e8571071f9ae3e805934e5682e5889824f098d7ca41dc142c470364d4bc65e18c08fcbc9f79bae9a4a8bb5d6327347bb142371", + "incomingViewKey": "2ae46f651e74002a60b57c53cac470992b466d68262edf9ff26921d54aec5904", + "outgoingViewKey": "e73cd32d43c9dbdfe0e54aa7f3a3fc8870799478a67318adadf70e5c08e4563f", + "publicAddress": "122b9cd8be9d8002f1e3c8642144beb7919f5cfe19a3a9f993054f4f318aaa46" }, { "header": { @@ -22,15 +26,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:Rzh/imhjvsB6uoaYHLH2iax5pMxOjjEW4/Aa6uBssEs=" + "data": "base64:pd0+1WQIgUN8dgZHnPucQQ6E2qONHhJdS7XkQNYnr3I=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:4rsusC84mXrrXldk9kbtuc9NaTofKqZg6f6oPigbrPM=" + "data": "base64:nCvypr8H3xH46vm+5eRktL6SV0NjP1onhbvb24YmDoA=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223145528, + "timestamp": 1676575072981, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -38,25 +42,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAXJ54ukVVr6h13Jr3aTUna/O+PHUtsgY+4z/08zxRJ7yvuWksc2Lfh/vaxwb5yVQ9E/P1OOLC0ChIMG4MRsdctuS7ies76AZmz2QyMcadrVKpPsnWLXR0TFbzGLoVKRs3osppk8fzohks5PWjt5Xl5gx9hb+07HS110tSCvljdHMLDbqvcZ5hOU19M1A73HPHNBIzietNzLGn/6MXDlkSI1NG+fYm0hLPf2s4XMLLEEKmjrtuPH0MMWcd6CBtCeTyXSLxdWfIt7xjkcyuhT/ncyOr4Ma7Ny5IkCS5R41Wm8bOMfgGUOkYZkjoBV/ZkmYUabjI/gsL05yafftjlEkywvprAjNpI3IZEO2rrY8sdNlU/VjXjaftkZE6Q6hAapFXwjcgjusr1PGWJRaBOdHsTsU/Ssqg0nNrRDPGrs3ZCMfB4QL4MEdhjWuh7loXW0457Mxm3VEUY7nAldx4w+n28TF7+goqp4AOXRYc3SartQGpqklLtglWNWATqOex9qh0VsT0D5LhQusHepYQGKB2toKzfk9C3vHWLw0/w2fkpu6bRnLJiP/r+ZyaRKGFP/HWjXUzepNeaWp5Cm+jif/FwD1+vIG8LEVqanqZntNWJ2mEz8b8txai8Elyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwJTEKtplsxsWNGhJEdPEu4V4v7hW+WUrkREP/dNs62IyLJplXlSPHf5pDgy4NGfMEVTK4tCjH7PWFQ+FtO/9TAg==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAKb6Se0C6V3ZALpWGY2tMt0WKfhVQgydpvpN8ZFLEtnCD7zEWxxifyZ9HyaX5qco1huvZjXQAPtjadg7Sd3sej2D3KGCEeYPq93sUER4UeoOFgOr6d+K/31aGg5JIynEuHwQyIJvpSX93nH1+Tz5F3SnH0YK0s4mXneZpm34clzoUQjd02GnAy3yqsPGlhGwpQ/k5d3s/vgGh5wFUbXXL7YAOOVCNfhwsoEFjqjkXJyuOIIQlj0G5nJPcQ5NtaLWo2Y1P/CT5/l7/IBNBij3AgdZzZR1WavTbveObuyByoyMAxMQJNPrZ0qvMyZFrgN/weLCi1AMss0TJX7iPBn4rvbaKhlSyCqrJt6yJ6scFXlTYHZ/gNhlDkaiSmLBcvHVvgKK6AJvBH42wMeJl9UiDwdxE48gbiNBG0AIbn25ma5eJskL1SmID5D+cTgMd0SpjeMjkjfYmyugLIV0Be0hzQQESymzKBDK01yCPRO0DVOJPk5LtvjRTWlGf5imMXKhZULNaI+l0CQnZ4h+9ISFnlx235c3VFNK19BvgTG3n6oqS8tLgT1bxYOct5eFTsjQUY89d89KDODS1JgNHAu4F+Xz/D89pfbZO6FA7FZuAm/m1ygP2l7m5pUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw7jfaff2qfL+Mu+DPiXDf0VoGEBJZaKhnBP6Zalwsq+WQmILZN0z57oj8g9gLFeeNGbTuDjgFtT7Pg3E1utgzDQ==" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "2A3F92135173A861988A26A28142A8729A07BC753D7F001B2F406FCA4D937C01", + "previousBlockHash": "D5C05ADE7A81BB94DF9AEA3852EB0E0FB1532F433583D30D37CCE8D4A1716449", "noteCommitment": { "type": "Buffer", - "data": "base64:jsLGF+Z10wORVhYxRhysEaQgAZEgOUKxgRmYMM1/wwo=" + "data": "base64:X46tNFs8PUuh0RSviH3piebKejeLWBkniOLc98TVbEU=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:iC4BdytqzsNl1rNEtNdBFzUF8eW55NmXIuxLlOFsBB0=" + "data": "base64:3LJIUMIW8RFkwcrZBICqRTb4T/vPdCAO2YA602p+pR4=" }, "target": "881271989446208257911980828427057262643615932976441214377264856368067535", "randomness": "0", - "timestamp": 1671223157488, + "timestamp": 1676575080465, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 7, "work": "0" @@ -64,47 +68,55 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAgd/rcVsZZm2kHDPrwcZ2GKS1fZNDH1mdrRfFXWL4SW2gjZqLweLhzI9c1ZLalpIiCXgZfaFSH4IedSs8ChyRXzpIRxVVkzQsGjQj1UhWT4KD9LPig+zchuujaFWA+bLnPqtaJJmdhra6mDWxa5RWHc/b11dngkPaXjrCp5m+LjMEVOs+AkQa+E/6eh/DYrHxERzX+bjHHoGsbOvBxjh8oQTuZlHH+J9duol2QyW5r3qi90OFWYoehjhS1M2QSGjaKUFNY3M64m/D25pZQkS/Ow4xA4bpG7ZC9i4YMx/g+x2HoiZIkl0iafzLJq3my/QPVOTNi8ZuzO9tWRY4aXl10bjKL3NNWkqvN63tgMbB1eRUbezeBuMN1yWczpSnqB4bBE5L6PSkEAlKGlbVsDTyg+7CWaIXNetF8R40OJuQR7P4u2cqLFfQ4a+qaF4nJAgajD+RwXQ0GJ2gHpYx9zXuQ+slhIbPPFp0V8w2Elg8MAXlnC+grY/+4twhrx/uXFhsT66fKaQEPCK6mHtIyBU0pVz+cFfal5/R7NDEg1GB2qhSOCAj2TnPkXaxBuMhUOB+d4CvQKAaqjL9fo0jNorPrcTSYsDwzCxwJzwvw90UMu0Cm9f3CplbHUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw1wmme6izo1sRiDw0nxy8DyfGVe6YW9hTcdC/2t9FVsiNpRZugq2K1+gySB3yaFsRowsaY/mOJdPrYcNV01YQCQ==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAYNXUq9NAXUK9lWXn96/+VDinCcpdZ04iBn2rzIEpiCyYlgLqo4rJuiG1ECZuNsI5b3sjR+2nHvGu7fPQSc2MXU+POR2zy8K2Ipw1mVJlbxaAxe/X1ry0A64hoX8uHRHGJkPZElDHIvESfq8SS6WSdPRczgokpCoBfpSdTcZ5oJUZ7RLwPn/Hc9IUyo4pgQghxNDWUu5ZFDwXz7WsMkJ/AokdhqN5Tqi+vMJhuWeXihiZ9A7X+r7GwA4Ml4qPbaMs9q6CIWBYrytq0kDtAlfwFH8f4tsewxVGLnt6vYIbwxRdWhLNhp5vjiwW6ZZOyhAx8cGXVZJx4RDcdCSFJqB6rZsvoQ7ZKrd75MNK11odcCnd58aTAx2deVvryiBMSjhqPeQnpk3s2OBq+0vrqy3XDwFAfFsySZ9imJUyYwBJuZIv1fp+52EJdTwWt6y64sw5KVcFYKA+xbGU/0m9mnCPnVt6KWGxjbILac0ny+OT6Ry31gLZXprCml1hE0osSBJZ4zsvkIdcFRssasTlMMXJOJYWrwOih+EE/Gu8hx0Ra7Tw4ilb1TrJ0mUj6okaBsHxK0bUSzJcaz9v6/ue4pnEWZPl2X7JtPFqaWGYV8UoG9CqQ33+VAEyS0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwock07qis5ggySCj5ebWqafvKPbmdpiNa5OvWsVQ2edUDdtreipt0u7jT0JSlHF+g3YBVpchuP920vtqU4TmIBQ==" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" } ] } ], "MemPool sizeBytes returns the size of memory usage for transactions and nullifiers": [ { - "id": "fa7e8809-d61d-4128-9dec-6781fde8ad37", + "version": 1, + "id": "073358fa-181c-43c8-850a-c8f97f589f18", "name": "accountA", - "spendingKey": "0bb60f48d8080ac95055a663b5bf1c6ec8654f99d1e3b3049042b054a8bccb59", - "incomingViewKey": "11fe008efee170fe6454e7394370e86cf843f4d8c6b10b664a1824b1c7d7a505", - "outgoingViewKey": "c7232fa36efcc47df5d98ce765f6d3cd87518200e13ddc9f28401c6539769562", - "publicAddress": "ba62e0fcd8595f83d80343825732dd9fff6634932c4576803b9ceb4e60ebdd6f" + "spendingKey": "5ab31ca7c1892045978c0173d308f591e374912ea6caf87bbdf54ebc32328ff7", + "viewKey": "e6443ca5de2228633e736cd9bae4793c208370a02e61c9488c253b0564d3bf8e161b9afb0a55c974390ecf2bd7815bbe4f0d9ddb63ada97602d4db4167ddbee8", + "incomingViewKey": "3822860c13ff97487f09f0664cdf1c547cedb37c22b269d73b53cde9f7c6d506", + "outgoingViewKey": "590795173d2c60e0976c1520cd961f810b29d6a731ba13717345efb60e7b960d", + "publicAddress": "6f2419650a9c1895f33f68f6629b20e0dcbacfbc93923df05e77a07e806815ba" }, { - "id": "ba930967-4700-44b0-a0d5-2548c734bbb3", + "version": 1, + "id": "ae4ee0dc-f3c4-4132-8a9b-c0111edbeb30", "name": "accountB", - "spendingKey": "dec631222dd0136686c0603996c5b774e3976795c5231295e1f74810d5dbd45b", - "incomingViewKey": "584cf9c24c234f9bd5031389da43353aafd08cebd35d68dc4467ba8ec5c3f903", - "outgoingViewKey": "860141bb33d91d327e78334d9445d21d38b61ca532228d19d4542c6b68a5cecb", - "publicAddress": "c85cb1e2bc7c8aad903aac8497f0db6e015e03c0efeebbfa8df8149928c242b0" + "spendingKey": "58049698fdd64389539184b562a79ba3e2a92f52522239058838a7f64c5c711e", + "viewKey": "c1e7e7c1c50c4d82eb68612dbc9c647004948a9a5b5912fe6ee358c0cecbdd60880c0594a4ce4aec1d2714e3b61326082680fee38f1286b0635096a44e98ff99", + "incomingViewKey": "6422ccf9ee262bf2b140049d7f237da4a23ceb707f35bafb87e567ce9c4f5e00", + "outgoingViewKey": "a245eb4ec65e74b26391b8366472eec5c78172bd0c3f67308d7ff260699b6277", + "publicAddress": "4b5130db294323cf6faa527a66a675e6e4f97c8708da7b431ebe715969a59161" }, { - "id": "90b4b2e2-5aa9-41db-adca-892d4810117c", + "version": 1, + "id": "5207e8eb-b554-458b-ad83-440593f7dacf", "name": "accountC", - "spendingKey": "d11271bd41af0faa7159f0891cd18e31522881a318b419de3381eb460ff7a598", - "incomingViewKey": "dbe4090caa98a01194df30a350c7a5afd8ca3246426a7d80dc02e6398b28de03", - "outgoingViewKey": "41fe3beed9f5bb642df597d1e642e49b0eb9c843da8f6ba3aa45e2c621624257", - "publicAddress": "bd9bc8bbd7ba1a1993fce1c25aa64a90b3b0fecafebee6df33515f70608c5aa0" + "spendingKey": "cec97560254bc23349f07d0d01edfc9b1236539986da03974eb19e97b9beeaec", + "viewKey": "7cfb06e02a8f2f2eb689d363ef3fd134467ab60660d772667224d3230a7ec4bc5751c021664e4b1da8b3ca3dc1d581b0efaa3665cfc57ee85100a0feaef422be", + "incomingViewKey": "cc4093e4d42d9d310a16cbf46f66524dc81adc4ff8164fa9858e20eae7e7e701", + "outgoingViewKey": "4a2036724f57ea84a1d58629b5ef3ee5251edd50d487e3ea23a53159d923d41b", + "publicAddress": "d21d4cbdc76623b6951f4c13fa5edec8641fc1f9b571d157cd616b8e1650cbd4" }, { - "id": "353c6924-4fc0-4be7-b50c-20f5e50c36ec", + "version": 1, + "id": "09a799e7-9602-4044-8fa4-d1884476aaff", "name": "accountD", - "spendingKey": "a815f43fca9a47ca8e4ec75b892f6f34f1119966152af898f399d05a7def6f54", - "incomingViewKey": "9ce6e26368e14282e0726358f5990c7fc7a4f4fb800aacb9f6707e52fb1fd107", - "outgoingViewKey": "59a4b0b5566dac09702ff687eca66e630b12b63e6662862ad9276cc747393f5e", - "publicAddress": "c437d033f1ad30f53de02a19d6fbf0a26130af85a1b8f1db1ddaf8eeabc6d8a6" + "spendingKey": "381bd0bcb22472d2e10666c008a32a94d14571065cdb9ee349b72018c340ef50", + "viewKey": "d031b1ee487d8c40c1e35c2f33dc22a71d7a5fa35fb7d3a058168c5224175842e4544bfd69859dab0914bfd0e0c76e4f0f97edee178794ee10ec9af3ef4a3ebc", + "incomingViewKey": "0ef97c219b5ee1d59f957aff9ff816cc0bfc62409441e3687768ae968923a107", + "outgoingViewKey": "fe0d1f2cf1031129dd7003a560714004ce231620a3036da3640fa41eb991605b", + "publicAddress": "4113ecac0a0fe7af2a7f7e95b6eea0270aec6a8ce7c4ea539495ddd8360e7089" }, { "header": { @@ -112,15 +124,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:USiVtR0eQrm4E6A73PY0JBB8l5I+8HiY+Qc8GUVNUFY=" + "data": "base64:smXxlWK57eWRsLnapmetoY+ButoatkZdWrMimsS7FCk=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:BUyldSkkeveb97y3MiSl4R3b+mVWK9aEvGaFjB1NcJA=" + "data": "base64:HMtoVcGQjPW9dWfVd7v0qrMxjNAGNn6oBZ7BhzjKAmU=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223159665, + "timestamp": 1676575082292, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -128,25 +140,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA7zAAUTVx270w6ETt2gMQx5gO3Ct6edf/tNpjGnpCu8az2mLn1N9wm7K3+Shy2LVlRvXlgEMAbKCqdDPSK7PHmWYzQ9KBgL4DX8zDTKzBBh+Rqr0odH2eUCOhWJSc8o+v9bmjxrqaxObQ24aRixyPjE+LluB2JVazVxW3xXn6zOwJJJ5M8NB1pmNbQcc2u/bODeFWhxKoe0Bv9EukE6QjLc/mhRGOfmVybz6YfD8qpECMF+THw+zT4ekGI6rrqx/VMawpGVKxCngk9L+v6Vfw8luAXGFfw2QH/BVbl6TSRkjze36E48LM/YU4z0Ztfp+vu67DQzg9IoxWoNnFKBdUIuuwWlHAXnIL7wH17DhM0IU1K+Gfo/tjkL/FlMHombtsrQM9qSkFiwbQSN1ebFIqHxKCWcSibiSQbbJQD+Pgs+djUhpb07V0uDhG9pdTIBXwSqOuj/XRgtIJFi8SM2Nj1sA/IGeplQucwpE0i59bPDPoKsJu5J0GM7arKzqweN+sFUsWG72NukOjVjNAsIqb5R4IuLQWwMZcW0Z29/8CLxAfk7Mk/rFRQnOL4xll5txwEuYQuBi7WN3LvmidDgRNF0aUhVheHi1zvo/2i5TZRvEBJBR7SO1TkUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwZ5L6gbQ0FpFD1ht0NvnPZPhHdc8rdqgtki7kipewOmX5uu8l3ImLgnIej4hfR/jTCz9uUNu0v/5k9q/lYjxDCA==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAogiH0UuxYPmPVOEqQ2C3SMqEOVi7ZOpHhRkmO5x1dHCprPjdEdfay1n/nmB+Aru8UcgUJ98m6p6/4nQcwrp6KNFksj9rWUFkJH1NjAG88L61+LYN5JEQTUOQxqwGmhPE6ad/1cwC0z3El3LopTU9iLQkF8mLbE/2WSkrzhzj82YBAsLT3LxPf1oNBFTOoq1QFpGuP3L0lw6oRjyCkiRZqeDmWBl5BSBjwNeNGDJGxhi1YL8DUiPgpeENT+6hJBHEgNBKSd5juoHBH6/zMt3yCDNp0+bwenDRN6qOy8a5CGuJhs/x8DjFcCvT43g2oQX9HmVYHGO0Ethy9vhAgzWXc+GNxrp+9K6Qer6R5G+74Vfgc/jtPbtHnw7ojfNkMdhLJfh8NzODDMye1vJh1KExHysEoYnwMMcaJeYtHf8iiz9zcAaqqrJU/zKB9sCE4MUeyZ3veZED0m6z8b0xBY9I0vTQqgAavgK0HLK4fJdETA4kNAzQpzFShICju/zjeo8++CHOG2GWdurX4qgP4YOz5OlAM2VgHXG3B2ki+YqQQ6cDzaZOe3pCY7B4IuwYmOE1tGKEwSc7sQKZAjs1KHEYd2a0AevBujy8tEoIWWT8x8PDGRbqd7SrRUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwiLSIz6AYfz3tSU5RYHGFzf2z3mWb4wIsT/U3kpH0J6KQYS+CFyKc/5C2/TesKY/cmJuZyXNprrCdZ4ewGI03Cg==" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "ABC4DCA1543F1F8DC085DDC979D12D74A17F2EB0AA96E8E94BB533B7F3C83209", + "previousBlockHash": "C9A2F533E8333DAD95C0FC0DF6A58DB943EAD14343B01AF122C6B3F661097929", "noteCommitment": { "type": "Buffer", - "data": "base64:gKhMZOUCa1Iw1ZyoTNvFARoEIbcdMWV06lrMaZOIoxs=" + "data": "base64:Qe2hHkgd3L7WK63OoT+ZMLQ2LNSIdLfZsUIwEozD3TY=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:GFl4MHRRD5NQyLfd84j2h4pgEN4ytYfkiEdMnqhPsDs=" + "data": "base64:3f99FNAaKSsHLZ4g+mG4uWUX7e2S7lqCPqq3BV56G3o=" }, "target": "881271989446208257911980828427057262643615932976441214377264856368067535", "randomness": "0", - "timestamp": 1671223171667, + "timestamp": 1676575087898, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 7, "work": "0" @@ -154,29 +166,29 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAY9GrF1lDRDWE/TS1fURCzEWVpCF2vmRJ+xOMCeBNVb20BsBgxvP4k0LzoMnVQ7s1vRLZ7YshIc93m8cnCrqN9E1eq4MK7Ct8rkwq47+i6qy3BCGWoqkSLgWIF4sW9mkXAoKXr2xbekx+H2Cd+/uCCJOBTIDpbcCt+waPjXSp/9wDhoc9xSf/3Ds8g2aVm1hmXF3tyie2n4BS0wVOImGsKE6+BtxuwhZCPu3HZD2fdC6Ol2OeNX7Ep5KHYA1bk/SIFmw+tVMhWJMMuIlWfPMKabgEDchmkKWdloPJMhTBsjDoy6r4Ys0lmKQEj7dzb3chiqDpQKBaggMj2a/QjwfnVsAl2oqqzPBVeFiG7Y1So6TeUyIjMbgQNALLtXIHRWYdWHCYZuOw1VJzrbPN37mIl8jMsgW800NsP4J7HBUEGh/f4mpEuDyHhefY15TyHq35FT+umvbhWUg/2QfQIrVNdyqkCM8vN+UX1Zs2KOTAXH89JsE4nTSkt1E6A2ZcyHRMGLKzOxk47C8Xycl4FnW+1wi8RFJy2y9yxSRsMnR4YVwnGYeI0hJ17p0CLuHMn+aH55DWiX4PaWPyB456Hu0dHErGIPl69ZCUo9NMK2vUW505YRCfGMNrR0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwPzlZCLicO+FCduBeDuMc/XJEqKX+CNmN1v/tbM+R68kztNC5GSpSPCQKBNdjgCj8cPzBU9VK5tUHthz6e+skDA==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAaAcDKeF9eZ5BK9DH3YPjP5ZTOxa/HlwNucijnWawxpuD49yu9dGGktHhq6u2JMlYSflyAlfJ+EQWmD+2XSxyVm+EPmFN9FYEeKhU1FDMk6+KoHFf55XCkkIRPyW4/siSH0m9RdTcCnTaC98A+Nbe68MOJgQYgrzI1cxZKpTK2JgKrpXmCiCGkVKKB9lSl/ET7Z3r38aJ2iyRUG5tX8GNsAZ5fcRQhg5E75/kTdH1wn+Ljq13/YtfS2kGJM8gygzUXBW6UcyKWvQgvb8MFfC+MG68ZPkkeztb+6TziP1QORMljhn8OpfCz8YFPWyQ3ZgIFeMPc3fVLxbG7DM2DCxgEhhXtbCteAZMEtDGv9A1YNWVR4L5htfzXJsMKypiqOtJRx/MrRuP2qVNzWl6WYzT7pq414YBEuch1qPZ1z3CEAjbjj2hokGHSJ+FeSICqwOosWfkfZfycXWf7Jh0Kze7zIhlDeu/cApGN9WBdDfCqKw6uA0VzXT0ylCiRUVVh80AbFuNAUxJrS/6a9Fjjcv69VJomkEDi9v2UL5GuEZjc1K77ehNWBhj4F7BSdLBTGzaLi1EmryHjJg4QBdOJXpXdBh3WgeiktKY0ZNnu/y0oDX9Y1bTNctZj0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw6dBx5pCtknf+T46AhQiCzwQRQpsP5+lFzWlvYMRM/WdBy86u7PA0e8Liaid8qcZZb/TCkU1SfEnKjLakCqj7DQ==" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "ABC4DCA1543F1F8DC085DDC979D12D74A17F2EB0AA96E8E94BB533B7F3C83209", + "previousBlockHash": "C9A2F533E8333DAD95C0FC0DF6A58DB943EAD14343B01AF122C6B3F661097929", "noteCommitment": { "type": "Buffer", - "data": "base64:xS5K/xaJGUR8Oe6RXRaDZK9DDc9scMkrzXIFX9htDFI=" + "data": "base64:kqphHQatbq438jOMcaSHOg5rp8hyzCXXjFEC5DJwC1M=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:8hZQu6CjVJXKDzbGcAgZf/HoESz0wzrxrF4Y3yW0jiU=" + "data": "base64:yc4GDiyl6qXBcd3JHngTDFaEbDgc/RtfRnm4tWGblWc=" }, "target": "881271989446208257911980828427057262643615932976441214377264856368067535", "randomness": "0", - "timestamp": 1671223173610, + "timestamp": 1676575089261, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 5, "work": "0" @@ -184,25 +196,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAj64rK2Tb+pFD6UIfW3TbyIDkExuC33LLDH/pyuG4pEy04P3ENkuTN2w82VHhhT8QZwRhRzMb7ynsqH/ewZlqr8EQCeF0k9aYv6XFIcdB6uSrSnCP9Bh9eLpymUn9/gPL9hHV2fb1aet0rIOsW6aA8KkTmPhW4r5ZPxXDuKuxICkSmCAF+kCOIOgzuIUnNimWzcbWjXmS5MCX8epuz9f32dcqkxkGTh7Tq5Q21H1LsD6vPdsrBGG38w+pyaH9BfTsrQruuERw+mz0uZip+o4NW3VNJ3qkWj0GWNspnYklWqO9tLk9/Axn3NnAQyWPpXhiiC38EvbpgchQ42lk5NIeFHZXbf1xrgZrmMvB5D4ua5lccpKL+O4pVcPdj/DHO0cY/EuNptEOhA4c2V+YyaSBmQBjCmccqHzzUpqtDzKSxOU9Smk70OJYp2Xa0mA1XCrexNR41b92+lAOCnPLMag8iduZvV/8BDWldvM3+xZ00saxU4DlDYKam03Fu+LrlkSeO3wAFytxgVh5AyPhts+5OZPKfeO8jcrwG4GrZcmT+50eZPl4Fw6FvoK3HKJbX+CLu6dEtZ0T9LMGmMF0sfQwuNHpMaYF5e2jwC503erEaw6JMz0WN37VFUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwGiJh25l3dJ7ybqhqRUrkCyVYatMHFqIKWHrxutIDO8fE+uYOUvMDtPJbA1NOfmrFfPnQKTmZmti5wa4z32JRDg==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA+z2K3vvLhxoMBV7VS9L2mtenc/sx3smS8icjStWMuhO0uiciZ5xItE0W0Gb4Dh13SCzM8ZLLOJCIlfLuKuUdJQ4AJwKYnjJpuPBSzNblMUalYTLjIQdVdttex38C0qF/aJCgidvgFv5OMxeaozqNONFAXzkWdYmIclTpiIjAGjwIDMtLjEyqLTEg9ttCd8sC02B6HKwK/13vr7TBwh2H6SzPuFLWlK0ZPik1SZXN8oaYidH5EmmHhc++UYE3vP1NwIQsIJv1aY/4Ju422IR3Yb8/nUSvAsc1RFebxWm2+Asqkmn77jyKT3qzQ0Pb53zlaUHG5Koev2SGOF7//zx/vKUlL4nvhxr4w+l2W0isrvzkdmKbRtn+0Zsuu8fF9sIBVWtHxEcWBN5MBJ/DDvsGA8z84SzA6v1Y5G7W1KmaM2eSfqO1SjcfS2hGmR9dCu5928RUoAk2h379Qq+KLmnSbh7n37VzXxgt1ESDNYsjTaK6UXlK1r9PZcfqNBHtBwpciA9/T5uXNJPArGpKqqsPjlIXz94j3ZfO+Q5SuYVfj8DTYfUsVPFPbICiQpwxyvvT/QtJ68GwhFvvjxBldGtw+Z+QeKagM4cbyH24yNrKTMgRlUgj+Ble/0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwQSj1c02ZVL1y5xbMdB1mTU46y2Mk3UHLW5L+gGuWtMCYSIcMC7mZLbWZQqnkRVMtaIQZoKbJzm5FmCF/Q2whAw==" } ] }, { "header": { "sequence": 4, - "previousBlockHash": "F0E8D5DA00142C803358466A54DBCBE36020BA4D5DEE84D2E0B8A477307AF1FA", + "previousBlockHash": "3E131720EA7F4BD46CBA99AD212775F72A3064AD90576BE3C7B9C1A39BF6B9E7", "noteCommitment": { "type": "Buffer", - "data": "base64:P0JxR7HSee9Rk4VCVw1Qpl5+eaVdLvhNgGl4igRWqWc=" + "data": "base64:6rXJIvySYEhFY50uIN1/63qFxvAsXW9f4hvO5lcfTDU=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:sbdtTK/kTEd9ZAW+ST3a7heZjYjndzucYFKe+E8esT4=" + "data": "base64:ObET+BZr0XBJGoGKiLMMzqbdUQtI8sQnIKa0fB0CyOo=" }, "target": "879130901036475001697423051875971117690643105150939656519205417941517322", "randomness": "0", - "timestamp": 1671223185387, + "timestamp": 1676575095150, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 8, "work": "0" @@ -210,31 +222,35 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAKwTUeKNBEcI9182Scqd7h7tI8Zfk+9DUF7VFjCFD6mGn0eJZNzvG10FBdaevKC15ObaFxlnb6bmodNWUF60e5+s6ySceyTq+xF+KtEeAgqKo1kUdAIFhytJ33Fp5DZ59JQ1BShjzdMkjPRD65EZcLDS8JhyBXHL8XcTf01SUi84Sbh5/hZB180lKk8MiJn9sDAyUxqTCmA9qYMrFt8HdNLgr6XXpFRQLBsY/BDsMng+ONk4+94dV0GUOTT9q/x0DlRreA+s7oVclDueojtleRxCOQiD8MKKgFg8gjPcVTNQ1AyrXMcazlb5BjJuBFqf1zwLGUPlhc/LAe5ya2iZmLaLj+/1S4Hn+q+w7aRwkLEtsIW/Xk4VdqrIF7QoASl5ckmgOWHKbuuDN32BFN/LzblgYSC3yvhJjuadlSJl4ieDCfmUvCuAIMrGuy5VZ/fSuPTbqMofyzPwhRMKTW2gaz12l1yEqAOVjeqzfks7dHB+eUspNmYcI+qQuN/TRGq18tLPCmua3qPYbXaf6LZhei2YCvHiUiXHcT9UbIVg81fE/KFqMt55F42xN7ZcStNotwtTgmTFcoVQxf2dL0oq61Yukoq1bxMSWtwMsgyX5mlqjQLdQIyGHQ0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwWVl18eOdp5i6yhon/N+xmkv9ce/2Hj60ZWAFJK1Yn5mDhkDb8KRuORidbH0ofC6lUyDBN2AbsjEsMuUrrq/PCg==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAVa4uAo4AF85mW+AG7ssfAVZMbrCIWbYwINJeE7nYIhC2fNSheleAYwmie4BbiL/RdWvQUr0KN+z4+xeIn+2B3zaTKRJ+UFXDCAbs2sblTdm1LzMVPufNb3FynuqdVYkLK+ZTgwVMNno4SnZ3UumGLafThH0HZBcwhIqNqdfZEbsGnszmJK62hg9tidLhNMuGtiwA/jv9vkmVvCSR+KcOoi1k1g2t1FUmsn2FB1iHraCrgfv7skyqU6K3eo+RuV46cEv1M7u4V9/l0hMrRjFDYD5U3N4WYqflyo7Qs6PE5vvOCTmFji35dMUbpxgd934Q8VksLE0Ptx0NeE21bT77YixQ2zW68ndu0URWTtPOLfn659k257+uTmwJfT1jGRlxUYmljpWS4KUUXZQmH/asxRZacHpktt74OB1QsBUzGIhjej5VuPwrXKs0DEWDsyPNOY/GDSwN++PblhZ4Tzb5hUbGF24NoCNi66j4BrgFYEh3kiU4dkgE6IsaokVEocmAvfVOyShOAz5NdVPdstGvN+4VvjylQ04Z5YDSrUWzDmByXR1gPC5N2p/YOo12hcLCll2UzOpvMLKtTm7loQdUC7ONwbg00o4phx07yuWoWlELW6HeabeofElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwwAQu5C0ota7KCw8uNOpGAE1yMGiDWky+ki+ndvv5PzteGjIU5U8NJ+rDzzlO0vqAAAP4JOPKoS2rz8VOF/h9Bg==" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" } ] } ], "MemPool exists with a missing hash returns false": [ { - "id": "86d95300-a40e-4393-898e-70d686c84279", + "version": 1, + "id": "e261b88d-8132-470a-b506-cdceff349126", "name": "accountA", - "spendingKey": "4eb0a6bf80a4969796583f20610627a583a913cbd331848e421801f7d7d77b9d", - "incomingViewKey": "b070024bfab37339bf5fca6a0525e577f292eb4070804edfaf26b13c0244b004", - "outgoingViewKey": "00dfa625e6d05cdcd27d51b22adadf42817254f7e6d23291ab94a9d1a01fd3c6", - "publicAddress": "350a8fc79007910f958c64e63abf1dce9cfc0e94773a7287318bbf9592891360" + "spendingKey": "06186c4028161c1e386169b95742255954fcef3c30aa1132c3ab64dafbe9e64f", + "viewKey": "98acc889f2d5f90fe96baad70c476657b00682995cb23668f3f774790806e8c47bb61a260b42f55a9e78c1dabf051cff24e7f4e19e040c76567df6246f416a01", + "incomingViewKey": "a1296aabdb568c3913a25696d4ac22a336b13d6e64d7e16922c985e2dd65e404", + "outgoingViewKey": "20bebc8abd5c0b5508509d9769a3d83f8ce35f7de5dba20ae92abcd95c473a4d", + "publicAddress": "fed6e880c5a21ce34aad9f0f70e184edf6f0601c7b753eea422ae38da2c58336" }, { - "id": "7276d525-a08c-41d7-948b-c04133ac3237", + "version": 1, + "id": "d8e13410-0705-413f-b8f4-3cc467a9edf4", "name": "accountB", - "spendingKey": "5f6defcfcd5be18a12762e78060096979d1f0f5a0770187750ad66a68aa7dbf9", - "incomingViewKey": "d15fc9b2e5b1bf0baa758993740d88a79a55daf86f9524343bd08c3ae6a90101", - "outgoingViewKey": "531b9e7f82357dc1690798503b6b11205a3756039745cd9e3fab4631c85111d3", - "publicAddress": "1e6c037ce346f774e88413f1f666d0b2c97c4fa5f583d37dcaac4b069b22ef84" + "spendingKey": "bdcefe560d5ebd22e7af775c09be1a64dcc4cfb067639a7d11858cc04f2d81f5", + "viewKey": "c2bd9b5d43e4427c31a85dca43bc415af8e607ec0c15751c2c7e735ba3508c2005b585bbd492e569302bc52816ba0e81eddcc61de2f2e6f436eee8921162b31c", + "incomingViewKey": "3fa9f855428236000a7f1e88ac02efe25ea879faa3e4ce4b8dde38c9b985e105", + "outgoingViewKey": "eea7f6e41f918550b7474d0dffad4dbadd783d2169c176ab56473e2bec50c30b", + "publicAddress": "acb5259f658649367b238143c8d4fa80e4ba2aa710da1b2f98e8edc5d00194d1" }, { "header": { @@ -242,15 +258,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:/jYXbEWg2PKwiW4royOumxtLR8+wqyYi7DulIJNDUgA=" + "data": "base64:ZMnZv59qhiJz20jfNRg2hqEG8fJcl6/OEoibHDnU0js=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:4Kx8TZfXUzZkr3aFBwR5w6dtnRzYfhWLcRi29qeCjN0=" + "data": "base64:1lwtFxSGYS/FNPpNRvCTx0Cnkv8/O+XNZ6+9AMuNFPw=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223187267, + "timestamp": 1676575096706, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -258,25 +274,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAl5uQcH5JaiccVPnPmeyUI0Y740RkntGpLhi2Z9IKqFGJKbo0bzhZUhvbMRnro2Qfa23/IUiVcrhmAKoMOizb+0rKoXistY5e8qcAwyXJRA+5zhXA3raNC93LjjN2qTN/fBMLkDmZvjNvrfQqFih28dpoarI7AumR3+tMHJDFzx0ASxRgcpH4VfqNda/n4fcQPm2ZIVPPI6UJorSgEEkFFcb1t62yqS0S5H6H80pyKDCyE8OyOxAAON2LdOgYT8ASZwetJKl/04I17EuiGRlGRoumzAxvtDFpznaP7eSFAeekaaNXpJmMawP/NUwqriM0LIiMiC3oPmLEFjwUbUuOBS3UQ/zuckfnhrKqPG04t7yQkhALygNNQ343cx0QCQQEombuj4GPjVMg8vgjYos0NmiBDmoUa9Qa+L94l83cbBHR1wmq4FtKSbaoMeCbu+tBK6nrPUn5l2x8S7cgKO3uX+DldASPBJ8sq912SL21fl+6WyTgIrdM+aWw/4jZWjUq9IxlN4dBlxlXmeioxO6siyh8PJNB9wCRT8riQHSOyz+434oHK4yOMwXMTNnG7RU1Wy8HsOhXIaY9N/F48mDzYGlVlAue2mFuwIw3U35qev2XYbORMoee7klyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwXmd0pthi9wi/wxkC4DPDq0W852+A0CLoktN4rF9/zFH8oU0SPRoai42Rmkcl3IXaEvdVyLKKfDmHUpfoHhQDCQ==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAFrLLmj3X0XfHFfpoQiaQnqXtqTrV+yyYObfXYZnqbWiRzgcM5ta0Om+OanrWtfAjAvIVKWMtuUxliZNJtSVpt1elV9zpuCkSn1QETgc9BnqFB3A19DqqhqZ7h1wGPfzmx/p7/bHaDNpga8nD7HJ3sDtTpxnnFwHrOuDwq10FxSkEtv+DnDb7qu5E9fSA7QG4H4/t6Ia3UbJ336mj4ssuOvjWnADnjKawEtkN/22jLJCT1q4nCz+0yROT7alK1/o9F5nO0I1vPr2k+sHhpnEWB2udNd/b8t/Abt4oM9YhaKN97k/6fnLiy1Xy4BqgW39r+TxjPgZQD2oCQeWt+YqA7nlS33RW0O0hvB5+AMobABFLqfP7oFuHycq4HCxSwkgigvqUY68/YFtGo/bbnVGkmyoK5kVBzitM+pNSr5ZoMTOW+CKC6KMsSYbJQ92D348tCsqYaNUTm1zi9UVJhUa6v0MSUjWPJk7kTuOWJqugBlGW5qmxiGpPjm/EXOjIfM3L8VOhet0w34RfM4unObRRMyxKyUKLrtrjZyd5JHhefaoI7ctVf+/xlDWbzenTIv+t0+PfMQs0m2lhR0ypzufBfR/F9gngMUJzdSAta8JO2KqLH998PyEnmklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwL0D86xoBCMGX9lbnMReu7M8sRkys3AQ6qs+tnySMVd+fEdX20ukikHWvzysRhxxuhBF774K4nDwDwbXz0Uq4BQ==" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "087467E13188DFB1FDDD74883317BB2DC0A82022F59A16C5B7F12E4E0799ACFB", + "previousBlockHash": "02B0F4627678F9D763AAF3538F5EB4C782547B8A28E64026344093DF7C9DDC1B", "noteCommitment": { "type": "Buffer", - "data": "base64:Ia66P8XU0LzmEK5WCKLNqfFM9bIA9DEJd/M279T7gBQ=" + "data": "base64:e1Wy5LC+8WJi4S1w+nzE6HBl8Xzl7UDx77mjk2l/s0k=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:s9W35HjGnNHorivNzEP7U4G7hEESKzZc44dJQrPRuqg=" + "data": "base64:Sbn7JXtCGsazb403olhjKNxU7p6FtW55zTywqgxrWbM=" }, "target": "881271989446208257911980828427057262643615932976441214377264856368067535", "randomness": "0", - "timestamp": 1671223198829, + "timestamp": 1676575102265, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 7, "work": "0" @@ -284,31 +300,35 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAEaDUQ8XT7ZvAUm/K8VYm5TRiDg9cKLKfWpbM/ZDYo1CTuoi/pdBVJr6z3u7TPQ78H6hrkme951QeQTITrDD3krlTe4MJ4XWn8A5m3c89DEKw9M1fuyscmIPc6M2h01CK+osk0laPc/10Tlqz7SKKYqsquse1GyOnQwtQ/HfxxX8VkossBvEC1W4EDPn4+VlYvxOejHHXq/zzhvqHyvXH2UHqpcMM0po2e1B72umFY12SqjOcV2tjwRJhIAc/htQN66LNTPJSEsSgRJBWym8li9t9jHRyUVOz4QfG1er5G+uZNFkIQSer1K+UJWmCmqrjygjtBd0+LaVc4SDFc8gQN4ildUw8J5+5/fIgpAqKEfJJOH453gQbrROS8mchoK9iI9mStYL9smQaZKQLUwqwpNrEXzau6gOCX1WILjst+BRiYht3CGy8rlenYd74/rxUbhu97wT7IE6kDQNSSWoi7CFxvy1yMRNzelGvXQ8RM9lSD9Jl016YqHdqufChILjDU+OqcJIzVXXa6Pz1T0dM8yO5AWYzgk0r4krxop3VXNitjNGx5cJ31Ggh78vp6/0/6RmsmfPUtaGbQgyB7u/ExV6m+lQzs7KIyBM7VntNTTm/rYytHa8ft0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwCTMeHrLYFq4PRPzdQG7xJFo21gu2XMGInyxHWmaZEunkii/RNuVzq3ShS02r5cx6GEZQ1CIVAqlFn6if1ssKBQ==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAATd8vZ+zEKOar9YAOni5iz66otJVFe2Q3gD5i7DeDJ7mit9yoodTKsB2GF+DGV7d6uzNeg/UK8UHTz9xXLziAcyAOQSF24WG6POnWIOeO+zKMbAriferVJdy3y3A8gZMT4wnE43qbLpkj6YpZyZImHuVxT0jv2R078YaPNpUYcvcB7/LI9zrsIYROszAyo2Um0zETrWc/RbzQkdjcU/GB4+c20ssd42GEPjjWfixxcZOLdwc5+wC8ECT9BwetOSzM0+u8pHSQu2AR/TBZU42sDncg2196Y4VlnlWBIiHLgcwp2SbgY+DBqr0snSICxn0qNCNlV0ndgSoIMxKAU+um6YrsktVdYzByIWRxN7ZDu3gN6wqk1ZfyaFWONxSHeKkpBr9/v6IM73u8cwqBTJjUyGi/fEZ/rKyWPcMW6FnvqjOof5GnlPZWvSKlslvpXt7We+osC6QEva3uhCWo+dmaq3bD/DTPR2dHgn1jEBe0lybU16P7ghZcXOTVBWQNnxA8a1eD7MApPhpIyGyCK/dx5uwmN1U5oQZPGKfC4iO/2n4/xSZ/yUMgJco+DQaXpQnyBxMBEaJj4VeMIS0VCRKXvta1m6L53NiHoh22rC3TlzRQKTIUKAAKuElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwnUdxgyRFtUAF01GUGtMTfLu57jLGbms4xbEpUkZ9UkWD7JYY1UAy7lLGKIXQK/TNoxpmivFtl5swaSQ5ho2hAQ==" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" } ] } ], "MemPool exists with a valid hash returns true": [ { - "id": "58cda763-f214-4b7b-88ff-7f9b3adeda7a", + "version": 1, + "id": "b1716ae5-6057-448a-ad3c-841657d2533b", "name": "accountA", - "spendingKey": "c8242ed8f68790f3349ac3d652993bb09e2341140f9e9c86e10df37893d65d0c", - "incomingViewKey": "d8b9c37eeb0bbde0c52df64356f46aa97272acbb25a25ec7d7a0e62bc2b3d304", - "outgoingViewKey": "a389a14af9ac5d9c9006a2452317e925984e38c7c650a4d4114e51d742ae9b52", - "publicAddress": "fab7bcde9125aade8540ace3e16ba65246d75cfc761b5c25b336495b1289b186" + "spendingKey": "aca5469be7a562b46bea6907aea42b8bb973dca9e2b0fa94ebc0592d0e32b57c", + "viewKey": "54c51230092441c4254c926ccc2e7576991488374d859897d9a935fbba27929cd71d4ea05f0bfba3df67c5e6f30f0867fbf65914079d85dbb6b7d075ba653a31", + "incomingViewKey": "4917b43b95c1d8b38eb5b60d53fee5bf499a0214f3daa6d17b8473d7f9b48b04", + "outgoingViewKey": "4fe53ecec0d551027fa980b9fbee7b20f7bd0782e1ec48beb5e1ead10aa80b29", + "publicAddress": "765dbca33ed91961ad8b7e54956c5a29a05fae6f0ed1e64e51de5c7ba049bca0" }, { - "id": "2c579fec-5ce8-4a8a-b507-578e973351c9", + "version": 1, + "id": "51a252e1-f9c5-481e-a50e-a502a5e900a4", "name": "accountB", - "spendingKey": "c801099838eee1f3d34529f8ab9099cea805a2788f9cf8ddfad0af2dfe1208a8", - "incomingViewKey": "ec9dc23a770d53dcf87ae451e5a5fce153809fc25bac10925280297aa7518202", - "outgoingViewKey": "9ec8b9f9b01ce01fa08c70894fafe616924fd2e65f5648b12975527294eab651", - "publicAddress": "269c5a6860d0a214f332164f66a5f4e38e8d3bf13e339f79bc8e25ad80fa03c4" + "spendingKey": "67cec071e28aeacd439f91f5b1187ed66bfe9397e1685463ae691e09205ec3ba", + "viewKey": "dcfa0fdecb83ca9210303c6fc83a44c62fbb201206764118db53ce826bd26a3584f600d06168dd830c4ba477176819f8d22143d80e5238b20fd43db30bc38b1e", + "incomingViewKey": "0710fa4708a7454bac0566538121a1c86571211c0e29e52d94f9d403eeb8a003", + "outgoingViewKey": "32fc0d9660f629cfbc9635b5a543dc29f032794f61a9547c158b1fcdd71feee1", + "publicAddress": "077078c737a6e56f6c30c24009685947687a4e80d6fe60e23916c4c63040be40" }, { "header": { @@ -316,15 +336,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:e9Cm2TyZ90zzj5mUEHQEllVycs5aB5RO2Sn5hZU3KxI=" + "data": "base64:EpoDbWkPOuLz6QTdIRVnKuZJO6+0jHaoepLBl9fIAjA=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:L62B8fjwsYsxEkDQaeOplGpgvSSVMVcS5/OyWeaIYqo=" + "data": "base64:palPe6KLFBiabo7bLgw1VTOQVJBvqHdjAWiRQKHoZuY=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223200700, + "timestamp": 1676575103378, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -332,25 +352,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAklLExmD4vJVZIi40gIAU2awGNA6y+hzBsE31HbPmJTqodmi0g2PrPsST1RVR7NzVlgc1LFT893XUE2wfzSmxUXtKSQXPjwcZVnJd6Al0HT+NA6/DTnn6p/W9WknQfuHWAj7z5PIVsTvIHmzX9xx4PAbl1P9+SMPmWMpdNKOEgPsPjckD7Jy5OJIwyXhvySO1fz6LETudGP3JhKUtM+mJ+1N4K8YUDuaoOPErl7CxoLuH61ps4yCqUKF3WxuH+C01dzMzunIblpBlAZCRFaSpjaEvxlBQJh4TN5012D0kCEyq37Cv1o7ScRLWuXwNlJHQnsATegMY/yF17SpeHJLemviwUFtdyvtJrjb1SbGIcJn+gLq+Yb5xCf/pnSdS/k1T754stFoSGOFS9BYqBWqEPTDuExr8y5ezgXEbFVW5BKZmp0Wi6sGVkXqHQcKofIn7V3Q7KKQxNO4n5VaDiJgmDEr1kL/IFfAkv9NjmSPJSBuD3ULUxR3wcMl1YH7AgTCxZV7SvNTn900lW1hNZonRtm17SzZuj5moWSo0J0AmxxQxaFmKDlMJQYDxP62XoN/E5Gh1e12VhNa4EGIXYqFrRzbAyAEw7T+RGDdhoIt06L43F15D0nkS0Ulyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwjfXJHTI3o9oSeLm60x/5tJEZA/CzlqvQNgL0u8QdI6HdK3wUionU7kmjMStoDy5VKGVfJ51nMRGNJc3HJuFXBA==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAATgp8YHgtKcRJBnwSxJoWDU7Mu1IK5jnD306bzczgn8C5Lo1Wf7M4MXleJh0CKIYwE5/gLtxvDDuRQRrc7Y14gcM2M9Lxx59qxMdkjMcNtzKzeWvw9F9YjD4gQcXucbD65osmg4XQNDpqtU4RK3kT1h51yGPqYZw4Nf5dVvgjWlgIB2/lr6183ZJQg4CbFAKN/qHNk6GeHsKqmhEGY9C3Olrr8tvr1HfyuDzWHqf1WAqHt4TIGsI9G18BSdopoBYjx4nfA5cVWPyim1uTigUxM4/+ZGHbnun1Z3jnG+7UoIWpQGVrFKk9q6NNwmc/mGqorhy4qNUMHkcxg/NSrBUHSS4FlfEJfwU0fBvTvv35voySvM2ttdxdfw6XYqeHvO1bKf4YUDD76Q94UQ/QFzUYoZGPb2jIAmNuaIEnpuHSJAtzs7X4GwH76QfZyk8i/Tjnoudm+Bc76K5siLGFKGQfCkFQvtdWctf39osQ/hgVv2TduTgttIy7Iv5wBlBmRA6aLze4gKUehQPbaNM5XDcdftJrnzEm5/GjrbWYZuwZPw4EEN78KaCiyRa9cLyVZcqoekItqafnxH9Lph7AzWfxe2ebgFk/LAnRmDWjKJdn4RnrePB6t08Hz0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwux9At6HI+4c+L2oAVag5yNoMkZKEkS8+cw7tggvsIqv8ct15sW0EIvQtGWMwPxvQj+euqko0iI63sFxmoNBDCg==" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "652770CFFA8D55400D5EE78009EBDE68EC04053B687A4B45EAD889FB99178775", + "previousBlockHash": "9449CF8A5C8DBE9FA135C754598AB461413F4300B64A18DEDFA8FDD46DB098A6", "noteCommitment": { "type": "Buffer", - "data": "base64:Onci4IDwU72INRtkyve29ajq8UWTLzdD8qvsfO/fhS4=" + "data": "base64:DrwEZoEDGxrzefpMlBMYJYsvgm3hD17jv8+Nwwb40y4=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:qdcA1y+exWv8V6m5lkLk/4KJFY8a5aHVeoUnK4aa0b8=" + "data": "base64:bksRJJ/jIlAX9opufFp6Ez2Gew8cgVRKcbUn8EdOC3Y=" }, "target": "881271989446208257911980828427057262643615932976441214377264856368067535", "randomness": "0", - "timestamp": 1671223211997, + "timestamp": 1676575110260, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 7, "work": "0" @@ -358,39 +378,45 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAe85O7Jk8v/+RLIbMYACezzxCR9TYJYeT49GmpTwJdCuCm2Yetx+BTb+UullBylottpptbwVUhJGBY5D2dYZYG1p8pmkosYGcvuK1pkS7RS+YTGTEE6XkqScqHtB+VpmGZcTJU5JAmFhN6f0YPks7BzkyOQndLv9s/AB9IOjyszAHv4h5MwkqYkD1BDX+fo4z5NtL0xG3fdkShZiOcFvXqH4M91GLdjZC/59AFUh05tiH++l9mIgBfJi2ZtTspa8WAciD2e7f91WVd07DwNVQ2i4HGu9j1MZXAQ5ndLBH752u2TEH+H1ZbKvZ5Wkg00Zg2QXuewqtmiXjvw2k3wV/DmWvI4Ocnv8dafHPQXkjETDsjg+T68NZrHFpH+LvhR0dtAL473CJI1QmP5BeLRcIgTPwEvQL5w+Th8BZOmxr/5MKNB3ZHXxxawS6HfURM2VrZpOQjAVDWd702RgpdP6CR9He61OqXqlNzyRfwLG2FRUhpq6F+DedbPnhX98EZ5gHxqKtbnYvwC/xZl96mFp8AJEbYZADJ3CAcousRzJK2ZmSFVcVgIeyz4KzHAj5z9F5NMMqhxVbuPTKtug6C3Cz5vx0ZcdLZt1s5hiFRosE2Lza7SEO2euVgElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwf5I265tnAPN1E0w6oxNpx7lMEKmN/1AMUuOjmJzt9a1c7x2kKvSbPxQ/GA1wtpKIyHpZRTGz5etmOxGAoTvPCQ==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAA/TnePD8k1kfW2sKGCoLggJF2Y1fmjAWEg8JaZlTdmcyo40KZG52bGQSqJFdGGAIseAi1eql/L5frhTUa0St0qZekgbPMA4QQpoTLdw93UA6vjkF/iaDFSaLR8yWRh5Bph1ZrCr6wJv/v0AnVz1FbDfEEXa6kNn4FK+I5ftPSnAsVEHr0t+fNXlLEoN2fMtl5hrPc1CKX3fvxpidEoLISnv/5KtzIiIxTQHFnV1lzunmKgF9lB38VqP2EiUAb3aytCv98vh5S0Fgq+JjYQ7iNFitNctKbyyhOAI1pJlAxyoRH9kkoZhygpEY8obIyExQ8ztg8iKxRd9Ww2upIiI5XsAXJRDXYXFvJUfZiI2WEe8xs2ctSYAs/3j2N58KkLKUsHcoRL0jAS4AQhse3Sc5MF/hsbivsH1N1lxAMhpsSKbrl6UpeWhDzCAcF6OfCJTjddzLixkijNVB3Wa+4Vl3nLkh9vv4vRj6i+C4nlm11LLlEYayzKKzCFnGRJtK26BExEeyWSrC2ghNoI6DLqLzLRFf23aWEmnmFKSS9X4yXVGRtN8vzKxY9cLhtcjOxtwHtntOXWt5E+0VE7nxr+PjU/VCOCqXrR2llUxOzgR6aRqgc45r4ayWvnUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwaFrbws9vpCboeedOnBBFlcF7ZMIDfbyRZOfjCpjbaljiueLS1eYJJIoY3hph4TgFrXffv1fYeBY+CiFbHm9tAw==" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" } ] } ], "MemPool orderedTransactions returns transactions from the node mempool sorted by fee rate": [ { - "id": "6166b588-298c-47ed-9bbd-46b75fed5128", + "version": 1, + "id": "baa81833-4d16-4e37-b235-5b04746d44d1", "name": "accountA", - "spendingKey": "b5f2b521b82ee72eccac10d2b338162c6b90c5019f7a95ed215bcdfe4a9eeb4a", - "incomingViewKey": "6c7b338df4db15abc34738713d8e1ccfc8ff5ce0278c66bc5e371e3f575f0b01", - "outgoingViewKey": "6df23706f50196d65b33038b4d9052d45f2712bbcfc32c38ae6e466bd22ea97a", - "publicAddress": "a869b17d8c4c5ac333fb75681a26ca09883ab66a6e18a77a2c8611305fa2f992" + "spendingKey": "9ccbf3011960f653f7044a18f86dea5036799fa9ad6d4eeaffab9da0960be726", + "viewKey": "5a4c09720718dabfaa0dca95e594409b5eefd2633ca1709e63eccbb61e141d709c42f550fb56a9cc4fd7dbc54347204d9cf5adf44fabb8af44b5d34d6b8d22db", + "incomingViewKey": "cfdc9da25fdb596811daf07eaee2ce2d5e7834221ee9f2beba8b8fb0ef233300", + "outgoingViewKey": "983a5e9a182d20cc2913f152a9274dc1d762523d49cbfc0b227072a037baccc0", + "publicAddress": "a03f78da7b327ee2f8959e1f2d5ca1a0a3c8822e740f9e9905e2eb299d9ee51d" }, { - "id": "bedd2c69-7751-45f8-aee6-ceae5fd2a369", + "version": 1, + "id": "4c67223b-00d6-4bfe-8364-6d794f3e38c2", "name": "accountB", - "spendingKey": "a63178a95ed50b6149cb0cd996bee6b7b2037ba0760d4f53c154f2ac8928d850", - "incomingViewKey": "f602becce46eda16f03db0e1270548c66fd7fc6ff866ab463eafd0e8cb6af603", - "outgoingViewKey": "01becc2b8561705b7b2f70bc62d070e874ba6604398a2a1f887438bf37e31c54", - "publicAddress": "51c7b30973bf0c2f410875e344d8d9dfcca46c46e1a5d11e404b69ddb497c0d1" + "spendingKey": "da39400ece0983d4c41c136613625efc93d560fc01901161be5c2fac4b514e78", + "viewKey": "747f8d7bfe92cb52fe2b07b3211c7960c75969b7ed3f93ac14e875a211d3796da350e62b136242132ed4e2fae2595c38b6cfa42aadc17c9014507ebe8991c822", + "incomingViewKey": "ba53b765d122ee6235b088108389fb4a85ffceb63aaea64c63b7b73eeb21e405", + "outgoingViewKey": "64cc0c6c90fa493d316c30a0ce02d831ede82688f1c2a31720a8c0034428f1b0", + "publicAddress": "46771c137c142074a01edf52b119dae6751a8131b4845bc7988f6d0d1e7ee311" }, { - "id": "17cd8be2-8757-4534-ba43-982bd4526f10", + "version": 1, + "id": "82d4be24-f19f-4d27-b076-6c788a57ab30", "name": "accountC", - "spendingKey": "1665466259992f8f3c7d51f6a0ee6ae4d229fb6c55b91e20b8cce1fe5ec481e4", - "incomingViewKey": "875291685fd4fe3bd47a6bd6c378ac1fb0ad5bfc0e27e00b96205cf546300907", - "outgoingViewKey": "5d35897136818fe6ecd6cde87e2d3a87d46882de50138dc8ae06487c7fcb7d0d", - "publicAddress": "9c00fc6d1f1d8e129e5d93f7c4f7a4a466c2f26bd88b75fb5939e45b1b90c5ef" + "spendingKey": "4d43595d8c45fef268f1e7ac1563daa4b77eb030b3fd094304fed31b647446f6", + "viewKey": "3fac97840d308112829f46b9b44442680f1f59bf849385e3005eabc1234186d232a33dc1c2c94de1eebce00e455669ac425640e1e1d97f27c127d989c8a57766", + "incomingViewKey": "d64e545668710263e92ba9247cfe7ddb02f31a7c37c3a2620f3c08c1ddcf8b06", + "outgoingViewKey": "535b1a7610d8e0103d1afc2a7e366c630b56e53fe9d02af1e24b7131bb822aac", + "publicAddress": "7332eb67809012250ddec73f53c8d5e19dad5583f4afd292a857ed0bddff42ea" }, { "header": { @@ -398,15 +424,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:ij7vBf9cNlED0pJgv+qk+JOIyNK4LDuj64RhSMYtNCs=" + "data": "base64:e8yqGMjqKHlI9jIbOePR2OyEr/PWSepR9jmx0ecK80U=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:WqpJMksjuejDgQeETHltPeIUjFAFO+M/UcIlAqEblak=" + "data": "base64:tkC4PQTH8km2xCea0sAm4gkeif8RbHiA0OkXv3y5pL0=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223213851, + "timestamp": 1676575111749, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -414,25 +440,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAVfT9rPaFT6DEm4ldaHNqlqiTvR5X00/WMqu7nQoRIKiPvvu20DRUK7Tk+dIJ9r3sEvF4HRD43RV0b60KCCnrx9rJ4phVkFh3NrOjyaf2nlizhfJO3tzvzGEbIdu55lYd1RRXplKkb+1NIhglA5LKymtPGQTqzWa8FU6a3ydqzoQVO1ScOMUeY6aYtlz3G7e/SXp5W85VNFaDq1qRW8uemvKxYLelfYAxN7pcxlIGX/CszuJfjHalYdiidjvZRa9pcYUqnqzQSE9LMLmqtx5EVbLvDsZmik5CV6e8exn6Hxreh3qLRcwDYHqmkU1wJnW5DdSbbvP56xzdG6w3TckAhok+KSj/1+2YeUgrumpWfWlxWCDaJ1S5390ZulOiXqxlo4kPkmsKLzV5OAljt4TI6ZqXySFDdenTDFXhf1E2zNFwsHBkoCec4J30/vEombHYYSn3COLa3lzBbNy+0reiTAFoKdy3O4Jid1JmxQPBBvl91znSvfWkbD1W/xT3lP7MPDu9iun19RwodFysosGfx7l8Ubf4u1ufxlWi6oOys9bwiqQBJmRoy/CLPaDTDxJ7dHyjv8Y/jL4Gj1pwR+u8sY3kAxH22mc+bh4wHdFcYbLlt2yPnqUipElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw9ZhwrWxRlCU2S+DILDSfUQ2CWmzR3A3EgghUdlNwnok26z93G65hZpt8VcRQG8Gk5Du61HHtvFcA884jjhRWBQ==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAayMv8dW/0CLIV3DxMsh8rJjFXkwsMBLO1x6Xi7sHZgiUdyJrSnCn7KMAQKpXJX5rNjgP7hHPwiUTi1L6nl8aagdquFcbnbFIhJIVPTnASfyR2duAASwU4RQFXb9gFKVNGtNwVvf62LIggEYb1rr+tTSVnKqoXz7/04kgiN+/+68LXTVOgslxFhK93ZQ+qtWImAfWDAbCyJQi78wkpNxlgnTwKydF0KjZzP4Hx66oZ7KD88tvNTNtMbJFC2rPHdY8MTEOsGLZ4C/K6LtC+bFNYfYWPcELFh+JC1id9Qh+tcPb+OSDTbdjFHNR/Wv+p73fTTfUQU89TenGlRwPchkgr7pNuO4ZSgvj0sNcSHDdzLq4ROHaovLRxslpNoegG68sbhOp9T5nK+cmj0Gjez7sbOZyi89cLqcLpWdAALk/c+uew1Jve2Y97XilEl0ua6ff3F0XCnjrVgTxDZhiCVxv7Q11fmalqLrZqL6ZqEvXJv75S78IQC6U9DY4b8TekNM8UB5YkLbh4Iu7L8wSw1YLlcwFyFjhRvWGDsO2dLrCHviLC7i07m3/zNU1TBH1BstpZHOls8H+BzhWhDz2qv2kYx5ZyEIeuWFsjtgABOHttf/yetY1R+Vo/klyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwZONNaaNYJ/9ih7cOrNBod5aWtLfbTM/f29dkToN3J1lnJ3TyLBy+EnlzOmaR1xMy4QoU/mvYWZN5GezznDosDg==" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "0F8717F92E5F5A54D9BC004462F88E47AEF33F25F3D338AAE133147EA01D933B", + "previousBlockHash": "55716C1642EFA452C08AEE9DA1038CFD8BE6C2B9ABDA8BED6274EB4324562BC2", "noteCommitment": { "type": "Buffer", - "data": "base64:LC36XR++0TJy1SD87D32G1I/TG0ujHr2aYkYtBsF7Dg=" + "data": "base64:EELcsMNBC3ksOtDioMSSv43nPYIwXKvbkKg9+NyLXSM=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:PobE53F1ZN6mxaf0Ch58/+a7pTkyoORskcnRNXAU9kg=" + "data": "base64:Lni7YAHoUQVCI/52BU+SOw2r7LiItsBPPIJ+lnNszRM=" }, - "target": "881271989446208257911980828427057262643615932976441214377264856368067535", + "target": "880842937844725196442695540779332307793253899902937591585455087694081134", "randomness": "0", - "timestamp": 1671223225266, + "timestamp": 1676575115649, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 7, "work": "0" @@ -440,29 +466,29 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAICsrANlTwfo24UgXPKAXvoy4FD+0qL0d9IcWlhLATaaO5fjGRI9AccfHL6hwShYNaXW2F4k6jldBcVBkLBmXt/CqLxtQTjv4dn0GK5DdUiOzHxm1R6KmUK+N1CJ2SHiQteT4QrObU2dceKZd2atKzBlW6UpByfDN5GMFlfG3MEwE8RuhnWGLSjczJlxtu4PIyfVOol/TSUuaQYZiraOdTBsSHmt39QogsHI+nduCanSoqDmxPE5XLjId/zr+6rpcz9jmrScKmHsmYgasfbc4tSfM8ZUhlytHpAtpEIG87eZ4YNNiK4v9CQhTeoRD0r3BJQsCtWMtvdeX4AQoh4nsJYQkbP45svWUDF3/nygmpbMZ2LRNMz1hYp19FJZZ4QsFPB1B6AFGqf0aaUPAPeC94Os+zx1IWqjidkaFBCYyoIl+E68rmZY4O14xTGrusbedzyOS8S61SnIJVrlSbH/0XH1V8bSpgXmFQdj95uzU26cpo1LVpj5hvcwRANhULW1GGnMLvFubvH6BDpXhL79BN2vSihTMNLocrUivmuKCIWAXhRD8HaV8xbFvTTpzUMNSJdXyKp0JM5/fZC25Rsy36WrFvlrdIQH8c6zHfFIN3gxXcenfWn1EtUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwEjPj14lTAfSyHACtKwz1K/JBZWnxYHRUO5pvsAt1bGcCY/62vhnrXz3WlNtTRQTSo4rZw8AOm2ipegUIO1tzBg==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAmMJpYNbm1/GmW7gyRIJgMUnzjlRqIKvB6PRXwT+OPXO1MzsNTCoeVotKS7yRx120FIAkrAvWKJT3yYFkOllOJ6QT0r8nd9X5WSO+5hFwfvyp75BAGbYNnIaOo7aMsv4emoPS2rs/ul4/OymHLEoyiULFCEoH5Yo1AK27ZD78/tUBvCRdgaErpefEO3avvJY5UWKHqguFt6s3Wi2BccXytskirOdQHmkoWoBEpU34BO2G+JzlRRNrbW7gmkSRgH2UX1rLh/rWGGFwwX84niGV/zSI/IFvWWChj1m3ktZjZIA/WTOGv+mpTaK04RWze6vXPARePjtcy26KvXillaKyStVIj3mrdxe/BSnxr7LsbhCElY8Irj3aDi1D1zjOPB1OYVLhNXMVlGCjVu/FlQFJZD7AchwjP0YfoMiwlK+uYjMHb+7HT46d58RCoeQ0GhB9NiPdxGqLU0pm270i3d0Z6irFh5uPWdcneO0fG/jobax+6raTrgojuSpYvIIBB0vfX20na0ydXZhSM4pLXkFjbQ8urzpRIhqyE6Q4flZHwPIJB+oBUrm7AchPaNEXxvNM3fbVJOTlZDfKtj5rxDEMJGISOfBiOE4qeareHA//UZ3IJuQnW8UvX0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw8krlijP3RNRKHmrJit8zZr8eqfqsDJaSUjn8semiZTiifUAXFuRBhIrRYDppJTYCaR73X59f9mYN75s3+/XuDQ==" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "0F8717F92E5F5A54D9BC004462F88E47AEF33F25F3D338AAE133147EA01D933B", + "previousBlockHash": "55716C1642EFA452C08AEE9DA1038CFD8BE6C2B9ABDA8BED6274EB4324562BC2", "noteCommitment": { "type": "Buffer", - "data": "base64:bfinuS4rkOMmS2aUQMFWh0B8c+gl/ul27JNGIYxPQSg=" + "data": "base64:XOjrDQ00NwwGPlgjNeyPLqpQzBT3GSp4rKirstG26wU=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:pDApolEH61eMSLVlh8XYDvP7dEb0cWdfGDPfyr6voqc=" + "data": "base64:gUV2u7hdzIZ1f507Zm7+S/isT5iKIgez9qTI9rXg5gE=" }, - "target": "881271989446208257911980828427057262643615932976441214377264856368067535", + "target": "880842937844725196442695540779332307793253899902937591585455087694081134", "randomness": "0", - "timestamp": 1671223227062, + "timestamp": 1676575116317, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 5, "work": "0" @@ -470,25 +496,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAApSuJB8R18OrFNKC6SdgZPgw8N/dMD0jpVd784QqyOUKLW8s0bGoVak7Zfy2A9Pf0k1ONBCe3T4XBN2GPkMmW9MA2Xv6XsnZrtGJFeryeIHqjbW+w1UpDWKkm9NBhqXwX4xKstdW1G6fmkYm/JooGI4ibP6xdiz+C6MxtqStX+AIEuZ+eNfLRpI7FrJhpamim4L/G8+rR0m0NW1G1n8j0hgS9c77e69k4sgxy3bysPnqFAQ/0PXDSJkx4pe/o5gwmsTu/uhM2HmXf0/XxZ0+U8GxO0IJhoc3hjdb3LLjxNi0upgGQfCFqF0TIMDJyah18H48S6Chrhjxz9c/bVlo+5nCQ8CwoFz0IddRmwkOHDXVKV8H9dAipKBEjbAAEFixe5orWh+g4NXCgB1Aou9Y+oH9jEm79eVawstxa0zIsMIP5I6vVNbhxV8KriswZSwhT7TkluPzZggE7ClJG3zLk6erxMMyoWp+Rf8nkIhz3HpWWOzkncXjYl2qh0BmU299/TuGWZm7VpA+dsM74KSGsgpgqeNtoVY6J7RaB0DKgjiPeFrEoFunQ/ZKfN9YLJd4cphAuT5I2xys0OulOd5M2ZAHZYU9/NfivGWLGzJgjTkXLJ3bxGWUTT0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw8jMQrzWeGdNG621issoZwBRtdadnpjOco01PzYuk8GiUBQhQiqCbi2EuxxYNseuxkgoexouwF/Yt0MOKxL84Bw==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAlTFjI0zz3IH8OKXypKz6rdBrGL5g0+wUWD4KJqVtCKKR8xLjRvH0QbddVOibK4VP6dyWc/b4tOiR69RVXF5og3zvvcxZeZ2msn6FcR2LCzaE5MeV9dfk9NMRSZan6EUN/GQ7mlKXEUXAMPdHm8pAZ3sqo5ZNUo7ape/DtZHoljgLxSSX6r1WngRE4MjpUajyq4qbvkJDsR1KRQEbyDeOsN5xhI6a68PCcHQc4S3c6qCmmMWq/zdJYL+YAv3w3vZ4WzxPtNk8D16b9qd1yhkYkAu3SFtjoOYiBSIeQ2tFKuE4vpFYEFpYuKZN+wOZj87EHNN6he67/Fq0zz3a5xdKH9HYwC3rNFT/PbQeZyJfb5AUMUw5XcjCLJ1FZGYLJuVOiWBeb7rg3Db4lV0Iy9K9zShj2QIoI2BjYd35AUIw1e+1keRCFyxwGo+GJ3Ts9MqaxGzhTSwUcJ8qN1+aHdTlSwuwF3C7w/KfMIceYnlX6yvQDZ7Sb1gSCSf9ZHvMCxk3RN4pXGR5RHWpcv66UI8iLYDHl+bhkztxhOkS3c6UHvOqX89imn8Dk8KcYc7SNXbfwsd/QsPHU77TxYkdAbDsuKLucWBElZRsodgmTYCbrp2GU2IWO7aem0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwks8TkAax+5WBBacm4EIUW69enkupcEdrQirPzzu0BC8ZdyFK1ScuPCOrK2way5EqPbK8EuLE7YH7rBIVWRLpAA==" } ] }, { "header": { "sequence": 4, - "previousBlockHash": "3FE69F70BD3D1AF865E66A80562D47FC5BB5901C81A634D7F7EA900A94C761A8", + "previousBlockHash": "FADE04837C22A15BA7A3D997C9AFF0864E0AB92E9C250B4FA6FA6C4F472BC2C9", "noteCommitment": { "type": "Buffer", - "data": "base64:Lio6Xt1NZTbkMgdiPYx8eoc2MeKl+Ot+odLKyISD2U4=" + "data": "base64:U3CrAADZ/e+F6K1b87ihB2Uf4hLpDPtEA9dQPmHrtiI=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:wjBjFXHZfhGVDFmZ/h1Agg/VjKNk+uiI7vFVgUUHqLA=" + "data": "base64:hCLyNEmjUOF1fqta85KJIXUrSeRL2+7WdfANm3tYSZ4=" }, - "target": "879130901036475001697423051875971117690643105150939656519205417941517322", + "target": "878277375889837647326843029495509009809390053592540685978895509768758568", "randomness": "0", - "timestamp": 1671223238416, + "timestamp": 1676575119561, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 8, "work": "0" @@ -496,31 +522,35 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAA+mK0KP5GUUZ5S03wL+RnI5vq2yBqm0YS9ZIe5zmmhYC067vv87DVFnB6H6M4eV9JNMIv0675Z4WL9Ewq3kvE5r24GmURAIVjdGIIjiV+c5ONyZDS33s2Z6kffYXZvVwdTHflwVzs/mKbOYaBUPx6K/sbP4qDLG5v3XO4VZvtVsAJ9a7E5DHoh5qDtdN8gsUO+wOKxLXLuGkLsvYrCjEbSsNcVvn0pfWmEN1b8S+pGHeNCeIXRzfITW+bHBjo22KYjEl2tdC4FPcL3U7Jj/3zVqkyXUt33XfzQwemkR86ak/rUr2Yvk5CygJi2aY9ho+yhOEsQO3nwdoQeDiphG1NJsUPRLVk/biWZSg2uyVKq7YignLQNz5MOPcW997E1p0SaqpdDzGWyUHco0eA+LEzivfJ0k6V9wL6A93/Vqx7Ne4/DvDR9clSm62dsB/mrXWZn/SpMKArUsxqEL+i4s2RxJ6VRh0I2XF8uOZSdplcWb13Io5zhUXXhU+qopIpyd8+uURzFUMCkeWkh/eYp4kkd8BV+jI8qVeArGfZD95Pnzyhyg+gsxQVlLzjlXgKhmbKCPxFggkR2GP1ehQaY/VylbjSiDl5EOSNFfxIvdjBEWwZLeg0381rtElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw7Q3ZdIW3X+yfCffstNrfkjeasONTvkiwy2yEq8n5fbb3+GlbVVxOeyPZzlb3hM5yVlOpp8QaACH2e5GKC9naDQ==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAfAhEy2S2LvdY1JQ8cMOUJQ/eHe1Tq/03PELAPuRAp8aV8HoDttk8mL/GJePwtVLdq3Os6ItaAaEzZtxCbj+39cTLGmlylE2pLXIK3F2UzMyuVm2bWLo4GRmZ88uLiYs3a7JFYzptjfnKFQB5aOtLzV9WYEnBGfY3KjgME+Sb5tQXso58SzUa8lE3frF1d63lJmp4jY4NBN10E/ajfxUgo+UDSGgxr8/No9R00ngRpc2NrPKGZroowPuxjnKPHBTll4JUDB65JLjCtLJP2/R8YUeVl1DfC7tPgss5qmA5PKS4ixIGRHzBOQd1dpnxfnblhsrwMv8qux5HIVafhi2NtiFexT3IVKdVKDZRLtJ20lyOB7TutHhv1UerY6z9kwRdguvfMyU8wVKtXRV9HcdfOIQi6nqRDaoTXBO70kRIzqYYT9mWJFXvKlSas2NnwGJ5P9/a9K8MWKOj+tdMVZTGpAtdgbO6SSmu9Ft0IZ8CVxb+GQP7WO086Ho29kLdzTKdvEWAJInw7e9wI98aiqiPHzjYnlWCRQnPI/4uZHgwnzjgW6LvXWdkdwCzym9Q/Dxj5qM3qr8/sdtapW/7dD4hxwyR/0S3ljNdbhcN3bNHb6TAAd1n7rohyklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNm+bFb2e6F39KjrSWxLGM6SlGzbCry3z4oOqkJSBwGA8Svgu1XTKGu7nlBfp+3MOT1cAhRMhrYy5zU49Rj2iAw==" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" } ] } ], "MemPool orderedTransactions does not return transactions that have been removed from the mempool": [ { - "id": "dc01c3cc-b87c-4fdd-8e75-a3afa986bcda", + "version": 1, + "id": "244fc51a-17e6-4e50-b230-4a66d61fdfcf", "name": "accountA", - "spendingKey": "107f274523f3809f333260c1b0ff788bca6db2748fddaf9ca01b7b89054aef88", - "incomingViewKey": "275ff0ba1acc30a9539d84a34081e1d20bc8d3d2f96de4613fb0638356025701", - "outgoingViewKey": "ebd73da5860cba7863c92000a42571dd8e93b002f3fc3b71d2b6db7596583531", - "publicAddress": "81749d2b4942f24ae8223431e7c9f829907c64247d97f66f8894cb11f606ecde" + "spendingKey": "edc54c9b0baaccedd1a5521780c4455a05e53e83f013a67e7b4a76dc6ea7dd02", + "viewKey": "f85376ab7c9382f795cd1f159749facafcec224c7a981cf26fe14bebbc1c3ce5b79bc313fa4ee6821014e5c9811f14111bc127deee01236ec34aad3bd3b47acc", + "incomingViewKey": "19090c35f9cb23ff9027799de261b2df74fc7006f73ff03bb4693bab63a33d00", + "outgoingViewKey": "2eea649977aaf32e8888fde5af20322822806586b6a450a82b76c419e74ed645", + "publicAddress": "b649de1c7b0838dee2d2ea1ac03b6d4471611e9adb78500e7584671d46cb845f" }, { - "id": "20266cb9-b5f6-42bf-9c4d-bd81d6dc5556", + "version": 1, + "id": "8848c273-182a-4ae4-8864-5f35eeae2a35", "name": "accountB", - "spendingKey": "caf07d00fb15165b192a1eae223c7970725224893546ab76be7bea9e79361a79", - "incomingViewKey": "d81531ca1c2d1229ab350d41b8cbba46bb3f2c6887cb152300b7c41c76033002", - "outgoingViewKey": "b19727743ae724289b91b24a957b98bacf719c118d606447fd5e4b9a82913df7", - "publicAddress": "a0534da023fbae827b9482e4caef2d071edef2a95157784c6e3fc739a20be232" + "spendingKey": "9023118549a4b9977f441d214c22a769a34577b3f2e88125020ddad5318921ab", + "viewKey": "aba71eae887afb7e36056b781beb7356f921f9ce7d80bdcafb105af1763de32050d0523b2e1408d0903ccc97cd09644ae6c39b01b30e20b0586625c1159abf3a", + "incomingViewKey": "53c8a6acf29833f362bf5b27f256cb8596a669c33939d993180f5e9754f26e02", + "outgoingViewKey": "3fdd19dda9239a51d823983baf023e0c42c5e271f3fe1b4d014fe87ce063bc02", + "publicAddress": "7588306a3bfb8415a0e6af7c5b50a8f4ed14835c2b706eebe73e4b0ce59be25b" }, { "header": { @@ -528,15 +558,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:7YkAq8PHjk1jeJcLH8uL3NeH76IulwTUScbO5PgJhhU=" + "data": "base64:LO259goJTEzx5qwM75wwB/ZK+W4wYNWRnUHC6MHvDBI=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:8UqTG57iMdjcF05rAh9mPEu0eU7pv3wdWNDsJLrTa30=" + "data": "base64:0689zs7GXWoEMrD1P8XDOSGukT83a3T+ut48cBs7q2E=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223240309, + "timestamp": 1676575120499, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -544,25 +574,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAm8gcZudB6rlDUscVdFd20CE1OT2DycEDIuWnkwk6pEygO2nhrXVyM5myzuoEHP8vOozSX9uU0daN0GFLY1oxg6mCcy3xE2UPVLO1w7XHWwyAlFNZn6Mxyo1w3VH4H/NJ6yRTm3ZXdBspy/Ju6jpogBFfmkKSmbB894EoE/N17QkQwmSmH2cer1a8mHeUOW6Rw58hKS8vxyN99+RJDtPF4hyKwDdzqRiae1SVCbvkLLeijiDH0IdPxpkkwvDDIBwOsZxASv67Oj1MzY/UG4jPurZugYWnzNad/LI7GZzL1kqvUieKKV0yQ0ABiZyOBjnpm8iNX70c2SL3U0R2FardlR7TllNosvqNBWP9g9e2Q6LyDjtGq0bZkyvb+L396Q8relvCLlqLiX+qP7AiW7alWsCUdVKJVx7W8+BPMKEopU3nBgjweORbNME5Aj5P3x4WXH+rwxFObC2k4bacAOBZSNbyIijcKsUxtl3qeq1rZDA3VQXfFOErCjePVGeTRbsOw3/3OIobM2gEKn72HYFI8NT6Be87r3J8tA+dHiYDB82Uf5VEE9Oy46XMJ+RwQpFx3Cu7TXaV4uyxbVKuKuH8ufmowiSKhJVvGEJk4yApQaQsSDw96TikPklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwc63CMlvPvnXNhGKuk96bUjrsLAwz9Ug8fXROpYVT3e9K5U9OgnMuVqv7VDbiaFX1NxCcL9AMMFr9Nv8OsnDxCw==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAPBTFVl8Bd6h+wtYAb9MZjjBZN8EOsoRl4n7eBTrkarup3I6pVODjYTxj9tkZqz9hKjNNamiKbwO+oSdkHSbB7LAmcxKCrriTu8zuGyq0OEev3z5te1FUuOzcilH61VAvo0a8KqbEVx48Vp6E5AzxbrVdJTBhLSTI5Y7Blo2MYZAYOMbmQihjMfvZ4PsWBKL9Uvr/nC5BzS4NrEHEemay3m3HNaI4cOXcaZ+ijOho5TuO8S/7jpgP0QFnoFEEZIFKSx1BsAVtFRMte+iMSC26B04dGi/yN9gGmFGp5V8eGoaXFKhuQ41U/uJdbleIMeXBhtVd8Vx67orZ4baYKHjthO6X18QVr74stG51NFmcQCOhNBj+BXgb689mKEbP70k5E4r/e1EsGE7YDfsTDUkurff+eGYeoulfDdeEmGTKxgPl/ITUExC5I5sooQ69G5u/hWmCR5SPSyCFuLLhjb53Chm3OFFGh9itFUC77bQA8y28Qf/Fdjc6azuJnlkgFeiJd8TuvylJyp46b45Z4XhARC8UzdF8+UDrta4O3aIWb47zG913MVokF+lP9FnB+EgyptKWoP83DKIRiD6FssLFwzEiJsloEMCqPb3PQ8cO8iax9vUZQCZAtUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwJymSh6SztiyOVeCTp7E2AtICQ65Np5Eh676swLFefJU1FZ+n3ewDhmcBqvOY2jLnVygpXNmC+ulZ3Jonk8TPCg==" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "60147AFDD60C8F6084F7A0E65BB8AC68BAF919F5A16A2C81E56DE8E21D45BFA7", + "previousBlockHash": "6B4D73AF4CE87F6FAB2C4EA7704237747F57C4BCFD54AEF126ED59F65B38300C", "noteCommitment": { "type": "Buffer", - "data": "base64:6FjeNVHgFLDaz5dmdYYhrYlpLqmAIF5UYnd5Hlge3hM=" + "data": "base64:TpGQAxrPaJv1XO6bIMXLN4E1zJgMlUi6O1lSUPfsSAg=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:LHe+Dove/SYZSo3QD86QMebkMi0zCzE/R2rk1AwdXjU=" + "data": "base64:Iierme3xvqLYea/aJPqU9P8a5OHTLDyGiBXiWpzbKTg=" }, - "target": "881271989446208257911980828427057262643615932976441214377264856368067535", + "target": "880842937844725196442695540779332307793253899902937591585455087694081134", "randomness": "0", - "timestamp": 1671223252293, + "timestamp": 1676575123230, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 7, "work": "0" @@ -570,29 +600,29 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAxc4ZDQA5ljRD1JtPWTE/uT4vNLToiYgDzQWbXFrkS5OqdDmLHdUhdTv6NB97uMedShsDQfz2N2pChiZMZ54g6MG4g1bS61M3Pasq6BdbMHaP0jy6u0vrs1/Ou+JncqWZMZGE7h/Ive8O4+RRfEeSUXyOVmgsJWxcbE5Q2GyVwW8YTPCA+cdWKZ/loWL7+Sxv312TtYTbsgLZj2mLDUafE74X7KIJaGutMbGeGM42oySG7kz4hVOVP0HoDaVXTKIkzTzNmIetpSxCXVSm20I0V9qTHlbPTc0Jz6MclRjHZx67yGltJQgu98RP5aWzyDnPAZiIymv0+jeB6OBFUn/25MLcxCbI6YG1f1SDBnWJo3ABFzEw2OHXogH+qdQbfYBXET5hBtuh9UbJDzZbPEvXEDArNyCrhCSz32I7LjXK8GsLdp9zRFZk+fqclpH4GEr3I4SWwE4ZAJOoW8haqvYfWT6MVFPS4L3i3OP8fScVVRiREAh8daTT1ELojXVTMGa4NogbAv4PljSnwwj/6QEIC9R2IJqOKrwb+zYIRAHVFRiXOitZJ4EFHmLGLt8qF5Co0SxxO+WinOx/kk/z7L7paJgrZvPq21qY4io+vDeJVKEQYZ0/3ML1d0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwC3gN+2+bxqKgioLtVoi3k6oOr4oQeIBm+aDyUiM57CtO7t7CHhzFV/gCKz0jSmMu67H5uoy2RR6M5gUVyv/6CQ==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAA3iGPJ6k8gKfnuquqFE9FQkUUKkLuCK9t99OGE789bLuq+/kaHOvB6vndfBOAKFZSmd0C1qO3BUdUNlQv8jCHlVlTXmR6JdQv8ZWeQTIkxZCm3wLLBDvR9Om2yRDM4il+zInf9P8zkm3Tl48CzTJ3AHfshpXr8KrH1987j/fq308O4lhSnUR3/BjuDX6g3wlBLzNaslieb/JZA0Ov8Px6Q5aOsPZgfxlS6XYMh0zRMqmYIUEqGISuj8+8xvpqhCDIMx1V4ginw3XNEmnB4F0hopbqAOJHTZiQ1LTZnT/Pq5gE2eB+9cGR3urD8fHUTJUrqYUcRpSOYEn/FFr68vU8APE5PbA33qkC6EhahbqBUVM+lyCnTP1TNa0ALA0AhB4gWV8wUQpiCzbEBr6TSiGR1MrCwAMn556ueDRO1PLoADTGVOK3ZY6L98XLJeGUNPQ4opqzRy8qbvuR5lELCjnJYn+a/I6L5oCR4/yi26qt4jcN8Ni2Ui7BuHYv+hHGiH0rfJRtvy9MVx6YeruUl6+GcygpYTjMC5tA0BbGM9r+OedyEeg2wEw0wunZZ50yJL5PUUREgJ5BdABs+7PQnyYP+BQSB5zyaMigmRFIagjpnvwKRfpmFn/E4klyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwQL+kXh14LliSGu0YPPGgseByFiGepAzRdKC5AYVPhMhMMrImvUVMmXB/KsBIYr1jKeP1p2m+GUOhS5iIjNHDAg==" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "60147AFDD60C8F6084F7A0E65BB8AC68BAF919F5A16A2C81E56DE8E21D45BFA7", + "previousBlockHash": "6B4D73AF4CE87F6FAB2C4EA7704237747F57C4BCFD54AEF126ED59F65B38300C", "noteCommitment": { "type": "Buffer", - "data": "base64:hSVrHkDueDAsZPe8U88Yo0jWz2Ct+ygarTabtC2OnUc=" + "data": "base64:ZUIc6ihKRNBeNt4+To3CIBKLR0WzAQ236YjY+qzSbWo=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:+dkscPkYdKfnG0O60ybSDIvYSDkiRvU7S8cV3T5L2Jw=" + "data": "base64:ntzH+sZbFPyamiD4AfofwMvqsX4VC2L7Mavi1N4cSho=" }, - "target": "881271989446208257911980828427057262643615932976441214377264856368067535", + "target": "880842937844725196442695540779332307793253899902937591585455087694081134", "randomness": "0", - "timestamp": 1671223254191, + "timestamp": 1676575123617, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 5, "work": "0" @@ -600,25 +630,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAhcFixjqK12S/J+2+aH9WRjlGp052QFT+apZOJSzJ3LSMpPnTCNaz4xocTvmVKModmqzldp7W+d7Duaz80ltJBq0bIWghi46D+zI+61uK7FWNtFo6HKbeWocVhR5syE0coX41hbcsg7zod3ZvdGip8bvckflsHhpNVSScp6RY35sVf+jfpxh6GKUn54y2zI20kSr3fyF3/zLvsQqL4nrx3U+CjeKKv0LkKSxcm1fVn9SKkSIfn89o7ZTnWoGrPsi/4iGCj+IjJsDbTJxNP01k9grR7TK30I94QEimBHI43x7rC9S410d3Uz7+7vhwdu96gM8bgQ5Ceu0Ui839cFCkry1FN2srYDQ1BcT51XGjSpVl//+LDyGHfdv/wuZHiuwmjou0TEy6gBC0OmNholB5RdXElaH0+Ctgoet2s8betFO1FN5jCPsqKgbihnqvcBz8thKgn5MXQT42Asjh3/kIo3OK7vCepmu0qEZtogsJ/M/e6M88cDx5rjRoEYKpilpmGcLoN/0FmWjGz0Ophntvoxi/eVcCbOK123BHeRTqpffLY9sUcG4XNOYT1XbLnvttMCG9DaXDbjTunzSPYeWauKrQwAXjNnbbEH0Ns0UcbQPLbtE9yxf7FElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw//ajzQJS3Qr0Oz54kN8XSt7/DRddd7owHb3TMV8Qsuv9/TBklDD9Rzhe51EBBLmYNjwAc2NJkWYI+FxFebHlCQ==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAN16XFuer1aIEn5zYPvbasm1ZN1fh6yeR04uuJaFuqh+oxes6efFzzOgXOARF4N62B05QWMVSeYhbkN4M2Cz90qnDBsay68Uyi8e6JBSCEJOSKCVIRmK8hFvFaeaalkoA7KtQwinqDyw5IOLWjHstTTAWU/xPsjqc3X94N8mXrL8T7hl0C7or+L1fNzoUlyXk8GMbJ1vONEC7wghcGXmWVr+kpM3Gpihwvn2RlZTuAw2WzEs1+0wm1l/b74U63iVT/1Duyaw3s5rSZYj5E+OD9xFCGpl/N+JI9dfZzIT7EADVQ70UbRJJ9jNGw7XCzDWUWgHjPuspd06YWbrunmHbiB2bF+M3bHCoTzXlKzfjs8rxNfBZLiNfustzA434dHclfmq2RLsxrl6KXNr5VEDsk8lMDmbUk5vT04/VoHKMG9X+Hph15po2Y/+ewUjctWC46F7B2PnAwhLcP2UaOEDbK/bMZfljRJsTQ+A5OfPqANr4hzuYTeh9z8re8GztHHiDaajZjtg+dfFGRa/lLVZYNKiXYo/tsNQq2XLF7d4G9Tc24V+toajKyZQ3slAA7D35Kk8ZUexsq9mfogNJWCVVgPVc5uvkwEz8OOULnCGLypsO+DuZYO0osElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwHLiEPqNDv9VjIOrDIt4IxrWFivYBvaBwqsT9YogJbABGzSgEfg9N7REREOf23D8A5mGOz46wopHVTY1i7tZGBw==" } ] }, { "header": { "sequence": 4, - "previousBlockHash": "CA90ED36C5FF4E701A77A73C45529140D74386048566D9307F3E8D2D0D63F2C6", + "previousBlockHash": "6D237D15CA93EC6077E11BC688596EA6CA81BAE8CE563F31D502898D5CFCCC41", "noteCommitment": { "type": "Buffer", - "data": "base64:rFE7KHTt45r+Tlz4pFjUftVYEeIcK9FHO2kuemWPWRQ=" + "data": "base64:pOEbDfYMd3Fprmo/rgulKSlXcY4CCx+enNERaqqmHUI=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:MOqGK68yzJfz98/sHV2jeyvsxDRjQxuSAluGCxZJ4ZI=" + "data": "base64:57J3xPOZTlz/ubMELrbYeGIBcP+b8LX4nxu1TggENz4=" }, - "target": "879130901036475001697423051875971117690643105150939656519205417941517322", + "target": "878277375889837647326843029495509009809390053592540685978895509768758568", "randomness": "0", - "timestamp": 1671223265822, + "timestamp": 1676575125637, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 8, "work": "0" @@ -626,31 +656,35 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAA8o/wEvfWfLOOWoNhUfRupLlaPSqgNTbvoX75AKxRpmGtJDGosnHhKT4ul3EC2QTk0cDLWb92EPZ3IIHTdUhhz52pcTslHTva8z4iKj8bMPuQZ3DVLJAA/LAb4ljXfPXIHfX0SEI8CkzlL2dNJWCgw7hz+eL0f5Ek43dpZ6KfcQwPs6mXf9d4vm92DpcwluIbtzNdVuXTCuIWyaCavRzZiiKaI4t4NL3WbMAyKOMD3BuFbPbzWGzYoA6bmfSObZJu3d49LIhIVUnPJxH1E5zFuC0jJA5CMhIGzCDWysg9oqV2Dm6Upn8U5X2O8yQj+RnyMs8RdHye6iJrjwk28k1NtWcjQKM9TC3us5bbxMDinVh4gwsSj0FujbpISIfS4KEEeeeZbcXEtBGhf2W2WfH074EHi5La+gRIwDbzwfNvsKQOoNDv/SEBydtOTueoe0jlYjw20yk4b7RbQLNonQkSM38eGTc7NlDW5fHPBfYxN7MPIu/nGuBEnl0XP5UobYZ455/Um2jzWfPwBeL/3wkLlFhajrh2HH9EXOFwXfUTFTgVgzu033R5LD2aG0DOBIBLOKYUCAFm03FoudiBqaQOD+7cQNufUuZY5odEOe/5UepYcs8A9VjWE0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwOgsVguspBKOdKdiYrBDFx1gnfF9mI8BRv7LxTAY7qrO7P1g2JvNoFT9qDTS1KI3FCncRfn+nz7lRQ+1RBHhxBg==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAd1pWOGYnwdZ/nBDm/eqa4m9oXf4mxj/yYWzt6dHdc5mrMbwTYBnJ9k5Puomd1kZmQs25sc31uFJ+ncxDIMsD1/sEiN4DneZYoEY2kM7IFlOvcmalTxLhhRDQuLHGLsDEgoqp0Alic17BS/fWMCcyuXs71B4Cs9cvYTJrDz7wBzEARGxFluJhjqbPGkjz5e3GDa9lQ7vWz6MVC5k1EH9pMmaqW1nd2psASmiCuFT6frWja0SVYDNuwCkdMb5TRbdBp2KiffPg7SsZd++6o1MFUW2+hlBu7eJ7o1BCXnE72euNEhw0PnXDa1K5sONOlj6G6vhXhhcbYzoDzkykI7OHEqHBQGr7s+4jLGQ/K7cv6vJIYR9uM9Eh3JC5SkqEV0g5yBaXg1BECjkoUOL4xr6p/tye9C+ZLhTME4K5r6zrQLQbil7ksLdRzXDMpq+IJ54J2rOxHziksipkd6y92F2mtwEPTNlrECyy87XJeqTvrG9qEUuOK6/B/+DGHXzxaNRFqdlEwZpNnvRbfyQCGtd/Elq2TlTEMUlzV5l7EzB61i19fJiYyFPz/e95fCU/8Uss1bmeLioTYykACA90qXz0rdms8XdzNugs79zR3s145NbpWxjexceliElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwSLFpZQSdFSXqFqGV5OzEYingF6LE+w5EUmCSJqr0s7IzTb0RucugiJ/0NS9EpbLPjqP+nl/91LlU4NbH2XOaCw==" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" } ] } ], "MemPool acceptTransaction with an existing hash in the mempool returns false": [ { - "id": "a4e59174-3035-4e17-9b25-4f366efb47a3", + "version": 1, + "id": "dccb290e-47c0-4c00-aebd-9273689a2fd0", "name": "accountA", - "spendingKey": "545f1c0bd50a806470206d9d93140ee741004a86e6a94febb7b970d1641841c1", - "incomingViewKey": "cd3d56b9788522779bbd00c196106f3fac8501584772cac535ad84cc05f23f03", - "outgoingViewKey": "c8c3c6aea2a90504ab8c3eb6466ff34adcba9a012ebfe21c265aef91a8f351b8", - "publicAddress": "8000c804534f8608c9742eabb2f8c441d46ae903623b73bf5b04d644687b21e4" + "spendingKey": "a05ada11087fe4c30ef058a1d1e08f4b376903fc8a6322e91a640fbbf3759174", + "viewKey": "15328d8635f1b86ec403a0d5aa59fa85e42fee7e4a0c5102433b4f9922dfb0620c436d57d516cd33e49b71fc21522f007ee264355d3d50af6178ba4935aea6b7", + "incomingViewKey": "116607f04b94bf8030a46ed091e31ed609d63559beaf085ec6deea5e6536e400", + "outgoingViewKey": "08808d3feec0bce1364f2270beb6d8660bcb3159482da27141e28941f199e68a", + "publicAddress": "4ca7c95fb4154898c9ee86b9a4fce56fe16b12610f7ad577314dd5175d544d97" }, { - "id": "08570b6b-21ba-44e7-a302-4675914e4ef7", + "version": 1, + "id": "12cf0273-996b-4627-8dba-3460afe4ce31", "name": "accountB", - "spendingKey": "d5a655255bd8bf0e3a1ed3ec1dd6f83275ba867894c16675fe6212ae59c2d98a", - "incomingViewKey": "b876fb4bcfa108583d01e6771ebbb30eb43be57009fd81809041ac655c30b800", - "outgoingViewKey": "48432a81b28610757083807cf73d2dc2b620e003b87f95d7d30afa2bb4270732", - "publicAddress": "0a8169f6ab465d6dea668bea4673c2c347e6fd34c59c6c8da0c52a8ab4fc18bb" + "spendingKey": "8eaeaa4f61586129450bd9b89657744281cfc05220a62ada2bc693573612495e", + "viewKey": "ebe4c8fe68ba33065c3ed2c00a6dfb262e21dfb874f2c97a53871f364d134352a1fc0c13e807a2a64a06977729ae7898aebe1e82bbc9d87108921cf6a3795c3f", + "incomingViewKey": "b8ce76ee7ff82b84566db14781c500654fd36a991e5f0441d51e83ca89d58403", + "outgoingViewKey": "383a7ae3c2474945b30a8bfa3195d9c4c13d9f59dcc286bc416c9bc083819b76", + "publicAddress": "ac3e04c5a648313137ee66af255ab0f8f83c3f61d3bdcc1bcc06a3efa6d44ee1" }, { "header": { @@ -658,15 +692,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:WL6wQOC8X3OeY4qiS/7RasEA55tZbfubpLvu+eSfO2Q=" + "data": "base64:AXF75aaeOsC3HUMWSZmxJyAnaY4zj2CAdgsxJqplAA0=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:vKSK+gqZNTI+lB0FVY64iDdlXZUEkW768yQEROutSAI=" + "data": "base64:pMXglKYJn3Eg0ah4tv6Jrz3iLFxNEYWoNed+nYS3n/U=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223267694, + "timestamp": 1676575126321, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -674,25 +708,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA9KrwJAUa1ZZiMSkLLzcfw0ONwIpQgWlzEw9477e7eFylaFEyWaaFegmCm/6+wpAmBiNDcrmOUcsObX+QNAiagSTZMl3WOQEAolLbkmdFVzmT1KbA0fixQWgerk0JzkW7QNpmzaCijYTkDnprCvXgABI48a9R0odu3uT5tFZrWKkJuiO/m4tD8vIlRflBOSFMigZ5o2CB/o9w+gqYWQosO5ubQI6obgoOowLr1SiBNxKAru96j9f782hM5ytSpgBhMM1oIiRAmfJW6WoAPDQYBVBurwxF0SJbK+6gKjzBl7NI+nnDBHPotCwOmRGGNyRNHd0NKgv7G2Q4wVGz/kD6reRRJylSj5DYXoC6MLLYrjqqjQQTe9CBNNAZ8JXZT4UtqFZRit7BxRY6yNH1XmVEMW2cXXGqLBj6Vg7Y0oDflsA6fjOqL4c0PzNlgVqBajDVZVmybTPfIclnFCIthTwhVT/WXRVoWhK0VXuFIr7crzcWXsaQVsiHrOIAlUICdt0cO4L5cReLu6qT49qyabwUs0QKvobpaqzN0psa+1DhVnG1yZkO8NkV9I/m+60IdvxIzPt28nJw3UcnSYaR6nX3kNUpVLKasWBWEOv+GlkSzY2s1WX48I5jkklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwGMxM31PDBevQ6akZp3rmFxZinxF9QOTupyAerTSo5AJ3QLUjj9plnl3v8nl1DGkUk6T3yDr6uNoRzm9xYPxrAg==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAwh87D40rSBwvvE4x3OvgbQ2zZ48xTintDTDVHCrORxaxe1O9bIsvaAF7NP4joEgkYW1+PmYdXkGm/n1hWoYyi0a1mLw2VK8tiDk3Fq265rS4KJb5cIz9+nqDnKGHiy3Mx6RXxWenfz53Mm+MT9zVT2e4PQH8e2c1Fr+RnEo3yZgSm8FVVRZ9xe2D+5wm5UKs37gU8QbMNOovBnGrQOSj0FPFYxm2SN4ylTp75wcYHTyPta6gunytwtqrMIB+Xp4MnL8ycmfrsnlLVqPWpYwbBDVD+0DdQA4CzIAf6tXGvvgWQ+99y+TN/+6ph5C9TZ9yCnANLss5yblZXb7gR/0B5+C2i8ekm7cxJsJrMa9v5BjREVaXiWqG2dRtqqFONY0DUelgQsm6vUFZ4eBVObTM1FFFGbJBBqAhe+S+LgQyMaYSDV5GMOMY0O/lesIk3yyb8F+OF7Jtt0HZ733pHdoDAJTWf6I7D+Kl4txnPn4Dz6vgo4GAyRDJsWSgoVJ/V3XgzVj+JLj29wmhuviVOQ/2uQ1iJBDAaB4EeYP+012N48z/60Di4swTeUZYJ5v1clNAsbrLE+fLZ4dCmQGbq+9w5JLp+n087fwdSchODWvYVHT4mRYn5BCTLUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw9M35e6+Gnt6L4rff6rMJikLiw8U+iZvnIsfL1GRIaIhg6gb6LRT+HOYrMvivX4Ie/vmH5rWvp+HT31PtD26YAQ==" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "C26560769DD5DDA82E491852F4AACCB91E1882ABBE31F768A389F7A308996EE3", + "previousBlockHash": "457BF18A9FCE309CACDDDD9D901C6846DBD3DE2083929D917BE51B14D638BF36", "noteCommitment": { "type": "Buffer", - "data": "base64:lcNcsuTNl/O0jvtkZyqBXSj6Wwek1/dp0xj3uSH95m8=" + "data": "base64:PssMtOKJ754PhXYMyexv82g2zBQX/0/W3xdSBQq93Gc=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:1DAKmN1nQ41aWFUK0ROhvqVayJ3krG/xBIw5glKb5Cc=" + "data": "base64:Pk/Mze0fucQBh3E59QVnZeYMBQ1oj9+DX0IWe1BeIYg=" }, - "target": "881271989446208257911980828427057262643615932976441214377264856368067535", + "target": "880842937844725196442695540779332307793253899902937591585455087694081134", "randomness": "0", - "timestamp": 1671223279064, + "timestamp": 1676575128732, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 7, "work": "0" @@ -700,31 +734,35 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAcSIEMx+6c10XmfHJiwa0uypysu/F129FSrKc+neVk9eV91N+Q8kGB4aQeS5N+pgxxeCXGahO+oU76a88DlktK2b7uk2jTM9TAYH46eK0mESOdbWaUExC7HHJZ+uR+xYwbfA8kYOGMa5lqNrzkEScEOTcLYu4QWVX9Fd9R9E/mPcLn8GH48DUsuz+gwe9FgVHhhH8qkqgiLKct1YZBTEGDPxFNcrEmS8QH3hAo2aFsYuU5SXsD8KGeZ++wFVZfIhDwYtfOKrVoi8H1BqI5dgFvoAHnaHkaNZH+Qtf6+Y8BvGZQmnZElPloRDZ6Qq6YtDbvrZmu7+UNaX9nxiAJ73/nj47Z8xaJj6+LTCB7YkjbVZqvZRKdDald9gI8JQ3YD1yvcVFMHl9YeBJpYwKMzchGOyYTPpSaFCGqPon7kqFftPd7yBt/BxamDyVIqhLK2kfT+YGNL20nzlBeij5LYQlPA8rzD3ThiBLWUmJTZtlgAnjrVj1Sr5kFuj9XNoysrPVvy3uIybveMr1mTih+s0xugeEG5iHC5eLLgF58E4CKwx8TN5E7hvj3iO7HnaaRFsVqzzxoF9qkhGtpKhed/1FpcfqqgYHFpXk4+AiSgjL6gk3hqVnqbnAdUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAmMNu+h7BHsk7E090sYN0O0dIiWfy9oigAX4q/yhkRNJNhRxEjmnZVadGrBt2FqqXP7hxpumETGoKTcTefEKAg==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAmwyIzGVF4lqe7xPBG1KgDX020UGmIu3jGZhvPVldrj2VDTtH7FBgSyWlkftaQL6qJlOBL3mj1jw7ykv+wujCb45ALjLcwdsfPHxJX6PJp8mXwvgNSvYjROnxIqQ53D4VDTBUELT4LzhCQM0KQMrsZY0U60k8go/3xrYzr+RBOs4CKaXI3N9M/MTQYzH1rWz2tVhNlfeZcHJL6VW5e87LNtM+UHJeo8XQLRFJPpkl4c6kSWRZPunjtKOKtVPyyn/mjNrsrqHwOv0u/W/FOLBWtkTKIShq+B83eQahnfy/kpZqxtykJfNFd035wd5OqRUWaQ5LIoNM0AeZx5iN3EZIKOADQEemd9/b0Ot/O1RQtQ3RBefULQSJF4kTWq1a0bosKWZJalqm39Lm3+PfhYKPP6EyemFhRl4FcotQHLP5j0s1boxzovDJ1B2GnXEMHQWLj1Duyy3MTIAff1n6ABF77R/bhZqEf6H+KQ70l6Wl0iKJupZKLbTSECzEhL6btGSgSHQAaRi79NzLrmScHuaUd+GVY8SCkNmHkMZPzY1oTPJFTwSAo/M0NX8VEleOPaFLsjXNC/hpCM1nNme1FP2bDP2ucuxdLHl10rYj5mKJhf9lZyd1/g5mpElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwX8LZv7WTXA4MGUrAZyGmCs2pr9vtszOAKPP8G5ijH+jossfU3/z0fmsocK1FrinjS97VHqjTNkIsq+Fy6uJLAQ==" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" } ] } ], "MemPool acceptTransaction with an expired sequence returns false": [ { - "id": "29fe3e76-a755-4ee3-b9c6-a84bdcc10667", + "version": 1, + "id": "1972b387-dd49-4fc5-9eb4-ecf0d7316612", "name": "accountA", - "spendingKey": "a3af1ee46af30bac344557bbcbefa5f6c5c32bb27e0ca323f6fcc1c455befd62", - "incomingViewKey": "ab40314f8d0c3c7dba11f4f48acb507e43f626141b102a5405b1f5b9a61d3c03", - "outgoingViewKey": "cf8322109ebf543ba9011c5e75a97dc569237e70127b601bc5790429a8d854ef", - "publicAddress": "44384734db76ed94eace5e6e72b344e0eadb9dd5012088e982e4d16893ad1364" + "spendingKey": "28f52a7087b4b07d8ac8e96bdc4797da0fc78bc6d5e698ba4fcddd347f6a9b2f", + "viewKey": "af0b6b041bc827594e0fbbe94fc3678af84d8f49e4100bc35612547fba131d032a462e68024a4961dd25330e8eda943c10298a79bde3d2f31857fc1f64417134", + "incomingViewKey": "8a03b1b4d3610011179ed34881a8d7047cad7c0e13d59f0067b1c3c6d2ccbc05", + "outgoingViewKey": "4202e47bf614c1700b20a082a7f34679a204c6f38cb166ca56b11a09c42d5428", + "publicAddress": "8326e893659ac947df0309f9b85de590a3edca0716b093401f64634f67b82973" }, { - "id": "2941f38a-c2c7-468c-9ea9-4f8a27ea3bb9", + "version": 1, + "id": "231efd80-4ae1-4182-a74f-7db74e0693a9", "name": "accountB", - "spendingKey": "94d6ba372f130e19f16b576f57b75994bcc0692d5d6aa048be78549e8c03518a", - "incomingViewKey": "8f8d33dae9a6f543d9b934cb422883bc8c5f91b96a2515bd84cfc047efb9d907", - "outgoingViewKey": "4e80ff56cb1d0dff148e04dd040b8455535e83e5da013137fd5e87676c7a85f9", - "publicAddress": "b5f9119a20c67dc5d3e677906accd0744e74eb2a771c75e36960798437966859" + "spendingKey": "c6ee73eb0d877d2c262457e2e3e3f83136017696c7a848b34919483e34899f4d", + "viewKey": "58ea6c466b795aec734c7b49619a70ca7c5b981cd59051d1c5a22a6ce96f29a93465807e1db6b9ec4f1a11651aee959e4bfff622ba139fda55e5244175af0447", + "incomingViewKey": "33da57b1c0c752378afed430026f8b09322ec980c9b2383a3f5274e13bd58b05", + "outgoingViewKey": "9af8f220a454f80da8e679011fb876ec7bfe2f1572b5761780112ee10b364492", + "publicAddress": "6476b56bef7d0cc84fef0cbc91975053f945a85a0a02f8e456e24eb9f6cf736a" }, { "header": { @@ -732,15 +770,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:E+y1v84D6RZU6SAZBmT2aZAQfQwoPymkKOQBrlxMPDw=" + "data": "base64:TTs34JzOOWhGMLnAC7NuvDx5h9NP1OUlzQelhEBWTWE=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:EcIH8xQDYEXqxYMn3LW6dPcwsG4RMLeL7kcRsZJd9Gs=" + "data": "base64:AQEqEAUcqwQLt7s5uCA/Cwih8p+3t0MsKZheRLSc/QY=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223281167, + "timestamp": 1676575129163, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -748,25 +786,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAABiX/yVr4Etsqb+9sb1sZCvef6Kbtdrlay8WvYTRX4Ta4TR2QCIdwx5fHepo5eTkU+eK/37jAjWrXn3m/7DWgHBZyxFJhfGj/hVGZA/G0yXSsmAEMPGI0mfXuRO6SK9fwdy7wBcIPF5s/+DQaoiQN+W3iuV06NxwBmhNmjULeNHsNSqz4Ro6bLwl5GFqD6Eb6kpB6NdOHt/hfsps5WPMWrg4sQw3OsrN9sIxxi0rLT0esBty7Hm99dF5cHtNSVbQ9FvKS+Xo1sLvANdbDzCakIWfyRYYho7td62sCw92XtHwtdkhxur8nuFZlHP+PjALEeExpBg2bg4PwnTgiAR/bcuEnTRHZe7kjtcdFmvdTbBOAmdKophyskA6MzQqsMIoanIgdic5iVXs0Zmvjjdprg9A7fqPKR96TBmbNCyPGEplA3Bk4y+AnPPs09Qcho8v4d0kp23Taxk/KrpKkGz92B9Jn/dTWOtNrEOGeqIlQ9O4rDeoRKQBjSA9eXYZ0r2nfgwBGbVE4h6NvoIVOdQUvN+UOm0Pdk4q9qIPLbRe+81lOrKHXgI/+AXX52vLJTasNWs0jJtwCX2TYSfuWGKMBGLshJoH9LOZBIcpw+L+dU7oA/lgPEkAaU0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwxcG3jc2ZUUgl7l7yrMI/wa8BfIt0va3GqWNXLkqQwIAX9FmkRApP2NEuCxViy+z1s3DT2vyt4oGFH/Jrgo8YDQ==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAIep3RogQIpy8lueugVTDPOmmhrEkWw5X30BM1JJJpbeoFfXvvWq9+ioFrbLymnn+/O/LK+IF6FjMyC/fJOSkbr8nJScJjTSFy4aNnv7w0sCT0tOb/kaXVohbCAyQkfSmjdLjiW2nKTHQUCGbBzGjZcSeC2ZW97+b5xwseIz9tYkSKsXJHcZI5pmJnqNodvjJlxgqVXxfQw6VWfM3ababGvo7gWVzSaeQk2GlYpz4pXm4lPhXrcHg4KCMMHpSuQf50vMMcTY0oE1nX4ethuIYNohlM/nV58yYVqCeQsDEtIwZ2VFohKHA7nJcJvCc3k27RMc7AIYdVbrLe/pZNzy13PBgnQuIil32adBFGOa8Qi6WBT+sAS17FEkpnMp2P4JrCH3oKeMmc1+MHtRjmlLe/L4KNqniOo5KLy+kEVF8gzgOu047TlGqXXioKzbxI3LypMv3XEzDjNkkhzaD8ZFtyOLF850x6QL1R7cwLDAM8r6DWw186mqc7+ORq1nDu2NLlXS1WvHIyBmXZY4o4JQ5onR0RzckQH1WSbGD98RdqxgJca1FoCagK0NrczV/oMzBCfL07y5JEZbLG9d0peRd0/bSabubn30Z3lm6PDDuCOXr5vugTHQwvElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwdQHsRU62IogoxafCNwKRTcnLbM12TMAA1Y2yaZmKP9wBCdUWO2EwFV0dWOLTkUAqc7gk2MyHxClR62pJn9+GCw==" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "26830738EAE92F93AEC1652EA72DB7B9E1480E03A67FE210A737C5FD2025241F", + "previousBlockHash": "1D838987F36AFFF66CFFE4FED8978F377CD5901E34CFB5E889925BBFA14BA607", "noteCommitment": { "type": "Buffer", - "data": "base64:SOZDefUKSvX3jVc3O5ygMkI5fpV8E2mJuGBm/j7VqyI=" + "data": "base64:pzocUQF322G4nOUYw/n+BHLoG3d7AWiNems6oQD4YSE=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:NweQvplpw3X/M3YJYE02ZbunsEm13WhKndfMbMVKIiE=" + "data": "base64:oXchQPYoDWDn4awE+/R/ZdpYy5cgNyphRIp7/81dtUQ=" }, - "target": "881271989446208257911980828427057262643615932976441214377264856368067535", + "target": "880842937844725196442695540779332307793253899902937591585455087694081134", "randomness": "0", - "timestamp": 1671223292292, + "timestamp": 1676575131511, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 7, "work": "0" @@ -774,31 +812,35 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAZIuv0s/t5ACp9r3tPYm0nE0qsvX1L2w/6B0XLn5YadqPB6T4ubcYJxPXLVRONyEfhoBaFWEFzvyaTwBS6LnOS1YG4Qdu3hH3X4TEXLrNOseg1+JxM/fwBTMR1BkaxMApNe5VmjzPLbbXDOtM7RpqutNAFhMhWqowm0+zM1epwgADljPIOzXv7mVPqKmdpyQzvwR+LjJyhRx0dLUcufJ6IWAsLV78X/+GqnE6PIFSReWKxk9vlvQZBm85IL8jN8oqeLesOHZ+FYpjmVx4MqZAw1WDClu16SqdGBl1ufyFwA2Y0ET74GPU7zBOpP90NGmTgGkR8Pi3MjPOdkuthl7kMyEVFHwo+cVBqhm35PC0YUUeYCne+Jfc30nsAx/E/ktix5qoCbiIYJrQB7D59itVVovj7m3WUqYxnPVmMfy0rAsyTJxe1youJCmJjhm1UMAZLlhk2uZJzXnhzx3Aube/hLctBQuL/a/o1MPP4hVOuoBFzHOJYetk+fKhErj0MHyk1wfoa+lWK0RsMgRfDi/FyuExxojwLVD1CYy239RwU+d5H7TDDrbSWouFLtThi1ggP0ML+6fwaGGpnbMi2YrI4+odHuWuFcekwTFj59Pu7C5py3IxEntl1Ulyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDhkiTLgaWEDGR7km+FcT9l9vAo4bCjuA1GI/XTG2eSIOizKQYyQGxxtehjU/FPWTPi6qsP3T2nIT4ByvXF2jAw==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAkjtfHZ56E+urPlHnGkgWOecxRiawZs/s476UYS8orb+U+J0VXWhS4DwEErB2lWodSSWytY7GB9uQx6hLY4ww63OUFRcZUbQnKFqQ/a+mQjaEBz5tepPU0oM3oDbTX2tRXTvcRMrLKPVG70u1kZdA7YPVOLGeR8tm5WsHJeLXSukBBKlk2109yofLYxPjUZq801LvfZ1nwfd4rZxuUc40Ihj2pkfWAso0EaGA4G8TDGmE1InxAd8gzH54nsVNU8YZGgZ/heXcsKYUWtoMr0zL+J8hIRg9t3HkEeZVdQKXIejT2rTOhDtWQmePXg6wo9IzUt929KEryjPqbWZF2GQP0kkNSHSNwbA+M4CykFQDamIS1N1p9CHJ2TgL05Lb1vptPIwExRIZ0JwQiOrtRbN7J1M6Tlgbflr4QS4zJn+JEdPUX5Od+Kwb93IOKIQqGvWp7Os4ebVtU8y3+romEU0YsLlpVXdrdwkSttVcNr/PR+j87Ch4aTBVfzDjIJ6S0RDE2zQbHfw/wjlQwlWl+n9TVPnYI1GNRFM/YjAUz2fAPpaFph5o7HaxRSXxFllMfLXHC60t4bfQwEpZgXnT6OHrpBzeeNOvZLquEDs6cJgABLge8yFihdjhNUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw/Jeslojro1rOSvDl5EciJPw5rv/GABShYmo+kDY+y0KGKTWePGkri6EIxLq2f4gZn4RuYC4OGygzYdxGh5rRCA==" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" } ] } ], "MemPool acceptTransaction with an existing nullifier in a transaction in the mempool returns false": [ { - "id": "0eade294-02a9-42c1-93e2-ad7985452e53", + "version": 1, + "id": "05033a0b-a1ea-45f7-a1da-f6ea26af0723", "name": "accountA", - "spendingKey": "c9339f5cd37a5f279f0d88543839d653ddc81e6398665d49b0075abf10f99f58", - "incomingViewKey": "90bd61f7af5b45ef9088b4b56258da5d6adf8261fdb0cc15065398d6616d0f07", - "outgoingViewKey": "b7570c1ff99194382a61c0bb5413f6bae0b6f37e338aa6883862550d333a264d", - "publicAddress": "fb95f45e6d4dc5a4b3dd744354174ec8bfffa00ecd36cbb16b6d6da2ba53a585" + "spendingKey": "89775f21bce4c190fb3f5b12605efb391b668e1fd2128ef6434dd2463a720edc", + "viewKey": "47d282d40712ea0ea897ca5edc4cf11dd8c95de2d2f005892a239d857c12b5558a7afaf6e4d791d26847fa33d23e64f7bcadefa84c94579a8ed8cd950b9a2de3", + "incomingViewKey": "9e2c3a024c6dc6fa33a1f338b9415f4ba9c075d1f70c21948dea6299c20ed404", + "outgoingViewKey": "b536419693175bb620d82794200aa7168e9c7ca0e7361dc670bec16444546d7d", + "publicAddress": "117a34ad797d41d295bb5de42e859854a3a5e62612ad3991cb497be9787ec3de" }, { - "id": "79970d03-b2d8-460e-b3b0-6f36488be4c8", + "version": 1, + "id": "8ae49faa-cf36-4c77-b531-9d250dafd409", "name": "accountB", - "spendingKey": "15701697f5c1dbd02b0faeacd70ae7e381fee3a648ca4b27fb277e32410e4397", - "incomingViewKey": "18a9c747620b1b1142935b332d13a608b9a72e9cab8c7c4308f7e9ea0cd62402", - "outgoingViewKey": "5e88b6127a32eaa343c6c41ee28cb77500f66cfcecf54db9dbf67c527f2aa558", - "publicAddress": "9970611e75e5d7c0ea4916f4dca209305b65d4009cb5568b71ebaddeea6178ee" + "spendingKey": "5b84238a00e4e8f4d2041c88626ed24fbd4caf37ecd9e7fbd40a45c513cf803a", + "viewKey": "c433f75b89f10d10a11db09e1a40a4ab613890d9c4a8c0be5456459d1950423cbc76ca2b38ec9ba7aa15b073ce67bb22e027acfad5f842a0b55fb4d01f583ded", + "incomingViewKey": "5c8b47d85a7c219bf5458c9deea13c5ed2fff4408ceb4391c097891484c27807", + "outgoingViewKey": "9da9d702580d3089a97eabbc9de217a61159ffd12a75c175256b6ca96a5f2615", + "publicAddress": "2814a3aa4e1208853f2bf58ae9599d175518235bd4631d45e3e0120166cbd76c" }, { "header": { @@ -806,15 +848,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:JrfhTYwITrpjBf61A2h8kcGEjdVmFJ7o+pTw1lOQUjM=" + "data": "base64:ivHpwlG97qA28eWWF/X8woQ8xhDlRXRSJA7K4VLKUjo=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:gFM6drtnKpIlca6nYeUuVw8aAE4oJeF/3cjUcVBdqlg=" + "data": "base64:7maq20KmB3HZbOac/Km38fwgdatNYlFsU9pplNosBwI=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223294291, + "timestamp": 1676575132003, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -822,25 +864,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA2WlPCsIDp5lvoZNDbqJPoI61l4crSqirGoGVtBe5fb+y02mMbZjNKFIjE6lN9/AN9mtn4kb8vwOesIwuht27bqe66XFBVk9tQwDZwZLQiMKh+V9dmAAvrAuhVx6NA3RjyL78g5vRVmUUh8gUSGjo9t+kapYGzUnDeQtL8pjeGssNdaak0WOCq3dNe6Fg2DlgPIXTj+42phzs4v8VtQwjxGHicdFTGhK3iaXNSFUbCdCU88po32M4khd65atCRQ23nGnzdDFxtK67u3emDDKbSYFE3WNztEvdRLnQCKMCp5XNWSwV+mA+kbIr5HZweR0kMHGN1kYHo2XPZa9LDq7BlkRII0c9zP05t8/22cepm0+GM/DUok2UwtgxQXqN0U1FbDZreHin8hZYMblHUpyzLxHDZQCeeM+BO2iTeecPfyvegREpwSTLvjAUIAhxYHBqV7WWHVHbFelAOw/reaUhw/3UEROoU3+GJEwG402tR0ggMxhX7jPHxD7miwma2Qm4Ci2pSrf9acr7fH7ZeLmy+dwQYOa2VjLTz1+c18IcKSjKd+g+LxZgqX4aX11cTgcJqcr89CS9cKK31Z6gqKcJ5bBBGp+43IL9LeaeCu2/cXJUxbhtGg7Trklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw2QoOuOqfsGDtRm16Q/zwO4sU2WCY6YjjxAJyASnUBebqHWJeZcQY9aUUXdpZmASOZYl79sqn85tD6VQoMMbKAA==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAh5w7ZiFGwY5HgxT/IGxPQZmvLfNjiXfVsGy9exwHUoGX/PriA4rpvnZE/Z4n1p7z3NyYzD7VQwlfo/HzGuPFuZqk2307rFSuh0wGpRjXuOaZPkeooIVnxdXCRoWfDZpK2W45VqSgqw5128PatkPYiAM67cbnDhCJZEqbg9FopekIwTxnEcX4lvmd3GeGTm9/6Do7ta1k9/wMX8Gxtbahw8D8/0XNWkhPmdZKqiF2XGaGF1n69xkN/RJwTC632iOUP32gMRaJFczVm5b+V6pItsMcCXlMBTSY8AaqNm0I9GpNq2lU2nj39p0Tf5meP8qVCZX4KERUn04PpIsqWUQwkurEawbmRGGzJAZGNLJCF3fYu1VAn/1RE81hSmH3cppMILA2t7yQFDLrqAomw1M3MYEjwxlfbr6Npa/2/F+1o9GiROML5uyMoHAbpJ80WSU47JQvpnvGr+1X05latxmPKDes2/swuLmf6pAQDQR6vhcmSWpZkRGfZasnR4gLxZclV38ejOKMw1O0uiAtpemmzHM1diHMq1nwa5pxioiSKCOnZg3CEcpql/vgXmEeWfDt5V43ocy5yv8YKcVlhRxgxt08H9Tzes55v1+hS02pK8MHMSvQocJEi0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwvRXIUhoRfSyi3/jDAQ0UgE7fEeFdhyFxv6G6u/LgF6h704IDN9bnPRfH9zK2gNkn2/PM99t3Oh2jaW3VFL4rCQ==" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "8A2551F8D0E157EBBA2F7F65EC396F63037C02E101999590E90779AEE23C74FC", + "previousBlockHash": "3CD45D097C589EF27A72E0B361349F3C34F511CE2E2BC9CFE32FC2DF3D697DEC", "noteCommitment": { "type": "Buffer", - "data": "base64:N5fZcbw14jCv83GvzogyhQB8nqIsNBrca05pFahyugc=" + "data": "base64:FD+6CclOqiaDH9nlSpgRn32nQFfd3KV/ZiszZz94SiU=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:mBqJJDmGOzkfn0Xnw0DjjIHxFdVyw7ShhCaATEZkLGo=" + "data": "base64:3qOlpv73oMnyzzo0fR+3F22Xq+wgLXd5fdeQpUMmJr8=" }, - "target": "881271989446208257911980828427057262643615932976441214377264856368067535", + "target": "880842937844725196442695540779332307793253899902937591585455087694081134", "randomness": "0", - "timestamp": 1671223306128, + "timestamp": 1676575134119, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 7, "work": "0" @@ -848,29 +890,29 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAA501PpHJBSC/LEyoNA+uWbBwNAj7b8ck4R3XuyyqoWrmwjQQjoEc5hgxriU1VeX6Gou03AWWeRrNiD1SRUSyAsMUOUvHWCuPS389S9rvPXJii9bR+HDUxGnIDGm0IsRHzw++BLAaaUamuaLJSV94/TovLSV8+fsRi2k1apKeEGAcXN344D7TjqDhXyX9HVAzsVxYzslDCnYxbv7qVCkY7BzGsXbpYpopl65+LrsDFeKmx77uqlb8be93MJUF4vFJasupeN33hERx1aWAD+qQZD7t1f9t3J2maVpi3tP26Qv7seilefZz0rnkEMsQbE5D1b+FqY8Qv64+7+bDuOKm0UUIyyV4c3gTfnSLg3750hx5NjoXxVQgx6MqYaXeUC+9Gr74OTzWnPkqJazoVmzBTNB2c3pIht+M02fWVkNseSlskml9BHp+yxP2JCY+NlsPupKJi/KngManrOTNhC+ZNUZCvQ7jqSIxQgMURU+Z650lFyJevsO/gf1dY09xUBmlR0tqXRVOmAPnnmDcZSFJbgzqBiF3JHW056E+95D7kQECbJqGs0rOCqkZp1rPLXJYYBgxusKgwgUKO+oA/loiJ2Y3mAUfiMhcH7wiefj9zpHEftctcFTSXDklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw2fK4cz/4RdXfPEbTAZ+WVi1pHbPcQc58FIuPeQGIONgYfgmcfQryibSUaZiZQhPRdg/un2eZEPVWvKtzOSB2AA==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAACQcacHnFDFC5b8v7AyUTCf9cDS6wWDo+C21EeQJodx6lzGRKBFjrZWqkkJ8VAAHe9FRQZo7GqtuJBBY1HR2E8YG7SwNM3UIkvZ8HaQdVlIqT3Xpl9fQvxzIMD0T6y++DFLsAT6+PZVlOHuQFPghjYvapXvx2r7vy2rYob4f3T34N3QbdbY4mnirs00JMKwz4FSyp3DshXnJbWHjm1fvXnQMBfWwJjOHLOweewkqM+VC4jOPYQ1zcFxl6C1swHWn0Mr439F6RCx4rope6f+mRoi2LQ7IvG5DZuxFZo+5dvhvpQVE7vqt4CE642dOzZE2LpkLLY6cNDhpzCgUj9CU/Vq1dLmZjVUTjH6cblZKV4DRrgu4bUC7JnEg7323oYDxS57QO5rzmiWhzb5j45d/DSojj2GPde5j0zLy8LyaT2GFnropCgwOs59LgEvYwj7kU1BIDxefc0PQQmzeCZ6wjO3OzIzoRBx/Ou5F3p09i6Uy3dQR26qbZZxBT/tOxVUWPz5+tdtXqddJ05Jxm8eXscrICM9Otwc+8HLRJWlFRzqjxCVIZeRhe+SC/AzhKJEiFXGWp0ElY51Qpp37qibuKjJ72IevXl5CA+YsYO0gIC1tR/LdI03zM0klyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwiOfaIQcAgLiNVGmSs2uv8ljZ+gWPRcU7WYJeGITy0EiDi94H7DinAyDx5wxQsYO7P30mMQ/vii86UwdqxK6QAQ==" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "8A2551F8D0E157EBBA2F7F65EC396F63037C02E101999590E90779AEE23C74FC", + "previousBlockHash": "3CD45D097C589EF27A72E0B361349F3C34F511CE2E2BC9CFE32FC2DF3D697DEC", "noteCommitment": { "type": "Buffer", - "data": "base64:3Kwe+Uymi5qXXk2PfpiNCA1GFe2AJAxXBp5RFZxqIW4=" + "data": "base64:76oAjBj3zPJDKgXQr3XSP0gcapqPAiQqAaZJw6MrrAg=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:1trPDE+U+8OPgzO7gdf8XzOxQJxEfYA4YJod7bOHohs=" + "data": "base64:+66kTyUCyoDCl2Fsg9RQQcKluUwi8cqj0KuGOdMrwV4=" }, "target": "881701459226640133281333645594906705754066038206936556099670930859474975", "randomness": "0", - "timestamp": 1671223316942, + "timestamp": 1676575152076, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 7, "work": "0" @@ -878,31 +920,35 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAGRDnyDVbIjqA9N5DUkCiCebnrlEUh9XKpVQwsbHdBIqr6LKuwkvEQlTq4UJmL/xrQprsulOreeqp0YTFZvBGgnfiypricgXr1Wzap+/LeCutmr2872toT3ZAeXxNpfFLLrgGU5an22cCQPhNeWvHzZzV6baui8y8VXnd+/lN05UAFklzJ6H33pnvWuKU0ffc2pkJCjS7I3NFO8kRH8x4rhbNaG3Ebh8YHVY8H4T7nQ2M73s8wSqdN5qdEMCDD9M21IEqWNQ3GrvPzVbEG/UbssLcp4pSnlqubPDxiLXz6H5PwdQsyAkb+juskKCiHPcj37LaHAb4gcfvVTWxniJJ5WDGJfxrS9R1+eMdd4e3bNq0zZyS8wahebV2FjynibMJdCicAR0fdLp0hDsY+hVRzXkkgW+x1lZcQBYZBwotK9Db2fSiJoyZtOzkqzqtCt3RFwATrbjr+9SX1/SqKae8Ib7FMx7/FYfQdd99rYROH6XM16mGGUPbfeChl7/PB4wJagbjGQN9vN2RFmXGitUEyInRQdYW4FPvUhsoW5OifViL+11Bda8A0WaCXjdw/huP5xKoKE1evZUtMTJ4YTV/AHFZgr0Zc7xBwixiLWwE8+tkwnOLQiiN7Elyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwOo3Oc0DbOzHJ+y58juEjgu2f7HOOYlOuBHe9oi2MMlC9KcYwHrXO10W2r4tEuCv/CiwL4O4vhGkMmJgyJsQQAg==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAdwYRDm0rN9PX15RvIyazqCFR00gzOnYFAGbVl8HDrialFfbRNBV4SRB2LvXwqlcFrYYepelhy78jtGuV2rOMQbIW6n98lIXRnlknhnNQtSmVziIWRNiHQ9VXPzQf6rdJ975TGP2AJE1mO5+PacyDqXirg60sFI+L0jwxyxPPeUwWsSdL/RkAXtYDCR9UpnyNARKneF9veBBpTv5o7HG9L+T0T2BK3l2uAcxWtkZCp3ORF+d85man0L91nSff7rn84yJ2wdPkPJQt7YmR8AALl+fz6bklqoXMOKHnMVks8ybqYCICrRHKeFzEx95CAmrO7othI9wPdPk7OX/mMBGv6fqlhX8/F7vEp+xlI4qa1p9M//ZTY/4RoXWLLrVuSPU6JC/zyF7ZcqvQIUjhep+3k6ra2hJkpM3agvoNENrbkh+kIzZ+ofDl/b8jfQBqI4zedh4PUDl6OZPvOs0FYwvUXy4I2Dwj1UsYXXm17Sd08lusKSodHtW49XeO+bYXTJ+mNqTciVWBExJ9U6DOzTQULpig+BWTjON4xUM/GxIPAFa3RiYFEaRQwwKCO36jokUP9qp8wlsXfVPu/ztCRfz5i8ggkHaQYJts8Z9wAC/gsJdaoM7GZ12f3Elyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwLHprp9o32/c61P+dYeNE6OXVrVH6fLROQk5fbcfEKWXpm9uQeGLI6nLfjckeuxZLhTldW73bVO3aJnsBh3nzCA==" }, { "type": "Buffer", - "data": "base64:AQEAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAA7Bk3OyktTHkze/prg9frJq3e9uLe1qwP1PyEG9ji0leJ2ELAcd1dzKpYpmeLwOm/4WMMW58FA/CvJ80dAh0ChKtw7M37Ey6bj0cMVruPNEOyodwqsA0OHul85fG+/QgCK0hqbiU5vh+ck4A1ZZuPjmwDFodcVXKHKdnitRb26XECiy6okTHLd2wb/JvuArNeWw7w6Bl5dUtZN5+P5K1PFvkJRHIMMqn6X81ZHWowcZ+v2I80PbJhmhXeUk5BiGUmAmqUCQ3PTbvLB10idikXJ+Q3q8rhs4Z4einx7cdIV+jopyBK0RHaZ9MpjtUoCRQhdq8IjgTJROb/9JLv3f5I5ia34U2MCE66YwX+tQNofJHBhI3VZhSe6PqU8NZTkFIzBAAAAGX6peludg7ySh9h4C9nArqQlb8CwEkbQDKAC1GkTwTCk7ZsqU2ykCKpQnkX+Kue5+1jo8E/VBZa/KVdA8LyTu/53GGWtMvSZqQ4tw8wgTDd3m2yGexsUaNrjCCidTvzAoye32DW5X7A8jp0QNsKPR9t2KexPJvzUJ1ru9SFAwNTMPoQwZRCtTeMltFYFmWrpoUBcUJAjd6SFU+v3WNreA05L6RmLgeAMTi5ScN8LU59BJbjR8YFb1vFBIWhNyscMwimftc5EsO9JZcLF9fLcQmyOXaIoCIJyW2yqc6GJ+uq+HZ5pYvp2c97WI+gom/v9oyHLRYPnZp6jsHWVn/QcSqQVD1XXIUNFG/9q2lXydpvJ+7xhQWIc6Maz5EclI5vO1/W6rgRAR5C7JcQjKsZAplmGQF8+CFKYjGLeunb0uvzi+svVMvNqli+BWxO7hqin/0ILAVq4H7zzqdX7oyIkCfpyhK+hpDT3j2qKhx3JzhFNE1zAy4xy3cIvlEua0BkNGe4t9A8u0GlqHTa0fCPsJXl+9OtbkU9bKOtXJGqp4L8bshtOUD9GUQz/TEBExOKToslz+zOkXBYjFMKfVAa1CwfrumHdA0zq1nawVMkPWrXG6hjBzvEQFZaxticsWX1W/17sl2+jqyr2nwW2LLRkdhzq7o5u4rO+WFI1rMeI5BNLARknX1Ar8LiR1d5aIDGu7mEE2hkwyEBmszypdvKgAOndMXxWSvQDc2SQzyHZ5tyl9dSfcrg9anS24zjdUq04HebSDXLGoABe7Qu6JoW3UdayPskXLenRGPqRye21DUTcETZtReyPtqDL826ttprFLlsTXPEmjjr5OXsC7kew9jWBjJQ0r7V5QX5mskthCbCNiZ9gGsElG6vvr04emH895sjP3bIl7MT70Oduhe2C1n3zmBFNzYM9HpSudMEKB7fW5ojLb0OkGIH2EmQ5agq4Dyu9gL88dTuehRn4Co0VzNXjw70r71LIdzcmSgk7BV1g0eWeW5Dp2mE6ZPCu1LNHtvke/8+cL1s/1N70bg0xfXKK96EEZfY6XYZ8efABcKF6OFwyb0yF7SDzprQI/Ko2oPiiJJUS9+XbOcA5+nL6c2K3ze1UZnI8l0nL1tpqdatY15jYxlr9Ag93L+T4pDMm8P3iAcRCJIHDqs7XSiPJ0cOpjjUX2l5tbPS3z6KoHIp/GWNyy2unJr61VovGwWeUZQNbnSWg6x5B88/+lEXUB3A8NS0CLqNzgZ+b6cY7VbavjQq5x0V5Y4Vpno57rg5ZUnRLihBblWgteEF8/9ghU5wzQwu/bWMCc/YzG6Feo+4e2LK3S0HGzWwq7R21DMiHtviI0+HSkg+iqrr4wnZV/dUR7zUv9i5qedrPE3j1iFrXtT/BMAFG2hIqZ7nlmCTSCI8QX9qmyFn6WL2YEEsfrZSvFZEulr9ctw4c9LsBMZxixppKW1Ja0w6xL5QibnK5NuhjCWawNCWg2Trd1A4G6VYmKUsIPe5NJ5A2cPCZ144ldeaNIoOYE+LcLTYcuNgFAHP7VcsPqsoaQ1mw5ur2rPFEWn7y7ZxqCweCo9EJXFDmX2jc/pVdSlvZ6aJ1ElFBA==" + "data": "base64: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" } ] } ], "MemPool acceptTransaction with an existing nullifier in a transaction in the mempool returns true with a higher fee": [ { - "id": "d765666a-b873-4238-b814-640d24d890a2", + "version": 1, + "id": "32e9cf2e-33dd-4897-9f52-e33f089cca7e", "name": "accountA", - "spendingKey": "c1cf770a77d3ca0149adcbedcbaa54e6a2d425f381597415f61aed020a4572de", - "incomingViewKey": "39e97ee20bee171c12749c9b123a50b0e64c8cce11c359f7c36989e75b499603", - "outgoingViewKey": "2d67cfae6515da2271e8aa7a2dad68afd858ef7c36b25e33fad487c8bd87f7a3", - "publicAddress": "2c6f5b6df887681c5684dc1715a6939ae686eef90d295edeaaf7cd495fa5790d" + "spendingKey": "8c16303f4e2b6197df03dde989786e1d80db2fb2878906b51bde7fe6db2b84a4", + "viewKey": "17a6c371932fa30a3f39f6de6ea23a56eb9a0036246ce851b4560d89540ce2292671e0461a70333c1e7624df44b5f755a89294349dbc728f21504352b591221e", + "incomingViewKey": "c261a94a671a4409c0b1d1cfaef9ddf7c2cf37d117d9de6cdaf8b3336c2a4204", + "outgoingViewKey": "275862452e75402e5e54f0eb62fe67ce28bf392090cbc3558f7c5198f9df9b3c", + "publicAddress": "2662d8b9fb4ccf8f0542f81168bdfe8406ac462e9abbd1cb050ba9dfadce9fa8" }, { - "id": "c9b6a83e-617d-4846-a338-5d4f11e445e8", + "version": 1, + "id": "f9e90d18-1c66-424f-a323-8b5db40a6ab5", "name": "accountB", - "spendingKey": "f5e1eee5ecdb18dfef38c93faa8e1d2de6bfca24dc8711b00fa1c5bea4321928", - "incomingViewKey": "59dcb760040b35aeb0014b4d7fb6a0d617e8bf6cc389ab2b3883d8c3c1b8e007", - "outgoingViewKey": "ee15926c6a7f8360e4c6641e9b26e64421a534b9e9b5e194cded6d1febd752f5", - "publicAddress": "ea233fc5b68c93977d703cd39ec01008a1c7e9925856b5e79ed496103902944d" + "spendingKey": "d1b19e5c5e8344365c7d0295c4669a67e9d7df98dfc4ca079bb1675fc6a8b435", + "viewKey": "b448c607afc3c14af65b6dd61228c819ee77b5ca8f237cbd692a887879bc23247600ca33423c836ab49bf2d6dde8790a329fa0cdad39cf23fceadea691f453ca", + "incomingViewKey": "99c6d9ec712b629457109887ecfd868114d2c741f77076fc179ce633db0bf607", + "outgoingViewKey": "07aeb964217d2ef51a6dda44cf89dea38c035d10dc6e517247f04bed6ffd750e", + "publicAddress": "40a42895ab9afc5ae74869b002a4287f95a8672c545337872147a222cc3c3883" }, { "header": { @@ -910,15 +956,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:nsCvLYgGIRgMQ4+oLtIDGMg3hRnkm/Pg9VX8m8gx+jY=" + "data": "base64:9thk/hgjIUHSH/q1P5Y/4BE6i/5Ediv/UKxSn4gGAAA=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:bMO942k1NaxRr3Zw3ukyPeXxUCPyHaAz1axAkyC5BjE=" + "data": "base64:m+2PWeYHlRs8WuoUoLpbKV/GQxsp84PNlJ8hltn2Iec=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223318798, + "timestamp": 1676575134555, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -926,25 +972,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAl5seSQ2TmZC5DF5yRzhb4latAibk3mFfKxBUzLg1eIGp3LkoPypEbwephVU2slzXyx1I/XMNiyW0N4DbQ8k0WwJAAF7GkgmQfVduHA2QmC2uyyuNGvbTUyFX0ZcKlWsQI5NccbWrgNaEzy74achmIYauvd6wk8jshHRRFjyFk58T8esRCdumwk8FwifmyTKu0b18QBuu9CWBt9I3CdTJGOMYT4nptNs7CYeHjzrec2iMCblcRwVGb31UjuIiZSHx+qHgMxA73NqWNaQzbPNAPvAN00U4X3Mnjyk0YtFpKbQwL0O5bqBplnXAF4/rhgy+mTKNJQApFhPrgXlsrvu2DBRJYjxftALrwRvfbDCktjmBLpcLN2N9y/RYQa1dxqIutQyDYOVuWfh0zj1xgd5sQyKRNWpgkp/2+kmOzFLyD8wkfPU2D+EgecKdgmd3TsVVw70lljRDaSOkguHHf1sBslkSmDa+Cx85SU17HUsdokTXp1cVvOcjjAHrIlGM66310KeyfS8FUjrpUFSzfQP9iyrdy5h3VFQxyExpavlBO3KIJtj0OU66koQwVQZmNruWDtkIM8h1s0WirmoZhg9vrJ1EQTcL10itJH6+Q4j4obMXAQgvk8w24Elyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwmk1HONzQi2AHqAJUqdWv2kiz3tqVazLBpmuj1fPcQpQ39mmnRDJSbX96lDPqxNUG5XlEkny+KaiARVAi6+6fCA==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAArOTmdM5LJJZ5HJUAup4K75DqdjwGyTlNWktBRUBeWROlcyH0GLyQq4OzWxAIJl7C3A3vi1NTSFAbd30ZRFbeG07GzGdZquWnkndfa/d6VL6SUVK0TiWFF6yF2whdDzJPXW++g3pWFI+N0VmIneBz1xxUwZlVYYUeDjqwhaaZOfIZzLAOTti+ch+oNiqXFMFRr5N8dOrpce8iyqPtavUEJaXtFP7uuEZUfeUPq+BUq0yLsmHWNVF8mmu8ebQxsIGyZGzM4G28QbremHQrPH0cixeAlHQ1K+m7KuY/6gx1wDV+YBoEpislkOx684z2oynvyUfgU2Ee/hNR3+B0gVAPvytXD6aM9LuBxfKwRRJuNnsSbNH/cBdVnLFv+Pe5+lIicBYscrne+cKh7XgOyM7zcYc/g2Q2Qbnu11NhfS5cuxPTm707vkxtZiPom8ufQg8+HPLTsIT2frrIgvsuqz32nCUJxW4sMM4COFpBnmHMspiRmXVLk5pAq6n1PSJ98Nmrd2WFo+TpRzpHmOR6Zxd34bH/1z8UiP7DXL6fGBaJPj/edWNJKiIDe2WkrC4C43x3cZogRUtrbVSSGNZGFeCmmlkNyb56wf+kmL8fJYNAWnoR+J9ZOv1F40lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw2yL9LK2O262G64OzS8JznXH1eP+h863aETG9pR1baYef3pnhlR3Hkz3dyFXDSQH9EW+veCgzvBes1V9GH2FBBw==" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "3BA50942AA031F89396A23456B97E0617270C80A13BDEDB234CD4D2D48BA255A", + "previousBlockHash": "C43DD612E2466BDAA28A7EB576BA4F5890B833A3F68BC4A5CFCFDF41468053BE", "noteCommitment": { "type": "Buffer", - "data": "base64:hciVOWOGKF3TEk2AgWuDQmrIWF4uTyKnNBvIRuGoj1E=" + "data": "base64:Mj6WpVxP+TwGTUoGEnFCAAG0WWItvwvhLwi+xRbl0gg=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:lCQ4msVz1LDPWo/6pHGmHjt0QN8g8YXKwFvOB9Jx4YQ=" + "data": "base64:qcJwfUwc2xgFrAS56ctZlg0WBFIcd6joMC2D4PhPruQ=" }, - "target": "881271989446208257911980828427057262643615932976441214377264856368067535", + "target": "880842937844725196442695540779332307793253899902937591585455087694081134", "randomness": "0", - "timestamp": 1671223327813, + "timestamp": 1676575136420, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 7, "work": "0" @@ -952,29 +998,29 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAmMwwDfs2Uq/5VoECMQUqEQ6tnv0xo4V10vLSzna0UbupdSjcjKvAZFzLqxJq0CGI8Ts53wek79UsRXURpfm57kSDhUhAuxD5jwu8JX5jZ/mxgIytAea99H0kAcjq3UCggbC2GlQoSICVwvI9PvZe+3eiNTX5FI8pn3lcGpqwJMoL1yWHc+AGY4G2sVAK3OoPu0MW044Jm8r+10HurM3+Ak0EYBptyH/kEmKQvM4CzHG2vdb1oyk2/I0mjHkmdcn9gezNN4zsYeYYbTFdivURVhYILiMdLWNQ0GSv3Dz/9XJtHLiEgtB8YwNasFbNrOcU0oFxcFEUMihWbABvKh2ywgSSJ4EPFISJ2zwGrjJqGB6lafPXE2Ibw5ap5xwBw8Y3lVqZLL0d7aX/6BuVJHM5k645NmKo5gNnSGKXSXYit8LDQMOsfv+RhYvuvUF1kNqUfB3oJvAlfAiFZBB4bKITdwPdwGmItaSonB0SNlNKLfe0M7opdk67zY90OEmgjPKbYucEMpJMGunR/iRm3EW3oSUH20Y14Hrlk7hjHRKPwUdvwhYzWf7+lYjub4hMLCpXGYlPi3VrHNzHjt7M/6PeH7IMG8tN7dCJdSr9BSO1IO0lJ/UFjpypAklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwykxXwrTjvyVel+47BB+PjYcSEzoRunB+Guix67EJ35+bMpWSzC3O5nErf50LXTP7+oQFR15kICiXr+ynrji0Bw==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAJ2HfACvNlB4xK8o49I66R/nTKNmxa+hI95CNrrrFwLGO8QNzgj5SAPGgSmmgI/M9++aPnlU1wJod3lSfLH1XPdjVQy7kf7OTz0CQKtJYidKE+swOMSrsZSXcChsOzcpGqVE6iAvwBgF25BwuDJ3nKfQSgPzt34iQU8PnQJmMqvYAHNT+L0cy5ojgE6ihJume6lHMuELeXh4zhT+H5cWsjUy2kLaYroi1MQaSpxcjvC21hGup9MB4S1/AbVayhEuCcpJOJLb0e2ADRxYEyBZG0Vn2s0ImM86tvI0Yp/ojmkD0+pVdWOk7PDNuxtWPLhLXT81Uv4Kx6PkFn7xJm6WrbzPjbAlMCddKl5KgZVZv+qV572V2+OiSpmFvr1u1g30nVn+S/TDmfPsWZdWbqrzLOzULNrT3qYwAohEDyRTO9aofw7GT8OhGZvWzImCP8GYCTaZqvb9jOXGBTIKAID1jb0kufkri9Np4eB+gfAwVGwhVeaY9JDUBLmKyHWAUcTle+YB21de35pFdc9fY1sWQ9lKqF2CuH/zOPerYmvPs+/wfYg1yw2M0bTGNwzuQs9eVdxhh8xyVhS9xmf2sXt6wT90sCujpaePp00zJ6JGcj4/S49IGTy/z40lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwiwjd57k74fnY6bAcE9VjS/Aot7tTp95Z7oBvE+CfqbzzybmxY50aw64OeQpmoRu2avzu2qeoTGqKehgR7P9RCg==" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "3BA50942AA031F89396A23456B97E0617270C80A13BDEDB234CD4D2D48BA255A", + "previousBlockHash": "C43DD612E2466BDAA28A7EB576BA4F5890B833A3F68BC4A5CFCFDF41468053BE", "noteCommitment": { "type": "Buffer", - "data": "base64:xTEcJ6xn9vGIun1Xt8rtgdTDMiPKxCR1HRTE3c8cCT8=" + "data": "base64:cIML4kcl/XiCGWbUd3XnslgB9QmmEZqwvp4Ew7rg/Bc=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:fNyeoSEWVq/F5XAsbpVC9fqXAmkZLV9Oyi6Zwtcgbm0=" + "data": "base64:UeO96R4qoICLVa5L6lgCnn/8wvb7MXDumV3RlorLi0M=" }, "target": "881701459226640133281333645594906705754066038206936556099670930859474975", "randomness": "0", - "timestamp": 1671223335175, + "timestamp": 1676575154204, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 7, "work": "0" @@ -982,31 +1028,35 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/mvKiP////8AAAAArTUyTitrJ++PK56teIS5NWTjTJhj55z/4rGYIZeU5JSUkFZMJOO9P7KEtdlgG6ay5ayO0R56YbR79q/1/0Q5y6T3b/nt1Yu20oQ6i4gwbxuZXUcoV5StbMSoIG3BA+/cxnrl3nxnuiwBmK1CB1lEZ5eZjJyscPVFj3xvtzMcuNID1tDCbqo/YIwy5eXJUabzFNZ+u4XVNjJ2R3M7qM4DR7djftISXJ7DVBNZg+n8gSqT5mJoex0KDREnw/jx/n3hcv8GIihT5sE7sAHHQaViRrlhu+gCyV71TSAnXAppdCSYWGMD38CBTIecCYyeB/RWyH7JQmsp5xzeUPHP+y/eXC2cc79hdDSEeba+sJwYdS2dfIxvBL0VXMuS/LekBYQDZ4pb/zO+dTQO+CYeF92sQ/Dqz+Lpo1FkCJTV76E3Q4O6S6/nQxchz9/Ntr9jnY75zIKcTgIluuEXmUtmQOxPJ3QGpiy2pcH5QRL/U8hmp5ycscMFjVnmnp6mbDisp+rotgMaykTDC4GPJEQCeoeOys6cigwAbnc6GiJGVHbAVqDFBIETsHx9ngQnfa6VCs5TLMTUCeI54SZnNmIZszuqUdd6CMpHjvR3Nu4yEN7WN58HvPnXfOPShUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwrXVmIOZ9AB+rbyt7XgrEM53PMD7eGfHWSihir3ogUAzX0LhLFMqvSO3Y7UqjcpHBCEwmXo4aBF8Xg6qah2yCCQ==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/mvKiP////8AAAAA/ieFLG/g+cTi7tEhuTFekZfQQ4F3mFVmh+bjj+6zNmGEn3+uu2T+cdg0CpuaW8DL1X1/8SjHyc2yFUvDnG0kRQevZssWHYVdTk8CStbep+WTCivLd2Zg1svZ9R2HIVgreQ05OM6PTKwJ6AxYWPKhO5IWr7JxvXDzHxTx0FvOHSwXXD8SWTLBGGHkLyu3cy9p5vtS51ZWDQGLWT+UgNrR4dtGZAfQXjyyHII9PxVYdEqCCEtlklrDNyeW9y5fSN3b9hcatnEmScJsYQHgeEks12CxmeBvJwse+7wg4+WnuK6PS8GKvbPMbJ7bfsc9tCuyYzwownYr+KGQLcLw9NUWoCEgMEf24ZY0xZaRS80CZTySKjYKOvSNwVy94KtAb2YG8owsLgZtV2zQrhVDGe0PV9it0qC8xbZNQR4d+YReCMd4EWK/wijUdgCsVEXFv0uSRO+Sbfkq+Zl+lon7hbTwDuljvPIha5/R729XaSidQ0bLaVh/iT7MZVwUkeX/M7+g79Q+zv8xokYIvh6JknrgtBaW6aGimfQl6YjcT/PvvOJwqQKIEnYB/P1MKeyCucekaORLCnyGq8duldxNakAvuDzJxMBCos//RbBuItl9NqDXD5IsPWz4hklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw1tNaUkgBaSh7MWF2vbhCGGmIMfATHxlOqzCK3mIq+yQ/2Wb3YdD2/mZiLe4MNmv0dI6Pd2M/GOXlbSB/x9odAA==" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" } ] } ], "MemPool acceptTransaction with a new hash returns true": [ { - "id": "0d9ab7c8-5cc5-4087-b831-c17c9d594d60", + "version": 1, + "id": "51c825bb-4cd2-4f2b-a225-e9d459444241", "name": "accountA", - "spendingKey": "8005efb0e4e11831946511b98e1bca11f6c4040fa5b3276b258498aa91ba89a3", - "incomingViewKey": "e4d999590af5a3d4d49d7ce3eb4be50d00fa03635d7cc98e850c7272f272e906", - "outgoingViewKey": "6186405ad725331c5e2efee4709fa0b190da80adbb45028842c2a25e4d2b631c", - "publicAddress": "81e039e8f4ee9f89072fc6b3ed2da541d4a813697b90a94601107e962ccf0209" + "spendingKey": "3e0fb3408231479fe0ee450560a6617b6a0aedd4df233d8e0f40d2fe51f5ea9c", + "viewKey": "984998273cb80007704a944a3fabda350b7979664fb3a113c1a59a741b84e8261f2b2c14227b11b3ac7cc39807f364842e0ad55c9502449d877b3841205ca933", + "incomingViewKey": "f9d449f9a33db5d880d5a62cab81bc44b4799a0a9472555aaf4a8d377f1c0406", + "outgoingViewKey": "5d9c94da10a539a33a585105e7f89976fa4cd91b4df82207e815e426874dda0d", + "publicAddress": "e9c88c97a814585d54dd4c95a5901cc0c8f7ae96a6e8b5e76842d4aa806a6dd7" }, { - "id": "a42a97f3-5b2a-49f5-9f5d-48f4f3293c1b", + "version": 1, + "id": "dd29e194-1922-402e-97d4-83fc9cab2320", "name": "accountB", - "spendingKey": "e06652ed13cf10eb8e86321333e5bb46e953a0190785c233c64052b959fbeaa6", - "incomingViewKey": "19fd41542c345b103a5483d6709eb407656918653bf384dadf411f9cc9d3cd07", - "outgoingViewKey": "59a07cd0498c768ee362bff84bc9431612810b16e100bd5391df0e8a21c99709", - "publicAddress": "1bc91b2ec14e23b26203b60043bcae0204f16432694d7561479ecde302563937" + "spendingKey": "21828dd7cde341d860b9513c31ea673da2d6dbeabd997e6f4e1d856a961324bb", + "viewKey": "667c3a1ad9e949c1d6b0c929015153ba35d4266c367037ebf4c46679a2843f30c6c65710e4ae4197899a016dd15b22480c2ecf8c844bd99f734caac6d932384f", + "incomingViewKey": "12f8cd3a537fc48b6b6a48d117521331fcd4963c854aa56649049c0f14a54203", + "outgoingViewKey": "08ae09040ee7332008fd6388872b13159637e28246def947c2bf3277031b5d4f", + "publicAddress": "40012fe61883a4fa7727edf3ab80a06a870f99d42c53b5ca64975ef96e929ecd" }, { "header": { @@ -1014,15 +1064,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:lxNs6OAIeYZAyIxI+qUhBdMdH3WdP53TJ/BnbgPA2lA=" + "data": "base64:05OjP1tCxXy7/KKlXLWfNeaCWTgvGgDf1BTwC/12dUc=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:z2+KiHlFA8Ye3EmBREi87sRYXbZYzkJersnjbAJ8/+Q=" + "data": "base64:ZDx4jASh1P8vLTT6Mho54nREQhoKH96ufspHakoOPFU=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223336553, + "timestamp": 1676575136793, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -1030,25 +1080,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAqaRuGfcO4zUztQzySu1L2q5/AhEPFl57Bf0tbnag4WCq8zY3cprBHtkHOAzp5AHgX8x1rGkfCnWXKrDPEBpQtEex+X2nzkxukSGiOw9NHVyUArs1fhV6cbPlzgD7WrQs95N82mmdQTp4HxsmyENAHuvnh1CAc+d25okcm3nXfI8V3eWMc+FpZp5QagETHY4Lkn28wL+CeTqU7LL7THHtPyMzQLA9OoyMa0sEsRy1UUy26QDfWoDBuxFkH5PWGmficAm2Limy9ZbS59BqT+mKMl86LrYvbB9RVYFNPOrqAF4hY36bSCj8TaefIngcDxRtQnHH9TOhfo6lOlvjfYjPSCTaXqHVE29CpX1rEjfS/Wbga7lwMjZjF0SC7G7iTYZlPUn6K/3CiDj+fiUeQvR5p/ExWVELHFdkuL9C7h/4I5B+bn3bVhqNB8Yh0BxnkScIB71yBNprLpkn+pqSUwDt9a82VdzHLsISLH02VxPwFDCm+r7MvhWm01arHYk8qJOmZdFI3LObBe1T+cd/9rMB8h/vIdXMs9ef50tsfMS3jsMVfdD329cTfeFDwgP5+okknHjQly7NOkLYcIxLrS7Qh4AouQHgFXceJdC9r7N9WMLxbKqdLLzx5Elyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwnWYp35idzpnNyDEwaHrMmDgTnT3xrqcGohzJDmSrv2YqeDhCy8ogEzZSXZ8fMCJvtw4xyEo29JLePSjD1aJ4BA==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA11B+AkoJGHmf4JgXfcfgK7c+M2IEbVGtTUXlKIQcRq2j0BDfVViv4VMX+qXFwYakGaozGP2b/AxmvH723Zc8ZajG7YiEX6gkInkO1Y6QWLWN68L8xZa0M0IRqdJW1l5zsKN/svOOZhXbfEKusiisHl0muo1LHV0HKZ9YjFujZ8UEYHCI8uO1pskq3pFYr8D0yjmC+LnJBjQhQpuDRpbTxScgxMqSSy1utF4NOK20K0aR4famulogq4kHUE9GxfXYwqL8PEkjBIo1xYxaFXihcwzg6WjdTTDupmeY7vnAP3ecwU48FgNhGtooBBpO018p3PuMpDkN/RHODe7kNkHW34PLcDxCkf0A9llWfrUk7JnRsstJFiOeLCoocBJ6LV45SgkwbG3U6Ek6Fedv706X7s8FWT7/oxWvQzQ60mNFkQOgdjIICSIeQTK2kGIOqx9Di0OXbqjKCb1azp52g6So+Xax6FLZPQrYqxZDJzHixhEAjoe90rQthhByhVPUttcgwB6IdK4SpKHWLevmKtCQFOxPZVbL0fcDZNqBGdb5ywrpA979F1i5S95mFEVOnoBpAO5K6OSjt9spTaAoOf6TOv0Jkavfna5RyFFcLax5hemcLWiNxlN3AElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwjEsGtmY0JbDgOb95570/F2ao3bD0ZZT5++fJRBB7xxjr+W9fq3hlpShRjV9X8Jb6vezLLcEmjYMzemHW9Ng5BQ==" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "B6225C156659FDA69098A606B2A25618BCFE3DAE66EFD7690785F6AA80CEFE96", + "previousBlockHash": "9CD6E17F97892123B344109C7945E576DFF3E0C9F4CCCDD83B3A84993834EF06", "noteCommitment": { "type": "Buffer", - "data": "base64:FMlPtuPOg7zqHSTpnq+ptdomvXCwvUG2D8hiEkuaTEM=" + "data": "base64:gMMDP+AN82kVxQd0UP4x1Jqzok2yO4DQFX4roCFyuQY=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:gcWdF2KqCvbUcGUlXiUe07JLu7VV5VKbOgIP72Cvuu8=" + "data": "base64:KWIz2viN/iQ75MiwGX62AltuMjXp6zmle49dvnLMgII=" }, - "target": "881271989446208257911980828427057262643615932976441214377264856368067535", + "target": "880842937844725196442695540779332307793253899902937591585455087694081134", "randomness": "0", - "timestamp": 1671223343746, + "timestamp": 1676575138699, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 7, "work": "0" @@ -1056,31 +1106,35 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAMPZED059XDxexce6sh7F13kra7L4Y3707CamnIZuBzCg6E8rVCtrJxk6eL0Z0qF9ZD8KCgZBz310Wa0dBkl8pmyGz/gZCSV+SP9FamGtKjK5s0cLDnof/g2PhYpbetK4LTl8mf52Ct7XquiBqC8JoEimCdSZRYH0r6F4BBRkKIMSUC2ouCnSX7H+mkGnhGHjFSYaLyWRb1FW5i85SvsQZJmvizmrtufY/dFJjbPgrhuwutHBlCUoDiVS1B0cJQIyS/9HZsMbZpeAqJ4LxQcQbVKCJsbWbwAg5wUSTLK16XSDajB/GlYrAIqibK1rvBKLw7e2I+f1/gNtnsdAYwK8mwuTqQbp9dmBNKWr6ap/vjPB3sDNuymYOABBWkzF/hVa8RFuaTlq7z7jcFqGiCkDefBNwVqO89gimlUXjVfcsWUkeBF8vlgH/DHnxyX5ETwcwTjbADSRd8xa6QRbcJD2+KoM8t6NQ4UJAvh81mkqR759xkNw3ye27lp/dIqh/JzOhXMGcR0pGic6imhq7vNthNiu4qTNpVwTuZ5uBdky/FENVpyPBr6O5D+NPS7fVM2ZFPCgnMDFvVyhph2OaW/by+bXh0CPOHqivNfSshjFVEZwpO3Yjj+Fyklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwOV8ThdrXOtNs9fpX1UFutNozvb9oGZYbWMNemTW7MWCErQSYkg3lkHJbQJ2KyX0Bmcxja284aTwp+XpUS2+2Bg==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAg+/WikRnNb2YuJeoFgwv9ekDHi/gamKvQZVJeyJ2k5mUG1mbIdEq2NNg5c+1TjjfKPqVVJD1wSxULPWCRZ00NIR7c6+CbY3z350h4iJahWSmwXjmXeWob2uwWIiaHebLeTU34A7UnY1r5Inm7AH3yowJzG+6av0vxU9/dXGFKX8WoLIr9NVPFT7vjDUnqCInGb21FsKaS+b0JydonwluTGjI38VTNAkCF+421NuM8X6Wrq7zMpKuQYVIFdd4Tjb7p94PH9ScNVsVZGs7sydjunUakIOxtU2a8eZISRLWr5o6wv38XHRqf0QJw36jQhC0vJFOwHPfP7J3Kv9/ogdp1mIRdDxwGf8sMkPnkJ1zbhVe4N2e4mHF5+bg0HgNe/gqJotcGyNpDoERZlGEN6BdbTKt6r0D4yfhaEsSQMVxVFwWIHTy53ZBtM3CRyRBpNTCqr18IC7lW0pp7LRySZI7vM0ghavoRgU4PKBt1hy4M/sEO3pMfbUE71OwRSQhHXWvq4nn0xvcKsD6rdFuzINgXWl2F+HV21KZFFrRAMVnYWEVT4nAvA/dz5nDXNdHe+u45PTJ1L3ATfxggq/fUJ6Jya9j3WUfyMclxr0U/L3nekVkSd+ZPx0JgUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwsaauyW+cBXkP5nE2stQJtVvNIFZ42gMkrtaWhE1L7URwO9NmoplgA06D0mXibZiK/npea5ZEa1j2xYaHORcVAw==" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" } ] } ], "MemPool acceptTransaction with a new hash sets the transaction hash in the mempool map and priority queue": [ { - "id": "fa4047aa-a000-415f-b458-1f1e67a15b7e", + "version": 1, + "id": "282c09b7-47bb-4d5d-9bdd-8d959eaf1665", "name": "accountA", - "spendingKey": "3c2069a264506431fa5eb303e49c3f4a3ea0a5863393b083b795e85ed17deb88", - "incomingViewKey": "1b3693f3d5afffefb83f977d49f175561459da4a3079f9928d81adba24e39102", - "outgoingViewKey": "53a1fbb2a64481365f6d6b53e4f547729cc4172836372f35d90cb432eefae44d", - "publicAddress": "db3a18ab6de9621179892d6aac8332c2e1cefe05cfb287336c4145f63cc8cf40" + "spendingKey": "16f306494460dd9ee28698206d19b7b46da4927953dd546679b57c39cd9fc7af", + "viewKey": "2e3b7b2b244650fa87fc88680161708124646e0182d0a66c48e0a615990cbbc22441f81b0508eca87408e99365d4fb518048549671a3bd0ae6a30fbe41d3320e", + "incomingViewKey": "318fbb86231c23a124e2bff0e5b260b67933eb49c7abe9d179fcc0a0f9aeaa01", + "outgoingViewKey": "c93466e758ee6ca006d21a2deae50dd34c0d624ce78f4092c19badad4b8428f4", + "publicAddress": "341c03d441c1073055b72d26ccf7452575101a2bdc0feedd6e0a4721d5001be8" }, { - "id": "470b083b-df78-4cf2-9ef7-ce106e51f509", + "version": 1, + "id": "a4b3ee92-6343-4c69-ad11-a9a53e975d48", "name": "accountB", - "spendingKey": "9102ec1f6f4a89d7aa2b33c4a2454fd46dad39b17a008e56da6cd631791f29e3", - "incomingViewKey": "a71d3082bea276828ac4acb70c25822a9b98d983c74957afde088eb4d69d0004", - "outgoingViewKey": "61e5eec89bf58ffa03d529c9b3ffa1cc6b9e3a3d2f3603ca65312dd5ceb89048", - "publicAddress": "6c27c31ee64b45c73e23a4f6c1fc20c3dcf83a551a17966cbe990266fcbfda1d" + "spendingKey": "e8fd23550143fc76b579dcf0e08f6e4ef942a84b6b556d992f298ef0935d0dfa", + "viewKey": "26d41f85bfd6d883c72acafc64f35e518a3d2e900173e82a7e614ae0f09ce92c0e708d7d8f5d505bfd0a0a78a55fb884092d3f4a6810f9cf5e1a31c283215fb4", + "incomingViewKey": "d12d5072147321fe3627559d0f6e226fd5beea1f304544f98354d28e2079e103", + "outgoingViewKey": "04cacf0bdf001a7dcd3875071cc2fa0a948b524286e926870b36c622e78e4486", + "publicAddress": "8887a480d42982f6dcb96b02892144c58b11601efcef3f7e0e2ae9accd3e8516" }, { "header": { @@ -1088,15 +1142,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:5UaEl5sUx/yVDaC4SljqQw8o3xTX9hj9fRc2VMDPVBQ=" + "data": "base64:4K9hlEdsleRzWuSITQiTzlrKTPDg3aV+IrOfTuDWt1o=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:wKdOdQChqqMz52x1/U0VlmlVqsuM5Dsd1vOm8kwIo/s=" + "data": "base64:UX6pmdeojyImmBEns8Hc1ZhJB28HMVf5IKMcN4hhrNs=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223344712, + "timestamp": 1676575139075, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -1104,25 +1158,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAxpf8Y+zpxw6kVcogxGxAdb3o5Mx/9ooZ/IScYSPzkxyFChqSS3Uw0szaOK2/OQX5MuRKPbb6m/KFrnGPrP9wzFp5zBf9I++fiHCE1GfjXSOWzz8J63y98mAwf2XmzypmVsRxFNF3Q6mHK62eJWLa8dXEBBcdQxG/EBbtxpod8NgAZ8bCV/cdrJhcdEX2Pm0ucOwsQebxjyh1y57qG/KRnrUeDlYj0rhPxBQdyglZwSqzLYNYr38PVtrdJkem1Qid/pz1M8Xe+1zhadNBusiA096ju0uc1/Dd0n10EfXu0sLfhbAaeoYVSRWEv91I0RDlbG4ZoWYdTMF+FjY3jbhTF75fpD7PLZ7aHbacDB8TVnE4+8ZSpzfYkqdN3EJXrZpsZeQGafbNyJVwEz0bfcc4MY4UQVSbnvEgvRUHcUz/k+FpysHi13TTUXyDpDGsPWpF1TQF1uPb2Tzv/mjx6sAD1hv2AhwdHND9HVMuRLAMNod7oCOXL/xS9a3BLPrRRa2S4tMndmqS1vxBnWC2dFKst97s82pX5sjE6dnRxJ/pf3+rxnheeXqTCOAwvYO5B8Xb94FaQ4npKM92jv6PWvIJ95c78P6LF+r+chole2GklMsFee9gQ5nG3Elyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwFvGfMutbBh48nEZDYJ2ToyNEnMMLyYWTDyOkURTGDrXly1koJgrvus8w96xjDEqrhpTT014+vAM81hcoeiQoBw==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAT05y3KfsXe9ZMf9JJi/QHiQDGM4Lnoo0tp/Wl7domzSwEeauZrEcmiaIN/WLIfFBWf2KvP8edNbGe0PwRUtoejWEWiD1VcMV5GKbyjZnvr+TcqeGFV2gGpa3NLWpHdwmCB4+oOtiL5nYig13MBnwhFm9ZJQfASTBqnTjGWoyR5gF2h9M1MErIvrldKSoo+hlaBrKV0fUlS+4MQLz/zyIs6kzH+/XNtRkcSLTZMwxHn+nK3d36K6oqIMLReGlR8ooxhX0X7u9vwGlPN56SoqaZzm/YrPq8w8PhTYf95NJbMEZEBlsaOqZ6e+zLf38rHIZLw5UR0VofDPgaNja0sckyMwmTIsUX6+fTsyrLlP0cHAgIADXy5Z6prjWYErS1slWPOip7Gtfdykh1nTJxU1B/NwZ4obz15/dCOx00PdmuwbaE+O8SEe+h3kxNpMwvq1Mjh/aU9HCsJcnBtwAn4yf5/q0/fHMOQMexKzCDC+40h88eImynY4kHzloDkU5obNVCoP7jjY8/sdMYRLmk5JsUga4S9UYzEGOsKxJszQIp1f+JfhD9Rpo/x4THe2Kk1ANq1K0waYzR3itI75Ky5fQ7w72E1rgGxBNS9rLRRbeHsU0SZ0HCX741klyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw+8DS8TQ7Nr0HNBJiZVF95f3gZb/1aeqeZsR0i2rRXg9oO2rQDmehHYk7JR+CbKZneWZFL8ioMLOA/TKKeGyNBQ==" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "F4CC9DF014C555996A68462EFC42195CDFAC2256EC2E04173D34AE6BFF32A93E", + "previousBlockHash": "DAD6203DFCDFE2CA138B666B47A9139091AECBF17DA11D76039538A331DD2537", "noteCommitment": { "type": "Buffer", - "data": "base64:6FBUuzrj3+noFi53x9nneSaugTtHfxzeREGU4kr1DQg=" + "data": "base64:rQJeVE1YuyI/Ldd7RAQROIlDq2uB5L2RxxiUtDHfLic=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:3oX6y5IXziOWQIKwwU2BlwowpkaCmNo0u3976b2UxDQ=" + "data": "base64:gQpY3QnHF8gxWYGGgtGsOlhUlF4qOzhwoz+7+XiLSM8=" }, - "target": "881271989446208257911980828427057262643615932976441214377264856368067535", + "target": "880842937844725196442695540779332307793253899902937591585455087694081134", "randomness": "0", - "timestamp": 1671223351554, + "timestamp": 1676575140836, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 7, "work": "0" @@ -1130,31 +1184,35 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAk+hjNzmOA+jBSH1PDgq/++3F1C9iYW34tqXtqpoz5m+xkV++G4WrMhIS7y/CdVI1ssQn3+s6awWNr00wMlGcOoHB82v8kPxesd0fmu5sGsaE6WmXiK7Wuy7Ls+zzWTmiIW2NWIAuNtP2RhR1MxyXFWexFdro8lyXB2We1XWomisYByfeebN6HOaInFvOcENXlqrTqDDW1xg3zyAjdOkDby8bLCZoPYPVernm76HALgmlDd0Tc90nGVm3+tKjddaAU8bYHa3Z1Hj/1OJlf94zxIZjtmDVzZCsHP0yyPSZTnF2bbkD5g1TOZUeifkVyJKSvSb6o6flt3HrECrkYNdhEHUhTembfiLVjWtTNEjx6cj0gHtiiBN0i+h+nY+QoKc5uPZNdGAgsOUUl5BVbSrfrDglqv018U9GuOzIFXvhxycZbff/Yh0D6LO3Ks6yhjyRqWAK+1mbLrtibTeljXnhAu5w2C2+tl2r69fE1qUKs+8pVGFaJgIpPaCQlQPXJfS9qwzH+Mq2J55mQp3relwyfd13kEK8DPnH0gUEm0Ke1ffQ40a3s3cENVEnDiLskBFy6zyBrlxmKvJst4xrWfk0iu+KBZ7P1HuEk4DAIOh1kCQYnorN8P5hPklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwi7KcuRg8puwGHS70xx/3L/12CiQvEibL3Kz8HgLVGuHAWBLtrUXrCusX3mtTpN+5P62UdfBLC/ezuRIPHEtMDQ==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAteziLa9S9njtoJyzbA9hqu3JyJ4job4uIg77EIW/KMWnfiLFQB8hlT9hlZXD1d96BlsiD0FlzZYtPxzclNeXt+Jfn4rTf98Gpl9aYot8c1Cy+3VgR/ucB3W4VNYF6mbNSU4Gqcls0DnWDt6Ry2uCtNv9tpIWxQepw1kIk6cis7cSNnl5B/Xa5dstq4xaWpblLgCZ1l/npzU3eYaMQNin8Rxsf6H0nXcBB0RyD8hp7vqvC2C8gjb/rM+MOAtIhjoowtG9kf3MHkwJ/iTMSFc6pRM6FqvtxWQ9qvlHdQm8p+viLCaTGGavfUL35DtK1TeNJlvkHoGSgbOSiX4G7JLoQriB5fpgPCTTLM8pUg/fk2unuY+9JxVoDdKsBddOwU9wemwMzBYuIHToySmrpMQJG37YGhagfZKAIq8Nd72bzIBO/7fR7AaQaDC/P3/+BAin82bktTfUFMeouz8RqaHGPE71iGIcCX+mKLKOTdGbRWdEwKUBMOLePI8zWgN7iHx40rasUk67eZoI4gAR9QtOheOP6F6TNfVte2aMOAZ7sQx8YuaRqMuy186i2bTeHxp4v7TchJ0T9sQCAM+VjaTkP1CBcLzwRR/8nLPu5tNfhQq5lxXCPO1VjUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwUL80ayYa1ynaT9CTc7pWkVQnPiHdnahlQ/mpvtlyUglLCbn15F0Y5205Jv6E/0jFd/DfYurOyUXekPzJxSNzAA==" }, { "type": "Buffer", - "data": "base64:AQEAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAnZeeoY5MKm9fveLpfNkOYffUGhZGNBhhKwifDzLnzdaz7bppN3dYHU6CvWApDanh0KdX1PoqOYVdUgieFMsLrFSvvBHmNXcSPkkjFjbsnaCBlAg/6J/WEHEka+p4ps9OzxB72ohHkRyxA3/3KCN7yWslcU28c0wV7AvrBpCJuyYECO+QVKTo0nD1ZB/vmyEjLm9CWBxWo9bfPocqV1GDjuwSI7zH/KU30vovKh+MHEWlyqictDVUZWbB3iqsFUX4bY4XIupPxFXoHIY/gAKB7aRqPaRsOj82W9r2gYloMwdZblzwC/GkrxyPwep1nVd/zsxLALLZ5qkQW0YJoA8VSuVGhJebFMf8lQ2guEpY6kMPKN8U1/YY/X0XNlTAz1QUBAAAAA+SgtC8DocR1f6VZhrs+QMeIB2IakiotNkCdKsllr5lVF9do2vyQS+HfYkfoNn9TauTF5IGaQ1K+cq75nfFuuxHcabC+4BGLogk3BCC9o0VBc/8JcyRTRV+rfhlDdeXAI4f/vbtJkgeemvt0gvTeiZ5CMUSh+KoUsJOW0CJs33OPIG5Ftrxdi8/u8touEmnSKgVJg8ViH5khqpH5wjRZpmuZoB+DkXqzRTyYxc2GmHHzeaCbXY6d4B/7KAFSJFtSgrgcz5m0qPMc/pAJ2ZzRdXiqA8ewkY3Xf+GMShkJpiF/3Z6JyiaY+mtOqcikRPxwZkyKeddp2N4ZYwmMuYXjwtMvJftbAvRMQcxX7Y7up1gPHV5THK71CDalsauXcuDMfXfirJgiA8W0TNs1w4XvqZfKH//cPBqkttULM5D21loQe7Juq9eXMHH9sT/1BmJwUUf/Or34LXXd+UHlIzQMTgifPVQ/xe+A6eG03+JGPCmDrRs6UtQsV5dk7z5qzdE84ugksIjiTZsZ+73zfNprAncjoXb6i3RF9gKYkFDAoqNvmd4pFoCICJy+Y6CzwU2dpLogMHzD11TJ/TNTpd1UZwsASjKOVeqmb5J1DDXnLXUs44WDMc/JUeR/ZSY1WX+oZG+oMIa173u8kOgH1J7dCC3PV1kkroNlip3AOPuOEardEixcwmgE+VjZLZFVkbXjBooUgF/1z8DXfdWi8Ixa8b/I/5kyWjs3jQ7ziWo4c/QAOmOZxV3V5GdGzfOODCEQpzRaJe3DNkXemyLbcEZaFT6nlFIYrtSyKK/dx3IRPqfeO2MIcpFm36J5l+dG0R3nAI7eeI6rqKDAqCoaVpZv0Dt/n2cpnLWI6o3EIOgtD+s2AcS3ApgA9mrECeOsC+gnZbCLtDYDGUv7VjLc8T8ihVl8qfJHnap/dtWJ8uSlW0bBtoTsDzmtZYLkx86zFaoZVW37ecJucNutUZFzGnjC4El4VdjID1WyNhen6jpcXvj1T1B+BteNRKCsz7c/PGh3c0VS7ig6fw2OMA7ZKxQiy/aAZMuxo7c0BTF5JnMb5W77iPOT7xB/JXNHH2clzeCrzugad+Jz6cCC1f2HsTtifb3VjSE3X8yWT1i5fgk6eGP81+Qp1vyS9TGw79L7IgNZ2Ma1X20j0dmrWVLD6oF1QJrZJ7QVAqFrIadiw05GKxzsjpNTjx49Wv+ui6yzPJG32NXxoPd9wHcJ0xSTCWwz9zIQGt6qFedjtII/g3SbiCff5wM9FUk4BcIkvKETBK6SH0BTGmJ0Cugj2QsebxsR3vdT+gA1uZJAiiiN0DtbaBLrZCExOWfkq3z1mVA+MrEl1FB9s7MM3cIO25MmIqTu5OlOdoVoITpJXJ0HaI7qGCFYbGVox8VvnMwcekPCYI6THMLSFv3C0IWClI96hMupH464hUsOqtgokrp4gwTlVOike7ZmtAITY51IgpBRtxQ8ZuQIJ6jmwAIVunPf0qg40Vcg8I6UdIiBBcCefu6BL919p8yoXrvXAznNOXYF1OHLWjypi0KDVulSmV9Sq5/tFZxCHcwBB0Rn57ZG+pJ1dE71gfA0r4R5ZrP7kUJZ3slBA==" + "data": "base64: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" } ] } ], "MemPool when a block is connected with a transaction in the mempool removes the block transactions and expired transactions from the mempool": [ { - "id": "66ebc9e9-d4aa-4fd2-b7f6-3b14c54de865", + "version": 1, + "id": "189b431c-4fd0-44c9-80d4-1375b0f17f7d", "name": "accountA", - "spendingKey": "0cf54cabc8f3ccb17a2d6a87cca0a9cd5d0d156180e7c942bacb77ca579c8247", - "incomingViewKey": "2a289d2c5cd8e22b5bbf86d7b07c52e7cadf72c312cce488061f0d5119604807", - "outgoingViewKey": "acaa9bb9167808cb9e198918f053694aade2d8c26b00a15b417e59e81f39261f", - "publicAddress": "2ae618621777b1ef6ef3abbdbf0e6dff0781453ee3c829591dce12668fbf51ef" + "spendingKey": "cc63f32d4f7d1600b0d9cb6433c443d44fcddd2427f01f6b465ee3d9a5f38fb4", + "viewKey": "5f3d783d54d165f2febf229bcfa454d01e86cf80ea29eb79ddd5a996bbd27312f1ed8351b06359395e527f7aa7f2a154ee599e4ef6227350126e693d115e15a4", + "incomingViewKey": "2e1a1c16ea3a41ece900ed5b46602fb16d20a74a34cb78c14a7d46c46180e004", + "outgoingViewKey": "effc5ee017832f35d916ef6f57d104794e0a706a736fd3c666ef64a07b1e34da", + "publicAddress": "e97b68cbdc3da021bcbcc060d1053ac92980f477a95a000a3e46749b5d3ffcb6" }, { - "id": "6a67889b-b1e8-4e49-8733-42dd4957ccfd", + "version": 1, + "id": "cfb5099c-5a1c-479f-9b3c-29c751b1615c", "name": "accountB", - "spendingKey": "44456a74576045ec37730cec621d515229e2b6965ecf7a399378f7d540193293", - "incomingViewKey": "c75b754a5db0a859feaa2c4d1b9e2311f2391a99ff9472ac3c90bfac2dce0201", - "outgoingViewKey": "a8d3266f5102652f132f7d44101b4a4843fb4c88f66dc40d873c848333bc9436", - "publicAddress": "b076ea8248dda5bffa08076a85d728179bbf6ccaf11f9f0afe273f028ca6d153" + "spendingKey": "0d9e496b118d4b7c11a80f90a5fa0ec4e28b77538ea63f3b1101d2bd6b71527e", + "viewKey": "11b841bb9eb06270a51805e242e0fb3e87dcd82232b86301d1c27bc87837b59c70de675722c041c8a863d825f945a351b41bf71286256c5f8f5be7e48c0db71e", + "incomingViewKey": "7bbfa8206437f2ef097fb22f501710ecf81c945dce6e5a570c7937f51bb79e04", + "outgoingViewKey": "4c0b7ef4761a072981d2e521ad4a49bc83a2694479083cacd1b6132d89150f17", + "publicAddress": "032156e51cc12744e24b362d475cacfb9c7bc38a887e2bc3aea3577c1b999f1b" }, { "header": { @@ -1162,15 +1220,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:fySQujHuZsAfnyc9NWL6KLtkGGfUpZBxp4F/vwGRQ0Q=" + "data": "base64:Yks5urVvlRO3dnBkLCeHV8Lxmj63Ojk2xtHL9rj3ShM=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:bSJkNE8isfGWByNq2QS7YLo60nqrOdTvW8e1DwF5rMs=" + "data": "base64:uCkZ9hsslC+VG/Zc+YV3lYCWm6ja/MNz/Pci4ZlcR0M=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223352335, + "timestamp": 1676575141200, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -1178,25 +1236,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA0Qx7T5aASx41gFnQgJvIsTu5s+/1367vktQlAcXHkaOAVNg65xugs+hHikEZKqYfZOj+QnQdjDqJcGj4faFnj8KV4qJ9lnAgfmHbL522yP6Z462j8PMX7Hnhm2aTUWuYeY/3qDVFSpvAM8txNwvDe88C1GXxW2gfSvbZ9rkMOMgCT00pwnz7H+UBruo5ykaIihYBWhd5YlAeL22mHcRCvz7a1of0utSzYWoKp7t+z6+QrGNLGN4vElqmJ5R4X5+iukdxBAT1xq4Upg6XwRaxkQ226tVIVkGmkdtv4fdYu2POpnLiRIW7tBaAde6etRoFsZYLWM4CZfQRKHlxh0Ji1R0LSTG/bTIOZFe6optIlSvprBnmx5COvzwLeyBNmV1r20ZXeQk9mwCu70fMM6phvmRbeY5vGZaQSTQa/YfA36hueU+8oauiQ4Qe/5gRnE5xIojUt5btjOJnm8WU0DvmTt4IWui/HFLd9zzppG3Kc8tu73NsAyqW4sbvxhFwS9phZ3wdMOPaDjDCYjxXf7H14gIhKl+szpwnXXox7+Nxk5UCwNKkuyNjc7mVk1Gbmzi5mlx0aA9nV7il8YhfQOEE37Hp9IDc73D2wzxPPoHFCqpEGkt2KMuKCElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwkVac+lNc9XITa26OXy6FrYvQNyTQscnLL83YDHDm0+qmS9a47nLNMgDVkj6AB3L7W+hh7TzgQOxc+TgqXNVfAg==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAZzf4a+3Uq74TbjtgdZ4W1CjSjWXgXWmgbWU4PF8B/z6M2Sd949w3X3/bfPdei/+qnl0CYb5goypscRsE/DDzMFdM7r7wqeMtVJUpv1uuuvGjMkGTyj1ahu8F9ieTiUyfw6dadWoslcqV/NWaFJs165VM26RTKJUtOtpnenBf/kAPUKelDfMCZD/uXk/AfMKPXXnwpzo3CScTNtto+7pAi6zm5vic/KHR9tg6gB1cR+62k/H5M2dTRRFcP2U4VE5stDRQoQY7mxyza2p68mJ8YI91jdvxQmfvqP9ck6HUdSo3ctMYf4TJOCuKD/w3zbNvj3LozTyH25N/2nrOoCEIC6rxXhIrcKXj/JYtV1uAphC7mZWsDsM8bFYy4DvPRQNATv+rCaQD9Zcl/znz/hioA2XEog/6je19dstUJ12Gs6YED9MUh2TvzHUD3I4GzUS6Q3XAgS1voxTy9K+XKYAHOL6gYjOrAquYeInl2mUFd3qJTuj+8XXpEQibi5w8QPEcSoe4YoSzQGUAgwT/EqP+WskRwKldwU+H6i9T+dhWXqzHtvrZypKkk3ZjlfODXF6SLjzz5TzBX5HOdvnCBg9j+Spz2wLRROluUEedPtMHXO/7TOeagcZbUUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwcRP9zmyUZRNeboITPK6YbjRUkybRNsafPYgGAH7/OrpkjKy9VRbTZKJz+/h7N/UkmI/olgzlfCO3k+x5QXD1DQ==" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "8AC8491ED917A3155D34F488A64DBEDE1FFF6EC86406C01F80E47655D3102626", + "previousBlockHash": "798864DAF89B35A832E523CF852A2BA8EC89455792C2EA539E4EFD68D52B1697", "noteCommitment": { "type": "Buffer", - "data": "base64:ET5j6ntZxHfVJGIALusilV42D4nLFjS2qr5NheJfTlg=" + "data": "base64:Dn4pVNvSLHZjAEFqUrLo8scpQ4rxvqe9gLY0e5X9ql0=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:Lu8bICZ1RV88TwvfsKPX1Dq+UaXeWZqUl0dVNEoND0w=" + "data": "base64:DX0Hm9t63hKjsh3Xkhl7UibRCA9VveXNV/aiST7Dx+s=" }, - "target": "881271989446208257911980828427057262643615932976441214377264856368067535", + "target": "880842937844725196442695540779332307793253899902937591585455087694081134", "randomness": "0", - "timestamp": 1671223358855, + "timestamp": 1676575142902, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 7, "work": "0" @@ -1204,29 +1262,29 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAKlMgMMPTjEHPEys4IgDk9WCOYoGqe43G6NwJWjwBwz24U/SgwUQ8/frGT8jQ8ljKri+uCurnkg5gxl1PggzHJI+Wf55plg62r2JqkM9DlH+sKuuc8un38Pq8EDT4M7RZRxLZMdB8xCRiyw6iA4nV+zSc0zrT1bW5FYWtauArxEoKdIAz3Fvwsxp4CoVpsshLwP+pQ5nz4/flmxqrICSREdpR/EWGn475SraI4PS2EaWR+8Hz4+gsGCNVW927bCQ/FH7AUo29kGHCgWuwoA1Kuau8X7tUsRRqcModSVRuxEH9ENkVyTR4usEAZP8rMPLyBkezRl+8baoZikU1GMN+J4DJtKEEtQ4UCVLz/SUljQYW9szCa2KfqsiV1lgE/ukMYV2FXJqeKcyzYAYPvzHZlIxSTYDJfybrcFLsB3AZ7Q824P67vK+fqK2+YH8Duf2LMHvXh7DE98gP1iaMTiHlmpei7l5sj49Z7QroiTPid6k0XIdbIMzsj2OKsfLS775WFI1J63CE+TgMAnlDekdOx8VxjPofr4F9mwEG2z2gIUUqVIbY3icOiTJmM1BIkWb9vHFBFytXZkyikgippTZ84mV4hPEa6vVKAmRPHGscABqcE5xEmnE4Vklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwiMJLLOPF6s7p3tbSD5MDxKakABGsdpsO8/ekjgc1FoDnI83qCwmhTPiRI+8M5/Z57hULsCLhPL/oteFI0bVhBQ==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAsCm6WA6Pw/6OY9BDshBtR6rZU3/lpkFZxBJErwRWiiyHXuc6vGFIH7uOXgYulqafDDKkeNRcb7bxgE7XLZZN+LiJdJmbfg/TDVObsRHQFPWP62gEzypq9WeOkCF/W4sbUu08B+rY0ZY8HkNU5AAyWfkOLbj+FoIaQU+t9Q5fincWu4K3uxa6Yd59bT81EnMtJJ2cM1IAWffsWfKwMFDC578kyk0Vvf5/QLtTkbJvkaey+WGHTcU0bJRs9o4Be86dDWOJy3UaPCXvtwiFAF4N4zPRmeIAt9o3pxpKdvNb46TywX/Z93tzUDk/hD/lAKXwENr5vSnVg0rUc+ptMTXHQLI7UEZbTSATEYEl5+e7lXQ24Q33Epe5i2AiBiQnqZ0+3MB9MaDrqbda8SRlyZOz6VBjiyIJdYH5UBbv0JrBhDNdiObZk0BLI4jQy0QwJc7dXOQZaMToQ62qqjQ2AgvDd7mSa4yq3CrVnonSNcriLmSwMsx36IpckCTxY/AGBC2XDw5BMrd+UabO2CHxH85Zu76tNlkcA0BD7aSjEi8Tv8USesUsqkiCoac0e3k+qRmC2/zfFjm+xJ+5m3dR9V1cXbPw0+4bqXVIpqy6wnDoX02HD0VRY9IOqElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwOReYtdb9oeFM/XwpMxKEXCvTxkSq0+wS5FbFXMFRAC1YIVVbX3pQHGBB+Qu9UqhKPQ1a41t6Lv/ikgXeOuYsBQ==" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "8AC8491ED917A3155D34F488A64DBEDE1FFF6EC86406C01F80E47655D3102626", + "previousBlockHash": "798864DAF89B35A832E523CF852A2BA8EC89455792C2EA539E4EFD68D52B1697", "noteCommitment": { "type": "Buffer", - "data": "base64:xs5ASWSL6BqHu4cQDtUdtgD/kVyT7zTtpKnViQUHdzk=" + "data": "base64:aS1cpEbhPi4asCY3vNIuJouydaNvpFZHN3C3psXvmy8=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:5b0cM9RR+YmpweVVjL4lQxMeAuLbWIkzzq4LfNkaMK0=" + "data": "base64:WIK3RNtINzRSG4z+YIUw50KEQGvnImvGramf0AGTDXk=" }, - "target": "881271989446208257911980828427057262643615932976441214377264856368067535", + "target": "880842937844725196442695540779332307793253899902937591585455087694081134", "randomness": "0", - "timestamp": 1671223359905, + "timestamp": 1676575143231, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 5, "work": "0" @@ -1234,25 +1292,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAQKw4LVFvC/J+oDMsflVgt3xzQJO6u6oIIV63zvdroa+AcYogsDVwHV9XwXS28U6N2LtkCa6HRsLVOCI2FAJGvASJIzWrHiMY69X+tJ5LigCAkH0kEMimBljc3EbX45ksfCZvTrk91Oqjo9wF6n3ZnQTnEGmCSc4D3frMrO5lsnEK0ZJvQd1RifQzMWov0z3MyrZGASLUaiLCzjVvYaJqomaVVagrFIBabTCTQiuMywipuJ5f7xBdETAw1obnosBxhYddBasAFIopOqqMk5/G1MtVmMonFrGBAe6wjZWYmp0I60BXn9NYXhwosLQI1dIn2pN5i8WXPnL0ikzcrfNfpeKke2fga5FenoHzlMyehIDFjlmYmLGoM2zIZQQY9Es03QsiSay7jSsKdMTZCxFWqACtOd1Bk8wcQnzeCRMgveayWJraT3aKpamD+TTT4AOrrXG9TKDylWEJDGrFql4TrzS3FGIsWS0ir8YsZ6KCOZFavFOY4g+whQMwCZ9bl4Jbi2mhAuP1xB+uXJa27ZAmZObVthTSUOjq8tVpmPO0Vo1EkYpNrZ5jkqCX10XOgUOgTEqdeTjnBSXeIwxxPwOqZTzp3wcI1ZNw1/IxP1GWgqFw64zZxE/Okklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw5tGnFTKqpmufIBMUI9qq2gncJw9rPQXp1hZTv+17jZOCUQNwCAthHjBZ6GWd9n/UXul6ikNVW2xF8tz1hNNmDg==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA8wvWS4gwM7MfwcLcTt02wu0qKIm9+J7AvkQ/GPEC9cGWEPFlLc1TFiBIgIQqgUUk5akJRvtSE7m8LeJA/yzaSVJzK1qsjrrtKd1dfdmw6NazbF3tPMy0pnrCCF5c4BXSXujsMQPBp9cVsnGyDEq4D1a0LGseZDRl+bMyYy3kSfYBDRqifZqKyWwcqWqDL50wkRvGWdCnb5AFHn19UR7+Lc0EQSxspKqdyvHUhaaz202uaW2aVLOv7KWJoxg2Vh7US0Uu3Nmye1vOLQ9B/MbwHRQbdRs42UB52s361xJF9oK2pp3IUjxmRQtM0jnmo69E7cjZBCDP4pJTCPZNNFvluOerWhc8H3Bhk/wGmSrWp+jJKt1t4ANm3KXYqkGpR4AQu1tsxuJwNAuGlhtsL2e4Mqt/kXfkVHofCwPpfEbOLDULUesQPQV/fUgD8q5dhStPGy5VdiL+W1EpxF7r/4+HNcJSWANrMubG+LAlhi72s3+86w+k4EMy63liLETp94+l2W1gfn01byduMMp2/pk/3yklSXF9mAKDThDLHedE257NUmDP2AIiEL/dl9ikAyhikvFZZH+VHcIuLVn7tnDYafk7tnUQ/MQilscrP2kt0w3wpU5UxAZO8Elyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwJSlaEql/TMXkV6Wg0HMKgAMWqXqcGbQRYQOteSEP6T5Vwi4L1AFsEEr7+6aD4Po9HHaPy9wBKG6QIuUvft5BAw==" } ] }, { "header": { "sequence": 4, - "previousBlockHash": "6F0948B9068447247EA7005B1F790C8C3D199F5329D0624523DFDCB01CEC9615", + "previousBlockHash": "FC31D8C841F669687652E9D848E3E3EDD1EAB4FEC00F55ED653656D20254BB15", "noteCommitment": { "type": "Buffer", - "data": "base64:t96tbadEAyPw6tFqh3zXdQEQE/dF6SqrZ7slcyQPLxI=" + "data": "base64:xEAl+7c24PCDeP1LTSkgCPt0vy6E/L7I59SeqQV/8SM=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:IPUpdJSk8dppHFmjCb8HsV3eXpNLwKOuxg4lh6OTF58=" + "data": "base64:Z436LMdFRsPPz4j07hTLPZROR6ownlYEgdB6Yoy15lo=" }, - "target": "879130901036475001697423051875971117690643105150939656519205417941517322", + "target": "878277375889837647326843029495509009809390053592540685978895509768758568", "randomness": "0", - "timestamp": 1671223365979, + "timestamp": 1676575144879, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 8, "work": "0" @@ -1260,31 +1318,35 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAqL2SQDtgspFTLaTXB8Jj0u6VdUBSsL8/hFaEXfruOAm0ZK6eSvwzHm3O6HFByo3rrd1S7nURjleDQt2Fo40MkOtB1BGmUrD3ikfh1WDgKn+wf32tfcYVVIBNO5IHOrmD5heDJW8vdbRD3TUWoNVaZFRGkjCcdGHFKv1wbTxaj/kA7iMobadk7p75khMWPqH4YAVhCLZLVgqBIQ8ksP9GnsX9gAcnf2fOXJhdyfRkG96NafFiTvSj9/UWSeOY2kLD12nIgLQjdzWocA1oZs9xexRirGQp+HdigF9VOiTAijTJOOmUgbyO6jJEsIn/qH3XrZoWuc3AncQ1BTVlflQ9IZH8PfbkaTTLvbKEKAG4v/3Got+xxeTi2mHTHIqST+8iw9hwX8kwHyFPmSQwwvpxCKpuR2leQaDTBK6SuttHgBUXmNKPwVXSPdGNB/QdKcnEnloBoXRTHXCyTAkag4JPxxZRPPALSmnwe9O1J0METzAnohdzA10FDl3WMTDJwY3hLN8fJFA/cqXr03kzOoPyL/VDetrUX+VKJB5Jh1k1UHsxpK2xl9zdWSgjQExTXfUbv6Fo6RALmosB7IFUyR3AEvnDgp0Aa1eSfJcD7ty85saTRK7ALRsfC0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwJHbVeoAz5H8iHrXv6aikZl56S7Byc068uBwC+E8JyQ5mkr346kIBzGIFpeJhQpF48wd/7qPPP3oGWHtaJNvYAg==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAWgxFrAErZfNyOMvIAVUQ9sFqrgYYgn/wlVbDWS3vh3Cl2RrzwqRqqN7qpwU8UTW71jTMueTWcu/ZhPsEcO10zBIhZWWf9fGqQ4fdk6ASvF6wWEQgpZbI8srp3a/0uDvKRDWKhjNFUBTtAbvVFDI9lpTzUaflBrrngUdCeJeixMMB9Fx86jjEaP2GY1EqhDx2+1CsbIHt/bxsk6qHze2O3FwkF7lHQoqtZ8HSlPIWlLyN3OEPDctjnfu11cWM+9rj+j8fjYVII+tUKBL8SUf+1EAyZX8Ac3n/ZLRMEvs11VnzPTRzH1xPcjQfSIOKZThXXZgW4Nazs2huVUIhqDVonxIAla24bw9jA4Fp+z/ClXiydtAC7n8qgnDsYBRQ4FEllYVbJX2LSeeB/AUf+49qoNzXDtXTQZpkSUEaVl5GXWABquQHwbM4nS/f93FUshi8GJUwQ2DG3nxh1iURSboZSgIiBHOAaE8m76Io4+bTJ4Oz/NbyZvP4qO7jK0aKHcI5uqDmchGN+Fm/whVj+W5Mrw1mkyxIVj1EZ5e3ZeX3qtoehDfiy5VXmJj6bv9k9wMkae1dYrrTuWHSoueWXH2wYh+6WHxreonkZlhtGabt7zR1T8aPlXkubklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw6htjXJwUggMH2vQa1bpHVOJnN5MGUKwh2b55UvSfkEUEaUK3cGeaCKmhfc+T+3wiG9Lm1b7UIYnIYE6vZOGkDA==" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" } ] } ], "MemPool when a block is disconnected adds the block transactions to the mempool": [ { - "id": "036823cf-a178-4564-ba6f-433fb02a3607", + "version": 1, + "id": "b908cd19-bc0b-4116-957c-4e9844489b52", "name": "accountA", - "spendingKey": "0e6c760710f9c857e3662b99c0316c3fe0025c3f9daf23e926bf228540db4112", - "incomingViewKey": "99a7e2c484ed7d07915065a81ff83cec6b4fca7b79c55daa05dc1319e621e205", - "outgoingViewKey": "c2dea050aab23648ca8db8c88a14349c189df214ac1a1cef634b5e2a30a762a8", - "publicAddress": "019c7e408eaabdd8cfd4f132905f995bdb6757d848ace908ac2c3f91951d7b9d" + "spendingKey": "430510ae46a4456edf0a683b9165122b4ea97ab67fb7d72fc20982ae28abaa06", + "viewKey": "27ec8bfa300b581b4052908a8e53969165ffadead9ce4a04230b2cb0ef34adb999a638a786483dfc62bb96b5981b6447dd31720a21d19129b00db903bf7df7a7", + "incomingViewKey": "16c2735ec8a66943046b7af7fdbe63409f760f213b96fc6bcd3c1a6ca7d69b00", + "outgoingViewKey": "b5a371ccfff6145ce87d289e80e05f2e17428c3b427ae54154b885caf28f9513", + "publicAddress": "51063f164a384a84c7c4b75cc8caef2c662307b762d5498ccb749c85e0de1ac2" }, { - "id": "b06691d6-fc2d-46a6-8ad1-4cd42dbd2c0d", + "version": 1, + "id": "382ece28-0dfa-43a2-bfc9-cea8e2ecb91a", "name": "accountB", - "spendingKey": "58782161f0a1a22d1a498e2d4a3cca04cf11496c1181ffd3ec6622ba88d7e15e", - "incomingViewKey": "97cf816f126aab462906a29f99d5078d14a04fbb3785278ff3b0f5208e062803", - "outgoingViewKey": "58f718b28f901c952c88d7876c006726bc631855e6e3bba22d0295b0ce232e8e", - "publicAddress": "d0119d206675e406195c2238ee10fd53e6593613e3540d2c049f8fe3e8444282" + "spendingKey": "2105a2ec48b343eaa93c9bcc2e38cb0560ed303fc9b8022639f59500f20123bb", + "viewKey": "bc6ed68d03d59dbdd6178835d77ee6156f8323ee04efd0ff3c28661bac868ebd52439ec8c1663379b73566879dbfe438b165935eb769c1590b2b8b78070b64c5", + "incomingViewKey": "b0b5c560ba2bb97f9d391ead83ec5b533795cd830b41ecd638e199113cbcee05", + "outgoingViewKey": "8926b3e8bd3d2d2d72c92dcbb0cb4d6bc8a511f545171996234f4c3a6b20e3a7", + "publicAddress": "f1fcc5922974d7584b9583d560903eaab4587d56716dad0447d421283506f2c9" }, { "header": { @@ -1292,15 +1354,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:LvVqUQ7/xz6IpA4N7DBg/H7iMNdM17huLeGF3WYg4HE=" + "data": "base64:jfDaD+ef4Moyt2bNDlfOPAA7qML4Gw6k/lOChrRTFDU=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:KflnBfIgSw+pxrU2h4frKV+5ymyi77OmgfZG6klJW3k=" + "data": "base64:R1pRaXUmmCwDvrZmPpNyq6S4cE5Zua2nRcxIC1+gt3I=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223366669, + "timestamp": 1676575145251, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -1308,25 +1370,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAw1iBv/lvwMFJ73qBreXvGJp8mJKosZLib+ernhNS+9aT57idQzRGh0FNROex42kO0WtYPAHasWFM8E4B1EwFn0qs152kAIF05eHGXHHBJ5qZxAcJ5Iiyq/bf9JDuwYeIxfCGmIvYlSzjb2MZy+UAnz7/uv+ld/LZNpS3WbRZ/B8BIDMW3DDSt9QPCXrhNdsN3M6vANnQ1fRe96ue/s1UlMpUrL4CT6GwtZSK6Aijy/OT+lBpHLsNHdG+j9fR3TuM/Rr1FPDJZtl6y8nExUh+M+TZbO7t/w3DqLybaoKPVQDuUG74NPYOPUTleoTwX05bJROkJmcNBAf8g4OMvv/BsJ0Y3kMtRsCCON+V/PcMYe6sYMFJ7u1KHkceIlgBtBQrCyLO+GbrVVPqxgENZsKVY+nyoIcVU5OfHEO1QRwQY8d+LHmu4Hbn4a6P2vFBeOod7XlDMYBdyfS+Jn6f1eDcxCfaOuLELuGDZ7WVxyH4cLZ1KVniMzHHWFOiSBIebqkNMSu5aLv/dGY+G1qcIPjlqBXiwq8VENQYJ4NhkISl70oGM6HhGVdTR1GxrLKw+h0BBwKMvGo8FrXhOTLsFpMia+jey9tduTyLzZVHpdWh8LIYpTNQRXKR0klyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwKPb1XoTyp/ajanHyWrwbKdo515BoUyt2PM1h4c5ZdxP5aPwmMitnZ5lNJdKDPUS1Bu5MlhOyUUtsq8rHTi/HAg==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAzEfgua8tYV/kB/wvY4zgZhZOailGaFKzdeJwyfQ/uZm07hC//28aCgxvRMadOpQRik1lZXBTYg9FGHi2J2C7k649xIGgDQKpxVV/8MAUtxO1O1xvKZMq0g6nZlBywwXepV2FWBWP5pecN+WOH0x1rKdmF/bk4SeWNgzLwQqcLaAR2NpIqhjzu48NyQhdmMggU3lcZcP1CGee5p8uR5iMA14GRExt37xOd3LIiSPrI0antE68Ic/DbpxgBSfd2oPuxG7mFa6Q1flkt9/cM1AJjP+VGGkO/wUw6mBCD/59N3t8ztnDad0VPz2YW0iqPsEgrJAYZltwFYL8l0PYeUj1zp5D/MMeQWEYEIcJiYDJ3z2ifCzuAoqlr0cyw/Dc7DkQcN2B+AzdTtnA2z7lMuFOXa7KFvUBVXQOfO+Fhwv9RyZ4cJi6BqFeZjbrPPyMJB4S4kKc5ioMsF+WD2hl+CrE1XMSpmF5e20K5poiMqK4etHJaU7lGzTq5IpDZtrUbtNnEEV6Bg9qwa0xq9LTymrjkMU6PFdDyDjob8KgMcThkFAS4R5XlnzJXqdj5moetpcHErhgJdf1m7F5CGESJZFnwCSXExmmHVQF9z6+xBul+bjnFBgPLgJbTUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwcOlumSXsC3eiS1l8suymFMHrJ0APpE+yF14TIjK4s9SR69WozouZeu0iu7CbJaG/Ap9IncaH133DZB85df3sCg==" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "1FCB07C74C29F09BFBCC4054A1C2B40AF2279E4AE0AA4526E5E5240519FC5E63", + "previousBlockHash": "D260C19533DDA8F6B8D03C3C2FDDBFF1227B248041EBDCC6E816567588FB4503", "noteCommitment": { "type": "Buffer", - "data": "base64:hpoJrolOtd7jWrqQ0wg1ElUz4NP0IR6P80uoxotEE1o=" + "data": "base64:c9CaAx2PYS1IYEQWW7HXFQYxUDRoedzttZJZDlXPcEU=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:ljh4ETDqZDgiZVD5QSyZkszb+adnaxh1iK4N6rKokYU=" + "data": "base64:OfGnPZr8ymo5OTJthGKY5ejJQ2zbGL1vDk5vMg85s/s=" }, "target": "880842937844725196442695540779332307793253899902937591585455087694081134", "randomness": "0", - "timestamp": 1671223370638, + "timestamp": 1676575146936, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 7, "work": "0" @@ -1334,11 +1396,11 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAA8MLa7hf1mIEeGYxIS8BNTr31dKdYLHEvNu6k4sUPfSKqV9TLPVfVKZnW5z4npZgDgMXGGDHl+KxWR7fE3Eq5Bm1Tz1YZiRt8qn3KvYUiIJSllZjkYtrW8eAGmq8caIeuBPk+J5X+3h6Ij/Rel+4+0rRIwlSAOqAWkla/WnCQiYYDHI8m/NNSs3EA/XXp2YAFjo2A2huKgISTIgm3iCu0iKptAqDIFn/pha9qLto6/nezYBdGRfFGF0A/7KBMJ37poJ2ZQwXGeMvaIcoAijbV7hPbqUna9z1QLHODOalIgZ4xd+F0rIkYA6XoDV2OXiGsOg29XJ9PpTZCp4qf6fFs4VK0wFT71oacLC7ckRVdVw98rZdO/nkR2eFr8YbvisM5y4lqqLA1xYS0adSJ+bT7th+YBp4NFD8+Cog0BPF0zJFSHpfXHLONVi/BFg0nPcB8zYpGizCI+lO61jWNlUgaNiU8dIOqTT1ZGU3kvl1xEGlZ2sSVKJwVx7LIAbCDZZJZCWU36yBDgKELN8bpW1aAF2YH/a9FnCkzzxIOMpU3s9Vc902yNZV1M/LftEZIZhRGS1XJLMjaACGozxy8HNv3Bd825eVJ59Bc/HsOe5wSq+SAfS8Utjf7NUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwGDTzamj8OgVooPxFsDF+BUrjGpqv2VnLz6cBwOkP8EvmdYQU5EW9akazTMSZIU9dDLvkBO+QUs2oQhTA/rYeDg==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAAijkGs1Git8y8cLSSn3Va8tVQSHORrExzwzNrugnrFFa0ihzqDQ5Sg2AuLyuPOcZ+ZJ2QuCoAoFS90SpNOqNA+6nPgH8kOjkW5egWcERkiSO4uUtBp784eWnFcP03ICUHNPEKgVprsqsF1CiERyvBXEh82pV+2qfhNovcbGP0fX8OPnno/ZHEmdZ5/NQthYfjfXsN2NWV/Jue1VrYXIjy+NR96Bov3CO1sU+JyXJ53K+wJxoKof0FwTU+4PVKazNd48Bg5pTRFZnnQ1sCAL95wH6AyhuTGNnrnrwygWeQLw3LecHHaVm8/pyPXoRpHsMcVuSZCdyOussvUDGpv8sBpUVOqMLizroEPIQIHNjQrLAGCwzHOwlgvv4QNO9A/hc+dngKF9Oq/dpapnErvcU+nnNuo60ce5j4TUHn51m+A8GaGcPd5b0R2cWb+Jaxf/ljrC8eVYo5teDBawbTMFjvQzcrXGa4jaLkUTkpCFFpHutTCsp3Jw4XhbLNdEZiA5upPcykeMd9ECZH9YkShvXfe9LkrKiKANtYty2vLZHLXwHczVm/swQ4OzlML1WkCsXeRoxRJOoYdVQQJkT9rlbfA3wr8YJXSzsV/viuvUljlJZNRmdLgcIAUklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwTBl/63h2WclXaWfLBLlaK0K08f/m3u7y9H2UjJ5kU77A6Hgh5oiiNByOXMjP4CtPX3NnZk2Lgo8hPp1QLyVCCw==" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" } ] } diff --git a/ironfish/src/migrations/data/021-add-version-to-accounts.ts b/ironfish/src/migrations/data/021-add-version-to-accounts.ts index ccce58d913..90306e9d27 100644 --- a/ironfish/src/migrations/data/021-add-version-to-accounts.ts +++ b/ironfish/src/migrations/data/021-add-version-to-accounts.ts @@ -1,15 +1,12 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ - -import { KEY_LENGTH, PUBLIC_ADDRESS_LENGTH } from '@ironfish/rust-nodejs' -import bufio from 'bufio' import { Logger } from '../../logger' import { IronfishNode } from '../../node' -import { IDatabaseEncoding, IDatabaseStore, StringEncoding } from '../../storage' import { IDatabase, IDatabaseTransaction } from '../../storage' -import { Account } from '../../wallet' import { Migration } from '../migration' +import { GetNewStores } from './021-add-version-to-accounts/schemaNew' +import { GetOldStores } from './021-add-version-to-accounts/schemaOld' export class Migration021 extends Migration { path = __filename @@ -24,99 +21,41 @@ export class Migration021 extends Migration { tx: IDatabaseTransaction | undefined, logger: Logger, ): Promise { - logger.debug(`Loading accounts from wallet db...`) - const accounts: Account[] = [] - - const oldAccountStore = this.getOldAccountStore(db) - logger.info(`Gathering accounts for migration`) - for await (const accountValue of oldAccountStore.getAllValuesIter(tx)) { - accounts.push( - new Account({ - ...accountValue, - walletDb: node.wallet.walletDb, - version: 1, // this migration was applied at version 1, use literal 1, not ACCOUNT_SCHEMA_VERSION - }), - ) + const stores = { + old: GetOldStores(db), + new: GetNewStores(db), } - logger.debug(`Saving updated accounts to wallet db...`) - await node.wallet.walletDb.db.transaction(async (tx) => { - for (const account of accounts) { - logger.info('') - logger.info(` Migrating account ${account.name}`) - // reserialization of existing wallet will occur in here - await node.wallet.walletDb.setAccount(account, tx) - logger.info(` Completed migration for account ${account.name}`) - } - }) - - await oldAccountStore.clear(tx) - } - - // eslint-disable-next-line @typescript-eslint/no-empty-function - async backward(): Promise {} + for await (const account of stores.old.accounts.getAllValuesIter(tx)) { + logger.info(` Migrating account ${account.name}`) - getOldAccountStore( - db: IDatabase, - ): IDatabaseStore<{ key: string; value: PreMigrationAccountValue }> { - return db.addStore({ - name: 'a', - keyEncoding: new StringEncoding(), - valueEncoding: new PreMigrationAccountValueEncoding(), - }) - } -} - -interface PreMigrationAccountValue { - id: string - name: string - spendingKey: string - incomingViewKey: string - outgoingViewKey: string - publicAddress: string -} + const migrated = { + ...account, + version: 1, + } -class PreMigrationAccountValueEncoding implements IDatabaseEncoding { - serialize(value: PreMigrationAccountValue): Buffer { - const bw = bufio.write(this.getSize(value)) - bw.writeVarString(value.id, 'utf8') - bw.writeVarString(value.name, 'utf8') - bw.writeBytes(Buffer.from(value.spendingKey, 'hex')) - bw.writeBytes(Buffer.from(value.incomingViewKey, 'hex')) - bw.writeBytes(Buffer.from(value.outgoingViewKey, 'hex')) - bw.writeBytes(Buffer.from(value.publicAddress, 'hex')) + await stores.new.accounts.put(account.id, migrated, tx) + } - return bw.render() + await stores.old.accounts.clear(tx) } - deserialize(buffer: Buffer): PreMigrationAccountValue { - const reader = bufio.read(buffer, true) - const id = reader.readVarString('utf8') - const name = reader.readVarString('utf8') - const spendingKey = reader.readBytes(KEY_LENGTH).toString('hex') - const incomingViewKey = reader.readBytes(KEY_LENGTH).toString('hex') - const outgoingViewKey = reader.readBytes(KEY_LENGTH).toString('hex') - const publicAddress = reader.readBytes(PUBLIC_ADDRESS_LENGTH).toString('hex') - - return { - id, - name, - spendingKey, - incomingViewKey, - outgoingViewKey, - publicAddress, + async backward( + node: IronfishNode, + db: IDatabase, + tx: IDatabaseTransaction | undefined, + logger: Logger, + ): Promise { + const stores = { + old: GetOldStores(db), + new: GetNewStores(db), } - } - getSize(value: PreMigrationAccountValue): number { - let size = 0 - size += bufio.sizeVarString(value.id, 'utf8') - size += bufio.sizeVarString(value.name, 'utf8') - size += KEY_LENGTH - size += KEY_LENGTH - size += KEY_LENGTH - size += PUBLIC_ADDRESS_LENGTH + for await (const account of stores.new.accounts.getAllValuesIter(tx)) { + logger.info(` Migrating account ${account.name}`) + await stores.old.accounts.put(account.id, account, tx) + } - return size + await stores.new.accounts.clear(tx) } } diff --git a/ironfish/src/migrations/data/021-add-version-to-accounts/schemaNew.ts b/ironfish/src/migrations/data/021-add-version-to-accounts/schemaNew.ts new file mode 100644 index 0000000000..8b6de1ebf1 --- /dev/null +++ b/ironfish/src/migrations/data/021-add-version-to-accounts/schemaNew.ts @@ -0,0 +1,83 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +import { PUBLIC_ADDRESS_LENGTH } from '@ironfish/rust-nodejs' +import bufio from 'bufio' +import { IDatabase, IDatabaseEncoding, IDatabaseStore, StringEncoding } from '../../../storage' + +const KEY_LENGTH = 32 +const VERSION_LENGTH = 2 + +export interface AccountValue { + version: number + id: string + name: string + spendingKey: string + incomingViewKey: string + outgoingViewKey: string + publicAddress: string +} + +export class AccountValueEncoding implements IDatabaseEncoding { + serialize(value: AccountValue): Buffer { + const bw = bufio.write(this.getSize(value)) + bw.writeU16(value.version) + bw.writeVarString(value.id, 'utf8') + bw.writeVarString(value.name, 'utf8') + bw.writeBytes(Buffer.from(value.spendingKey, 'hex')) + bw.writeBytes(Buffer.from(value.incomingViewKey, 'hex')) + bw.writeBytes(Buffer.from(value.outgoingViewKey, 'hex')) + bw.writeBytes(Buffer.from(value.publicAddress, 'hex')) + + return bw.render() + } + + deserialize(buffer: Buffer): AccountValue { + const reader = bufio.read(buffer, true) + const version = reader.readU16() + const id = reader.readVarString('utf8') + const name = reader.readVarString('utf8') + const spendingKey = reader.readBytes(KEY_LENGTH).toString('hex') + const incomingViewKey = reader.readBytes(KEY_LENGTH).toString('hex') + const outgoingViewKey = reader.readBytes(KEY_LENGTH).toString('hex') + const publicAddress = reader.readBytes(PUBLIC_ADDRESS_LENGTH).toString('hex') + + return { + version, + id, + name, + spendingKey, + incomingViewKey, + outgoingViewKey, + publicAddress, + } + } + + getSize(value: AccountValue): number { + let size = 0 + size += VERSION_LENGTH + size += bufio.sizeVarString(value.id, 'utf8') + size += bufio.sizeVarString(value.name, 'utf8') + size += KEY_LENGTH + size += KEY_LENGTH + size += KEY_LENGTH + size += PUBLIC_ADDRESS_LENGTH + + return size + } +} + +export function GetNewStores(db: IDatabase): { + accounts: IDatabaseStore<{ key: string; value: AccountValue }> +} { + const accounts: IDatabaseStore<{ key: string; value: AccountValue }> = db.addStore( + { + name: 'a21', + keyEncoding: new StringEncoding(), + valueEncoding: new AccountValueEncoding(), + }, + false, + ) + + return { accounts } +} diff --git a/ironfish/src/migrations/data/021-add-version-to-accounts/schemaOld.ts b/ironfish/src/migrations/data/021-add-version-to-accounts/schemaOld.ts new file mode 100644 index 0000000000..4c4e0af6a4 --- /dev/null +++ b/ironfish/src/migrations/data/021-add-version-to-accounts/schemaOld.ts @@ -0,0 +1,77 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +import { PUBLIC_ADDRESS_LENGTH } from '@ironfish/rust-nodejs' +import bufio from 'bufio' +import { IDatabase, IDatabaseEncoding, IDatabaseStore, StringEncoding } from '../../../storage' + +const KEY_LENGTH = 32 + +export interface AccountValue { + id: string + name: string + spendingKey: string + incomingViewKey: string + outgoingViewKey: string + publicAddress: string +} + +export class AccountValueEncoding implements IDatabaseEncoding { + serialize(value: AccountValue): Buffer { + const bw = bufio.write(this.getSize(value)) + bw.writeVarString(value.id, 'utf8') + bw.writeVarString(value.name, 'utf8') + bw.writeBytes(Buffer.from(value.spendingKey, 'hex')) + bw.writeBytes(Buffer.from(value.incomingViewKey, 'hex')) + bw.writeBytes(Buffer.from(value.outgoingViewKey, 'hex')) + bw.writeBytes(Buffer.from(value.publicAddress, 'hex')) + + return bw.render() + } + + deserialize(buffer: Buffer): AccountValue { + const reader = bufio.read(buffer, true) + const id = reader.readVarString('utf8') + const name = reader.readVarString('utf8') + const spendingKey = reader.readBytes(KEY_LENGTH).toString('hex') + const incomingViewKey = reader.readBytes(KEY_LENGTH).toString('hex') + const outgoingViewKey = reader.readBytes(KEY_LENGTH).toString('hex') + const publicAddress = reader.readBytes(PUBLIC_ADDRESS_LENGTH).toString('hex') + + return { + id, + name, + spendingKey, + incomingViewKey, + outgoingViewKey, + publicAddress, + } + } + + getSize(value: AccountValue): number { + let size = 0 + size += bufio.sizeVarString(value.id, 'utf8') + size += bufio.sizeVarString(value.name, 'utf8') + size += KEY_LENGTH + size += KEY_LENGTH + size += KEY_LENGTH + size += PUBLIC_ADDRESS_LENGTH + + return size + } +} + +export function GetOldStores(db: IDatabase): { + accounts: IDatabaseStore<{ key: string; value: AccountValue }> +} { + const accounts: IDatabaseStore<{ key: string; value: AccountValue }> = db.addStore( + { + name: 'a', + keyEncoding: new StringEncoding(), + valueEncoding: new AccountValueEncoding(), + }, + false, + ) + + return { accounts } +} diff --git a/ironfish/src/migrations/data/022-add-view-key-account.ts b/ironfish/src/migrations/data/022-add-view-key-account.ts new file mode 100644 index 0000000000..1eefdb5944 --- /dev/null +++ b/ironfish/src/migrations/data/022-add-view-key-account.ts @@ -0,0 +1,64 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +import { generateKeyFromPrivateKey } from '@ironfish/rust-nodejs' +import { Logger } from '../../logger' +import { IronfishNode } from '../../node' +import { IDatabase, IDatabaseTransaction } from '../../storage' +import { Migration } from '../migration' +import { GetNewStores } from './022-add-view-key-account/schemaNew' +import { GetOldStores } from './022-add-view-key-account/schemaOld' + +export class Migration022 extends Migration { + path = __filename + + prepare(node: IronfishNode): IDatabase { + return node.wallet.walletDb.db + } + + async forward( + node: IronfishNode, + db: IDatabase, + tx: IDatabaseTransaction | undefined, + logger: Logger, + ): Promise { + const stores = { + old: GetOldStores(db), + new: GetNewStores(db), + } + + for await (const account of stores.old.accounts.getAllValuesIter(tx)) { + logger.info(` Migrating account ${account.name}`) + + const key = generateKeyFromPrivateKey(account.spendingKey) + + const migrated = { + ...account, + viewKey: key.view_key, + } + + await stores.new.accounts.put(account.id, migrated, tx) + } + + await stores.old.accounts.clear(tx) + } + + async backward( + node: IronfishNode, + db: IDatabase, + tx: IDatabaseTransaction | undefined, + logger: Logger, + ): Promise { + const stores = { + old: GetOldStores(db), + new: GetNewStores(db), + } + + for await (const account of stores.new.accounts.getAllValuesIter(tx)) { + logger.info(` Migrating account ${account.name}`) + await stores.old.accounts.put(account.id, account, tx) + } + + await stores.new.accounts.clear(tx) + } +} diff --git a/ironfish/src/migrations/data/022-add-view-key-account/schemaNew.ts b/ironfish/src/migrations/data/022-add-view-key-account/schemaNew.ts new file mode 100644 index 0000000000..e47783f22b --- /dev/null +++ b/ironfish/src/migrations/data/022-add-view-key-account/schemaNew.ts @@ -0,0 +1,88 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +import { PUBLIC_ADDRESS_LENGTH } from '@ironfish/rust-nodejs' +import bufio from 'bufio' +import { IDatabase, IDatabaseEncoding, IDatabaseStore, StringEncoding } from '../../../storage' + +const KEY_LENGTH = 32 +const VIEW_KEY_LENGTH = 64 +const VERSION_LENGTH = 2 + +export interface AccountValue { + version: number + id: string + name: string + spendingKey: string + viewKey: string + incomingViewKey: string + outgoingViewKey: string + publicAddress: string +} + +export class AccountValueEncoding implements IDatabaseEncoding { + serialize(value: AccountValue): Buffer { + const bw = bufio.write(this.getSize(value)) + bw.writeU16(value.version) + bw.writeVarString(value.id, 'utf8') + bw.writeVarString(value.name, 'utf8') + bw.writeBytes(Buffer.from(value.spendingKey, 'hex')) + bw.writeBytes(Buffer.from(value.viewKey, 'hex')) + bw.writeBytes(Buffer.from(value.incomingViewKey, 'hex')) + bw.writeBytes(Buffer.from(value.outgoingViewKey, 'hex')) + bw.writeBytes(Buffer.from(value.publicAddress, 'hex')) + return bw.render() + } + + deserialize(buffer: Buffer): AccountValue { + const reader = bufio.read(buffer, true) + const version = reader.readU16() + const id = reader.readVarString('utf8') + const name = reader.readVarString('utf8') + const spendingKey = reader.readBytes(KEY_LENGTH).toString('hex') + const viewKey = reader.readBytes(VIEW_KEY_LENGTH).toString('hex') + const incomingViewKey = reader.readBytes(KEY_LENGTH).toString('hex') + const outgoingViewKey = reader.readBytes(KEY_LENGTH).toString('hex') + const publicAddress = reader.readBytes(PUBLIC_ADDRESS_LENGTH).toString('hex') + + return { + version, + id, + name, + spendingKey, + viewKey, + incomingViewKey, + outgoingViewKey, + publicAddress, + } + } + + getSize(value: AccountValue): number { + let size = 0 + size += VERSION_LENGTH + size += bufio.sizeVarString(value.id, 'utf8') + size += bufio.sizeVarString(value.name, 'utf8') + size += KEY_LENGTH + size += VIEW_KEY_LENGTH + size += KEY_LENGTH + size += KEY_LENGTH + size += PUBLIC_ADDRESS_LENGTH + + return size + } +} + +export function GetNewStores(db: IDatabase): { + accounts: IDatabaseStore<{ key: string; value: AccountValue }> +} { + const accounts: IDatabaseStore<{ key: string; value: AccountValue }> = db.addStore( + { + name: 'a', + keyEncoding: new StringEncoding(), + valueEncoding: new AccountValueEncoding(), + }, + false, + ) + + return { accounts } +} diff --git a/ironfish/src/migrations/data/022-add-view-key-account/schemaOld.ts b/ironfish/src/migrations/data/022-add-view-key-account/schemaOld.ts new file mode 100644 index 0000000000..ca81e6d12d --- /dev/null +++ b/ironfish/src/migrations/data/022-add-view-key-account/schemaOld.ts @@ -0,0 +1,83 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +import { PUBLIC_ADDRESS_LENGTH } from '@ironfish/rust-nodejs' +import bufio from 'bufio' +import { IDatabase, IDatabaseEncoding, IDatabaseStore, StringEncoding } from '../../../storage' + +const KEY_LENGTH = 32 +const VERSION_LENGTH = 2 + +export interface AccountValue { + version: number + id: string + name: string + spendingKey: string + incomingViewKey: string + outgoingViewKey: string + publicAddress: string +} + +export class AccountValueEncoding implements IDatabaseEncoding { + serialize(value: AccountValue): Buffer { + const bw = bufio.write(this.getSize(value)) + bw.writeU16(value.version) + bw.writeVarString(value.id, 'utf8') + bw.writeVarString(value.name, 'utf8') + bw.writeBytes(Buffer.from(value.spendingKey, 'hex')) + bw.writeBytes(Buffer.from(value.incomingViewKey, 'hex')) + bw.writeBytes(Buffer.from(value.outgoingViewKey, 'hex')) + bw.writeBytes(Buffer.from(value.publicAddress, 'hex')) + + return bw.render() + } + + deserialize(buffer: Buffer): AccountValue { + const reader = bufio.read(buffer, true) + const version = reader.readU16() + const id = reader.readVarString('utf8') + const name = reader.readVarString('utf8') + const spendingKey = reader.readBytes(KEY_LENGTH).toString('hex') + const incomingViewKey = reader.readBytes(KEY_LENGTH).toString('hex') + const outgoingViewKey = reader.readBytes(KEY_LENGTH).toString('hex') + const publicAddress = reader.readBytes(PUBLIC_ADDRESS_LENGTH).toString('hex') + + return { + version, + id, + name, + spendingKey, + incomingViewKey, + outgoingViewKey, + publicAddress, + } + } + + getSize(value: AccountValue): number { + let size = 0 + size += VERSION_LENGTH + size += bufio.sizeVarString(value.id, 'utf8') + size += bufio.sizeVarString(value.name, 'utf8') + size += KEY_LENGTH + size += KEY_LENGTH + size += KEY_LENGTH + size += PUBLIC_ADDRESS_LENGTH + + return size + } +} + +export function GetOldStores(db: IDatabase): { + accounts: IDatabaseStore<{ key: string; value: AccountValue }> +} { + const accounts: IDatabaseStore<{ key: string; value: AccountValue }> = db.addStore( + { + name: 'a21', + keyEncoding: new StringEncoding(), + valueEncoding: new AccountValueEncoding(), + }, + false, + ) + + return { accounts } +} diff --git a/ironfish/src/migrations/data/index.ts b/ironfish/src/migrations/data/index.ts index 9376e80a12..770e18fde8 100644 --- a/ironfish/src/migrations/data/index.ts +++ b/ironfish/src/migrations/data/index.ts @@ -10,6 +10,7 @@ import { Migration018 } from './018-backfill-wallet-assets' import { Migration019 } from './019-backfill-wallet-assets-from-chain' import { Migration020 } from './020-backfill-null-asset-supplies' import { Migration021 } from './021-add-version-to-accounts' +import { Migration022 } from './022-add-view-key-account' export const MIGRATIONS = [ Migration014, @@ -20,4 +21,5 @@ export const MIGRATIONS = [ Migration019, Migration020, Migration021, + Migration022, ] diff --git a/ironfish/src/network/__fixtures__/blockFetcher.test.ts.fixture b/ironfish/src/network/__fixtures__/blockFetcher.test.ts.fixture index 297c16f980..20c839748b 100644 --- a/ironfish/src/network/__fixtures__/blockFetcher.test.ts.fixture +++ b/ironfish/src/network/__fixtures__/blockFetcher.test.ts.fixture @@ -6,15 +6,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:Or7fvRw73ZWNXuFhpzKc3Pt2QgWp+uP0P9MUJ2xo2i0=" + "data": "base64:UIulcbY8JW5ZfPGQyPaRxseDZvqJ92gDD/RSybj2nRc=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:jt93eoINFAnJOII7cLNEvdkksbNO/0dS+duohMVHx6A=" + "data": "base64:O2O3eeuNvd550onzLS2vg+IVs1ZXo+aeFM5qRQQp6W4=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223204633, + "timestamp": 1676574827448, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -22,7 +22,7 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAxkQtH7Aj4mWfxn3dB20eBI24QG1ji6H2p/G5a5d1nWqj5E8+ksCxbbq7YYRxcQwR4hpeMQLmFCPNiGp1z2UbynT0yvxbOAr+Ekq1F+LXHkiTh1Cz3UZ+Rh0jfa2uU3zYeQAhJLEXfm2WY7jfLaQtPi3d7oCsAYMLN8H1kBMFCmIKs9pJmNm1lyJ1Q9K0WVbehrAW24Rqg4C7cGMW/IC/uHGsA3g/QaS0xE6LrIg37UiCTHKzGdhPRwDD3JMsTdD5gKSu8BVcF9cbADomRAwRUdk43anSYljWquPIz/SRVkZfrjD1rSb5xPJEo6XHwFkbHEpblvo8phbgy8Ml3gJLYfBAAgoq9ijgCGJQyGG8lfZX9iCX4pr8rwY9rHRTnxRDm9UjaHGjY6AU8MFlLse5UVUW2Vga9s2JWTMNyjeIMuQ1rG67OsVClJAPStgLKJh3G+M6QjY/Bhdj6AmaxpkhqdiL7k0nTfTanU7IqN8bwxkILrl7065Wq54Qcjd34BBXTQjbWTPDYTljE4s8LdNBFi1xqz7zzba/a7OxGHFBm5i61E+2glPzvWttD5cnkNGjctwjSIGbV/ZoZFML4npHCA0csJkwmmA1iw+5duXSqhNHM/TRmgSxwUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwyVYtRDTorrP9p99BXVmuddiU0GjHOA18jUfsxBhU6kL0M6fJKlDwHRF5L13rECLZ8K8mvoPdwzgpaGbW7YT7Ag==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAp+tOPE5otBjwmShj+OqalPaVVJ5QiMGqkMWZQuAsLr+jabO+UsnJqeDdphhxeeC/l5vDrh/rmxSKPArEjNNcJdGPJtSxtkhWhuuFPo6cYTSO8Q9YKYT6F5ZUzDDN67zQidNfpv8DiELfsx5eITxMrZBBZh9VVdBWvQkdSYUth5YTC5q483XKiE5PBC1jQrnBXU4xBGUM3N70GquEq3SAO6o9++aPUwZNzOpEQt9crcyI9doAaPR3UsyS4AX6FSS8pCN26fLeip2gh8NArDWXEock4nyGDVRUYwMmikwbqnKNtIXpWPtFL9zvWP8AJbFFc6aY/3Im8cqEuhnyzbaFOIxEbZwdh27XUYFAghWwhQNwImGJ1lATiiNV2/L5YMtnNbVymMQWFKhtNKcCYYVoK+y/HzflFtuSXNuCEQMzPpVNgJEsPv50rWNrFYhFaoUcr/OX2DS1kZTDlxwQ5TXab1SMa5l6PK3WkgFrLyyPvYlYxcNq6dBS68eSQYs+tyQODgvmp2WDeerjMHyVHrTQd8FaZbsdGoKrfaL1433fXZ5QEckUdgIKePbpT1BJw/a/ZqKu8/Sg/ArwlUyt04VbYYEJ+MZCy3YyonjVkKhpgC8xeNJqSvq5jElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwN5IG2fvWPie9+n3cNO7WKLZfTXYdTKmSex8pS4huP9smSWYw6Eve+VvolvWsL8+4RqlHsX+ti/O6BFVTigLvAQ==" } ] } @@ -34,15 +34,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:RXhdvQqpfVDwzLdwfPcNGcosj8bpF5sq2k8WrfdRhEA=" + "data": "base64:feKwTF8p/qjsV1y/tVmfHdruUFYiVyAzKeAhYIwzhmU=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:VDqfBGn8pFfMPhwORLkqTEgf20MgDiKsVif6rBlG1b4=" + "data": "base64:GESzd2bHUBrpyeBLI+8MIo1X7nxo6uD+dP1Y/j6XUSU=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223206846, + "timestamp": 1676574828535, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -50,7 +50,7 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAkZ8Z4x/8ua6DM6A1iR5s5YTcfzDTmuC6Pk5A85o0T9SDHgIjGjCiCCsXrTeZwbtguFiqguBqOeVoe/Mtr5/zKhqEBKtLgTTYqDd75oO2Tzan1Mf/yUrUZI6j0VQnbmmK1wyjxF5T1KVvEwcuFE0jyiNSwfxBTWnutgZcPb3PkeQBmTGdA5c876wRWA5gsQPBZqtXRoglAqqbl14XdriSMUNGCpwDVHOjzABCBYO7OViHi+kcoTVV0Cc81u/XDUklqsLl69icV9mDz4livRmI1yaLKC6qb9LKV+ImVRYS5lq1INrZO3jClkyJpFEx4FFIb9y7J0vxZ9rE/cNqFrvInmCOJC6/maxXKaffyevs/tcFLKcTdTHayFTAhZzC8n4IPtszof61QfKtyat18Mofd2KIIb/J206y60sFLExFPzSKVpGT5PnJ8WT2Q7I87mPWFBsy46XuHtlJ5B5MwQear4PyqBPZgS885e1T0vXEZonFlmo7IhYqHq4aw+5Zq5XFyOdON1hXrC/yiw7B71rAATX+yXZhQwDBYpK0LnXrR7N6l2wqcCRqYXxTLuVz47wN6jQzz6a56s01fkLx7PVC8UJuLSj2MbuxjYjzzG/keV/kAaAusetxB0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwT/MtorGU6xMqaGH44j9VWHEk4E2lkEXnNY0O2S9aQlGPSQcfjqXyNHFv9hTUXfkRWxNYmgFQ1Ua0GXzHAIOXBw==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA4XjHjVyDSCvHmWVczbuXdxCfB6IuO4xOhzb0KHwJ41qp72Cfdc+WRWsbnMCNFgJBZpqs0X6IqlmQfMQw+uKwX+HdZM4ZOvmXdiWfjpNTFJy2jX+BM6XZMrJ137aLxZmbPxxUMpyWbLKEOc57RU6BSNg7ltcB84eET9j8th/bEfsK+SpHdAuaFgHkbbV2iqgEObA8obUifFzexkO+5cEls8NrKHsuZsT3sSg6YvYSkdCv0X2JAjzi0vElpvU4V4uz5BIMguyJaIUv0kzXzt2xRGHgYHEYEZpKVXvItxHJXRoZgWeVGld5Taxx2T+JRXcmIdvwO136dd+4++Ms1JER2ReZkLy0RQD6OFHzOXcf2ViOASYDcfFDrzI4pvTOgREn3lOdOssLgpgHHp4mMXMBaXAk+2rQ0c32D/FlTAGLw9npAimXpuZARklvS151MrCmJw3um68VtL9TGUZNnkZMHjReXxjYQeT5bAuwf+9NLJMvlo9mZJe67t9j2yGHORZW/gs3cqMaQxj2GSso4of0Htfn65QheexYlUqZ6LjD6MTZIjyjSROApIKqqAdmD5EiYctBtOQWzcCnwbjm6iT3hzfT+smOMgP/4teSfsHL5BNwzh/Dwq/33klyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwE3ZeeYPpYeMjAxz0QF/vx8Zyj/URcSJbchuWlaX+iphzVWeOAIQK1fzYZkHKjdSdhp9lTh0efoGBp0rV9mk1BA==" } ] } @@ -62,15 +62,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:m7zTmaES3x0dXQiL/iHz/9dsEPQWih8J2sCSceaSOBE=" + "data": "base64:Rn+F4+r3voTUofha35pZ4kE+mjee2UdLdvzFwAv8ZGk=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:vvXidIpP2uUfpIPSfuQpRoC4HlUteaCDx6XNAVe7QZg=" + "data": "base64:rSARBH6J3tTW4LxtQDhMQLY686f+ehXaHDf921ZivGM=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223209044, + "timestamp": 1676574829770, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -78,19 +78,21 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA1dGB+PWw6yk4DxDX2wMtxkRr06IyBnE6GIkMKbwR15qDp2lix3I93Y368KvpQP4C2MB9LKbUQVowdmm6SflaFGByPlUaBMvXPOSsFqJ/wVCzjzbh5zA+vAqqvOqohRcRQl3LCD4ntDjY6r3OBml2Kt3C9aGb5kJnNRYYD84iicYReZTRmZIpsLI7sA1u2ZsSaPq3xEjzUjZZdMuk3TwXaWacaFbXELNXxh5jzNtztQ+k+hfoj6eaPJO6dokKedcs4xkp80puxSV6h/oQ8cS8pfxecGL60/C/BAes21a4jo2+cN6LD418r1BB1gUh+MhWkfm+ff6E25i3BaD+QK4T4wsjFowBFh24ELeWW7TZ1p3+Ssi1ZiI6WYZ50JlMdIROW0SGMrGsTOqHXyMUxGnxjHsCt8v19E5LwYigxV7zSyMZsqlBm05vhoE8QzxYc2QNUwRDVwQYnKxy/l+XJWaajou8Uegb9tJpfG9Pid+Rt5h4n2qMqLCXCjzGvuKMHKUSnDjto3NmNiU9IUERkWWxld9ZlofrmbGiOzxSQOo6ok/9xXsIz9qZkxNnPtS/eHG52AkSBiru7T4EnKvaxhLYOtoso34b/eVM0h8fv3eB67JKVsRaAjxKB0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw2kFGHSrq3qKsRdWbXzRws3RegdTsgFXgZhdMZ83wHm4nROHYSIHb3h+9pdBvRBkdMEyPJtSpSXF2sLxLaGTWBg==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAG/VR8O/E2IenIhYYV2st3srMLhLY5qTprI4Z4yTq6p6kiTeSgCROyBgkzSiUItHOoNxRfBiSrEIPVwBroHlyCo619aA0+LHTiGVsRb2MzJKgVrkjo8D5/PW3AFuxKBVxYbRC06+oXIvxMhLXzDK/8yTaeyJb96IYFHmoDxjQs8MSRXzvrzVTmG0GTz6dagowojoCzJBHKJqVXyaGDNZhxDp0A1LWYJDuaEYRaOSo/PuY+TACjCOU2jpseBLOqPk08xPPbhR/0MCrIJhuYzAMzTDgkPyfrA+DqXJs3Pedd1Gc4xVPRsC3ouQQb+/61vzdOy9X2srGnNt/r/1h8wV1E3WVvaer632Mrvv/WC4P0cs8fUo8SLd2zQmHT+vIyTRrsLMP/Im5se9vP2IuE43L8nmaZ9t/jzygPSw49opu2YcEZWgpSsQdC1alND+QtOClHwR9Rl0Q3asRammqBGFVJHDHXTaGc7bQh2fWWVejrgH2RZ4IBMe/d8O27Lbo1gLQOeGVZXO3V+N/rsHmH/Ao9CG/JzwU4GpcHywXUgZKHjg1Zz2Z/qrpAS3zAe+IVQ6Y/9NHkPavCtoP66fKkb9v+Z+XAAxjtuqqU0gM6BQkBp2rSAH1hsgbb0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwQN8zthAbHzrv2b5iqOyxCY4eO57S8UOv7BSCsaZsQtyme9Awi56cSmwdiFcMLjpG4cOmleq7oWuUfc5M6KeKBw==" } ] } ], "BlockFetcher fills missing transactions from the mempool": [ { - "id": "5cbd4ecc-ac36-4e5e-905c-48f87b066f59", + "version": 1, + "id": "175045de-a64c-4740-b668-1d9d207aa1d4", "name": "test", - "spendingKey": "8626186aeb3e49d59078e6265a7cfc3fb221f4019f8a52e94e9a9ef0aa4ee0f2", - "incomingViewKey": "9ca972b455c56cb6cb79c901cc1b569f8efe2935cf4268a240fd69e1b3495007", - "outgoingViewKey": "0d2d2c1984649d8e0b1a686faaa37fe7d51305db4a8f80e3b76031eb8c0b711b", - "publicAddress": "a155b7215ee9d3fcb93117fdce9a938ed7471b6f80a5e0dfd37a2c174ffe6dde" + "spendingKey": "a6da7b9f985081b5458c52934b3f6104d6cd2c9656d85ab406bdfac0cf53ccf1", + "viewKey": "413cbcb90727d7c4d2e43a267b5392dec477482c43d070348406296ff570bcbd1b3cb25a51b1713b4694e22cb8950801d8d55086b036acbebd777c60a287923d", + "incomingViewKey": "19a0f9d490e6181c094912f16f5acbeb3948e9db9f8ed36d08eaf53be4d08901", + "outgoingViewKey": "0442700559be65dcde6c318c2850ba012049df9b2ce7c2f4059edccfdcbf2139", + "publicAddress": "f30a003eaf1d4e32aea62c88158c8f5990fe657d6612d7135cc8d0642d88553f" }, { "header": { @@ -98,15 +100,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:3lOfz0LLF3ixme6cOtg1sZLdR6e4HMB2S03WQb4XIR4=" + "data": "base64:DRqlByG7MxETr8wqDUIGJWDQ1J8MrQLlaPU4Ki2L02w=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:sOAVi/jXmNOy7uFrB5ARhqOXJRzb4eBTzOcN6j5nuVQ=" + "data": "base64:BapfmXvARk3wlzHk2A916y5vAYGYgBgtZSCK/rkQrl4=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223211154, + "timestamp": 1676574830643, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -114,25 +116,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAQO7A1rsB3ruGOEL2zhSNxG3UXqgcp1TaSyHx5pcgBtqIzRCyWmplc4t/0qPMXhT31xvyIiVFPPUgafUrSJQRPiMKW1lXxLvojKG3a/9K9weGiyRNvhm/2/uL51NwGGh6E2FOBL6LUPx1ky6sSllCuDxjjt9FEkEXYrsIg2077Y4Ovp1NpzwXs1DHTZ3XRqIN0gYKQ6Uqt25ivQWCYESEviuEhWDPJk4RSzf55L14UYuLa55E7xq4KwBG0NzwMvlgcSUNHe0DHnt426veplFLOL70XKOD1fW2d9wYf0EpwF8JPoM3JmsX68GqIpw1yhNC4BdYBDyaPXxssqxLQud5R3Gy0vF+dAM9D65BFM8bSS7KKpquOQkAibE0IvSZEDdDRNMgY6ahnRLglUVNB5cGUqHBg0/8h5kvzFZkB1FzWyca4C2sOyEDBBFPCXgtZShO+nHoQEFKif4lyU5iGER2b8uPyS/sRvTgLHvj8vBDWb5UTwTYQqMGCHDYuof8SiSb41fZf27uG6lwFlYtFQMLgwe4/fJxofCzH8mUltbQgnAbL5F43tk3yUZ4z+a1SpiQZibDZDGLxsNrQwWenspXtypbHcq8jmaRyUv4WaFJv+QNygDrgeUZXElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMd3PcJq+fulvRPXpboh6uALcVECn/PisG2G19d0L5KVBUk4aghdjv8ClbQfCrGDsP7XRQwdRls5nVQZnx3ThBw==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAQg381EThDjl9hgVTY1p8usMKsmEHtyEQCg1uW0dF/TOMKaOHZNFIrwDI2sJenDiKWZN7+u3sWQuHAZMmMwRqt3nlBuMxYiCTsG9mi4U2aziAfTmMPnIJ0kCO/iba8dZD7QLluDNtBz3C17eldc8iou6vcozRXVg0TpbIlREJ8z4HLcB+rdnXNw01zWuprpYtEUkbwkvNN6hUHvP4wwgHfOhcKpC2msvMvaRuRh22Mv2JsHG0ZE8aTXatdfq1B/QXSSzUjb7oeXAgfPvDo/NMSMUjsAN/OCwSVlSv0Kwf983MksKi37yVnzDq65xtTSWZQswiWFUWq5rw2TKcU04qH6vl427ov3QijHoTpD0G3iS2vrdkzHDffNVUWpXf4XVuRy5P1Lyd0uuJwHAZMog2K+RDCkftDXBuhq57CgUJOVK7VntIbhdMx3x80LrJuR9aCIEp8shsme4LWHNvTrAOVisRkPzBT8qPpQp9XUf8yBJxMq+S9IKH6mU3FgtWxy3wVsQO2Wyh+XfvE1/5qzNfELF2Zh98T1zYuwQxBy0ieSWtuQCGqDZkCQ2D2rEGyBt5ZioaoRSXOiioTG7fDN6r7udyAkINNJBXDt89I8t/SOJT/ESr0OUo10lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwS40CoZyG3MXt0/qocK/aN7vL4K3M2d9zFsXiLP63B73VoVbSENPvFwKI3Aq7M7CwU2ASNxMrVvhkkyTnJlEkCQ==" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "05F81A6D7FD7CA1F5E5D47F6179C4F6579A4312B7480B192850B54937ED8DD87", + "previousBlockHash": "FDFE6CC835C05167DA6E8FE2BE312C6C01AAD78ECD8E6361146BC5068E5B94A8", "noteCommitment": { "type": "Buffer", - "data": "base64:mGvV84s6X0AFp5HnwBcgwHpQHKrEb581W1DSnOvnXFU=" + "data": "base64:s2nutMHZkLh1iY/ZsYpxoFoemFEjC70r5G483QvFbkY=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:lHne1autPEBc6n6EeU/yg8cUPHiDZussqhI9+Hkte2M=" + "data": "base64:saEgRvfpv0Niy8yhVE7fLb1F20isaAAXZB/4ttuyeX0=" }, "target": "880842937844725196442695540779332307793253899902937591585455087694081134", "randomness": "0", - "timestamp": 1671223213032, + "timestamp": 1676574831541, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 5, "work": "0" @@ -140,25 +142,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA3cFiHQ1Rbm0Yt7LFELyYfggM8aIrxn6aoFEz1EKHECSwsbsptRJ96rJkhV51DGBpxSv+gmqkc9nMZl/+YLYmFZJ2AiiRMIDxRnVUuCEttayYgl3NRH/raCUSs4+7lSSmKYdtRadAftCu9BNVov/bfGKakkjuaC5jyXQ3v+/5SKQEHLtN+iQ+oQWXAS9EtxQcPZHWHnkdA40NN836J35hQnFBwoZYCACNOp9r2+PIBR2BS+V4gEGlCbg/mbbsdObLZlAo2Hsk4GJAk0NRKrIS2qUCMG7eyn5xgrAgQ67wO00EwtI7FjFcX46t6htQfBESE9lWGtuMOHz7O89DGpvxg8nrB7iq75oYO1LathWQj0qQayPIvL+hvpi+6k/zy29BazgKi1wtPqc8qinSKH5g0UY2lw1XqnexhRUIqBjS1zR8CJxfprDmeT9Yc54CbZcEqsl13i+WVtnNQwW8ZMIS6q+UCwEGVjG5ErFH7M5Bloxs+EE8bD5kY/ZCev6mg+2z/rq9PQlhwycgNO4CNaViefHTWMK3X1W1nN7NDT++texCLPbVVpbrumXQD4ldYsbzNJ7eUtOq9/Z342pPnUn1Zbux9NbPBZy6FGT3Xpk/iuUG7j584655uElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw/jpHbcCKbjb0FQVxIQFsmAwn2v7ahs8qJ8W+hnadOvPXI+KgnPlqwqp//tLvYuAc6wHliZzcOpd+0qJFfKqfAA==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAu7u30MhfgIu+/7l9zEVWGGW942cgXdiQgNWqMs3CffOjQmtMmg9nQfQO/zkQwuqE/6pAyzTBtnZ0S8V1xBdgMCsUdpmTkdMBb2mS3EMeZtm2e6DcO8Dz68cblieLwOzcPiheWZE4kYDVQXjrRxnqaJpVG4kdj96WtY04BWXpNMUI+pisP6VUrfjxD6XJChNfnhBUsf8MGeLOccUno9p/F9h3en2dB7Aakq7ZgA70rMmT8Dir5VBseXeUrY0AsVsUhWg/NS3F1OyDfjKppetububq6w5+RG/ZPyQyAryo22JYGiOjPB5GaRFugMcws7Dfgyc1QYQVLM6RePpQ4cnGkt1EF1ZBBP6+SnpL1sn7sEBveu7r08BKp+KYDUEEuVUHo02lcNHvVhbeFW06iKuJgFMz6nRIJs9WMfjBao5CoN8jZUAVR3sxQSvd4yBmkmdzOWW+UIu9CZhB/ujSQtvtdrux6pPSY/AJ74u0INuEQXOKkGT2jXMURNVehfLkctgymdErmZ6AhqkZvTdCuRuErVHJ3s1bS+u4+E34dbdXIo6FR/0mMSVDP/uXUo56lUMW2d3ej8jsM7ZKR45HZM7u+Cz8v6wLksuogxa6isuj/uKCzivnbG9sTUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwYIfSpgABbYJSUJvr19OuxMs3L+d7koQ5Sbx3kvwhp6j3hG8MohGfa3AXrqAM+vAEVeTKW8/h9Q/e2y5ZUtAaDA==" } ] }, { "header": { "sequence": 4, - "previousBlockHash": "BA864253404F971E7526C74CDA389852E4E8F39362FFF46B4763C778F34734CA", + "previousBlockHash": "90DE61FB7851ABECB306DD9E53E75D76075553A6CE5DF1C9D9745516FDE04F2D", "noteCommitment": { "type": "Buffer", - "data": "base64:agvw+jd4JBRKjWM3hg4hjqkuM0nJQjmejeQMcc2zySc=" + "data": "base64:VelJRZZHJvAEL4+l0v9z7VpUFxsQ9/pmanpLMNA0sWM=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:WOox5mgMCFF1gQWCf4JXbibXbuqTt5VsVGqOAHYPv34=" + "data": "base64:YaQryVd9ppr5iSpPfrbYebkCAXmJuh5IjNIa96VXOeY=" }, "target": "878277375889837647326843029495509009809390053592540685978895509768758568", "randomness": "0", - "timestamp": 1671223215035, + "timestamp": 1676574832315, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 6, "work": "0" @@ -166,25 +168,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAP/ZBssfVlXUF32vR57wF0HuynBDAUXKZml2HSsFPhK2uqZ9tNY/KuH/IrzlIESVjag3raMCje5589+JP6J5qzrXMCFACSCbMJNBIgAg04EKgLCQf1CNQA2utmlHouERafYUQmhHwNca64U1XEh/LGaApM++SPjn5jJKgDOpqHDoQm8YvTxPVCr65veRmLeANddIv4jluJottnH4gDTG+kmW21Qb/0e34wNgL0h6Deoe3v2G7wPpNL6zoRDMrKlrvDUpcSpsGDzfroVJfEuy5CXi+P6wpHKprR/DesuvokDhUCkKd9XPH+NAP9oo6AETrMl8DCeOBIIZtW0ly3KUhFD0L3Iuojw19oxYITyGY/1TYjdG74A0F7S0D9zqcHP4fbEdr+De7kmYF6ccun2VWjQEi289W5lJi2Q693hB98JUejKZA6fKmd3tQcYIWbq7sz2TM5cz26S8ddrot0PlXxRg8i9XlH4LCmpRVIQyR2KEbwbHiEyuzPGn5tnsC2hfyG7VliauDsT592/3eKmzDnhvODZEg6fVKp1SGReXMIqC2Z55C+uDkzcnlEwPXwSp3PdNKuA9oYKP+qa/VuQdscOnbMBQeO19Kfoq/C6FrqDiGmrguG3s7KUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw92iUCO90lBsji5MnirI7Vq2u5iDGnYx9PYQyIpdDoW/47j4vuD8t5nVHgGTf8gPdV3nUoZ1qz8oDbsxsFzaHCA==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAvXmYAcMkwfM83HMKn0wIxSSq/Owo9fZIcgIJLWcdP2GybtOBtVsCovCB2BS7J1fG0RQF8QOX3PaIym4QQHpSYBnuM7p08pNQYXrmQhiPrka5oJXjeQZLLWvH/wiI55BJbaC+Rudc+gAAUN7QqWyf7I0UU7+96CwW2Eu+NYrqobIE06JOLN/xDF3vkkbUVRBoPQ+wgyaaA83eUpeaEegta5t3P60JTqOVx1LCfeVAjX6xuA15WKMBBaZjA0efRZD4NZQjJZr4bc2SgLjr/MO6KMEFnE7lUEg4KkYFHeNRU0AdJJOISgY2EXKaS1M4ekovTOLPDnnWdOdmELR+JtrbBM9eGanJ6mhYCVIzxvRgM14KGKT/6YnhJUbrIk9J35Mla892aBxbQNrwrhGTPZfo85ub0CqLpB1Dk8AKipxX75X2wGL2yCyS3bR9lMaObrPEdc0YIw1b4L8UIurBIkKh2Cq76LXthB4tUV0GZKj1Ns8AXUlSB8wvuVWet8DV5iTX4CzfnPGIBECD15fLHv0nP0aUiC8texwkCBDj0WUKHjhxQzLXXZNfDIFNRPAfTNmC+MoIbIn7TpQmTNt8o4kx/NN5TJ+6S5yLyYYdj5/c+74hlJzdTAstLklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwFHyQBXNCkUK1tC2YPO7cLXAfNr2iRIw6SgwRSuPCRkRhrCOyIpg5ekDNK+OOANRytb7QdZWKI4n2Cic6bQ13AQ==" } ] }, { "header": { "sequence": 5, - "previousBlockHash": "DA9A29B05711D6798CC7793F303ACB111C2021E10E2977B761F0E300BD133D0B", + "previousBlockHash": "AC7655F47F8F5CB79E742C1AA359FE1ABE564A8A6230535BF494F55D51625B43", "noteCommitment": { "type": "Buffer", - "data": "base64:PQV8EeGN/Rs/jKjTwtspeV0nEqcOz2PlhzAHMec7ZiQ=" + "data": "base64:L2ozMAQDBMTxXOdt3P65CejtKdFWNHpa/v8hxPPePmk=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:rPT1tbRlSHJxWWbLP6MRZH35ZeUNrq2Na5dM0QKYKxo=" + "data": "base64:l9UFSTEUys89y08vph26kvsqU4W3f9OKN7ynU0unKH0=" }, "target": "875726715553274711274586950997458160797358911132930209640137826778142618", "randomness": "0", - "timestamp": 1671223217256, + "timestamp": 1676574833915, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 7, "work": "0" @@ -192,25 +194,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAsfAv6IaSwfnFl8h4YYicZiy/5qm9fgr5VYnIPqUQmxOnSBt2kEIQKo+bgd9y1ukj111uC5AdzBhs4eIz/5J0QhUjVexi/JAXWFHO7SAA+ZmKjTgjRSUVQUfuRYYRpV8aCA+INEewqALa96gLARbczDiVUNQCb/S4MSCRcPMTRvgSv3ylGYMQP28g+n+/GjeTxnBIp+Uj9XT6vBLImnFWckLpc8WJJyINiI+gB+g0pw2jc7RCDtnz7byNuG8dY63XTDInq1BwpZ34rGYCaRcPsJ9SEKj6K+5WtR8v5VdQQ3YTv3V03LrkemGbD6lPPKV1o5VJscNl131N7qa0n6OID+VGUCihlwQc7VsTerFW0yllIJ02xjhezNDL6RoXMlsm+xK7XS2l74QbEyeU2ExuSW73F+Wykda0ZmE7RTYirD/24PI8t9ESFll9YSqUkDTuBvJEQLn1+S6d6OjJklbu1rNpgMsGLbQ+bbggf23lWCcGbEzYteWSHNk89NGBqzN+FYHKgXWvqdJX9Nshse9mlFu3hpaJhXc4mk2NuxWhfLUo1U4bw4qC+w0MapMW/gPpiWgpWC5RgR1P0rNQdD5BIflY/GDYOYS8XvV9hRJsLkVfAWoQW6jDGUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwXGEULbQUviXMfAdLuElAHx7sCKyR15YA+n3rg1pDKAxs3ApDqNjfx8sYLYz8s+LPeXizlSRB8xhvZPEBPxyOAg==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA8jfp6BiantFq1TjiLZEU4XBwTQrBaY/Cmp24tOZwWFaFBWYxDaM6F9IHv2bDRZEcXi/A20h4JYUASPfXIw6u+ncZ43hF9TydymcmAQ3moumFBi5AX+q8CsY3EdLl/DqxbY3029LNPTxVEzQNpiegZXpetyhxYj4vJ52/r2vFfg8W8a59Vwq3FuSLqhbNLRs0jYH0CmIyWbKngltcSMIBSZAXjVuOTEmNrM7IB7PBY0Wyr2qvBjkan2YXMsIKVq8jPXeCNTD9E+4LEcjq/6F9FNxpvtae7+I+Ja8VfAXIKRcBeyyft7VfMd+20wsHblaDHXFpHJBYgrw9QUi4yD9IUgHzK6YXBs2B7nhCsStb0vu7oB9tmAiiP7L8iZAeFcJbgeJhmpyd8A8XBFUsfleSyfZxe10LPtg7gO0rezlu9OPKWPSgeuaS2U7w74l5FiyOh9hrzMRcrzJYSGBps4y9LnVvDtULaoTboAXn31rvjsRWPPWwBz6rNIdFcEij0QU2FPTelgPSFMNqS/oWU1K49aB83LyhDlcZGtjBvz1C4MA8QDzinBK/M+2HZ27KXCZ+gqCWBjGLEUZ6yK+QFvPm+Wz6Xjvcx1p7fUPSg6zUzOwkQpK6+IJ+jUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw4pxyhWTRjYQDp2mEJBzvbMzCRRLMvpaTk2H92e7oNYlMUfqnKDCv8ySyKRbJG6DRngJzZM/XC1F8JBPtyXsyBA==" } ] }, { "header": { "sequence": 6, - "previousBlockHash": "D59246935468F128760E21A6BACC829A76C27F908BED43C733B1EFB4ACBD9C42", + "previousBlockHash": "72B489572EA35FC2F0AC291A9884C45F87B9D5022234C9CB28BA835F1B0B906F", "noteCommitment": { "type": "Buffer", - "data": "base64:05ClBNRzGvRxnvZtITOqnojzjU/rZnzUfsAovh0VEFk=" + "data": "base64:qcQJtx8D0E+VaOkq62y2PURIepGfsjfC1QugLk8jTz4=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:yatTtCaHIChuiXIBytY2fp4pNjRkq9402Xcrei1BYFg=" + "data": "base64:kCNErpLgffhGvd2lrZ8/SsXosN8+zIGJtxN8Z6N1kD8=" }, - "target": "873190827380823143577845869093025366895436057143163037218399975928398962", + "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223219446, + "timestamp": 1676575074104, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 8, "work": "0" @@ -218,25 +220,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA5vpneq+wh7luo6ofuAMDTigCr4UzRkU4Vcdo2IjYZmanRCfVhqQY7P7ruhV/HquoztI2g57Y5kBvODxRKR0RZnWVpF2qpF5F8snoS9RoQXeAYvqo8Uw138JqJywfmG7xizaepyUcqZZmWL0wEOgUqIWgnlvXnaq8PyqDuwSyF9AVnFxv4QFi0lSlTePWZBMznyxOwbFKKDTlIHqDI/dVyVrjCEX6Sy5K/AgmCsYghFOw/9LjIIY9WzIl5DN+CAIySSF/xrYCccJ0wBF0BhfBoArOybqmyM7PRb09yaQvquZVaf7tCh4XmHnebLIqjcL+yvfwd4DPwAfbhrHZ8wM5QbNMzMuKB52hczKC2gAXSIrr5LZu9g26+4QBlhr+jnhTMSHWCtg91K1bA9uBnPf/9mDt1Gm1FByXB36Tm/TOx5XInP9EVus9hg1rNOXaoPZWSRGMlAwLIL8OpQypiOXaFtB2f6JsH+wtFMEaEaN99XM0C1RnT3V1iEWQMLWUw9GPXhM0bT3aSD0Gn8VgFFjm9iseAF22aVDLV3jL8FxTdeUVvTJOXtgnH0o0A/ypdTAsjC8ytGUf9msE4PTeENS/FSS5Redj6TMoAPD2lftgBv3FiTfipu7EtUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw96L9Mppb1g+/fsEGFH5T9ahIFogxvM+BbzPzX4yLcQjapEYsS9D4OQXp1P+oLMrsPlaPSl1rBc+m7a82uwcpDg==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAbqjV8VGgH6fJ7T9Gu5tiiZErLh5q4ssL3l+n6Io52MCV+9kRBv09G+l3f5mFqSAeNaDWhJ99OgeBPZYdrNHwExQcEOdaBx6wdsJpGL+Htzms0oowquzPh8uZNVOpvgWBdG1g/HwYAAMQaalKWfWtlkqro+2VRv2cp1a/7DZCIVsBWTEg9BJ1Y6Ksm92yrnK8ok/rriNTkG09vNNMp2SpL2yEeYEPbFmqlX4EHIIHAwKQypFMmeb5I6VXU+FtXckn4I6wGID5LR1CfqA4fEZtZAxarNlu/rzWhBFrd4mCXKVN5ezOMrbTQGILhdIhdjoEPyM74Y/VVjTkGXMXMtgpi3wrPQCljUDgaQoZQ0Ad4MdOfroubySc479DvyY8UQE9x+8m8Asp3p59LwMCE04eJBbZaQBPueQbr37Bd9rWdqeiYcQJinwo4p416ILqhjKnDqeOWuFeBd6pqFIGnEsSFnv9cTuxea8DzdRrN9/6UELhNQU5LCXb3uqVqdtlsr8tbt3JoAmrGn5LmLvENO/cNLGjTSZHXJypa0XqLqoSRm465IV0Ja4pbd9pM6y+ETCFG8994hYqXQd0FgDVndCUXO+n8OJNKi7EbPV8cRbyEuKtoJ+/JCHPcElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw4xwIkEW7ABvZmCIRfOkiOe4MxNzPWhJRA6yoVqqYpwYSCNFziCBYEHhlltq7+YvjMtf7rrq212O3Lz+yMggcCw==" } ] }, { "header": { "sequence": 7, - "previousBlockHash": "1B327A42F1868BC12F5FA82A20534B6FEF5906B4A777379F2270125FE3C0B035", + "previousBlockHash": "6EC04F552106D773DBA81DEAB023D84B09CED55FC6DE0E677ABAD48F63054BDF", "noteCommitment": { "type": "Buffer", - "data": "base64:BZnaYhhT9bT5/Wt6MerwF68Gvjzo3Ii6F652EpL/5yA=" + "data": "base64:oFgHwj37O92h3YiLUJNnkTkKuEzPjeYuh64m62B1tSA=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:jLpVW8FDD70AcyqmPOJ/gSh0YTMMuvnkmVeJmWeAVfI=" + "data": "base64:s9zWSNYUiRGK1AbPEXiaTPUgbCKr2bZA8P/7+Ntqtrw=" }, - "target": "872769606528251593580943869156173931600262185432047184330209720271897081", + "target": "882131347797691639928472277308994909901191375134389962514151511518109532", "randomness": "0", - "timestamp": 1671223268976, + "timestamp": 1676575100242, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 19, "work": "0" @@ -244,39 +246,41 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+2vKiP////8AAAAAYHojqOA0KI0/kPm9Hu6yoeZfumjcac80V0Q4uxhjq3G0PQ0wzAbBvdVtD54vpamCLk03Miu+tNaeQjMlSHXY0kVP9zYeXAKt7i2s3aCay86WCNTmy8Aw7Hdyp1DgVocMPnDzZMlQzZbm0PsnpXvPbNxY61+RPuRxkBdok0Ezu9kEMTNMD9H5viF1gAlB4eU4iOnYILS6u8PKekIW65OApDsaqfFlvUxo6pj0oSJx/wuHJVh2ObkFI9nqP+uGTpsMKnoHgED/N93AvALxgq9FUNmkpjmatwDKb0TYgnADyfqYHJ55gfeaqFTTaotKFOdJ0Z9UtboYf/HkGIQb3G59KgAaZ4m8CU/1FOodL8uy/C9DAxoIpgwXv6fXT117vh5Iy6ig01vxyIVxzdtrt634SfGvtC5az+1WEO/UmYndBkhkma/cb7vfsKfLsXP4iTodTYDoWiLDFb4bvgMr4KgNa7bLHMvuZBVqsrt0dNmGFUEhZ2L0CcRyH2OBMZX/UNLApV6Ec687KNOorFpHsXRTW72uMgPgXUrDHEeI0LX1lBZYaZmOmPKpOZ3CPmXmTl+1/TwgvwzBQ0RqRIgEwduYysYQB7AoqHmXoFQXEOoW8gtrzRHs3RVX10lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw6kJ114QDYo6Ref5ZqRnk4DQxwKfIAJ7pDl6mr27o373zLg2xirSSnQmtDMrtBdIS7t8QG+2cR/Z4ER5CmjQsBg==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+2vKiP////8AAAAAYHylaYGca/stsinow/idu0z7XclCgGYYwUUgu5t0Vp2QA8ZulQxfROYFsO/M6803CWGpJWDPkrXSEAn05xHdUUGJ/sjwACPZx4zbcNDMvwKVpsBzESRjQnQCwNMNssTzH9oM8at7yj4s0hJ7XxgdVuzzj+II3ylemwFJRWUSe7IMdimLANmrViD6Yzj1NPm9z35PsGd/psf8tVWOrKYzLrSlHlTBXlRXdmXmUFk68tuqlNhAImZPDJ4CtXdw8dbYaZOHQvLKDNFdtZN6DKfRpI42y7bmXRJ+zamAfGz7oDDAVCDEQ/uyVSTI+95mMTvT84UXWSdnQO9lBg/k3pv/TpqkETr0HE+ofnwALCNxc04bgdOyhB66m2oJ45w98yZlJqWz+Et4FH/JOuRWn8uHnryyq7pXCMsMsb5ZNNmnuIBuITklx2ou7B0IwdCg7MNg30BzF1nyAGCVnA63ev48go27XzFxuaEyWpMlYlcd5P+D8pUWUcD8rO2iC990Xw3uRqCcbcMoZpL9PFyrKT82yTgAMVkIu/00lIa5MKMTPAvgKEcWXPhUfCvf2N2aIt/X/CJUHzx0nJGMBnMlJpkLhKuH7B59RL51HhPFIcmu1gssLE90AxSXpUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwnQJBYHz9+ommyUmneS7rTJHEXFd8xQxJIOeoajCDq+rSwxHOb2nCSozZ5nFVPIgYwNavJxVyd/hBR6//m555Cw==" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" } ] } ], "BlockFetcher fills missing transactions from transaction request if not in mempool": [ { - "id": "23ccb0b6-0907-4cf1-8adc-c37d18bd06b5", + "version": 1, + "id": "d269d158-ad4d-4e6f-b9d2-d4a3dbafecb3", "name": "test", - "spendingKey": "cd1b5793a59c31c5d85ee90f6218107c6289c3072eda0763b18c34b122c56b44", - "incomingViewKey": "ba64a3441cc16cbddfc0fb9e0adc71be92d9ee948f49b89ebde7d075b604d206", - "outgoingViewKey": "005c7bd93d586fb73d0f3826ee43a7ad1b2f6bc61b3a7ff2c640b64ecaa1d8a9", - "publicAddress": "bc2fc15b5a9b68f41a69d10495b87359d1365e74add2725c6faf50457f75db66" + "spendingKey": "1e9b9ca0dcca9d75a0ed85bb698224808bd6ddd03f17d14d6a32c0c310679240", + "viewKey": "bf8f7bf1cbc2aab54ce4b740145ac6cd89d1337a9dce10dd85f2f88970ddc3e41cc56360deb8892d013f1a66464e525c827999db5e66f1887adefa64b8f99f22", + "incomingViewKey": "6cfbf957ff3a53e29676f539405d80417706bd5cb270cfbe31724c868a856e05", + "outgoingViewKey": "a47c06fccc98a422928bed2617aa229d0ff2fb0a778b119741b6dd98e2cf3185", + "publicAddress": "37d26585c2869e71472d2dd66600fae83e4bfc2bf018c04837e4ea91f17f7f24" }, { "header": { @@ -284,15 +288,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:1RXJdeLxvplekxlxPQiTaRyiAs7bSWY19y2oktukwkI=" + "data": "base64:q8l3Tq508aQuPomZWLCZ9nIMGcv9k3ClfZFKaWe3HxE=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:q5ucnG2PLgKRhu3HKyA2/rg7xD4ifSgjvOQv4NPsklg=" + "data": "base64:+ldEBV/uECbpb4FGWbEKVq7ariAkkJCqsVb0J2IWoRg=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223272437, + "timestamp": 1676574837494, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -300,25 +304,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAoa+3+DiA2SQz1qnm/W3y7pYgzZQ7e135mXfnKScdOxOq8ndNiSodGZEAIRzWODoamte/f+haGNMNEB7HIY0FgW1rNOyfP+neZlloqYfTPXGHExYahxqDe/Fp11aEPZV5tz5xzx622j9mZbvHbDBqYafdPXAPkYwvrvMaoV6dTSkDbFWI85oEcLTSdsbv8JhYtFDIp6/qFRN9R2tvBCI0mOwRA7Sc+tt+bvc8iTGsOaOUvfJ6iPFoFitQuRQaigWBByoqNyy57Lep/hAr/DtMuPBmw7ucCBCuHwNHlwdV8ORPSeNsl8IY7PABTO2S0ou2701v4aZaEAZTcFumKSWqxmneR+tB4CHMymNG72IspVY4LEAotWt2JDPYp9G1KSlRjGLk1bm2+31agbDasC2VWGXgU2P5dpo8gncGUW5AjnJaE44q0NOzCovTcm0HgenQhD7rJqUyQT0ZfcqPnxkaZUi+YYyoZONFSDAs1/f58HPg1wAYq94cSegTspKcMgOc8pyPA7O0r3omli96ZgKohuDiSoz4INY4UqLJ43tAVw0XBHw0FWFLT7nYBdjyOOxiH+XU6cUUuJQlvC/uvdCC/+hcwxR7tQNtBoJmXHJBXh9A918cSXfOiElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDGL91HBpaCq1tMcRzSqdFbyI7NR0DJomiTz8NHG3oaB5MFoP5eU91dvFO/UEgSo3H/eCSXq+zV7W2cADn9KLDA==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAACIuqC62ypAKUwuyqnFAPM9FckoFUybC2pStgZRIhImmRRUPjaqI7Ltsa249hydPVmwS/XGmNV49fr/LCHHAswkdOruZJ9RgsDhUruSSdZpSNI3cVXqYWhEx9CYLNu7luaBa0XtE3ZQEOrs859N1iHoHUGGLOVrJREXCjEAXZ7dkNJuGS9Nua96KVI2skFjhKqyn+G9THZ1FhJO0JOeEYE6oS+787yXF4owAmi09/FkWKtI6AyOrfUEUgnzSg7u9BUHj9isCUmCaOCAqI9hPjzpGP3hp6BxeV6WpZYaNEs+MQt1BNCswvXxA23tCeYzBLD+G5dIOliElxNcWa32eWNp7DGuk3OUm1vRUuLdHBNnrqttpY1wONfU0CLf7tHHo4FKnEezhiKSc8vtfUuxZ+OzIMXGYFnfLcvpHO5SXXFIcyCEh5XUnvcRKU5V0CYxj3aUjz4n4wLF/f/sijM980CNwM/H7xu5Y1vWryxdyTMZFuTkZVVU1FflcVx1wH+SYxBYDU1CiGpz+Y8kiowGQS7v1kaLKJ/T/9y1vNlHVEYIIRb3wMxcB0GdHz08g6R+1qK+P3+gJtf1Jn+ZFzlN86PhXczWOng63n5taoo2tks+swb/yiegIw+Elyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwcok7B/lvAQ8TokRZfBkLg2/nwfWSdW48jvmoX93sAwXplzECU0hZkNktQovnVD2WBq4dzB0xEgypTzqDCBXcAQ==" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "4F8D88B8817E98AFE5F8336B429D306B06BC01A393027ECA52305CD2C8FB9316", + "previousBlockHash": "E3880198F81F810869F88941C287793C54A1B2F3E8EA55475649AA93B1FE1B46", "noteCommitment": { "type": "Buffer", - "data": "base64:kyW2XS2NL5frDw86i02ub70CVL8LhzTwqTiPGHfKaUI=" + "data": "base64:mSRQnBJOMPXqEohPtqcSVaahccs781VA+Pu+PJ+djTU=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:S5swf1AEuiZ8tVDF3ygTAAE8n5VeAI5KE2SaHAtYgNE=" + "data": "base64:mm6rWs5u+wg6/PuV6QDUf+rJ+Xh4vrE8FCLb2wlB+B0=" }, "target": "880842937844725196442695540779332307793253899902937591585455087694081134", "randomness": "0", - "timestamp": 1671223274573, + "timestamp": 1676574838941, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 5, "work": "0" @@ -326,25 +330,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAiaVZGEC2TLJZy45eltxrDE8J9KabRA9at4c9ZyvNgpiKYnMyJoxkXDe4EgsgGCVIP80dAQaAQi/ky9tXHQDB8D3uzeJFvo/8YksnbHK4w5uMc9NpjBbjnOo9oqfCw8xTTBjaiKCHvooV+h1/QYMf0BjPd6Xbh7CTcmWypXLfSgQFxvQb0pUe1l4+duHWlyv0CJjJhvTLQ+6s82348rGz9Rkc8phD6mzPL+bg7czXs2+h4F3WugHDydyntID8OB9nbHsaKQrSmNOw8IqVuC48cOnbqkJJt/S/RDaDhdH8A62aVri1suMhPLwdfi9G3isk7ZSIqAtPDJnP9clej8250enDI6tpUczMR3ozv7loh+nlhfwoNul3GKgakHB+kNtEhe2Ymyt170WdWSFUMI0Xar8dO6bFYAOzltaxJgxuwwoyAhWtiyOJInYhsW6l2NcxDKRAraiuBfj6RkSfCVhFf2WqE2KcWSQRYYALCvnRJfM/NyDgrK4qKQ1fsYWS7rCTnxPPtVzADcbo8ivFlzMB4OuXDJCs5ehREChrk1pkZ9ePA7F55xJKmKS9b3vDmex5DFDoR4l24Tnmufn6fgE0xLeYwVzz99+Z+LwV1iq9TD2zAOsXA9EkPElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwxG69ZF8+UEL3rH7xUgcKvV3CnxnACnfib5TuvN6ukr9LkDt5Wz8BTQZxauQGgKfDnrNKi7ZPaCW1ysgvMG+8CQ==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAhfJXJ2Y5wHoKBEoryYSojk93d1ioh1bs/qwFMmGwh2GpHllhs+fmYglIge3H5LqSinbXzjlcCBE/wFCuemBtUfF0AzzZEUnWGKaBIu4ehWaWSE7BNe7EVCdwSA5mULfykfbahAQ3u+cKq2IwRFbwf50EOoUD3w+ycbEL58UuaKEWAWD/TLQJZY/wbEffIAY63ZyHNXK8Bx2g7wIOVK8U4b+zHQzTJp+rHOG0ZkWRlVaLRR6qnT+bqQdO3sAlgIMXaP+/HTbYJapOSYYLJyUHS9jZ1A/sAhpVH2kFksmtlDl8q9I/sKESi7BL6WStn1PVh3laK7adzGtoPfiibL/kmeQEih+ym3D6A8Qi76NLLI/6OnBfEp1oW61I7xcQ/VkiW91KUhI12I8fLUmnARt5GBgKS8rbC19PJbrR0GSptaiKur1Wz4kpzxaw+D+hQS8PUoPXAJkXNFpZL/IJfgPutvgW+RFxjCeRvX3x9KzwX14arTAXB7buu4F67ZYTSoYTu50cwyUcwFb/W7RbbkwW0C6CmblsCu0grOAIQ4YwApDhRNGd6ULSvY9n2WG5TY12b80tw8/rl5QU0KKkZvceeUFDNmT3LxDbikmM236TZy4NhnNNsT9SOElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAV0qWp/7s9XgUyD3Jq8FmClnLRPPp55lrX5Vb4tHJOwstUpUmB3/Qfbo+V7P4AklN6b6BtY0C0MIAoEoO7A+BQ==" } ] }, { "header": { "sequence": 4, - "previousBlockHash": "9A5182FC6229DF1B856B256630473D16D33E8562635660179C5E161DD0794F91", + "previousBlockHash": "F119465F80F0FDD6A9934BC153C72B4363693C82B894E8AD1F9FB39C607EB785", "noteCommitment": { "type": "Buffer", - "data": "base64:Wn/cdU6EyIhEXKUzJ9pjYmxZu5rZkh/Ni860JQYO+gM=" + "data": "base64:5b4Edr/ziRf3xOEvtU/hlN7YvMsrEVyiYbiC6+mRKiA=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:E5YgRg/NYMrxrzfFRzM3skIcui8Pm4YpS+lsnkYZunw=" + "data": "base64:vW1lrY/Qjul4PKoWa/KLLeMHgTcy81y3gLX1GWw8fCQ=" }, "target": "878277375889837647326843029495509009809390053592540685978895509768758568", "randomness": "0", - "timestamp": 1671223276964, + "timestamp": 1676574840218, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 6, "work": "0" @@ -352,25 +356,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA5bECmLmBemGOWUrAhH/2v8G90xMRTE9bgjhV266Zh7S215gouubAZvs3dk6Zhxqxcm6YFGd8GC3DuRtn9LvrHL6f75kP3x+pMI/YOPl/HciH8s2rvhoDQG4Iyl9ud/E66AxL+5Pet/m6Ow7SkDPb88taUbptBYy5Iu+PmlCJl9ACefKPQ5DvSBp4KvGoLULRVeOqTTHeOPEzEhrLcHnp5QFfsJwWFY0mbcbdaiqEZ82NHftVUw71489N1hNP6Sd6zuKBFVajfGF6tB+btWagCkTYA5jvZuRQ2gdGHZa70njJVCivH/bxCSJ/NbFbv4gEsMYpWSNm0XIAWaoigiGRkXxlkm6afIW5a75cbjQBIacsV+IygE+7Bwpk7GyE+pw+CfjQ7VSEZ8jmqwzjveCRjLh0TKRuIWvUfdpIZO0im8Oy7FRCxUp5aNAEVL3EZmgQZzxZT/gifPM60iXY6/MOf1e6aRC9PsqIx7tEjCEXB6Pbx8OnXPkd3VeYtnJrkkk2y8y0AXrYZSmR0VIJ6Du+GbG4/vHFiE191gpK6KZ7Nh7JAVJaPqTp9Gm90LIaGvVp5i7XeIGloYJqSd6WxCa//iOHc7P/CRRk+yuNwRTluQPLuCPPbgFQW0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwZavHXqHUmj44f4PRSpPmx0+TndqHbggt7r6Io2iGp8jPwNUzuWziyrdP1uEgNZGD0b2YFHXa9OpNNi0F+YPYDA==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAp0xONLfI2cwC0B+zVCAKBNm6lnScg6VNgMn39Rf1/Cm5Vf7Y04Vw0+bdMsEO2ALpI7i6LhqbG6/AcGbWJaxmlG4O0PTJFaMAlq7c4n0yFkSkrIUVh+5fETKpgr6TarXPYPFFk+Gb/4qiMspZenpGzw8dUzz95tpIEqdEkpn5978KYzt63PvYwHuUkmV6VASQYXAPXrGASp0bMRK//1kzaij81sWg5mtvih+GQXnJc+esR6LVWnt4pHaoZat1k4sM5PIkOGM1Uze4E9vFHpSzdNLdXH5P+Sr2EeONs7nqiwg5s+vUDJ39PkxDC0GSm8p1TkXdCWA3OKlZrbaVtDuyCnpbODAfczKH+c099APcgYiVuOTXCoOTKkVPtZdu7sEIH0PjSVYM4IrozfTdbmFUgTXhBfKlmjwhaRMXW3NBgq6lyEyCOXEJ9fDc3ZPiShLJEOkWAeVUlH+C+ldVH3+joThwnsnqAEwzy5LzxR48fo/MXUDA772COYtQ70UBnUK1cOrd/nLEL4t3EzzOlCHqaEgQ31erKAZJSEDfD/RXPxdSMuF3e3qvJ4dnwq7i7RefjLObFANEPYrcW2B5CeiGgkebF5Vq14WIhz3/rGceMxaXH9jSKrKbsklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwa+TG9eNJAKjc3DfPn0y6ZqOY0CC2chWpNdoKB5JOkz1K3tLK+3lTgBFz1IANlpSAKOVj/yGZvRD3GczO0DjACA==" } ] }, { "header": { "sequence": 5, - "previousBlockHash": "AF7F66E0DD7E5E1B80A06BF5A7BA94F0EDFE694A8A77A90D5D7F2B38BC8A4E43", + "previousBlockHash": "8DC46176EA867FD72DF2ED201B5AA71466D93DF198D1FA392B024EE843D29E6D", "noteCommitment": { "type": "Buffer", - "data": "base64:DGbGnILjkp5HoJ2GJzyisqc8Roh7HCM/N+9J/UOG2Qk=" + "data": "base64:R18wC1EjAV+atDXlzHNMbUTOB5oDGjzNPoRQeA8IAz0=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:gq3JjmK/IeR1j2m5x0FTwW8gvLYL1Xvjm/SnOSY8qqE=" + "data": "base64:DhF8ugOfRaOOpXI8ktZMdhAyQK7Zesim6iGeWUCbpKA=" }, - "target": "875726715553274711274586950997458160797358911132930209640137826778142618", + "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223278903, + "timestamp": 1676575101906, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 7, "work": "0" @@ -378,25 +382,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA8DzGgqcUn+WHVCr6aRFftsebOE7JfCFSpw5+Rh8P0Yyo5+W26bvdnpHdRQVmcAtmcB0v91FUgNu3HnNTnXyWp0pEWyRQ0dbk1wE32SjuniCwFvJY5MDm3XNb8GWIh41/Mkmy9PFmkZMIaWZbbXK0cfkXzp+UUQqIYcJiUfhz5m8HSRChJNqwouLt1hEGtyV7f7dRWtiEqf2Uv+VOxTKvsgASE1Ui+dkQCc/tJHUvktOXdmxeffUGgBfxd0HCuAqt3yXqXmuu1b70Zz7PLwzD6IWB5FbwBpVrilBhu6CVOp+MMLn5dqUtZIplyQCayjJoNnWHxS2cqjyaZSoLOdJIL4rROxfuohlV9dJcNnNl+elSESzqzzhWCp7S94bAz2wMoxklhBWC3Y+0IzXUGCMgc4JuIEHdf7/5Ojr8ty8oEEEaTvnrTTsNa8StBEMvDYCjtEEEIT0oY6rzpgziIQtdTClim9PWhc96OjGzD7dRS7UHQpL146rjPiNHUQWV9j28yfWUC2gsEP/23OD4oTH2U9rARklkZP4qdJUtIZqX6dCWttDtZ5/sLhELXHI0jW7To8TsHZNodZIgFV1aIhHsEkKFT17FeV43yC1DXHr3UGbMXofqGhzIfUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw9nhSBrmDIxV3zCmnU38w9dXyPvt+Wg8Y5ilT5Spv+0aGwCgf2DP/FWJVIXBUdwyE0jIDdjGfxnF3QZ7niveZCA==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAUzwCjtiRS1VTOsuH7KFM4jrVTITQzNBcuHzRsU7jgyaoKatDF2a0gP9ER1PmHiV9mDBn2ALkKYl45Y3DUQlN1UGpKsUFq1d5UvH3tPjJhhamynMMIt1wbgBFWUjhV3wVI982AnyKzMyrURL0G4KbRPAjhkUq60kuzhlaB96gxDETAldIYyqJJhma/Tu69r5CSMcnyxZ2DmwRSBw2CKR/dQsVeogHLFEzz0hGWqwOjMuF0luziaYrZ+KXqpl9QTuj2gXM2ZvDUFMJpoGy82Evv7sZKGQg840O5v7wBE9kiT7Muc6nu3E9w3TF44NmRiy/vYSdssGrQe8tljB91wbshp30ioIMyZ0rrpcmuVhxFu321Ho1B+5nAGyGItWfNvA/U0SLIWlmOJF6YTa8s4QxmVP84H9farG8O1Q5rG6mkJAM3occEDRaY7C406q8PnphSncqs/ZhhO6bcsdPXz1ujsRuLP84Gp2pF9pDC4sbMZVJXKqQNRA26qZjAFbh7wFmxyO3UmxESiTmsr7LBqOk8O0MremPZG4yXRpIrCZLlan8LQxm8aFIgQFIKCThoVDpg+wU3BewrroQIkquIo8c/5slWBjV2nDMEWcTdEJiZ4/AbNbVmBWcnUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw0n3V2Tjrs+CyWSMbGUjgmNRuvAKV2iXL9krx0rr/GTt0tNuO1ICH0z4Cbgpei6ZJ5ONcCVsjrSfqwekKeR9VCQ==" } ] }, { "header": { "sequence": 6, - "previousBlockHash": "B6AD0C5AC66FBCCA180D3A31592CF50AF6A5A891270AE59E6F038740937EF1E8", + "previousBlockHash": "00EA4C7C65E4F968C4105B56B2C31B513EE1C48FFC9FE6E3C550A6B0C00F9791", "noteCommitment": { "type": "Buffer", - "data": "base64:Vyg2WQ8E02ihVPYoh89OJ08uVRUzLYgoWjp0RO2p4Vw=" + "data": "base64:oi2dj/fOzBqkrrCeKiPkeSL4ZBSIQwCsQcrDwB2J/D0=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:3c+MuvYkRmeKCqP1MsSpdbfozRCSVHA4NKEJfBl1xgQ=" + "data": "base64:itbeN8wEG4GsVElxNE3t1JTvx1brfphQkBS9Cc7rCNI=" }, - "target": "873190827380823143577845869093025366895436057143163037218399975928398962", + "target": "880842937844725196442695540779332307793253899902937591585455087694081134", "randomness": "0", - "timestamp": 1671223281100, + "timestamp": 1676575102879, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 8, "work": "0" @@ -404,25 +408,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA6x6bnX9Pgce40y1mNFeuR2PkD0TVwpzopXwz+Kr0AIGnsucEKHajJ6BefBUee8qcqD+iRuE4Z9vAz1F8NsPONHS9kVlbSQiBLUgyssCZF/KozZxTTofWfO92yf3rYQbFuawMN+lU9CRnMCAaVKBRRiK1sCAQLvChAEyopbYmHd0JujxTs2CJ0jBsUFjKTYpdH+1u1jTna1IMVitKPGfmM+MJLMnUE3F5uUQdPvJTFsqmRw6oxy7tcYJ2wN0PDwI5EV0CU/zIpDm+u4RT9L8MpJmxEI9QJCgwwP6o7tve7z9Sv4/0gSxNqJxOwAX8SDfi/eH8EKa2cU5mVzTdBqZ6Px0o0Rul+l19X0tzQFdTy5mZ5eYPIw6dyD0mHvhuzBpCAs79HFXulidFXdefsc1BAhEVjHsgwA6tKXnjPsiYsRQxWDDczD+jv8jguFKtExky/M8pu/5KaRLVRXm1REndYgbm91Glr8nZPc1zq5D7Ktx1C9Fp4R7+0zPw+b0Hi5zrha70huVyhxoMh0qBi+XZnv3qTDbs3rHb8GexzykoaLMPjPTEqTyEWpCG7B1Gxz0B7iZq57czJ5s8f3SzY3mtPKWpgHnn1sdtLeac1jEiggF/hspm1O3tM0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw+svkIvNsw+fcHY6kwIXoCVkiURb6V2BIM0+mSgWlRoGHJwb3C3pbSKZeFoZm0W41oIaa99kD0enFv7nVTvM7Ag==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA4fnL4eNb7qFM9ZnnINNeEcZBu+oIFAgWN4iychBj5zeLpKgYyR4lJK0Bxe3a6P+i0HtygWcPQ7jS4tE1+wIix9Y7Xj79gbkprso7l+FLyUuUwg3Xbyk9y/VolyitpbpaCdXDGj4EIkVMEF/OTs2JuTPzJ9zhmH/uZGGCJgL1oYkO2H5bYObNELfSG+zfnAcQkZJXObUjXHzo7IA5d/U1NzqkMNXewiXnZ6RAQbvBvKmNTizBMkB2t1RDlWKz4lP3y6qRF7JKNY9yBGZbRTVKpLw4GDV62qNsAyWtwttdXmcKCm9gcy6GrAr9uaJGKbvMgYruUpLdX+ZPSCCiz09Hkq9nZNGjptUM9rQpwu+Hu6e2NLs26uVW9pb1FeCK43NBE5qVDh8Z3Hi24SmDgPemrkYLB43CrzrSpu30Jvufq9hJhl4dxz/SHBS/8V3w1S2u8v5aDzUNzK+gv/Oc2oKyA1FFGzQxSKWlTwvtyww+GTv7MUOuEiYF2LIuwcwPHNlRFpWrGFj0llZUgYr00YeBTT7cFW8MPfuuVmUAoaFRgv1wqOGt0K46v18ATqc6cuAevVmBEgEMoyXNZN7LHmOONRCtqcX7ySdPBAqnljEwB8KCDpYVbIJnLklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwBwaf1wKosSU4i6ylcmeM/FAsF+QXp7j4qJvTue65Am1pGOeGtf9Ha9kweSDePfMVMUUVjKXEau8xZOvgtfN9Bg==" } ] }, { "header": { "sequence": 7, - "previousBlockHash": "950272152F02EDA2B6C03840738AE08AF1DFD4B443852B3AC97EC2C55AA5BE07", + "previousBlockHash": "824959AB3D9F6B43CB94A8E55B68B53D5F72FF129EC6939388A50F9E3656EB2A", "noteCommitment": { "type": "Buffer", - "data": "base64:kpOr9FEU5tycvawtWXGOej08reSF+16iJdzGjeuEYUQ=" + "data": "base64:v+vjdaFthMNjPkxf9yVuaK0NdG6hVsgoKXdJz0sbA1w=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:HwGvhxeFaXmZ+xnHkMMJ/O6hBuYGy79mP7dUr/eo6po=" + "data": "base64:Xnk/5ZdmgDzn6Ht6V7UKTgiyI8+YyQ3Blopn+zyMExA=" }, - "target": "872769606528251593580943869156173931600262185432047184330209720271897081", + "target": "879130901036475001697423051875971117690643105150939656519205417941517322", "randomness": "0", - "timestamp": 1671223327445, + "timestamp": 1676575122010, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 19, "work": "0" @@ -430,39 +434,41 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+2vKiP////8AAAAAbai0zvxmocDEMfWzgbzUwuxelkzrsEgl80ifJ3YsAUehMo51JUujdhaZ7IwxXNY55phDWO3UffPElxMOl3erAJBUACnynJlf0eTuAAzmREOFc+kVB/AsiFzy4Ec1wMR47uYUoOnX+wFqW5N7jm+V2zbCytNru3L0TA5VBewdRqYNgreO/LkVwh8roEF0Cmaf35FVo/aTNwv22bC5HMA/9GgFBxxQoimgcN2MlaOEcLKGVOfPzFpb/bHJSOw7vjDqoVNxDYMuwIlR0ukzc7K2A+5IRWsv8hlRd4Cf6LRB+JUvVU3LdlOdxbqGgrmScIrqhgNVxKOljKITIaEkpldD3ozn6v8EHvzSdoWmO4k70JnQIpJt8sieBOXo6hPRGIcqoM3oLwI1q0ZHmNNGIeNX7zKr/fFtaA0JdLq0SAHZhOoTP8b64X/Hi2zhxTwvOIICYthoDAplqz5cJ2V2p5nZXyiVToGxx8cc4ZsUtj93IwJqvl85z4eyfoBoC3aKRQ4QfZlVQ94+WhyIDLXWdC2HtPvAdLRBOCwNe5S5VRRiDlj36ttE8Oh7t9JQmngaUnKFaPX26ZdutNloQWQAmv3QG6Tt3mcEdwBDbVKbQk5CBVJhFGqQkO8YtElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMhdd4PRWiQ6pDpFsl6vP9fbQg5RQsOyp03e5YXIkZgFSv/5Vv3WppHip6Tk5JJ9yQ8EeOqvjlmKYMiCuy/w+CQ==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+2vKiP////8AAAAAjPGcIUkpLPIM6TNTLhckJoEzjVTCXfwYG9CK3OA0rMmwQKTGE+2fx7lav5CG13r2LdqEgMW44B7t6Kptjmh9+DGV+UtW+o9ilppmddY+X1GqvYuzs/+TIzO6F8dsnS3/8ooTHTxhvobo3g2tAQZpU9ONiLAl0wklMP0Nnro2YM0KUOBKfKK7qfTobrkH/wF/NOW2KhV+PHCr1orwunwnBoOW574DoH3QB6wNvlPctFSJtt6WKWKNlDMoikejorNAzRlCziDJa3OExLjuSpQr2eS1L0p4lI5ZZOA87BBZKYKSxP8bvGWU1ngIZ2DlQalKGy9FbFocsFo01mO+Sx5kAPQqlp6TJoH+s8WTlCSquxEJ4ZI30L1XgtTpYNSKL8k19ZpvpWpn8IVe+4i/p6h5/HP1sDFfJy/1mW5hg1r8ioCcYktJ/XlUfaU4+mGn59EiDPm8OuffeuxpztBK2PEMrtJuZp9mxGqOFEYTXWwQwwdwT6nX6v5XS8wCPFjQiHnloSiIfu/XTUi4znEBGCUOQuTpkPB4MoDrRbtP3MDF2/Czg1EhtWyRyzQMLmmZ2MCFkvahnRu1+xfMitQXGv0tTA3jqz5xnhlYxeX/iW1DsusT8tecwTe+9klyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw8KxWeJEbUb5nJSVIehGuc69uZ56eYPMe95bzHHXqFI1/uheZZMsR4wq9x1j44YxZPLd0Vur/Sp4KIKIdirgwCQ==" }, { "type": "Buffer", - "data": "base64:AQEAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAZm5N7Ne8PJqBHVD6pKUgeeHxi25S6+Ci68D8+gkN+ceF6IeaWejmpvZtDj7wFifAMCAbEfMS8AO7l7BhhdSItAlauY3rZOdMHtuRzpAsemaj/TvRtk4M/007HWTWNG5NPzTDunbKjLWnbgqVYyCVqcbzoY59C4eqAFdvZwCM7QMCZruwZWTh7nRfD85ewDQf7KnzZeVnSZNnCvD1Lwl109heFxKoerMOed3iLVlGVD2ml75I+ZNDh87UWoS77RaTmGIRyyJC1NbGXLVXMO4D2xd/h/UdAPcRPdd26YbYpCBLJSWOOCA3+ng7B5tDGIcFnuq3fJCC9kQJkOV/oAETEVcoNlkPBNNooVT2KIfPTidPLlUVMy2IKFo6dETtqeFcCAAAABp8v+UHscFQKWglCWobVY8rjVDNnrshyNi6M1uRHejjLLYxK84CkbLYinMmhnfVetbBsIztXRnz9QTjLco1XTs3lOX5MbwF9ZMNHhzaGPB57gsDkNd+c+OnSfd0ljXxAo11TXQeiAC52NDkqKtYu/LcK/i0ga3jyITBEgAx/iw92ZhcnA5mKWvLZMWCAae7uaOpW2shaTWS5SWXqj91+XQBsI/QiU9qipV6SvGfTRG8M7NpDAodB5pWzJUcJaC20REgTR6RXw3f9oORQDZhXsfU7D9rsC057GEllUT79NAeL03TVa7K7gjm3nj1BxhU4Y2+Kb1HsFppGDEAgzrE98rFOaot7FKlqfg/DV0j9TVyeWiamTQno4Ug+T1CGy9+GN9zCe+u+m86E2EB/b6/VuDpBwvMT/H6bip07t8NcwxVHAvD9JpC3jtdiL1QKvdoEKLyv76GqBO2mb6jWV5tr1GuSiIlmtjEqfr1kmzrhzkWpX2EsdXVic9CdMTP61e5IpAwEWbw0alqQKhmMrmLKT7nq44+4azn2zLJ+NTB9CsNRXHEDlFudIbzGamYyJuk/9hItFVXRNEU38+3rCTTj6Pf3Yl0hvtFWsHErxGjXCjvq19J7wqgNCcehOo3Bi4yVNx6e2U/Qltk6DGEnlqOyXpS75t2H04hju37c5043dpwL9Ec17s59vS2DTtbfumsreHUGhFqJz4UTTZdWfIFpRI8vWJXjdYr0zYs0Ih8NhKzuAvYfYIa90SJdtOtqlyeCpitE+G4Lo3z+F+XNhdXVfQZZjAjAuxTuNQMcS4yYxRGz/erWYwarC2weFpvjow1iffTqkGNE+sAo26N3ZrjHSL6RtGH+CtyWeYK0IO6tiL5MjlyFhNVyBCD4DzdEB3LT+9Sd64jukbwhJ4ategSI0IpvQ4neOmeXHZs3V8MIwRG572nO9CQoesAZRxCUpcVKBXzNPB6bD8+NuqqLQ5HaiPEu/Ygs4fOnYGOw1xYD8aAG4uR7dq78WeRI6Vn79d/Tj5/W0vPZ1l5ERxF9v97kdQa1lvPt9+D0M9fQ9BmcVhcSii0wCvDaMlu7yn7PPmqyYnHZiMhBkfDsOn5rEinolnEWhgKqVBts+w+y4nHZWubg6gE7I7v86ZNY3Lb6xcxTfO7uNeQpIwki9OY7l1e3uTTNpYJzsdIsY+8QfCHY62ww96pklCSdWsPRwBvCoP4/4DH7/iV6AJkhrqPD74FzVRRqc/3UWy0cGuWowXX8P0orOBi6V/vdajVHOfWcNMHCbMvKZ3woyHXZv5KlsJGdYfWgxXkAq9VPbsTDK8JTo3TYLLQq2VUMLXqaMYRUvIlsAdfm10VpKcYwE2S4a2Dvog9P+QyY+SEmJ2OodZT8DghGJ3dWcHh/8io1uKu6CrtA+8V7Wlds4Y4JWB29Ru/VwzO+s7rKfhORUhYmgxPhoKoX4OuM9PWohkdEgdCtXJ14nE5djdJgFPXQtNsyQc7AwhE/4SkgWQOTzt3YN9Q+0N9C/qkHhd4bTYEshVNTAmfzTL432c6nOlu+YNDEt9f765z8nLq/KsGod9deJv1Fkokl280d7hhg+IgAewjUclYCw==" + "data": "base64:AQEAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAyNQNniQbjNAl/MyDAA7cBfSKCUcqrrlxIr/5YIlQtrOHs31RJEy/F+oQ6GywB7GBdgOdjHcbbWCOQ3jbHdF7nbnmv7Tf1+76xUiy1BvldqeMxzni1McZmCbl2riPR0jHOPZxxSXPER2cGEfSVSgfxbTBcdvDllzvsilXl/6mBwAZXsYHbbINRf7mt41ubX8d7IeNBXo26vjoLqp2ao0Xv8nEbj3LCMLMQQs0hM2bz1yz4go3vZfKG05X42Awne3Ghw0DP64TmKG8EI8W93p647Vka3SULIIuV17uje+m/moOW6uwGUO1i03ntcqTXdvn/qhpce5bkKPQU/8j4o4a86ItnY/3zswapK6wnioj5Hki+GQUiEMArEHKw8Adifw9CAAAABILEvWgQqXt7wjOW03zRsMPs6XtojGSG4QaxZrf7aaPMZXGaw7sCFZnZ5y/5VFF9BaOoUH0xYQC4ob6SKYKgwBjnESUU8etl6WPe5JWN+gWUyjN5Xr10RlmMIzU2BD2BpXeDOq9F8yjWvMGPwmjpIQS09q5enJJmN/TOghmb/OntI/9XewTGhsJVojdJbbmk6Ezx3Fm3emS2PbRd5lJx7dUjfg2WAxnfFh3dbzvwQ42CxgfjRrvnTph4ZkMROD6SQ8fdRPto3++lMfl5wGa0SA+tBqlb0YkLUgwr275gL9HEClR6pKv3GuEaBRNnk7FcLXiwxWEM8vtUPqW2VMX6FZWgzdJM16yYea+fRVvcznGlY66O7leCmz32Nm1FUKeg01+IF3LACN4kXbVagxNfhkpTaW+ZKCE9GTnpaXQJ+lna7UFHMdtRjOKpMV4HfMkRbrHqCSEAd6SwDefuaTXD0JcyydyWQzgicnnG/aZQJzuWIIqDyJRwLtSnY4DGoUMGVPKL3mTicR0AlzwRLU+/EBS6hGS7ubBb6dHH4C0WqrnMsnNpcfUGCB4yYor5WnXNj4RBtDZVTG7nvJ9TL71mRQorV0TrYl6af8zQvwQ6FND9dHtNSfsOlvwfrdg87KyYrDRdn4lrx2R4Srh4UDzrdcB9pMYwy1q6lveJunUWNj3MzZ+p4MZa5ZGv1Tn707NCBWPWzfM4CTtLmKyMW6708CVgAptaKFvHrZ2Dv5A0bfW+aPzYSG3av76nway4ibzJQdP7itEJTR0gj1V/AYo7s55UR3FjqbIdQazd3bu3mqGAUW4aIjei46C+RTBRYCAwCf+Un5mmDOzVz0c6RmLcjHAt9rfoBfRTDYENTQ4gGtMTWBcWS65wR6LtkIgnIjA3Nrj+gt7Iqv2HtuCJ2sWmw3hw7/oBEO4RnyBSYPsDy6mzhv6d1eZtwQDUYAF63B6E1Oit2a/Ty5qeOOBNuGKUY0rCVKvyvHPXUAODbhGPP1pVyusT61HX1KMq9LCvk509K+7jz3efrHk4NwNi8HnO+yc3vZt3kyg6pPhufc9mk2JiFR7dJO1NRaCkwRm+fyJCfUtjDem5VOJeSvhvjOp02vYVQQM2Nat6LSJ6pCF/h2FxIoRlE0u6+Q5pDqIBk/TnTig3QFNcKFxFOnCZ81AGCMKglgMZwY4VXnEsDyrOdSJG8qTz2OtyoX9pH60/RGSb9EpcsAbKRwcSFt5zQM7QGnr9XEikCbycaV4PtAuFHeMbUidg+g8kLSuRDnAbfKz6dH52NdECuACVR57r/YrIyXF4gX+UoH2oxsT8X9AUgAv9NuHJ6rip9VUrZ9ZYXiQdesizU0nrbYK7COPXSdqllJlm9e7R1c7b2Y9ghFJkxB/Vp9tOMyClt5ugvTzBxAXq9k0+kxEtgMRrZZXpW+25d9Kj98EqRB32JbdB23F99xur4OWidhZiOiX9CMUR43DowOtR7UgUaEK2iRXrckmFjkttNg8Q1vTxir703Rj+mEBuM4HlRMwa6Jww401Mr80LOrRfhsbabOwfCqmhqsUAznIvVlWUR4FSRJyaVq/yyqVauhBGlBLFRb+QCjj+msjCQ==" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64:AQEAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAA8f06Tdss+xf3MZSMRQlB7xtR9GDeKsvPqrP9Xwx48kWECqGDKKGdQ8EJa52ViRXSXeWS2EGAaOoxlQcveEYw8+WU7WqwsKLcm7vJ77S74xmmJCx5SRWDLFwzCQVxIVqh+iWfWCGlPWFeGuB9uDwzXdIlYTVNaqdrRlIDrs7H+78JyIBMX6hBuD415VgcLVPxM5YWOEyb7F8PT2bTtZqYTa3TmA+aq5YIQnoNQdCOOrehZm2K0RTcviz21Am81gkiI7kUfdsc8j9Rre2wFZUZK7AJ6vNFMrfsCR7dZd5uMtOO5K74QSooA3vCsRrQe2ntYWjAZVXtvpOjy/94zLFSWKItnY/3zswapK6wnioj5Hki+GQUiEMArEHKw8Adifw9CAAAALZnd8bS21bf8kDS0bqNe4KfqQheDEZTlriWVSyOp6R6/lLrYdDhSRIvdAcMv7E0ZawiDSjQkSYFXDqHOhm0KOCZMFcHgEy1tvCPW3B5fxKxXPqQ586efxnYBsezEdaoArENByYfL4x/mvcSSmPjiQe0ihTYX6PaXYqBwPpf+lwm9MtahNLwARQ7OCFPVgLw9Jf6yPZFFdehf65XEOFuawxNJ8L4KbQUqAjq8oxlx2HsZ/NiuYpnKRoy+4ovrZc2zgN3qrJL4f4RCsCqZqe19IXckG4M8lPb1byTieDdvJKLbsazsAWzxo4RlXY09YMpX5JEkXpRoAmiYjIdAzHsbngBmORRrPb2ablDqcTPYwN3SB688JxKSR8IEBvKclP0BIbr2fyoOvbNplUrFsTIkSU0bWvEMo2ZddlQC6rIFNKe76GZsBsVp68QnAREjvnY+AeHQ9KxBLev4SAaSfuxxjUw02jZaCDVuSWZE0EYg4z58Xuslt0kHzZnI4a8kFv6Y1AzZQ/1EergpAE1VXZoNkz6v3RC+ESY23+N4SpFSwuOEWgXKwjwtzwDmswATuNIJetv2LbkmdYIsEGEqpCYwrotTEnwB8GhCIOaYpbINuu9gS72CON/oTUUb+ARmfqL54Dimqt9P4VpJv0HvtANwThFzPPOEKSctIXW3a724by0duvnf/HfkUmN9VVaUmLggyN6X8NOSUKWqXOfnYkMFtYAVUwv44wwIyY0pQhDn1PUPl+prutHmiiS/ADbxDql0LLkjZRsjVlY/XNto6OrPPEuU1HpCP3e25RxdNgvBR1IpEPEyxcTlVqioBqOojhYqs5otwARm+N1w68FC5OglXgX3rGqEouDKF36K7A/cEakT3m7wIDUVFio3ay6A/BdA9BAYOqxUFJxtl+kqohXmqCsCHvQ8PNENHlfdMXVO4JlyGcnrtCZvEwZk52BMiQMVSnQ0C58Yo3AIBDup9/wc/U6Xs+t6OQqgYIQTkneEAc1wKCMcfdO7ke31omxJ2c6NxA8xa56I7M/0C9/OzS0t9Qm0h+w14eC7zgTfl0V7KKVadzRvLqDCuIDbV6yTFtxx6ebYo8oMo+kq9tsEkllGhB0QfrYW5rnhumAR40jAA05Xthc6mQitDfx8RBm1yyUEFoYKKTHA0JluRRCJ4+7qqa/tl2G7IU65tT7hVTVEn/H0xSREcz/mWNQhl4pYLAQktPBtqAZ9TGE5SMgKlOe/3jSSFZJcaTWBnAS5c0qVcMyWM9qzv4piZZfrwlo5iht9t4fjh3su8PBjTtPIyx1QgoDP8t/KLdP5Nd3UISUxDMEEmQtCC0K9WmHtd1sZf+ByZ4z4ZIYkfjNo+CykM7IvDFcpyTdY8ebbq3Y7FApV8QKVzjjxllv6t6cfszW8LarupL/dawyoVe2qrGulskCvbuqAavhqCkwCCTQQNdezVCoDdT0MdGjs5fJA2q4uocpNPYKNz6D2TdmoR/HnValAigb8uc7SW4iIT7K6eG+Qcde8a6DVQxmjZR4pqMuQc+FN0m21ddOVGMSMrNVlMkbp09RuDC5NgN3v7gxZblqlTwJVkLg1ZGjQ73E4VkHHLvoCw==" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" } ] } ], "BlockFetcher requests full block if transaction request fails": [ { - "id": "d1ed124b-9ec3-4eac-9c64-2c8021c7f093", + "version": 1, + "id": "851dab12-8783-4dcd-aa95-c7049db18652", "name": "test", - "spendingKey": "6feef2633f7cb87956b7a014389c431258540b1413b58e8d6efcc57f2239be70", - "incomingViewKey": "e5f62e801919d6e9fc32e5aec112b181e008bff7b19cb0cf20fbff65c1de8701", - "outgoingViewKey": "5629869babd94c21f2d8f54ed893653446b36b4eced4286e21ac620fdc6cb887", - "publicAddress": "6e3436815d25365e47803f938679dd94e602fa25c07fee9562a34b5b1e3e5318" + "spendingKey": "fe26a1f737c88eaffeb20171bd43c33cf0bd28d1ae677056c75c91ec13de8b91", + "viewKey": "78d290382d262ff5d6544532a677b959fc1a0edfe2b707ec2b1c5fe2411680d4780282215cec93a84ce392102198674b80b197e058fa539323ed2824a8073ab3", + "incomingViewKey": "5fde07565b0cdb6eab70144fda2fec6f3f49bdb9deec593c2fff51fc51815a03", + "outgoingViewKey": "7074faefdfee9ba9f4701acfc36b372dd9740faa917c99a91edfa1be0b873e42", + "publicAddress": "4e57c333b167978e4a6e7e0ddb34e16342c7c7488529ee26f7ff9bb3af6173a5" }, { "header": { @@ -470,15 +476,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:DK2yrShp1D5CfRV+G/pESMvWN3ZNWFZrelkuBlNzOTA=" + "data": "base64:mGJ3tK9krJK6523RzRBm980dOuy0eBpv0oQOYzr4X1o=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:KHQvHygnOh1s9xhS3Gi2ylBUYQ8Drn0PSZ99n8lhB1I=" + "data": "base64:6vEMtgwx+YCgjqqnu2e4sZM/4z/NLIZW4aFTh5Qhe7Y=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223329559, + "timestamp": 1676574843184, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -486,25 +492,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA7vxqndcW1GcMvlZapHWDcNGe5EcJJPWnoAc/7zFJqV+oFqsCHUc795OKyaT6LH5mStrwP9MKCty5cVF1LO++biP0NgOE2/5b02KLqoJRW0mkxBkZFh+fEp424qt5snp+lnFFAuXZOk5I9SxwCvTfif0gdwKCXtS4tBIdV9tojT0AexcU7+DxCAptpcM3bl1rnXVvclsPp4kp6QAtyckJe2MVFfMLeBnlluE9DM3Vw6qBDbmCyI4maF8FUGQNyvh6hm4Nw3c68zODS46DCBsGGzpQd8YuCe7oGqZmBY6/rZczjozZCo/Z+12zOy64rqLGIWyMBU0aZfVgBehb3DeX0RUyT0gIzxpPESWZyzxUyXOyNPE3NKdcpH/ufw8RKUJWz+wQ5puyHzycAXSCKP2oVECwpBfmY/fdKPAdZUDHGRGnxSAjPWj4juxyBvBPfzD3PtFZaigAaRf913LOdjBJT4LKGfddRjP1xBFRwIHJbDQbfJdXJ8mQ10wnrvt5bANuY7Z5K5wKUAkxnx2B16mcSVZzUijW0VPg8xQL+xon9Hy/Qath4N1x/79wDTdlQmyP1YbRiNgRl0ddBQpSsIP4SWDetfj8s4bIXcnDPE4v5rZRvb1QQ/AGlElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw6lRwx22oI/ejYx+Hx78SFCH9GYcSaG61hMLJkfion1u9sVsl+zvZ7KhZlL+fiaM3lWxmtJ+R+LoAua5YBqEFCw==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAyuAT9yxHHVfE7i65+6hIazC/XmP2u5VDUPXWJ7akekyRImv0lMtLvIxj4r9JmSColdNVUj/mOl4cmIeo0Otl6/XumdPn42rAa1t/Fi2hZpyXbS0I0Y+wSxWHO64aTulWD5Dxhb4h2sKyl51/WkcCUWfot4tjiBMz96dEhGyvYvESqkfXhWDD5+iBkF1kRNYiHQ9MWMoTfNkRCS2h7A56KRDkoPOoV+cIR/JpiJo9Amq05y4u+wTQPZB6Wd2vVQDpWXLjLn3DZXKZPm1iHJrgFr4C9/8uAgIfvowtmkNHItYlyAh1Jt7Y7K1ptm0jWijoIxsheowvw4jkMlE6gSUUa7qMEXalV4lD+oyFD6ZI6K7iSwoVZ53A25G7v8fFd4oIK3sYq9wmzCKpkTfVjhT/fsrd0+fymFbPTNv63feOW6TAjOWzPVGvEKkLFHO5+VvdaBE0YmPwDwgJJVDNyMncQcxjODYhMx/pbriJ9ZoCN7jQ2U6baK3F5FC4/UdAVVcrmf7M9aTB49/ea3z8mEwlrC6vB66Prwr7FFs279sDG5FoadaVy5Gizng1o1aYzZpnT4E1tniDewreK5oPoH7XsFnF2R5X+gMEEV8uk9YsNljzzcfzbQ3PpUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwBGKbKeEIvFrs4Vn2Q8It05uCFx/TfzCRyk8Rz8IisOYw6WST11Jj3xjg/ackxl4l1KXyqbUixMvG7QBkp2m1Bg==" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "E72C618D8CED5AF28161247579763D9EE3F82B834C5087B399D51FBB1EF01256", + "previousBlockHash": "082E0CB7A689961AB52297D02E7811F69159B555CD1E75F729019E727A2DFE93", "noteCommitment": { "type": "Buffer", - "data": "base64:HXAN/5fay26QrPMoZye54L8xEFjK2UZYoqAljWQaAxM=" + "data": "base64:105UjN1FQF/nyoVESnXGiSIefAlJHKYttOsIu4q+l00=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:vFJOLFHTXTTf8RY9tL9ssdxEkkRjO8vJGIJGi9yz0Hs=" + "data": "base64:0MmeoKaUAvVrUtCvA2949y59iIUwW6kInyzDBMYl8Sk=" }, - "target": "881271989446208257911980828427057262643615932976441214377264856368067535", + "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223336925, + "timestamp": 1676575124886, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 7, "work": "0" @@ -512,11 +518,11 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAA5+C8VL7XMWJRamAPm2kBuw1xtw1j1L5CQUpj7i1x8oaMt7p2kSAmnpIK3TLOBg1+fyNpQ8lAPKcc/Xt/b12E1amD6pB1w1MyfMbWGT5+x06HQZUMB5om/y9jaQEj2pOBdPOjJq+KFW+8Z58RYmKXiCc/TkfiQECq6dCkuroF5kcH/jxr4B6wxwjOfXu/WzIBp5b0iUjunwSZ5VRjxTC2A9lmW04OudHPPB/zaR2tj6aZ7ESEJF0co838l0/DzIDSky/krLyu5HJmvCt2TZvEqp725ZliG3udVYq+TpZR/MSPgvs+VpQbvN1/Og9+fO6luTIVq+2AXKcD1U+5xt9MyTK74EPCDry05W2rLeynvYH7HfddSVGt9N4M0CImKbQZonslNwzSlIqdyQG2idUSfV3dCc1o20PTMuQbiADKNuLhRHdDn0RWXOTHqukIws4M5wT6vcqRwd2D+CO63f+8X1LdRMPeJRqPXJfVIMSUFJKO050AylDos+zcye4QWKCYbE7zTQrljC0T3xMyXHB6GdEUqf6jhHff08otPl6I3VpOj5kCePHy+kEcJtB56CXUGLsvaQqw1A7nuJhe+zyuQhzIS1qAdD1bdVP2L2T7b2IdffppijpCA0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw+gVLQBFImvCXbQYHvW1ZAA4PcbE8zk52+eiuz6fTLZNAJQDaYe4dUgXXEVAnNO09Sofx+hQ7bFaWoL0a/hW5AQ==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/2vKiP////8AAAAA979C/q/4A6HmKwKkYFDGvcTNiZzDjq7CjvzNg+KnfdSMk2aX81radbOJpklXqSjUy15/AE9L8/fPYY1gErctyMFbGMxbPmTpsHlJi9zVKHqL6weQE6SL7eK9J6s6FsaONxbdPRD6iQvC/LCpcwF5hrTi2zmj4B/vYlsTWtj97QIB5q5QO4DGoIVjON+2IsEJfybWXtPzXW5io7Vdnvkexhj4OSWkQ91NeJ/BYlyb6zmpss1iRN72842xevhoSJ+R16xl7D43KjDqplJiK+Rob4SxEYiM22pIfvhdeik4DqKQJIkelewwLUG+etLSsHFEMe2T99kJdJuimDNOy13Rgeb/EP/ltuxUwAfWDs3yuYgIh2/HzJp3QBMXCtHoMolDiuDtsCyc/rYLoQh9WBGHnuTEIdGgTeOCuoWPYoEJXG6/EIsO95lbm0PVnSJmfDRbwAtcl9iDAohk3EYxSrQIHLjkIXw0SjfTlD8gzQ6j0NxlhKkXodbTQszS5m7kArNk/zpdyMYZri+LXSwqlvWyH69D5hGtj6f1uPhDi7EzpKhsShxIIbjGr305F7yTIbYrMsINxXLzDgaL+4/jD1A50FOISJxAK6myoAP1MWY2p52kzLb8rJ8nyElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwBDucuCpLpU6HJCFxWsBray0M6axagPRbNl/5RaT+fdewJjFTHLk3Bon/kcgkAK/Cy67//ms9uKJQCfCmaIcxBA==" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64:AQEAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAADwuWdktH+lKHJ65N2QoEikPCqj2CfzvSOSSqZaLf/hSiqiH7433YoyfbU+Wjzgb+Mw+d7xzEaEvl84rt8O6KWRJVK2rm76168ByWdsiB3YuBCBNrfmO1WCtig7zBiQVsJcdssk1QBVFSFJoHsxjtJLF8BFIFlbQFGaKgI+o+Fx8TlkHPDLv9HCuDWqER9ztP9Oi7TlufFC6namGzyfFst5hJoyDQEWl5NAf2Vi1YYvKklKAbcyPVpNOn7ZopbIRVrgb5/Kp4e+AWFZHWzd/bLhpaxPeflLbNWyICIMDAZVXnGvQHmGh04m25lraA5QBYjpGTDBsxICK4Z60ENqIbQ5hid7SvZKySuudt0c0QZvfNHTrstHgab9KEDmM6+F9aBAAAAC5KG/JNqkAifm13HQdSsTe0WnM1LF2TQfWNl0tFu11dDJVpUNqWuaeZgI5seorRvVUbRIvVgXHBAeiUc3FPw8jCW5Zt9bUHzTUni0qhl0JIQ8hVUTRCI4wtUkuiXbFBBKdXlH00iaFFIqvxIoks9W9m+/57I1Ljd72zp2wvvRC78YiO+dRKJK4kgzfAOLqKs4aY4ygvZND5Q2GJP5YCGQ91ql7jd6Rf9xl2wXsJ8MRRJ1LhWYcMvpFLhet3q45PPwyFsy+r5yKlk+M4an24vQ/dZsAeG3fGkuI2aKggTilECvZ+8a832YrgU7FLF52g37PegkF89pwgpLTVswEjDbXq0eQhrORs3LLDyw7daplJcD4jzkjN7oq8Rn4d4X2FBij+NR75hqsGVXqS8+2Ekv7GjVn58sIsYV9VVEhNwLNDLV4+1sXWArKCkhsJyFc4k/E5eitv8zaTZhD1B0g35gimZHMVbGlWFeQDTmk3xHR8VMKaycXZGHq2eygRI6t/4bW7K/NgMXDGq6VENHpH8IVprSVw1yQE/EsEir4QwcktuXQCtu2P+yBzqVUNeJ1Z2ia9uhSHRbGyI6LqyElcwhdIaU6KDY4Ankcyw4T+aK/Yr1Zw2zhnBAPV7UYgKUKQgiqwUixaJ9c/qp6y+aKFfE/tV4EQxnejL5qQ0GPITN/KPX/KHVe3SkqZq8zJ/cI0abROT3H1bZkEazHJAT8qBKpgcwFXirrfdO6UlqPdxQy4I5i18lgLUYwiPcjspq6aD1LTUgOXUUkUNiHRMh95lhyFVQ1u3UFi64qE1wsHQxmdlisJW00bWTWNLFdCYRqAacZ7PPMjgz3rX0+whXN/si9ScR0nbgnTRFOOzrRwUEsHjEgoRsBVTS+CbCjZ0JKoFX8gDkqHh/pqEDXVDZ95SwFFttuoS5BamFsWiRRzNsKwwEckx2uIcHEUYJ4zDNdldrOKNAYyMcwmWrcytk+2+BDkygo6tdAuwukeVSBfSmyivfBgZw6rNTiIVyV+TX+ZihDkDIKD4hjQ2a/vAr3d4yWCLalqjTCUvsuFATeps4xDE22jHZUnN/Ipn4aSlQaCmmwSiMwZEFByT3K8YnQJ66OWlzimvAhXJ3+IZEHx5lx00xze7kSaug+e204Srevn0tarOI31ciFbhaBnZIZoXacLt8NjS8DddYLq6F0raloOo6XWTafjerSEC9ff0qGipRbY5rbYnSQY+tBHCJEsgX81SPX9SPkhbYOZUhUdMnIggHlIn/TS8OpZbAM7k/+wl2bah+2hOhJRDmKDpxwliB6KLKm7j16gdcbdIcL+oIaoEM+2WGXAzh2kf193mQbsNTgGLsBtbBlWllLrl5tEOoNoH6rcIYgktrst/PJe0Ez00wOe/L07NzlTMk3Wm9mxQXuUfzu3goC5Lpl6OlAy2dmsf+NB5xdSXnclQ12ATIL8JKEKQ3LByzmuiT+X2RzJoP0zhR7j25MyUp0ukq59cG5JhB/KvyoZxLonLR+McCqI7SwsjJd1laoiOnVDKhII8CQbdrijO+yu9IoKKijcMfEv0OMKRAQtZ9dqfxXi+pn67dNTcAMomxoPjr9Rxe5tAw==" } ] } @@ -528,15 +534,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:Y/ho4L0ko4UuUDA3fLHJHlUbMlOzlhVv9HH/tXoAnx0=" + "data": "base64:dsBCw8qy57QnUpuzpD8tz6AZgsAaQPmgW+BP38nbQmA=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:UKHEMP3NBZdHyDd2PCs4rFyvZoPrpO1X7iK1gUIl5XI=" + "data": "base64:f77MGn6JGgxbGBDbbf3ZaefOVwMsf2jMQIhmjLFvkaA=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223338583, + "timestamp": 1676574850219, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -544,7 +550,7 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAATxIXUkwIc6vehGdyCUiWhGZGgV3XmK5mCFJt1Yv2/Ei3Ffv8nznS4cA01VEjVayfVyU4cOXM3UKNuYrQvdgE87JEQ7zx0MWd9txQR5h/mAi3WRh9HGfsCmzdGWyZwOF6+de4pG7SYrK6s0wNIAJcckwbeHrBGc3B25s1ik9A4AIAE4OOklQWx+GRkhCMYEEYLQr+8SyyrTw8lAtUV2iTr/cISBwPL8T/WD7SF8moeImjiWgY1lx/in1SOUIKfILjjcnUaXsIxM4kpnMeFtU6wnz9rnt8bFG0KVuUum545JGSvlFzmw+x5hc6m5BXuh2Uvh+eH/T3cWYy2WryTF/lVgGWjfnDVh8bqkHRvkwVL6iPB172AMihb2gY1C7OBH9TwnKJph8LYkl4xtqf6KPSzIDbKZpVNjOg3P2Kq3JupekBshMxn+ZxxJll6bfUDFHpJ0wQBs9SDVS8JhoPAcQRxnX7fKPdlKUpeFDcx9RGaeEAcLPPqqn9FVfMyBSQtVctuN1jOOe8uwexyma/1A8XbVaAQ8Ilg73YqPYGEXKyxt99n0fJGaBw6yD9LVFV+iMygRZqdWDTHQ9lY6eh8d41BClWVvrvqpjR1oAz6pXPHWKWQCQ7TMsFRElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNyuZfefG4r79eX12W7w5uHhXH68OpOXEvDvHdDTwLQyzaLGASe6tE/Oa0wIB0V+3yKKTutY16twGRo8xvzX0Aw==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA5arqoBSPnQbWQmFNaNTTgeXxOovrz/QuqussnDaz0oiKHekHhFuUWSwBoczYO+YWHG/eXvvACArdfi/iwvrWn8Iu18YpfQSARlPghRTBz1a5x9M+pHXvOCzgGiE8lWtkuwBV96p8EKpYjYoM+tGweoK2e1MfhLOMLH0V61LRPJcP2r0Ikh35RaP4LcvYnQ6LGqbYaGNC2AW8k1b35kE1ABRTwCya+ynZsK3fOQn/pKSDl0Hu5LbhcZJ5E3XUcwRYMdPfvOcKBLlW+lbEWaHZVLUkMxADR4KzIdAdan+WXZCaVbTuxaeALpFeDRL+JIoMPUzr7Ki8rQOcXLlFh6C/3IjBF84xvd42IGSiomqBJzkgeaMnTkwtUq+K0jUC4mJZVtbEUAM/HJzCZhCELd6Jc7pbBHRvvNqAUARuiTxKCYmnU1fCg5LskZOSZDW0hfRr2YUr3T+xRItczyq97sdqfEFa/Ckb2iK1QT3erm7QwWi+MNY9nchtM7p3PxWs1xbKvlHN6cZEDpa1/ZboJKgAa/H33cNDSqGFzd34YwRrBLXeajMgBsARDDy10dciphSc3bDL74/4g2Kty0XmRrZZfcJC0+hWEa2fluCBh0wZtrb3D9k0zuASfElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw1mk5iIff6uIrDZqvvuLeczr4RhXtI9E/9KMC4Wy1eBZvjTiIPCMsTTvGEk4t3b/dDChIcY+RnZ6sy4uQmfhiDA==" } ] } @@ -556,15 +562,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:iRS3ahwQZPtsLYtjdwqlqLLJX9hGP27t6Ei2+twPWVU=" + "data": "base64:FVLG0m6I3gYE/GYisf8L0EZHdoZPePdHnFWGlHf+UwQ=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:73klSeaSvznh9ebhc3mXlb4PPG0thc/uYPLaEtENMEA=" + "data": "base64:1g1+ExoNh+zr6nEUS8iDXEcFtXQlo8SgZU2eGQHO8Vk=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223340286, + "timestamp": 1676574851382, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -572,7 +578,7 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAq60XTSrOKZfoviQ1IeYXUhsM9dPWFvVgyIbYFN5QqSaKAI9x4i9s3FJj/qHfW0ofyBAkPq4En5r6MD4xse6wVx5/c2qMtjudOx8bGXuhfi23bVj0j6zYSE8bowi+LdMDnnSdj8INHuotRrTyz9tI6JX2WBfEMdUnSvmDfkGSN4sJsLHsJBYm4e8SRac/EyJkPnbRORRfqYYoxltJGIOmVEpD6o5FVctwJqjvb/En/xKGGERwEzrg7birCJH3+wkU+ecL0+18imI8syQWVgQZpT46mU7qkPzkUDEa5G3xysQEByCGsdgpEGn/z0FnwvkDm21Kn2brvZ0kPcjlbJMiVhDKABJ+xAljcaXXHgWJsRYX0tEsoC6Vge6DijSRKGwIGCM+jYOkbcLh9UzD6Vbsvc5DVIuaLxWou7+vrBBs4p5ggp7TjLqajIiIq5xOwKQBaH9yldIjKXCbjqzOJI7yOqdxbjOqHBteqOGwHMLFHaOPFNo6gZ1mYyYctmz8ivpCKgAy8NLqcZP2flpyjeqgbX34+7toXEwkB32K6c+6vfe4XDBUfnsed8U8/bvB1C9W9bBW6hzu2JKoPcxHn5flxU+SvCN8HlpxTVHTXv6RHGyCn+ThVht0l0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwwCrtikpbUpLvhaSlIm3wFjHa63E4Ml704t0y3Gi7ormvmRFqbl19zABETyLt61PzyjfZ3/zvyE3V7+vAjYAHDQ==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA14earZ6f5FE6DkOwdpLYi9G4MGp2hbnZrD5XC7lNcTWQa7fsgOD/zIt92hWxKe5HTYr1YSDv6KMfuWIcJjMHExMbXXRd4BTf3a93LNHcDjuCKpYVqBtJHDUSRm5wpE1WpcLHey5/CNKHjRYbYLaqCT8PyoQ+MamoNdTo0qrPEUMC9hjge0Xkz3cUMjnt+3a0rfYu1UrlvFZQ3lZTq4E6Zy9PiZjvScA5NJzt6opq0UeDY6REknuEO0dFcH5uQhHvqUrXPiqVg/QzetoIPFKYucZt+Z8HAwnElW9RWIGNJXk0Pmoc5dCZpxogFXkmunF8afJG/L3/J2d4kkU26/ZgUhR/wHNvAq7u9GWWoyfkwnCvjQnfGWUB0i5ccTJOA7hibUCLdCY8a+99pEbKhO51wNJhxpdCrZVxUmzcK6k1FcNmuirk46fFH4oVM6GKywwqP/zIf606HwymbUe/TiXOe8fcpZ4Yh++oBzinKF9RJ9cRf5armfqHsOn+UmtERGg0e/EwWgZBqTCruAcRwXRTDtoY/zIyiLMsLM82dCj0GBKKKm9M0bSqL60XKD/wdJqhpyOwh6Gs4n4w6MY7bL7/qlxIMaZDTfJ12RjTnFvR7jV52QvWeCsi0klyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwuvGVEonyl2rOjguAuYPoLz/vFcMiGwZ/cYRsj0ijf5C7GyIUrUFYSAePqh8sc1+YWx5ZLpCN3V0mp8UBJ6cYAA==" } ] } @@ -584,15 +590,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:tz+N2j1fenH8WYvdkqm+HrM8fRZ2LlK8Zu/zEX6kBjc=" + "data": "base64:HkU/gENueyZXVKlZZrPWhKUarJNES9f35+9B01o5YTY=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:EIzk9RwV7RrcgfwwGZFaFRBxqDr1ldqn5+e3Fp/3sHQ=" + "data": "base64:fHOPzVu+rbMffz6XIteHlGmugGoE9Q5oTBrKtbiuCac=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223341682, + "timestamp": 1676574852408, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -600,25 +606,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAs6A4R/8tFgBtyqZsM6MGYlrpQGInMWdWxuHEh8rAV4m5+R9SEbdzAhADZpXrM7QRDPOLM9S870ntVG9QJ/YwtcQ1PToWagF1lo9c7Hpp4GaCG61ETloUWoiQTXjI44R+m9z5xPcvtZRv7nE5JT3MqZQ5Qeh6bU0WYdYiajAEPO0BDtuefb643pxC9BvOjbzL6sZXXgSC1cgMFcOLLq+DhHdXM8vKUn9xNGwmK+j867mDW+YsQviJfBCqbz80+usk6uMbacBiyUEBBqApMiTi6SH+yFuvVtOHIyio40dhbgE1vtNc/UQntk89xt0qHlh4k7s06M1rzJS0Mw56/yNxTqVyTxluTcwk5imlLrqjF+8CcG0CXovzDiN344ATC/1FexzZHiO2sIMNU7FzbJS30VSC/EnuVCVLC1H7hdst+Z+fuhPTmJY6RtNiF0iK7u/AHKrjXmc8s/CxQRieShgIRQEVNA7uJJoMUM5R4MmZDYDoo+yLh1IAZ8JiEXla4clssIuDRZiVC/CHB1yew+7jixkfUxGBYAVDnZadOvjPiG+bWbF5eBtmRU0TWrW/XgD0lj/PWwtPGVDRA7SVkYSunfOEaTGLZTmPtghdJ3tykhz3qrIZIr6SQElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwd/DbNdvlx7cBtbZZrvF3J9rd45eE3pDFe9/FWF3mrYayZsnZHNpLju8C72zDlYefJ6Qq4eosubumBXA2mx1JAQ==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAL3rq9EW72Wqj6EyyPw+v8xmtbVWqgo1q7BnAMFmgk2CjRm+e3x0pvOn7X9qeX60UlDyVvDVwCRSqlMlSc1sGp8VUlTuMetmO5lt5Umbs7QiQoemSW6s9gtzvVY0a2T23cQ7OYC5Yt4KaNSVUXrvW382wv2DHp5N5CONne3WyrjcJG0rPZzphXqOwsISKTcqEFuVFQLwy4IQtghDOnxZc1PTQhmJrySuvaP866BmBozGGFj7PTX7f+ezyrmWs/+ekZ4Xma8m+hnzgAaHrkAVLaZxs8pcE7pZHakc5PXrd51kl7TN7M+EevHx+XaxnjMOn4jAqcINMZ0A3DPqeArINoBHtt8S5fgoiIXU1ZxZS4r8aBq/OVSQyZRY0TzrCyEco2WbuyD4rDeQBNWIa9tNZOk9zB/6yz6Zn3F8z8njHQcUp9kveiEvwWrh3RIzUfiY+Lv5s6tKfWg8yBSsa4AoSzlgnxg7gdVL4Jvj6di9svo4Wu3BCcbTtfQCd+/CBRDyNlzervbGIoCb1PMNaUmJbw4WkQYhqqTd5mS0u5jnIdB60RthBq9aNWAMCmCbQZxVOHsHqW3x88Kwvm6z4QJmzzqxX+8bOLv4bivAEkNe5RGsYXsnBAkIORElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDHn0hkcMA3MqaS5GWiI0ZVBEEulg0tR/RxGG55TorTpcLX9S/4cXlznPkV7dNKFj/kE05olu5mP4MU761CqbCw==" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "6643181FCDDBE1379E10CBA90E348B5F923C4436B3C70F5500C53F51E77E5DC3", + "previousBlockHash": "5BBE6A49E58534132BB2CE2145841EBB1262E374F04EBA30A9B128416C8D863C", "noteCommitment": { "type": "Buffer", - "data": "base64:/7R04p9q7QCFkvRZUKXxog+TaHfFcH8JPW+5Ts9LxxY=" + "data": "base64:3skETNmekCWwVxrzH0WBY0ocGKRYGucOVpHc95ooATQ=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:qPRhhAcQmT9gbI4kQcAJNNeeoDB5mYTgzBRnc9sL+l4=" + "data": "base64:8DUVLd6gjf71tTGIu8uOYPce+pYYx9RGbp9NCH3bRcs=" }, "target": "880842937844725196442695540779332307793253899902937591585455087694081134", "randomness": "0", - "timestamp": 1671223343085, + "timestamp": 1676574853446, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 5, "work": "0" @@ -626,25 +632,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAfuxrnt9Di6OP3i2OZu6btlZgvvqp0DsI7sgsq0nUU1qWWoPU2fOP+SXd9RXNiCDeS1XJg/WjEja1uIf5qdkHS+v1nbY5xR5PraHTKR9gWCGEjTzfPRNmzZgrp2n96l9yHYThg5qs/BCY99hHfOXCqc6LqqDmb4dfDO5uuHKDzKgALmc1Wi+SFEDzoyMvE8QaKY5KUGi1GH1Q9LjGsjoR1p4KONo3DuPXNFZOLTOMCrSA++4P20XHTNhpNVZ+KUTxlW9+uHTnzVG1zh+T9sXmnJvRrawK1IR80d/8stjwNzvZq4V2IpcmEpMD8AfwpFeidX65yLo9FDcWFe9SVhMNx6gSHtNdmCHClX9gXCwBNl2WGel/zkSitN2OEy+dZfBuNYxpP54v6pQtudQaO8pm5Ua+ZravzhhLDNP9evRTnJcaTIVrA9hawKv+wcA/EJO+gUlSmA01rFr47IIfFrOu6laAg34RwHOdtl3Opfd00jQyxtslKdIyZ7ztyv7JhWu4aRyjL1QeeXqP0pgJlzjyeyjlZzSmbZcXyF88QjjUlF7AzSVsCfcWXAXBKvS2krMEvdbEQzryTiHicVH+hH6wEi8JHwWM62wh+3TEvDI/cZrvfPwSLU9iGElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwQpHUb4JzG76I8T3zzijaVFj+WLzLYwyuu3xXLhLZL0i+d0NfOJH8weere84N+Ke2rEl0w4u4kC44dPm8o8BEAA==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAS7sn41DG5X8df2yOwBNwonMJ2jf9CUtAvBViD5Wpd1eCuk57YpxbToPtWZmDHFwdcnks8lEoQzJhE1ootZELMXD7NxtMgAkjkHBIS6fL2jKWzZT+/eKrHYRp+BGJ/Ej8pT4G4swup66Yq/M8w+6PegQICo5jTdcn+xDgYiuCWx8Dn099LWlds4EW49uVbzTe5JRqhum1saKJSlLiD7VQyz0NWHCc8UOQM0er7ba4FHSmYf2JZr5p85d8QRBqIXF6VIhWSHPQ5p1abld0Eb3KT+fzEfh3cxuBVstFUy/ZiEvIvsL+IhpJ/vXUR95bNv7fM5QtRqPop6XP767XiQkOgLsnWO/I0Z0O+GM1GIfnkJfqjwXUSRsaShEYUpGy2PcOjjS8jPirldwTenTSnEpJtufRsIXdhqAwc17ntmD79ridpFdPiXh/t85xUPL7kMemdH0rZ+T8rVfRDB9vO4gGrzbOdUWf/zATsJkQwa58nf8/LEeCQkPhE4AdRRmTzCaDtLQezIPDhPFb+ehUkubI6WP2AvNWSCrVVMYU19MeD4PPr8sDPLQX+/hwXqlJeytrFY0K7SxlHJuf3Jmdi6HVcTXmhCq1q1TC6p9U/wqlifgZ/SzW4ucT0klyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw3jO440r5aT9lk+zuiX1IAzkOWE9yiKwkBV5P+KURqDREQGLbErkq7KJP3xCkHKfk3pSIhPrl48qmJiQUnTOrAQ==" } ] }, { "header": { "sequence": 4, - "previousBlockHash": "8D5C7A3C9B6F48D87105835D2F2466A5CB6F50CEB65F43FD17F3126E63C74704", + "previousBlockHash": "B4BA79716A01554EFE80D878E560C6002CEB13619539A287E942FC415BAD1000", "noteCommitment": { "type": "Buffer", - "data": "base64:FXGMBCmQfvKXf9lnSZychmBZQ3+nkdBhoMB0Jtke/Dw=" + "data": "base64:N2YNDVvWqptLLlRcLIvSiflHh1nKmnwmmBNt1LzC2lk=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:sDOnr6sdQ57V8VYMqMMNqJYdIJs7VrBV3w4Bqtuk0Gk=" + "data": "base64:bqKBcQiYkKw6qnfz4NLWgFDm0wZjEV7gY3cHCID8MYI=" }, "target": "878277375889837647326843029495509009809390053592540685978895509768758568", "randomness": "0", - "timestamp": 1671223344265, + "timestamp": 1676574854747, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 6, "work": "0" @@ -652,25 +658,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA2QNhXu2+XJKJ3Bo3rzt+wxMVuYYBlIrFh9PgMp+X25WUKwgVCFwRPbWysSA0gijWsQGgkgtjD+N0Wcnuin7pFYooR3HpcVbn65wRatsr/Ju3HTqap/1Dy2VqMB5+uMl9XuyrqZzEFE2Usr5Cn21O1oNOiSK2TIigxQYy8XfX35MIGNzlh8uk3sD2bbMrL60wiTBtAxWgU+ZFjuzwh8mduboiSTLnkVp5PrMIyWQ9woyDdZ3uTymtxJpcjXppUelE/pL784232FdiL3fP0AQbIQ5Pmp163xjavnXB+wfh3fZwUMO8t+czHSNVYB+9e3hVPzQn2sjtbpaU64u89rCkDyKneYwX7vR6BWG3AQHkK24LaIPHhcgqCswdrvGge35E9XQkDoBH26rF88gAW7a5dHN1CmHdFU7DIQiq26jxvmYOcOwslLPV1rB+Q/1BciFo71cVqlxEAsdv4mzkGqLz/TCP1EyXNKTeA6LmrSybUXWsgj25CGAkA3olfx9gFTYB0RzSieVfwS9KSfcmcELei+db0u7aqU79xGuxED7hP7CAPDAu16pKhrlccgPZ3RRY4jZzCZjLXORyUmNQZQDGWdLvbku6If4B2SpEPmWylv7aUBIwCrwUpUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwLj2cZYeC4ZHyZ7sPoGR6yre8dIgjEKDlW/m+Jq+mKGftO5n3/vu72CkabrCIWx5WPilmm6g+N8O/NGpHe/xDBA==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA08q2DZw739BxnCQ1tvu4vC9MFgaVF/rxD6lEVlXcqlCQYwok8WfMGXYsn7bnvDCYOKOF6T9nu0gdsCe8ev0rfqN7p1z4KrS5/jFEVgNAH92Zx31UihojoywpHJAfPcE/EyDkhm2IAyb73Pil2cLRxKP3NzVgVpD1gUwbCxf5jjsPucKTkmHYFbQgId8dq0vjgxQaEwT0jbXkJr0MJu/yMEoYz1gNw6XcjFgFI7jIPqKF+GWLTKw8YjspgXva35/DPv91iBumtvVODItorxFL9kRZkYfF5q57o8m2ED15fuKNRp9H3MH3vzb9HgqnFcg+GMrMxXQIu7RzUYXr6fPeUTUqOWmU19QLjVPad6cL0xcBf1B+O6pjVwJJ1rwzZ9Fwmc1gwyfbG9aBjJyXlLa8UieEjBtvoTC3la/u8b5wUe+F90btkzlSbaRGnW4CQ6h9irLlZfNG4DidojRUgj7PjDabKZS2qWr59oaLlVusrwrVwPh13zLl8i8hoKBY+Ey/60Gza1oQTidX/dko7YK4sFZa4Hq+cfUSoeTK9I4v0g/nGc2d4Tatv66Zh/moNscfZaWEmY3i7sE9JQ/oj2/uCCz6b6VFxVXKg/j8syKh5Rn+VSxnjDHGwUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwkpwfkJn9RDwd9ZU5jtocmUnw/pe+Fx76sICCqtNRTydJlCDqyscJ592sHsI+FrtKOMj4zIwsWYBYwJygal+YDA==" } ] }, { "header": { "sequence": 5, - "previousBlockHash": "6A60CA923D401040E71A2FBD4969569AD60C551C48D4AEA7EEB7BAA6C5E6EC67", + "previousBlockHash": "525AB8DD63B97DBE991DA7833C827027F470C484BB449352BFEAE0B34DFC080A", "noteCommitment": { "type": "Buffer", - "data": "base64:gGYDCPf0Wjfd5C7lNSm0+/Ofd9SOMbEPZiVfiGI1fWg=" + "data": "base64:rXk7ZKPD/GrmuFZYtjKnnVIiyZBJWdBrDru5o0XguQQ=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:hFGOLAR17x9eg+i/vZwQVHzmPv6sO0ypgIkEKcqXweY=" + "data": "base64:Ge7akGZ+C2XVFLGz53/S8XX1/y7V0sQjwKomgmEgRPQ=" }, "target": "875726715553274711274586950997458160797358911132930209640137826778142618", "randomness": "0", - "timestamp": 1671223345308, + "timestamp": 1676574856089, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 7, "work": "0" @@ -678,25 +684,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAgtNnGvY0h+F5VKDyLYkWUj9ukgosaYaoHoFDJi7i7QqAwB113td74azE+3JSmHE+pba/9bxCSJdlSnLqhaOmy/5p5kl4/7Ue0QISzUQbmvWzjZXD+fchs28BhyZb0aI0r9PB/BjC0bgNGmq4+YBCYJcpf2JJlhNqmcwhobtNTsMKJ1y5EzKrbGKywcVUX77a14Aavg4c4oY6hWiBIgW01dxm2kSoJ4nkIXyLcO/xKaiFzNkeWPEX1lCumViBAl2m8vJjD+pWkHICx0xTQ/BUxpR62m+BGkEW3V2GTwOGlAmkH9plIrtCt5xj7+vpkHMI10Hme0p+wJ2xFz1prO6ZQTUp5u8E3hsYDaVQPRThCSQjLEUSzcYI4h0pWQehtURn1+47vqYVdHR/0lGsJJYdVMZ90vmisDdDsY1IkIB2ehxcULGErT9ynNwFu/0GeTLpvCfrOqEyCUi4qF1Xo5ZljRgLWUVSTuRto8JMg7g80K8iJUHVipClwPBZm3M47agqnb4xALiUmZkCNQy5Ancl8WTDEznzQnS6Tdo2w2P6br4YtbegAlgOYiUGDYFT0CtC/3kPwgmL3YR8/QWG6Ht1OwyLoXeQ6LDJr0vaj2iw5AJMrfpJIi+6bUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwQbqIJjOTtUsMcMWLZs4dAS7yONiQaouZ5LRFpLFNsr3xfa7U0FKh3PwiCTqAHG2wTjYAIKjXs5F2f87Rjd+mCw==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAARNWj8ZnO/8Fq+Mq5Fn8KtQ1/8ObDJWPlMqr0upczI8+IWsI9akauKtXp20GH421PMdfLX2ZaRVKn8z/ekI5wfYJqW42LAU6tUpROXHHzad6vkcydhbSDrVN1TUJGT2cRb+6ZQerfElucV8vQngr7Vkxid5UfoCf/QTgY+NiHddkQ17uYrNGf0MDGvprzUuvBVfNC1XDIggXMo6IrzkXdMCOFJ4IgVReTfZP+zXT8unWq7bzIKDEjgRhW6MCdqxb0cQrqiA68LmkL0zQA745hcW1/a6O1QHkWuCM6E49AlgPbUgqavottL7A1R18GteMF2oCGXTa+qqLoYK2xhx5nt33tKU/P4JGXUaLDK/30dU+ke79UCDjm9Sglwsg74hVu1cWd7tJXe6I55i3R/ZERKuwteebKsK/9bqRANGGWfyagyM5dKWUrmraQ5LPP902w1sEqxQRLl5UT1bONPTwhr8hVxrc45VZAagYIFRv31JQaJfzuZeHsw/O+xyjv/CcIlobD1RbLQRpCyYx0h60PKyLaa7fIEt3mWZdODKeXvUHiMsOBUx+r1xb+skiPP56MKUySberzVr+Vr7J4XLU3tejl0RFuuZuIl5uxJbJvOFxe54Tnz7NAGUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw/zeeU6dAWMM4Y213sZIDslL/xvHwEeO5smJXWsu8EpMI30MxxewktjiYJ9VKZgxtdW7nh1mAvzYNtUizXPpRCQ==" } ] }, { "header": { "sequence": 6, - "previousBlockHash": "56C911579FDA744564EA6C814CAB157134D1E55BDD81EC3A71A8D4E285F02BFE", + "previousBlockHash": "546AAEF1BAF807A6EBCC0F827BDF825C7199E52022BE093A1A55EF4DF6B72BBA", "noteCommitment": { "type": "Buffer", - "data": "base64:oqwsUUnu0myC06cb/Q8RdRVrY1SKhT8Yqp33CBBzlFE=" + "data": "base64:GQIRIxlz3Zghiuxcyta5u3fI8d6sM05zR6vHJODd1Gs=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:L1KVel+HOQWCC6mW9+9aOuI5PbTP9by/CUPhY82Z/HA=" + "data": "base64:QpM93axO5pUAiua9N8y5Bi2T38V38DTyyYYbfKD1QJs=" }, "target": "873190827380823143577845869093025366895436057143163037218399975928398962", "randomness": "0", - "timestamp": 1671223346601, + "timestamp": 1676574856940, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 8, "work": "0" @@ -704,7 +710,7 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAwd+Tag3oYkfuqeL4vb6Vc3XImr1qjzBOdkEEYDBcqBOXGuUPraEvPeXpSA+rexXrPHTy+UaiMcwxgCIEi09eC6n8dquBXSD11Q77SBp1cyOSmMGg2naMi0eNiPVIXVdxn1WR5NHA3TNSQen0qlqPPV6Uzelp5PklQbQ4Ymo4wUYSj63ypIJNQpSRQokGCoeCpANylkqF1nLIXLvTXDK1uvqYYSzveI1Ho62hS8uoUeiLNkQpAbztMxQ4fZEHTeo0kD32XCCRuTU64xgrWIOnU3oj84e4Yqm+QRSJrYTM8uWCDpwvRW6IxlZZVBxg4IWyCpAGVne90XLlAnrKl7qpUW5BpWFVSaKCy+PuKHeXISvNrhugZEEMwWhA9UJKROlKNarQO2TK61yczEDpAploQZt+Iol1qbXA38TD8A/VKkuHAd3flLzVELo0+gj/8T2yV6f+nEEjotclUCZUa89cfTRd+SxBNxuIo/MRw6bHq4UdORwh4aE7UkC3sNN90SPSD1VWCNloWFQst3XOijCbAIszQW+M4knX49xiShkuj6Y9TQ/UJ2YwfpWemmRuCgefVMsd26X4+3ZFcgyBIdGPhNgQQOfFWkprJYusIAhRg+WMC9K4A84e6Ulyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwyI4n0lX+cBc4rqMzHg/MNm7lHjCJokOuLrnm6MLMF2TP8dIy+PYeG0fALUEuVaHVqLPnAQ8aZnUf4ltVHjM/CQ==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAApY23jPdVfEzzBw22trianpnOkoLxPKcuzQ+vxWyOzGmqDAGzYLZp4aRCNALZ/fTNeCECo8H1w5jvuIG+cDLX+SHMofqDuaecOKS6y55mf5mtHYoxIN4EnhmquOzPxBPm6b/oPSYlS8+H8FEQVLgZIrlVlTyVYO+YGCAHsuq2U34MsJDG7J9d/AElanBdWHC7uixb3E1NuG53RSecezgbWglJ9H3wV0TLzL3DoUFSOw6U2a9hDA6iy116aP1ZXvdyM/BMyohfbyEsrJG4Th+RJdDeNPHF6qFBNzvz/NxeYk/uA3uSEoi7rT5fvGrrPXSDOq3gQ3jq0M2683LXY9U6Uz42lnTXGGmSWC198viUfu49aqKWziXTyZyCD1mQF2QYExOh646377HNBxpOp4kuT+W2rkIP5iP9nWj2tGMeWsb4ezWtTJlei9YX9QnUsKACHHv3NMWaBPAmELl2NY6CCduqRU9RtvaehYwmMtiJR92FIEvOZ7BeE8Lsjr4ieeAPVltipDL5wfv9trr2rrM+nQv/nnTEDWiWRU33aMKaqIU1iRSEXckLki1TpZZ2jEGt330bwnQ811+hdddPS1XS9FS40l+DSGpcqYjWzOV24NrN92TJZbWK4Elyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwlhqiIlHsoLYFk9lXQirO0RGLTzbkRBwXDOX/GXOuok8iCwVw86oy08zlB0hUlElJ+7i21s2h+qonAPtW23/7CA==" } ] }, @@ -714,15 +720,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:I9zyM4MZMDltJDD0iANGsomvn4AAMF19wQG2+2YfO0I=" + "data": "base64:aVCxiCWGPwGtWDl2GIgwicIQHvIJzkJ7WLWoGelhlGQ=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:HpY2GYGmD88dO7rmgKMqbDk80MqR0C1fQ/fv8yvLBTE=" + "data": "base64:A24bT1nkLbyAD+f4itkBTJT26BxnTIeeCzX9vOC4GCI=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223348043, + "timestamp": 1676575125858, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -730,25 +736,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAiqCEmF4F5iJusJPz9VitX0TjPlsLpXv8kZY/ETNXiruTKR+y5i473rby4rNaWKA1IzpxbjtWxfhlSIxu23F6NktVYbDIsRJcluinWHjT8qmDTluDwhjaEqou49msy0EIYMg5EZ6PPSJwofDEXudckDp5kB47ne45ps3luDbcxAgCCiAr4YI4hbPk2nnbzwjEB0qBKJj01hlbJ9Ihi9bwgQev2np3dt4QjU2JEUv13UOR2KluVoVGWUnTjzKIxT6yvs6XTOV3KVD5vO8qo9TKIs2E1fQU4UkOybR9uyTD85Lo/yfrQOTcan5Q3DHeFF4L/NjJcwMBYvQjpTumJKjGWRBOSBVxffmbpAg8+tBjNDoVDhvWFk3w1SVRuKWOeFcHZgunMqt7z3JNkQLb0TQPEtNvVsXTCbLXjo6oNZXSVB2xVF4aXba7hpTxJZmrb28W1TGBITh0ErpauDbO0Sf2kqlfP5mdnQrZlycknEPRpO4Pxey6i9FcLsELqJDa3dHBgrseaDe/kki+XOzrlLBCKhPOg7fy4MW7daRR4j5Rd+Q3Wl+/NADCy5g801JcpEs4Y92+xHh3kzwhAxn+aNDCmbiOm28FXPOUEEZ0S+Epx8yZJm+0tqLTAklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwUJk4Lg74oHUGO+e8eHoykjAir5QXqsSK2xOXMsj8bKkRsmUzeUiaYLm5iREOBxAl0bY8MvE8tA36Xk1sapabAA==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAO8D5PQBYtjjXQe/VHK6F5yiICANBE7ukReCnZfNda4y4Sycc6l3YlbKQXE7oyaw7ZoFNGgr6mbBs+LDfTR9nVQuStWJKes6cA1RJVfdjK6eIzl3bDRasGaassbmfa+8JM9xSeiBrPXW2n43RsqDRNd8PiByPAUEg6GvZL9Z7Lc0EdeUgilgmL0rZESGJ+oqX1wd2JjaiZZYaXPbucoLJbiKgZLNCxb4Zzyaw2cKMbhy33hw/RoNtVNI0SwBe4c2kC7m0Z8h4n9bBqRoVWpikexgXf5BG+7CSAcoZJA8Bo+f4Bf47dDMPHWaSILWXFfCT5KbBZFAfUWnijD//FuHotLL2TmJKtV3lSe7k7w1XTcaUL8D15U/HhxeG+tduVPsYyYdW+P9RzPizhdc+6pgmbXknNGhbvQERqF27RqxT+QCIpJ2OXFKOjEJ9T42Na20F30UAWlKHNI/Tjc6nCe3oz0yDvJjstvV5Nn48dufg1Lb6PlMmV0w7ImBynyNvLbZGuE/pEyAxbdBsUVw2kNaDn8MlcGlMQtwR7XRduBJAAQFMqYY5jfbJ47ZSTsBo19zjdskSwX8uKut2BFY3P+9NsSziZMYANIzZJ+upUJT2rngzdShgAOa2Uklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwzsagZqDlmN3UnkqtoJ+yMPA67wg7a6tCS7ZaZe8HtmIXCb9ZFdkoyhsWtyUl5QTt6xDRVEd4L6ATrYErZZ/yBg==" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "4B4A3D838B53D85CD23088BA66092AD33CA1B011675569769039BD16D46F9405", + "previousBlockHash": "F01933807BDB1D095E97C984D4C940BCAA281A8CE573D604852D6D88CA7D70B4", "noteCommitment": { "type": "Buffer", - "data": "base64:mvA4cf034mHqI5bOlhPlC4ThZc2WQYRtcxMyWWShVGs=" + "data": "base64:UhrGhK5D4k44vWCsFJ1LS4h71Pl7NWb1aWB92jBeyAk=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:pN98ywsCUfKfTxj2ZurA5JnXQz0snVe0wVEBMU1Kt4M=" + "data": "base64:ClB8r0iPQW/cHEjE04xRQSCjDLkf0TME8HPSdn3IW8I=" }, "target": "880842937844725196442695540779332307793253899902937591585455087694081134", "randomness": "0", - "timestamp": 1671223349256, + "timestamp": 1676575126338, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 5, "work": "0" @@ -756,25 +762,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAyC/biXiS5+LgEhF1hdyINOQeLCfDaT4TZaLD+FgZ/WipBfX8ERtsHDNgb6FVL70T1+8kGTnkyMjzdt4qdtwbgtxNZbyefplKYoufzYeD+vSKHzkNlQLDOy6tzGCUPJ8Mp+KfHxRl+nNs/fqV7Hdigu6gALNzUeoIBaujfwGJNIEBFS/pnFHFlSR9fW74FaC15BHlLdOdSFwiiZH04uNGNI4i7Ac1asMCC93xEUJHxXOZuSNjDMr173N50MC9OfDSGZn13ziYWc/pP7ze4LvyeiVHCaVaKPPXOluB866UUdbu5Q+NqqiwZr6xiAR9izcxwLZgUXNiydx4CuQsAbJlIq/2O5hq/hCHUTCbr+F7t0sQGDZWjFQRJYsfja/5w3s6qMqhbJfoNb1WLVpobT3hZ9l2FhlefqKETp1ojjzSy9/ADRQ0zVkuEF2R2c1Jr2rFl9mdZfZGZSzFZ7d0vk4FNXK7Eju1v/4Ky4WY5c2tetuk9Djof9KQiZBKKrlmpNeQay4RiRFwagkbimN4vn5qSlIwQmw4kPCe9aF8qRuYjanWmfBQdKSn8G4/j8K81z4gzPavP0ijzYhp9rDtGRPewjsqlDvvVTOyequTFogdp2DdpYYGEuh9x0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwXh7ieIY/8HMucguHiG6WhOxZsZkVbMJAaY8DHZKpGZ32wKz9qbfMLx8YiKeenC9FDjl1WM4u0M9Do1Vmvmi4Aw==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAsozbKkVsVPdQY9VkYP7tkwZL32bEiZnWz6sCSgrKPReqjMnOKWz12FMMUhzbtKArh29LBF6fmpDBMQFf+J8OhA7TiZnDNU1oMbtG7xX9GJmikEePOWg0WRLFNiIO5UUUuGTLIougT/P0RdWLWbVNpWDF+TxhmPt/X4VvgsGh0CoWf2QUU5ZbnRf4dhyWTVHNvzcyAOfKh6p9Ca0TyNUhKa7yb33QiqFv0ra9dF4pO1yV6YMKidxC05kpqLDfX+aO2dEnK0QHEausgicxOR7hwrQ3fb2ZgYRgoUREfqw7Mk68OJz2XhlWiStnwfevPT2wJu2UzuW/OustZ/BsNZ7YpuFYVdk+E4x4oMAelQ1MYPiCtc31bvjC3eCQuhkaCCMDjljXwYK/rt7p/8shqt/RgX+ApyKVt9xzVmr5T4t35qZ+uZ432oJr9MYNP546Z7TcVizgYgZtvrjLSdtr3UnUCyxA1Qjh+ziu6niaKcV0kGfMeC9oPYDz6iCSSVw4ilKU3Fe7uhBbxVDJzb4WwtjNit7HyZHp0BEXGu8+ljyF8vK7SB4tcM3oMkELv+TUsXPJ+GEZVWlpDcY0HCGRYw4P9E9vxgrqZPEtypaKrg+Vd8VtdkYKU5o4Dklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwadpUGkdSEFuZ90/LGXI3O3JwcSI+Wt6qnIGItSSF2UzQrZk1jIhifcTTJaNDUKBnrVOMfCUrwPV2hLIO1519BQ==" } ] }, { "header": { "sequence": 4, - "previousBlockHash": "B1BC85813EF1820B85225E98A1A888672395B7A1A01F0E1F83B593D6122E6B6F", + "previousBlockHash": "8C8CE498EB9F2DE638351DDBF9FC9AC389DB2DDCC82A4ECDB22462F4565CBDBD", "noteCommitment": { "type": "Buffer", - "data": "base64:6y8Y5ktU1tIcYesQ38rttiK24yrWDKtQOzwV41EAMgs=" + "data": "base64:fBkapNhe9QbySn0r5UFHkwQysQQOQfTD+sbr4IhhAyI=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:qwyyruX8ni9m9jGtyKUPdFjZ6O4m6qTXG3hX7X63VTw=" + "data": "base64:9XaSee8XjrlmwN3aIa0mVdStmjERXx8cz649He+ZxD8=" }, "target": "878277375889837647326843029495509009809390053592540685978895509768758568", "randomness": "0", - "timestamp": 1671223350420, + "timestamp": 1676575126732, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 6, "work": "0" @@ -782,25 +788,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAKt/NXsObwYGMy26ydrym+ww3wqxUcis2B8Y1xXZNBSyktljYJ1PJdtG8RWuH+ffkcMOkSykEJStUlf5fpxuCxxu+q3snk+eQ4i+zE6jhzu2ozjNiluHL/DXWexe3nQ04FW5MueNAF79iCqFmjnvA24HHZNjkKNL5aKU0rZzqTrUX6v+1FniAAJOI5LsAxayyaDPyVBmeVa7GX5bNYj563+loylDH6d/VC+sEI2zoHT6CdcMyNgguAPPwSzWXOIVamJkc+yzsDPcdX+JdLtryIOEttXLtEYU2W3kCtDiy43JzRYA+GBIJcghiy4Y4Yp71in4lusjEr2FNsJTaSahqNjk9FVpH03mk+DbFMdM6F4HjYB6PUSGbRgtwEnJ2TeVfIY7elOfsCT6IPJyKZpord/Zhk44oBF52wIClBHMGpav5IPfK7UnVO07wpdNqZECXYmBV8jNViCkYvonA1m/qfDRJyZY78j/j6jk6Vqi4zvHWHDTJA9JxneEDTmSxbkyrDhPICEHMA/ml/Jaki0icCH07nPZedbsP+PPI9HA9uPGh1cX6enxGBjFh4Nz4CPoDAr9Jj3cI1JfSXRDWhi9Vz8gbz/AvMbSayvwhjevCimPyWwV6pAwpnUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwIyqpfGLhXaInOY1n7E84zgB6vsVUM3lAs44eVp2jqBRCu/rlNeYF7cpCOqr5a3jxOEMz2+py7JAEmhNYpCpFAw==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA7B05pRyPJqOYm+0b3qj1ZM5+vY8iLTYBcJNiX9nFYSKi7GRumh+PfiHqRVKdODlTOYx9ZPvumo6rO7TaK2ieKZRUE0UWqBdwotYFh9SgixW3PsreR5rTrpa1coK7pg+k4j/Y3HooGpShUWluhu++Ly9DMVaOPtxt4bVU+Z1ULoIHGUEYWlP5fSiyFSYbnIDhgRfyPsOfRz0HKgx9yAzhqGZXrHY17dewR+BgHC8ngdyJgfrHqLquio4fHuH1P4s07pt0Rx7sr7jUd5ikzULTGAFoNeRzyOvDgkensnO/7c5yTGh77zsMbbaEysZUUPZkRaDeRYK8IiJL69qhB9cw3kHLoR0k2hjYUUQiihd7eGHev4YZjQ+mAjGzQ1SQ2tdcAsJzMtUBF1ngD+SIGQgUFNxARvEhPCxlCQ+sJsiKUIgbgcQ9exVNh8ABUxu0n4Nn4E0VUiwdYUEt0s0yD6fddsndHCSjfBJBqgVqg6A72cwE9j8YV+ozAPeb8VgQj49zyt4Whilz4mi1pvwMB8DqoVtr5PJJDrHyTsNJkF0EDA/0IVvIP7SFauHqnnuc6X/QcEtFxqd7Wzvpncz6oAwS4vFGLSdWpoNr0J/QGeTlh9ZBOsHcQVCoFklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwXEYOvrfeU7ewnaoGUG477CflYlaXjXm/U213HoHDyzXdXBw2K90BprybmCWMTclu0S1BHm1RJa2XPd5ASU+IAw==" } ] }, { "header": { "sequence": 5, - "previousBlockHash": "6741388A1087C67A3E0F3929F1B414A6799DB6B972368358C543726901263080", + "previousBlockHash": "0CCA9C219EDC37C26F6B0BB19E5AE1B9B3769CEE7C864D812AAEFA8E0CDC5D46", "noteCommitment": { "type": "Buffer", - "data": "base64:CRD1iYeGGIoR4e1CNvYdkHJyIR7LS8Q0rJAEMX9Vy1I=" + "data": "base64:UNArwHkB9vohr0ATIXUDxb4KRX67Kb+RbByS+qBMMQQ=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:jy3C21rXLQLJOb3eCxKR2ajUp3JdFZm467hSD44G4+o=" + "data": "base64:b4XfPMnijAjEUqtD8EJ1dgcLp2Dp8DqVNPYYagYugps=" }, "target": "875726715553274711274586950997458160797358911132930209640137826778142618", "randomness": "0", - "timestamp": 1671223351705, + "timestamp": 1676575127464, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 7, "work": "0" @@ -808,25 +814,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAfM9vZ0fxSr8yhgJLuTqu9YJKHlnZfw6bm/P0l/oWofCNP2c8H7u8in0h4jRv/HZharMV+zsoRC45r5mso3woTOUYKsEPcplN5My0TPENuL6YeiXdCZHD3jFMUngsEhmaqMHtcCNMuy3PMmZFvMnLOrW7fjRVH4OiVz54yijHHgsG1yiCs675Ay4aKYet8/mLt/yDqZ9O7Wjr8SA6RR3CgW8+mndufgpcnGhKb2AeSXCkkf9E0H/DXQUi7FpeM903mc+YnzR12+UEQMwA90dBKaW2hCuTdi3BpKq96krk2ioU/6HAw0dEE48phyOMoxqmsa/B8xV6QanSVSaGPaB0yWYtJRwL/pxg/j3zuDgZO96uH5vVLo4za6n1U/q3Wu1UtmfWTKFq+BROBxtgggVC0uHC6XOIorRVWdNEX8y6aNFOSG6NlAZnkaCRBJ4W391vv0akbCQj4EiRM3RZ+Fci2bN5g1yQuoDmwSxZHTelceUHkgwD3QnzqSVvEnnYRjuTYtH5Mfm2B8nfvenB+K+FG9JbQUdburdaha2pc+u5QFNkK+rtReRfeSi7femQWYP/u8hKe9Ort3KbYv6rX2wPdEnv1ua/zhL2A6USDy+X94/RZtZ1AdxVKElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw4zciONUTVHh+0WH/0fO1yOrZFlvSjVNLxLtJ8xqP195HjxS/RquIJ0HXjnk5dISEI95TqCNh/JJ9e5Nzu8MnDQ==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAazYKg5nCQuAZNKDVZ2t4/7mwQK6sO9yO+glhAzsnVM+QarBZDlffemek5/TIWWEkLlfgUuJiSyqEjS3B4VsPgpPCjw7Yb3yE/3fDchWeftuR3MnDGBF3n2svr48ENL471UqIxGksoZPnF+vh2hRAraLV2ROR4rW1Gg/53S2lGBgDq9+PKHMmqwaB9OUXWE9/g3lXq2IZY97Ss7b9YM4j3Uo4PSjVKAeggJeAMbvJ/4qtd98U3LEAkcjSCxG03LSCDmEtnhlPS1Q7ZQN4GKFVdvvtliSQP4C2IcLf4ihZtL9wBNIudHUNDcvrUUjl7DxFKqqHoxsJ7k1NkEAW6dkWGOIx0X9SOeO4bXL9cZVacW0n4ls2dvaAnVrzF+e2AaEIBI3AzhdI1BKShyLNrOs02eWKcp5q1d542ZX/se3FYFtaah2Pdf3KLO2W2lANAepjvCdxRPWpNgvdaWKC/2WM7HFovB+NOD7NPvql00LKZPAcDg4K9HaTrFzdU+D0LlHsC4D6jYJnFYensJvLwY4R3+UHu+eyEDTTtuv2HTy0ngZdEEd8ADeMCzBM6NJBhzxiTubuLywqJQJnC4STEsFDEIgf/gNP0Xvo8pIsxfagZ1ZzxUfncBFCH0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwCVtRqcvExVBAP1hfFOV7n4Pfk4biUArtrsCs57wba8/dtaLHrJ9IDVhK5Qe/zpgnOw7Gv9oKOMMzmQkIgoM0DQ==" } ] }, { "header": { "sequence": 6, - "previousBlockHash": "B4DD83FE36AFBF2B059BB78D834C72BD098255F0A9CCDE8FA2909FE025A688BC", + "previousBlockHash": "1B0581FA7416E159D57215F87A315EE0520C9A04C25CCD350372C4FDAD2BAF33", "noteCommitment": { "type": "Buffer", - "data": "base64:bscAlHxGBoYatja1NSxRYkaMtN++A5n0bUvQtXiyFQg=" + "data": "base64:f9K9H5pYh4Dj/8e1gXwicUp6ujnADtEZxAt1K1SAqS8=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:cJbCf9BvrhLofvc2s3rUb2yxAa3O0wZLSEJwOyX7bcY=" + "data": "base64:zp8lnCKwp2RsJ9cKDro2F5/WCZwJivcaZT13MmEJOvs=" }, "target": "873190827380823143577845869093025366895436057143163037218399975928398962", "randomness": "0", - "timestamp": 1671223352858, + "timestamp": 1676575127878, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 8, "work": "0" @@ -834,7 +840,7 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAwdqI6QQUIFPLZmO3FFUnf4oDUFsgQ4xldjk2+OXqhIeNcV/CSda8Re5MGsjRJLt78K8iQ2oiS9yy5Y3QFr2uEbpNZk9ihQJ19vAYUsndo1iRPFPV9b/fagndh1CU/IBUjnI6Z3EzHWdYVViVzb7NZT8aG0ehNhLmCy98LNz6NOYTwquaD8bX7XvArcMX81M9vrS3j9BbVFQ8R/J4xb0OdumxqzV0q7xVvYwagb0XBLuWrfcYgWQriidjgixvnPCneRgmoO6QgTqxDdPL/Z51tbMeRBJEnUc9j5i4Dyyrt03C7kMx6S36/Pr0Z/FfOpuYaXC3Wi5R/j//rq+wjy25S4wkv+x26NYC1Qcm2d0Y/xvII1ubkfgwTD9XD92IpN5Fpl244GppSBk8Asdhg44WLOxN13kfuznqm1ffcQbcQYQ3VOMaYTh+QbtgkKrBAxkwRIIg7Dz6ZOnTfM74A3nmr92m1MNpdpYrgzeT6jAyD+G9hVro5dU8An7/cAKJ7LfEtgB1Wsl2GZM0KpyH5OSqtF/JStoT1NKwuq0Mo875q9cQOcEpwzxv/BCdybhaBNK9+abtFL/yP5q5pi5VwuHW2TA3AxKcTAerTo+/PANnQk2ZkKo/PchaVUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwBg+5zD3zs88MyZiicI1Cj1V7j2P7wYR5Od28QNRIy9s6eJT5qvSPjkBmRLZelvQf3xv9zumvpL/kbulKOefEBA==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAQdZ/5ZSuh5jcRA2V6qHtu5n+hG4AAswWvIy5F4KNLhmj9NlbVN1C3W0yle8omufvpCVT/luvJBokuajcqilH0sCYxez26hPxJ8hCjIEKDYmMIUWEJDXRIuUzGKAEFv8IYoccxeMyHh6L3/KcdKB6Yb31ZWyD//+lQr372fOfvqcHttz6JkOEUM0FR/chH/790LDaw44G6qtw6Jt2sGTzqq337Ug0X0uZEyLxXmzVUv6pMf97jrv4z4hT28MPRa+ikW2G40EA7rUnzn35Kue+NjMmpO/61wj3+JrxmrvrLA4fNX9Lf/8NbAIMuW4jy+evfrigkVa4tZiinKw6a0lOsZHaTkpLFEFyRZAZtt5qrC6c+wOWvQ18XLCAd3GKW14PFD5zVAAiRV9fMXPbkYaga0r/XiiQjpSTpXC6zg6pepcr0xHu9nY+CCWIdBq9mQFWZsK8dTmR1iizaLfwTRvmLv1LHwrsvFiydCUO8QcIdEotw0qnn9ZFj6FDrDDJMgYXvH5P/KQSdPJNU+ch7JJ2lnVTiPTd6WMCkuCzb4k6imIZuPC6qmDSpkLpnBXIF42dcFnJ4kOer2Rpjab6yho9BiOwp3WM+9NWaTqG9ji0GONkZoDGdz094klyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwJ46ai/jeqTr3svSmEyL0n0tnE6xjlnFuFm7/j9IXK8Anp96UMSE50qulx6aXy0E6hWMCpMTlA91pVvQLBiWcAQ==" } ] } @@ -846,15 +852,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:3R557hkxO/JaCKw469ZDrx/3lzCxVc+K2wLs9adUgjU=" + "data": "base64:hgA/1koTr77v4kLeM6y2RVdAc38oF3cmvXoAqXq430s=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:9U0SUBhGRv2xDM9e5xMSNuEJ7F6p6sc9cGXFIhtKT6I=" + "data": "base64:ZyG+ITIREugldGs5ZkHE4gEqVR7yqKPvfDW0hvf82X8=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223354251, + "timestamp": 1676574859423, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -862,25 +868,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAtXowzDueE1H2lcgI8Y2NCEqDRy1wXPwwXsREzcEeHh+Sfdn0qrVxW8uhIy+5vXzVeFSz283ANT4Xz6zXygqQ+KTTa9n8fwWKKww3KPONiL63NZk3DzydShqv34KfumXMeY4Eq3UjLFPO3/TAmpPto1j4R9OiwE5mV5QfmTVh/jADn/OrJuv8IWoDMF1VYR+6JnAiZtmVKTS6+8+MmOtB/xgAz6XfII32NuDX9EBlleGX9o+JMRWNhMi6+NLlruxvWkKcRgaKxzw1pdrfO5MiupLCQRc3ItXdB2dFMp5LLKzC8epXbItOz6CQBjnjYFtMOp2KUh9cQapGJlnf6athtsfsS2ylBJnXKVtZjTED2Eu0OeeyN3vlD1yskpZUe31sJBHPLNqkjbqQ3Jtb+f1548BMQxaMWYLakW9jDsflLFoUdAYp0dC3exLzn32FvgJpALkv7QXpChgw5sWr72Y9QNUcBjKWc6iIb32LOnp/gsZiXYyjyugkdfN0iC1GJ180FcMPUMXOazf35qWAxTsY1Qc63PQWfmDrox2T9jWlXY8IikW83hdJmktKCO2FtsVgZCtE6rkwrSS/Mz4YX5tsLiAi6qYt0I00qaPvlvAVRkTJC3WQE7vm6Elyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDZPmaZ9obDD+qkmvuKZEcexo0ddPqOD9BmnVGJfcvFEU48l1xRhEu9Z7c1Wqsqem1E5oGOzyWUkG4AXhiaNPBA==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA2LPAvznXa0UAY9BfS50pShb3hyKv8woo5vWRPHzof1qNkhm2iIPsjTmWYFPSPcx6G5x2nSuqzcONGR1Y86HK99WEr6bytG6EyeC2tSicH8OMGbM7vawiMWNeJDPeWgRk1nTLlGeJPaUigFGGZE658Qr3XzH3garcXtfpab9AeqwPnmz1KiWwpr9XXyOfWmzfKYUQzh/7I627xlWR14jBHfvVOScDpyuj2ORSfK5nH3OCQRmWP9Ou6f0Ctrcu/JuFIuWJHwT9tIhjM1myQAY8rAfuld/Dgonip/c06fdYsSZylbzeP2kI5+xUYaNQTez7J95y1Y8jYId22oeWphzhHbZY4VRkY97yPwkB8PClbef1Ed/bodbSsFthh6wuUFtbWjj7LAcQogF1na5Wc9X16J7Gx+xUgkDU62icBI6A97I5ig3v0HvbyZtla+ptiZyH8zMpYDq1zXPZKxiGdrAJAFMM0WuZ5odB0pADNhFSvcX6rXhfbfTTP/ei+rIkS91gyYUTlBLTT/wnCEYne3GWjQRVIIsMMUDftJvLUv0ru7DxZ77EkRHI6GJdPciOFQ9qJjXGTxGgLdEy9vAGEefiYh8HWuLobIwpPwsttJAIpTmpSUk1dXUH0klyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwJlf/1PpZnqN27EItP6vRhn5XKwYYC6w3M2ByKb4WNOVHD5YgVN8OLJf2tgSouHjSw8aeFxeAREhz1DURXF6GBA==" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "C58DFADA33FB29908FBE4F6524108EC291EC0218399438F027C3CD5CF95A06D0", + "previousBlockHash": "D1846A0587F413C31E0223631B7EE6E59D557061920B42F01EDE63D3F4DFB924", "noteCommitment": { "type": "Buffer", - "data": "base64:xz2QnrLT5r5sR6/YUQZsu9k3zJA9Qeq1buEed+1OgGU=" + "data": "base64:h+mG9IxuLT52fuxnLIFwQftKdrDkz2ZFs+sUu+G4REI=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:KjdSrRhRZLxm+McHjQL+oRX2ZnPY2KeMCEe+P/QLijY=" + "data": "base64:1ViyHBBRou9osMKBzALN9ZuZc19u08uA9ETiU8jwQio=" }, "target": "880842937844725196442695540779332307793253899902937591585455087694081134", "randomness": "0", - "timestamp": 1671223355598, + "timestamp": 1676574860399, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 5, "work": "0" @@ -888,25 +894,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAw2Ak81vQ3OMQg77uHUMqDioc8gHhwSCHg6hq0hPSgmqzP8fyq0Ybqx04sSHEEi0/322PpAcKaJ1CKd+6+jii16nhN5SsfnWZmqUydSWWpjy2WRZXrl+CXMS0woaWs6yQkcLtGueFZQe2li/OWmUiyzcw7aBHs6lO5E/0Ld2Q57AI1+55OpGjf8gPgeGS33oy//4ejKrAVTDAhnjWSSKFmLa5jSdwvtkPoOHrkqg7F2yYrmL6URjA5ixYSeUxtaeunrznZv9KhAW0uQjZao1aq8g+JHNZ1VSdVXeeRPAprhWTY0BT7yp/Wj2dBqkFSrgWgMY53hipoKSXcCYLIqtn6ElQL/R77EEZoKp2jbRsXhzyXQ3i34mIhE07BdWro30VTzmyKAW8HRRjOgSJC7mhj9uvWK6vQbbOZ7Vx594b0xxobmUmORaSS0IJLx22TXf10ZQrV6OeWCJjBkxnIfsewGUgXLBxJfAkEdyhY74rqZGesKGpIJQ+YmVaIqBtzCy2ikIxKxGeDycvkM5rywLckqC+wXCLEpwE+zoV4AmORf7xb+YOn5Y431dI7G488fJG5On3eJMObFViH9L3ydBV6zrAHumLAqjnoWVI8BruETmge5eRIcT3Tklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwRvClvww7pGYJD+fCwNlLdkWox81vClWChh+ZvrXBchC3XjS7o0PWticNPXu/ged2LQ8z8kZl7xV76LGFtox7Aw==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAHk6yWScg+QjQDCv9luVAsQ/+IYunwgMjWfAS36bT3+upQrjwB9ADTAnoQueHr/Od0oQdv2yGa75K/FIRnvvE9mmO+NdvwJ5GaWT5bU9H1mWDr/qnelA++MTwIHxBxlaaNSuRvbPPbBtWd6TpmIA0tE0T+/sYW+CjPCZPjSr2Gc4Fsam1Gmdbq07RpdnP5stdv4groBy6LcSlcxD43mxOP3xQb/o+cfSUqlFJQwdL7U+Fvae1415esnt7UQUgJlSE3Q4VDWuSjw8TJG8U7GuwhbvTV6sUkAU/OgVSvMMd/8qFYvjFdsC2FJLMeMXL3SI6rVHLtn+r/JyoXxfAT5gtwmqedN1JuaBYQz9xONasuOF4cTLok5jfbp3iiFjH8LktwNh11ufQevIyeBw7qtfcDnDDapzMzGYY0GszThFhlx96xe+/eZ3bHAvqsiQy4NNqVIURn5D5JbMykGCxFcwnaA5+vY+rWGiHqSEXO/oRCtkq2FwqX4LaQWeGccvF6w/Zto3eweBtZ+3w0Ctouyii5RtbyUd2oET1yzbO361sdkSZagRjYpp2C434C8udzOkMtBRhYrJeulx9oqShR4T2UR0t1f8H3xx6JqfkNsmmg1VrH+VY8oGOuUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwk5o2yXyWyHHmGJg/ch7ob01ThSnUI/nm5lM4MbqGA+FhO+o1aZQU50scRlyePSXGJxP0SjGisW0Zr7ZwXXZfCQ==" } ] }, { "header": { "sequence": 4, - "previousBlockHash": "529ED93F5B93C687AAD0077C4481DCD6F1760CCAE5E314AAF0DC6217036387BF", + "previousBlockHash": "1C9FDDF7306DD1F2FE43F30527861E0443B941BAAC52E7AAE8465D7B7E32F62B", "noteCommitment": { "type": "Buffer", - "data": "base64:9EA1cQ1tyov/iQOH1+VWKLE0z0izo14GKc5jNb91vVY=" + "data": "base64:n4ZHPCDwgUQBvQ/QkWM0Xfy8R45ZJoTX41E9s1o7GWs=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:Ejqh84+szo8UhTxX4TKi+kUmOXTWNAHuw+4uj1mbfUw=" + "data": "base64:xB7n7x+ukMQ36EF/yqDDVRBZ7lJlIU7XGSlmhM95H+4=" }, "target": "878277375889837647326843029495509009809390053592540685978895509768758568", "randomness": "0", - "timestamp": 1671223356741, + "timestamp": 1676574861702, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 6, "work": "0" @@ -914,25 +920,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAArFSeHjwcZTyh5U4r4Qn9XzCbvLlwc4OeUrFIC25Da+3aG4LSAbWUDwuwdu1eD2gVQI8mOnB6awLlefQ8WJf7DWqaBInhUIHhK6VVg1wyuWWHrznN627NAkIkYw3WR6mfKPSibEJAF72W6L6hkRm/tn9Of1I8bWvYta70ZYTeKUD6kT4nQQ5CGBA4ycBYw+BimtJM2zlnpzWORpVtuozhNKTfiD+9wvQpL9qX7OpuQmQ4tQNEjQO784zG2Us8VIuLsXTGH1TQ1gGGYdGgBf+SKpW3uGEBD8/G+Yc4yvh2HVVxaZjmsd0v8lYUJCqNVNWwllGHo6XjjlFBFnfMTm2IlcH0Oj4Hl5wvnlG1ZTZqMfjAGt0No5luts95zIjGWk9Gq6wIO3/iVSUad+wuPkOlhKPvlI+l46zXZivnfQzGXLcMXMdCag49qYZKEIOYT9DDn8cwZ7+LpVBHL10LP+gyga4e2KdaX61LjJRIPAMZsuj+bTkHOUY9O49RXuYtlNjpErQV44VQQmulgKjc7OuW+OJWufKrOdxqMX+m63H9XMPET/eet6+GYAa0lOYq/mIF45bl3go+JX1LFwyg8JC9odXViTMK5tod/tBXnFaIqkvnBC0gbOzrElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwfR+/w3sPPqvxIfkeIEYfyYtfucgbYOszMfPqzbgc1T1JJqHkbZD0cTlnZ6lRO8jb6Pb7ud0yEEj4Wtwcr+81Cw==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAArA27L2a8CAQ0aCQc3LZ3uU78HdvuyrKqUEmyyVqrG6mvOeKG6kOViV4/mAVyU7Bff2L3jnyvpNhPbnSEg8YWGnUWN5kFfm92KaeChMfSKiaTEg1kgmsuTaH/p5TKe6IxZJwudr5U1aVN3eoE7WZ4WE8WfUnoeaefPGNIPA4G21sGwpXQZmDcnTYR96MsTcQuK0KyaMla1z6i6KbGmBcUK8lRwO66KGAs5Yv+jLUYY9mnnscVMgsiFd18VcqECqzNFKcX99MJTTDxu/hLN/PH6w8lqDaprkaUVwBibMoXfV1JFKUka7jqvHVNl6fZYoNu3USBy35JikxxCZTg5Ifdmiyhs56gaehUlt9zzzrM0DDSwwLCOGKlT0hQA2nYKnZFcdxWZNt/zwLiOkK5ALAgRHkDprR3g8l2lflAPhxZhRXC9PJkBth2KKu+I8YZOUDc/e1H3ISzsTZy8suMfICK/BEba2V7aip2+Wd0aFmRVD4G+IINtDHbsuVDriPeIEMux2FQPa+7UGs2rgZeC4eh4IJ39NTcnZ+5dZHpJAsZO4eDVmYnGEZEVs5VJ5MrOU6SxW1zm5iyce1MZhO91udbSU9nLZM+nwxSuFwCGsdyPATJD03fA9qdfElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwcgLBwxhOVNfU0fTSFiGredzYOm1Myiu+Geqap+a1OEvI94wOeFMijzuDzawoPj4kXYbA2AN4HqUefOKbu08NAQ==" } ] }, { "header": { "sequence": 5, - "previousBlockHash": "FE1544B7C65011EB65E0A894BE4A2E1FF21B0CEE26A6F6B062EC26ECAF201AB9", + "previousBlockHash": "EC6EC3D18C6F3A2C1A6921EC4184594FC0F71EDF59993287C496DD67DF8FBE94", "noteCommitment": { "type": "Buffer", - "data": "base64:CSubkLKTxg3lLtnEoqd4SO/HHXNNLdkI9/wjz7A4KSA=" + "data": "base64:EKp1nR46+/rExOA/KcEIbMvHZRAfPF6WolNZ5zS6qVg=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:j2NaMHMka19x1iFlezreNJw3DEkA9AgCSgQ5TWlha2A=" + "data": "base64:Cjk90ymbXlCgcHTls6fSdnFFXFKZWLAh9j65hiO2M1s=" }, "target": "875726715553274711274586950997458160797358911132930209640137826778142618", "randomness": "0", - "timestamp": 1671223357898, + "timestamp": 1676574862966, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 7, "work": "0" @@ -940,25 +946,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAeJV/GzlsCK8Z1i4Enyi+OQWOkdpztFWmB2euVJawkkqFTVuGcxAXWO43eIbw8CExpOrnKMJToTPZCxWToJn4Aau26LeLZCPksB1XBBR3iUyKAtx8cPmZ7otJUsN08d8/JphG1awd/ix6GebykXy2WSFeqcx/waLDN5gOPL/yU1sN2H2PoAx7W2UwEmPUXXQeyn/hxBDYGUr+tS8vm+FeyI/DgRqOtIEUTlnj3js1xoqyXmqFQEcoXSZTGmKcdtFJN6eqRlbBP4MWV2YCH13ZWuiVLq4duyAd+e79ouWII46+mXGVIXJpwc/QgWM4oumLKBUUr8nu4N65ZhQBySz+4G8k//sR7YcgwTapA97+lcLYPIskMk0DFoBoJhyVUqZf+JePvOZlH0ERWLJgSBGyPN+o4PjWC+TEWza9CuR8mkLQPMG2RoXQAL70LHeS68CfUuoOalKexKLHziPmnFbk+U7B/+3AJ1+DXLifvewXjegN2cPJNGDYUwQ5pz4LgKqWuZ4sFvnzGdzkggNThdjO7Ieb2JR/EkkZJKsZp3Rbik20MaTwUba1yKbDUn0OZ4zbkjc6oKQme9Fmn9ZS89xdiAzL/1yLTytFh8zlRSM1TQIQFtG3wpwfmElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwE31bbqfqIcqXespmD8dLd4sC4hfgtfEbqbuR518L5qvlLcqeU0AdlRjOPw1UbMdmIXdzwtHzuBgRflWOR3I8AA==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAaMBOWwPrweN5RMapJgR3WKAlAJUxNt+r4wlzikIDew+lnxbfXJUIHeO++tk3ifID9Z96pFDed1eMptfB/t30G50gJJ03vsKRmbusKn+xEBeX5HNqLFpMIujK2tJubBBymaE8b/c1/FsMQloybv9YyD1MXPyEQZwX65gILTAL85QUz3RbLljosfbhkSXXCdSLov6RIOeuFC0tJu4WuHwrAVBS7h23hEoSzB2MLJn2zfmkfwvq8xwzm6Z+eCQbUq9V4IZEcN8iAa2KCbF1/MwGAIXV+h0yD5piaT4mSg1LGkjCT021qXidiMIOUD1aCwyRkNF0rY3D148Gc9cNdYDwp3C+n7kSK+mrq4oTjIQlLYrIbOWijwaoAK931vUisHtKJ4Ku2rm72gYfbI37N51uLMsswd7zNsFvvWGjjy0PzA5ttWPFF0Vvj7GaoylTf+B/GAFuOPO0xQBjrKZZ+ypJALCBLDISKoiB67Wj+UQk7ryZqdxYrqrCAU8dzb6Dm4kFRZIZI3l5uXs67k0adSJvrTnF/xcEPjnMEVW64fkZDSn5p8MuT6Mh02yb2ZbZbYVrqjUsEzC+Lg0PJgJjBIckyhmuSiQTL8xE948XOHBCvAlgkL/VG2lveUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwt8FPlZhsF9GgJXYJVKQabi/0GgcaFeyFpfLGj6+w4kMw+R4KftZSyvr/iO0uU6UN0C7LFxYPmyufxcgpkto/Ag==" } ] }, { "header": { "sequence": 6, - "previousBlockHash": "F4DB54C102D7ADCF8DC79A23505C5D5F8F7DB20B5F877AD33448BE50A6316A05", + "previousBlockHash": "BC287118039D4E46C01817C1FC48EDE01CD961AB345DCAB9827CF7660B37A78E", "noteCommitment": { "type": "Buffer", - "data": "base64:s2oevpITI13F/jTFx19V6WbUFGyPRfLVfpdZQtK7SBw=" + "data": "base64:N7hkcyrONu96RMZ1IcU3z4mQyyKGpoRlusveAorQAFU=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:E7bImbpP9gX2ufE0070qf1oXRRMAxtQo47eLu4lGLB8=" + "data": "base64:2O+MCXKpMP35T8zxwYdv5j0P5Bti/9jLuBDoUuxDvk4=" }, "target": "873190827380823143577845869093025366895436057143163037218399975928398962", "randomness": "0", - "timestamp": 1671223359094, + "timestamp": 1676574863869, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 8, "work": "0" @@ -966,7 +972,7 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAEiS2+Bo/ccn8Dj7JEXU1JYYqtCN8B850PeRiXKFlkiqODQe0eanPEe22f2BPMgSd3LVTdInpvCFlawAo397MJq0d30u7I1hk6C0Kc/tKc6Gwp37qDDWW6aq1veGwM0TMw/6f0z2MPQfTFM+DpfZJnegdsewcoowOZJaQxV7XSfoH1T6gs44tz2sFZsGkqgxj+3TNhurm5f7kgRnB+sSl7AUhDUMrz7KoRhLZG3ESk/iRgR1+IvEpxWQiFJnnh9LuNzsEgrt8M9V3k2Uw8QoXxPP7wj2aPqm9/0qxhhVHEasMiBJ5TSThGCJ5EoPSoxG7JR6p+0WXZxiAdFR1KJPnLPJDW/oO4lCh265wfQ8CiwRp5tsKDbhE4a8Y93C6mhkChDN7UTPZ3Hhr1dQA1Fb5ei2Z8dFpZaFUPUaWDUkLrLlcoB6NSBCSjj1C41xgHwk5xZw+/DnmNpgo66gHe2/WIp7e+iEUB/nRihb8U4C6VtewspdMvmVpf34U87txemCg38S6DdQVqX9Wg0xReU6QJcJ85g3/Ib25uUrj2YirkYeFxxrNUf9izr5Fsx/5544+V+GZ4fUfXJ+mlQUIJP1wA2MCzsf5ud3LnUu2O2oFTz6LXeyGfm2pnElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwnBG9Uc4O+ivCfmyn5/uUCXOYYh7cj65gEjc2sk4e7GUUwNIpMDJwxzvYUHhyQo+/lMvZdtz9K/Xygf/lmDaACQ==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAAI6kVNTjNxnU8w9NVTyR5beAiIebVRxrCQ3FxfVk2EeBFT4CJl5TsRmiX9vERMYAkFBI9yHYzvvEi5lCXPDnfBVzMIYm+vyP4/3Lgo3ITc+vy0Jr4W+CAhaldErFsLidMp8iNMmDdHqjilFN0vuMXiEQnuzOg16DcOv1hIrGG68QAF3sJ6wxJcIaeSGF882wvb3vSIY4z4SKxiI0hmh8lNtsNqlezGAcV8a+TDq63lSFVzeoSeAlXznk2xG3dv+UoEWeW8Nue5H0oen4J+/fcXC+62aMaRdE2ny/szBhP4+t3s9GwHqPZ3JIEaU+CR480pxovkoTOrwmrFaWSMq3tLztAINpsrZIdjb3jsLhMVpNpqzaEzcjDDMTWRQzfZUrXEgeRcwckwznhjGp+Y8C251SZlzx2W0aPWC0RDByqkTVl/9YCtBDTqvRpZmn7sXXWouTt0ImSn1jWGMvBBZAl+fr/3iUUPqyNdtoXIOOu/2a04wYATs0G6eFLDP8MccG322BhN4xGSJ3UOKvJgKPX+oylzMXOww0DMLIg8zTUqpOTdmgsypqNxBod4ZFv6aIX7a/tzzudyfGungOIPIbjX2yWdRXb2m4+N2AJgclgCYU3qFI7RYSN0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwmg0gazxMmIzIpr7eMyeNcINkmV8jPAeQ/4dGf56ZejK6DzZFQvKMq2v3qgxgUs8rHLKh5grVZYfV9lxM/9ATDA==" } ] }, @@ -976,15 +982,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:OiCTDPMrcotkCTqNRZWFt6c43Eg4ATgNFNccYd8/aAY=" + "data": "base64:g4Ul4OE4MCPRwCoHGwdfpIptEGQ3awaGE/kK4EhM7As=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:cK4AXy9zsXzO3mHYOXhIKyAZ/0EH7BvmmkYrc+1Clro=" + "data": "base64:DylAFLh2/eGs2lfpdXJQmo+FWoSpdxDcRjK7G7w7/u8=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671223360181, + "timestamp": 1676575128515, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -992,25 +998,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA/W9agwKTgc6ah327IuuypKE3NRxuZ1/1lDiY1iCkC9SYw3dIDszCLjs6DWn5cWf9+tkUu/Vs3J43LePw5LdNhutbF6H9iyAfhnHvqW/4XGKVMu9koAadUxmnpAwNsfjjBDDVatl994reM15Tb+n3ijeCMaFtuseVCkocYVvBiqYUWUfGxTp2fankiFSbbtvdJPiA3fqfTLRgV0cynPLUoomxxKzIcmagIehPAtr8BX6ZReCXAySy9Hs5oAjMoaYQ1m2P1/spuZ+U6/LXaVh4OsyIFkLXIrzTvEFaXBVo66GzGoV2ZTClttms24WpvS6jK5Lf6m477Gvh4byHKAnpB6JomV4+MeVziBvvuWWxE/l4CnpGfTAo74eAPf80q39RMfdNH+ezOR7dgGI95uYRqFij7iBkuQQj03+i019JDTAQSM67CI9bnl59MF14gV+/+zfUQgTtH5mAj8ZNAvQGuVK85ZUZM2ksaMsg9EdzG/H1QCGg0UeAmpNwJ6Shj0yDdDdH0X/A43ltKWamrt5akDTpdG/FhmPXAnUJVUgBks5GqLu4a5LjKekVX5we8ITBbLTtLJbRltaP52XCsAASin4ymCoNGX0jiK9APJGnabhpDSP7jWyAGUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwR55S9B13TxULMXX/rZHBkEYWdCPS5ZpB//plKozwBs6FCOFhMAzp2h6+dazFhlffVX/CBedCjO9scXD12FaQBQ==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAARJYTitqma+L6MVT9BInvvxXxQYHmUL7973V6rqcLpLii/tLUxzJjg6k4TOtvXFLa4VgoM+QkDeFIaQ1zmadhaKn3TZVlXvHbq1A0IVWzPjyXM6Q4aaivlmCWq5i5hbKrms4YCYta1owMOTdgAOJrBaLOjK1P4A8gJ5vz0Owbn0YJEjnpib54a68IBCgNXxdnI9SNtcuYgVKqlDt4uJUVpOGKZxRM+8jj2rlIzDQ7wrCM7IwhxBDGDdh6KqDBrcSoE/KXHpPcu/9Twg7tXY+6N0BGSQ8RwYBu1N56lE9bikxmTMWbFYNvfDrEa9zkNhciGJvESJk/CkT8Puz0QMRbk4nE/rLRgMLrE2rMrjkp693bTuxRnqXGNE9tXi/KcL8kAw24fzSgE700kghoOEjJHDvU+CjsnDz8swBMAHwaYlZ2CXkzqunSyVJ4TzVR/3rNBij2OjL573OhJ32RNABxEDyW4LhytxrG8kGGKPS7HB8wU0rFGFxhWS8LHQgz0jkqmwX5NSKZ2o9fzu+gyWBHU9l7O4SGOxcAKh6NL7A50BtQTxd84l5xJbAw7mddogrFnR7LKwX4Cbkxu/1g8pNEE2q2kE8S+LD3no9fVLy8bdhYuRlu3RIW60lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwpxAICrUa2cLZX1wZankW42e9mVYKYJrB3TtTPBUcoDerwlL4H6QHdpW98FadfB4aJaG++BS+RiJMBAJE1VbDAw==" } ] }, { "header": { "sequence": 3, - "previousBlockHash": "5AB16821B42D1184456AAF45547D572839D85D670425F2A9D261344F248E0BCE", + "previousBlockHash": "B9095B6BBBD579BCCCA2AEB99556D53141123DC7F04A90AFB100D9B839A3BA48", "noteCommitment": { "type": "Buffer", - "data": "base64:osLJDT2vYwIxLhCVXYvKCdIKdvgYjDQGfEig2q/1+Us=" + "data": "base64:WWo8saxl4qBJi6ZNzoibSlkgnm8UZH+6AaMedBHtMBw=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:8/93hesl67dtELIimQ3kEvWkxPCIeeR7s7fYPVFZ2MY=" + "data": "base64:MR7SR0S0z7YPJUFgYsLTY+K3aglIubIAgXktGDqnLts=" }, "target": "880842937844725196442695540779332307793253899902937591585455087694081134", "randomness": "0", - "timestamp": 1671223361262, + "timestamp": 1676575128958, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 5, "work": "0" @@ -1018,25 +1024,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAACcTb9C4+AlA089CvRz1A8zcTry7CcniGfdICypllEuixdGXdP9WKChdKmtobFZw8Jd04p9TFSRJUaUxJ3XzP1xuzSh4ZD/F1sRQPhf/xLdqXx96ExKXybll//GSblAhFwmOS7TK7QQjKASjg3VY/YLGZtPkEJRHLQq9MmvQYy7QFEAZno1l8IUTF8DuGa+8b3eYhxRb13VRo167WXbHHWzY8bUq/ksRGKMB0wkweB36Qub/O91AWzZCx8dQsHWt3kC3/+UiOJRJtNLzFrYILUViLz5vlbvtauQOD2Wx+rjyaHlmPpR7BNEYLAfoRkjR37vyW4VB26Vn7Zc3WjSrKJEhUO9++cY0QV4JhvxOQLhIiwKNJaHWxvgeU1svuaHspp4ZNi0Ql8qSaDf9mMiV221KwfGDs/GUnyoAzEq4xwjHR+ssdPbHAbvND3xWTE+gn0PoHQWkNDYkMRaLRUzVYGuSEo8DdvrLrZ0MbUsrqlIyo+pYKlxeU1g4UalF2oEE32cjn1cbHrXXiWdQRFstSmOGW11jeH/xCkwkw0Y3TiD35pXSZRv5QRbPtyGQM4+yLt4sK+zerst3CaTtdwyN23SpRAjxhI1hJgU/kJF+eE/ZdTpY8KjT3wUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw0cu5Y/ALlCeuXASU7eg4e5eLU/JR8D8rS2kggVLLbyP2uvLOXADPrC0jwjOhM5fJsZprblemeg/OWwv2OAlaDQ==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAApUxV+i3dr4Qp5Igh8nhnmMC3v9gn8A5SCzx12UGG1Ca3oRQtT5wDnGWsQGToSgBt+XX+lndoZKlAG/QJYURK5fTw1bQVnmTQAmdzVgvnU+KJ9Q7s1W0wbafK1ZzJO454sfGyGmVN44Yfr6UT9P5RoMFKpZs29DkI8gtJMcIdXd8Ywjd3gXwnH8SpLNUH/W6M2XjWcAZexkVNYRVSuSFBVTsWnX8OaG2MbOWzqCGUfsOJEE/8a3K016lHnkmuqqLapjdVh+WGnVOPmfZEymFE0c2H9CnE6WHY0Q3jhUn6tEJjTlhMjKkeeQEjPaB/cbJWz+eEUFgicTZmzQObnV6sxf8PBmnVlyOcYwaOF4pT5AF7b0OLPFSamxtCBWXpLjhkIGgpaIr5v0GRD0JvXvjhU5E4acs0ij51e5t3Aembk8h2X0HzxANRwD3dQ9oiabMiGP71eOOPs/iQe52mKVyLYo5bLAqYCUiWwAA8wYDFygb91sKBYPha9OwbQtDzdulELRSfxnFC5KmulGUNldpC0vbZ+4YLmN85205BKaAkA+d+wTWobIHAZjJxPiEnNjUDE0GdRMwp1O2dwT6qE5XCT6HF1vidxoGsR3XVmbatyR4wU3EF4wZ0Jklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwLyxx2aSKIhwGLuGTU52dnn61uPEAkrapt0wHbJemv1RaX1t2p81sqSCz+TUlET07aHgzlLClfrpJ0GDwASZtBQ==" } ] }, { "header": { "sequence": 4, - "previousBlockHash": "033080DE519D6DD0EDD5745F59E29DBBB2B147F2CCA66465B7BCFC896B0665D1", + "previousBlockHash": "070227436013B3B9909D018008590B2344BF4A0A82C93EBC6ECB9B57627802AF", "noteCommitment": { "type": "Buffer", - "data": "base64:Y8Flpg/NwdPaqFgonZHg7Md47oCdDlK2+ytk09dlJDw=" + "data": "base64:jaoLOHgFGJbtf3McQ+83WKkcq99vnJm5afNGRUtQhwY=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:4chAQ4FNDW1EE+RYRkwTJe0+BfAihd63WaXv4IKG5CQ=" + "data": "base64:8UycQHaNLKXrcprxT7E+QiQI1Ji+Huaf+IluLeoNurU=" }, "target": "878277375889837647326843029495509009809390053592540685978895509768758568", "randomness": "0", - "timestamp": 1671223362661, + "timestamp": 1676575129364, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 6, "work": "0" @@ -1044,25 +1050,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAt3aqgPBkW6fimsX7Kj2BPriOCUrz+jZH8KNXt1aWcEemF/OATwprDGMAGA9pc7jkSE4PzkeisVW9DtB8UZ7ww4fWXyAYWIQvn7FYn71gZtqkww21WJAxVbu0jeWBTvxksba8AJSR9sOJQ9BZ86QbXO51Yh+Rx6QniAJ7SWxPVpoIU5ID/pn+rCvZRm3cSChvTpv7XyVANxdo+rV4iIX2x3HJM4U8AyLTGthw8YphYfCpS56nSSrHyz0F9u0nOgIFZ5To4yTEZlIGjDZnNroJZ59B70qgQQVLlYF4cRA4lFSIpm6t+B4M7NKqoI1I4s6dq/xabuHcbHJt0cC91mvKFFf3xZDGxzh9sWpCoR117a4V3RuBeBLiWOKG6frDtBgBrWpyZ/PZoeuP0fSUpF9a8fIrYd1KqTMoCptgUTRC1bpDupbqUr52B92FCwyYK8O0s/f7XHuRYVy55PWWDobBaiL1yw8U4a6VGXjocpBLBGMTpjRaVVWfjFDFK0EZ8Y3ES39HmVWriqvKIvZTtl7X3TOalEdqOMBsW8vAontL5BOL75BFs3u0of00Pzivbg9mrF3zn7ZwKqE/3TW99aCFyHE8WuRYrUHNhT3rlkvum/cOdCIcydYJRklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM8DvJJrkkxmvb3ip/EGsz1d8M1XbrAlFudCiVjfHzQ8yCU/lA4x0W4SaEGsa2IYO9IFVdCVSsjp6woZwnqlQBA==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAjmUZ6MbKXR0u8pwiifKgNa6A4b2AiY/yJAPPWxZE946LrEhMNghVdPBisefgwSZsZdPX0SLcrBz93WjP7+COy707nQCWRl5tm03t+9Y7WJ+Ct539qWvGmr0VqE7lgKZ8N8yaUxWtc3i7EzlEPNWKDP4QChNJ5OFdKLE86emOWZkHVy57cBAFOGbt4xQGRw3wxzt0HmU7Pj40Gy+MIFrQWdVV9qnZoWytDToQCtGWvUmVi9v+rFtSP7Cst81jR2qj/qJDyfms48le/mB9fkbP5W02Z1havyhm3JLqKWc/PgEuzeh6jiy4ZR3vz+DFp41dcZH38MXxvJpqNWMLBKW1TkE9Mc0ISPIVU6p2heFgeY8JkkzM4TlgdgkyOMcAhigF79H5NLrGAbxp1AOXRQq+oxcdBDw/8GM4AP21filSgim6pcYPPKLXTHeneI+AfowuZIm0iW2BKgwCWQQSD3n+2fDUhMvX5zl5HYjKflP7nJpCYi757MmO1VNzSW2Lt1gGYy6F7PT03YZWgwu38qyvWBoPwwsWVGl4YkK6rTBrRRM3wT2UiBjcdpwdNYGTLRYcoJLGDceErMPBMYve3N8D8gelAZQHQfdTlUN04wliIhiC1bX8Zna/PElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw8/zxRamDe6OSLGbFxhFiD0PsinL5uY31+N65JCKUfTVwBx1TCiSL2KwBU2k0CnD8qyT6nrR1swDSzwyWs/yADA==" } ] }, { "header": { "sequence": 5, - "previousBlockHash": "15F9C6129245EA68C8CC461151E9B1DBBAA8652D933DCA8FF35D45834F392435", + "previousBlockHash": "D24110E8F8C3CE50AA90090E1D6CC29F84291D636086B86419CEFB73B56FA3BB", "noteCommitment": { "type": "Buffer", - "data": "base64:p3vwZX4xeM4B3YW0m3daI6lsdg/ZwNDiZK79HYAQTz8=" + "data": "base64:GLZPL11k9iVyKGOhMcR7Z3yKahW8G8w91YzYja849gQ=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:7hltdeaVt30b+ZSKleinC+SbMeURKsL7qDq7iOPiaIY=" + "data": "base64:rfEgF3CLyqSZrAPXwZD3zUQwA2Howv4CxBO4LaGUSkA=" }, "target": "875726715553274711274586950997458160797358911132930209640137826778142618", "randomness": "0", - "timestamp": 1671223363785, + "timestamp": 1676575130062, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 7, "work": "0" @@ -1070,25 +1076,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAxuNja4AT8NwbpjNflXgpxGq+NHAMKPez5v5TcsOiNHOiR3XZYlZRPcP4rEwM7qTTrpW3VdUE9JyGQ6gF3Oc/oeOscQW3jU+6SqrcNQ6HKDukD3tetp2TeWROOt/YR4qa1GsbEhuu/0WMSaMtw3ZXNym4EPq8OwAmC3jmYbxp1tAIi5JdtAqePXuJnVqtkSLWT19/nX95OUpIneOtDx4nM4YX7ELBMVsiV6ZXU6CJunKjFxUhzeAd7J9WDirb0liMAMOUHMP2lHmYwJqbB4aY0O7tXiDGKyLQnx+NzGDnL3AyppoulglDNeQTJIkfxc5guEuhomOtMiXArIXQpbwo71Eece5p7U/CMg5hXiAt/VkX3r3ITLSusSMAd+h7JOZHcuvbV0OcUTKdR5PIfueh7ucOZx6NrxnsyTW9pgHH5cmdCnytI75LwsvVQchheqrrV4QL8wWdRZV1zZeVpa/dtEMeIcF7yrZGVcrHkTNEgwzQZ/FyPZKye06GmPVTw13jzbw4ZEk+2joTSBmzUdRkNAxzeWLyuGF7swdKGMRkxLt6nQ9GDM1u6sJajW5Crzt9c/CSruvqxomWXFACUK4kBzQ9tmkrZSfhUMWvjIv8OIpSUOMwMPiD1Ulyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwsDVyTgCYgE9wGLfDAt4CkCnXK+tMkcClANZylrr/z7BBKJxefgQy2RyowdO9Qf4Fmvq5Rrpe+BNhgZmn3A3/BQ==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAiM4wcPWAlaEZGceTn8HiUXE01vTUY7jpUzdM4W+jGeShIi10gU9Jeh0X9LHCA6k/JUalg7GSCriz2qj90akdOTgecUs8TWBKtwgkpq1bac+i+DtOK/ekzQtboZvnGwEYk+QTJ46sXqME4lhwKl9eOlznQPy7pT80s8a5k3qVsa8U0nj4cjorb1WDUn4q6MmpQLdpVWWSOWCHShKt6/8TnAb8SeoO564gfSi4Jnsdif+O6NLtdVtl+TZ7adsWob/f810Hay0ZPtqGkFZt14G2FQNEiWuA7bVXnCFsIdOiCigJXyDIiJLOMuSPYp4PZMhsQY/fKTbXMETAhLrpVQ2lKPatGiEZ32BoyP18u+r2+DZuUtJeWuBixWQLNvf2B+gdKxmaKe2r3CM4QYXwqxQAss3va9HhWR54hqcSFtQoePPIlAW1406C9SUuHx2iwB+UaUs763nKLc0rOl1/S0T1W0FtMtkodOCgB4wjaYyz/LYlyq4qgtXwo2bSmaDkJJz1oFJnnw3NMqsd/3pJQ1+PWUIRRS9Vkd7K+b1yZK9rhdCZtnJtAge10eFv8zYNZL1PxkfAboDyvDj4eQ+4ftynAdAzaKi0k16pH81Rz0U3SwpYnkFTbfsWVElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwhWH7HVpxmFqagLS/HZ+qORcDpA6qtP7dOIf1lahC3N53JrrzdZL7/kzpBCB6FR49cH17Xd+uGAdcq/BvfL+bCw==" } ] }, { "header": { "sequence": 6, - "previousBlockHash": "ACB79BE9B1A501BB99881F0824FA3DB1F6B3D57404650B1D016466D33D978CAA", + "previousBlockHash": "D474E0BFC6BF45F181AFA31A2402D8250417CED595A034321E95A6BD84722A24", "noteCommitment": { "type": "Buffer", - "data": "base64:35KOO1qaD24T/8RjKtiznTu67oZYBFWTEdkPwBwyBjo=" + "data": "base64:w9G18qD1sx5iUuWy9RHr2qJJudf1hU6HEHIps5pWyms=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:O6yZFubd/hgb22K3Gy3wNf9OYJ6t70Xw+d36feiJzmY=" + "data": "base64:cwTpYCyloDarDi59gpYNTiRZIjqIkeEosD6R6MDkhKk=" }, "target": "873190827380823143577845869093025366895436057143163037218399975928398962", "randomness": "0", - "timestamp": 1671223364927, + "timestamp": 1676575130566, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 8, "work": "0" @@ -1096,7 +1102,7 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAgL6nm32I9YpoRsK0uiAbO31sYFrw+uhQMmtbmZSkm5GGbPgqlr/DycCccUZvv7Ic3dVH9kPgCt+mFSwy42P40NXTwUHGggQsg4ICMYbmltiKnlZOsGjkccxLdkB+sh0Hzf5Bx1ULUdX2XIHRkGf7uq+BGULXRBuMe2HRKOxx4Z4BmJE1rmUHHiqay92UjMyu3mpOgSZ2h3u4YlCixEQEiGAL49xgDHRnBdNMgQBHqkyG7sVfyj7XhgnwRfg8VrL2ONGnIKf41MIT0YqLJgIN2jYEmZ+tKVKEF4rtKOEBKlouVT0skjBM4vkWBIPuOxh8kxRAR1zE0+nBP1G8bcb6u65z/C85TPx/3gtUqLIY3auIYkTlQ3SExmpPyyVJeBIS2wdPE0f1nN9ceuffi29adrjNGQQkL/SZAYpolXYzarE8FlqLvKz4N7bb+6vNOyUJlyN5b4zjLxDzgbqPbdRZTJcQCnEbXu0nF2wprrQmgvKHhqOSiHQSWWu+iruZMYI0oNVoFvr5g3boN/Cpr+xFzrvQHDcb8ddeDOUlxu2LAPTSUSyQu9cwwqasOOng+xr5OiAre8f2N3e9fRGvCZ8ak4IimFLUqKei+fuc1Eav9EIsuO/9IJZai0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwb1gSwVLCZ9ilHmSl96TQL8CMlPV7iymOo5BdEWaXJQ1+UoLMd6CdfKNfwvDPFs97z/fWIc8SCAOMt5hC2fyGCA==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAyxBdlcQJlm/lRj+w8v1HpxLFgXJS39IJD853+d/htMiMUtc9ODdzxpXEru3aFE4FCbKJAIAOmPJu6ZH2q8l8LFSZWIsCaQGtfJJvsxzcAsGu+fHVYFEHALqjmQJOfiEEBFBK9lEX/eN4QlKu691sdp3vtTJqkBg5+xmrt+C2LJIVWJTOrDN9zyrKwZufV3w3JF6g++ygcqh+ObOMKep5f3J8fxrdWE6fXhI/oKBJ+WqyzukoL6D8n/v0gQF/Jak+oznIzcph07Fhax2moukHcllgMxDqrycb221m+xOLZLxHsllP+8FmUGVnlYyTmX69cEXoKxRpzRJus9J/hfhCP4wn3v9iAOVIrG8szgZ7Jc+LJ+CuvE7h7GZxTdcdsa9YlKknxIUaSMI60qle2rrmvZqAAV/j8yJW+0JGzvmlqpVuj0Jg0JGAFrLSkpOpU/gZbM8qE8uA+PowLM5JVbjddMh+cUWHFC0sBE8hrERVspHNgi3i64bezOgFlpUnYxN681rYeRCEkPx02xPSddzq7eyg08Oi8w46tle3qoncZM0PXE7DIJ0GkA8i8dRI78y0uj3i5yoE9uQdI7oVTk9f+NsLHd2OdxWYLq2iflP5qPPD+WevSz7ukElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwcqAVlFFlppeXhr1xEhTDrxIS8JvqMBL+tl172QrMKa955W8+7AsJ2pTEaE+tV2KAIwP/6HfN7Gs0kpTuDWSiDQ==" } ] } diff --git a/ironfish/src/primitives/__fixtures__/note.test.ts.fixture b/ironfish/src/primitives/__fixtures__/note.test.ts.fixture index c5d65e2db8..95aac8a81c 100644 --- a/ironfish/src/primitives/__fixtures__/note.test.ts.fixture +++ b/ironfish/src/primitives/__fixtures__/note.test.ts.fixture @@ -1,12 +1,14 @@ { "Note should post": [ { - "id": "9e8fa3cc-e071-47bc-b633-4ed634d27173", + "version": 1, + "id": "0e5795a9-9719-4a3d-bd60-26118f46b2b3", "name": "test", - "spendingKey": "a8e97ef506cd750a7d29cc849161b0c98b79cb396df7b040eca2dd5d361dc37b", - "incomingViewKey": "4e8f0954a08e363b04322652fb1bc4f88923c579cecabae7236fdd94a4603006", - "outgoingViewKey": "12a2777a88d02c9214b069a3d32f87d82bf0302ccf9281fb4f313a5c33fa16b6", - "publicAddress": "edddea968cb3aefdd98cfb7c79e2ac373ce996c455fb4cf1aa6bc1a8d69602ca" + "spendingKey": "04d83c04570f62758df43cb4b0e8386d2d5ed6301953b35ff7745193be40a890", + "viewKey": "8073187df610390881770594c3079b58bc6440e48ee4299e63f4fe8cc43ddbcd1c03005f791a3c3a8449b43f7040ad5a4d782de73628fd687d210e97f1ef05f3", + "incomingViewKey": "3e1b4d6b4bad0731d42ac926950d9e3a12824593594184854b7c85750c496d03", + "outgoingViewKey": "d0d820008f7571a26746a3a80cf7e9e443f7725c35d11751e619e5d9e0408732", + "publicAddress": "c955146a0beba8eb3c986924c21d5025b4b19b4c217a530a47115d69c9ef3a4b" }, { "header": { @@ -14,15 +16,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:Io4HVIP9JI9UEMvjfdOdiHzJnzLyZzhl2nx5PLhRbkM=" + "data": "base64:KnKXvizgHM1/4YW02cWYhdyvLkSgqbf3RPPCPV2Lpkg=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:+R4nZTSiNHRzvlKTsFY60ExGnbAHAsl0GnIZktua0MM=" + "data": "base64:7nO8TJ3nKEx5e8/GEbMmf1iOYD1+Y1OAcqetrYcJr9g=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1676308908327, + "timestamp": 1676572469552, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -30,7 +32,7 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA63B1kqcM3ehyw9TxqVk91GWNRsYX81ubnsMBAIbQ7bukQBdvwx+uAIec+HJy5mup7MKXxm03J9wtSAo28E5rNe7iM1hbGaPAZU1RwFbrE3izuPfEN1fjWoyXvZHG1vzlTI3ic9j7jcD9q4lCziO6NBfuATB5Eleg3k7KBF3YzHAVVSOv34atVUMLu9zCIXz3rN3KyHr9hEiq6heXnPUK/zQCvMdQydt3No2ACsGJw8SiC2CSkqCiGvkt+6VAM5XX8xv7KEypR9b01mRPLLygVD65hKvYPVYl1ncCNa2SnBc3QnZR4RYN11+P9Yx2diIhEqLuM//0tiqICgK95X43IqJ1N32fmwZgB8F/gw04iWI5Zr6NnY2LNLiCM6bDvoc857mMKNbxWL9o+jjnVN1hxH4coAFnWyX2tc2e4HOIclOUWZU9vpdxqqZPlFauX1TI1dtIySfBbJ7bnbYWqOz1zfWYvYYVXZtXSUdfATjt4mxEPkq6bOmwjHEnRP+cJ0Z5sbTJgYTCb0KcPoVNoTNAb0bo/1QNOFoo56pIBriGlk8IgyHD49AZG36wK13sM0VHiH45YpJz3MI8rmzMtCAUdPjvuwL1hDjbxSwEX71fjxsTQ1zrTdYcTUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwb+XkBVc6Hq/HmX4DWNmWAi2IZltUKBimGIKRRWi6m96Os1Cj3iKjpwyZ0Oc1dII+bWg2o5QrIkdBxLoHLjerBg==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAjoB4xG5OsbQ6uo0F13dM0o61gcx3HFANKrCNVMpGsl2THGFgz2UVUoh0t8iXe8FptSwBHGftQNVp5oDJEuptJf5Wd87H5mfiSGU2rQr9QUOJeqxa7bm28tRbNsH27bVzFti+8iLk4vi+uATYy9/TCGpb5X30YvQPGh+INtALR3UMNINI3BceYnsZsBq5T7HfEixXGvICHA/0zvVwY11mk82g9vQfXC5RiOMxnarNpz2gB2JWv0BYvy8P4RgG8u5cSFeAR0MvDTYz5JxmW8S9/EtP9AXtcIRlSMddAerBLag1R1KpzfspgJ4k81dcAKWjgzzoHbuLClqm1nPslFwDQ7hwNTWY+luLnd9GL0oKnpzGKNw83sawYrRGoGvbpkIpubMBFh9tTFWpqEPwZ8HP5YnmtSKT8QScDVoiNA4Nq5CDrvyyZXM0WoN+zbc/PcMikW4AHs9rloYxsxyfKK9w2xe7pgSdZHTKOo//jgqqQsf3W3LfTOPaMTc6mXeDp6fQlIA/6mTulP/xjYYxGPDgiaavVPX0UptO+5XEx6JObWVQxqtJtr6bNBX83ESQKzU/pMvcanWFJx9UlaQ3BKTxj/5jXQQTv8emXfWdhA2x+vmNTlpl2OAn40lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw9lqVonxhEz3zbAE917TtWBkBuYAvcl+Qz7+YxA91Vy7q2oS0PQdJ2wYcA8Ag/eYmAUE1lviZ+43W7Ba04x4MBA==" } ] } diff --git a/ironfish/src/primitives/__fixtures__/rawTransaction.test.ts.fixture b/ironfish/src/primitives/__fixtures__/rawTransaction.test.ts.fixture index 3c22c83983..6bfaaf8c51 100644 --- a/ironfish/src/primitives/__fixtures__/rawTransaction.test.ts.fixture +++ b/ironfish/src/primitives/__fixtures__/rawTransaction.test.ts.fixture @@ -1,12 +1,14 @@ { "RawTransaction should post": [ { - "id": "cda95d22-fd2d-4323-84d1-68dc1a1011a1", + "version": 1, + "id": "8a3cf2a7-f758-48db-9891-e562547ca631", "name": "test", - "spendingKey": "1bc7d08b020962d07a346a1d7fabc11b0f43f275da1f5518a4c764f68b522d27", - "incomingViewKey": "c8a4cb19e34b66d8d869c051157cc31b1dbabbe9cf6d2ea8a6043fc059d4b407", - "outgoingViewKey": "453b69d686fc77393fe586f0a81489a6f8f6c6b2da5dafd5cdeb8064d335e0e8", - "publicAddress": "896713dc850e8e299a9cc6e58b731ea5e72864e3962f106a6a128e48eb0cd7ce" + "spendingKey": "3fb36b1b418d5da0e53efa1390c20c1fbdb364cac1bb85b74d94967882fdef77", + "viewKey": "3ec2151f3efc9170db44adb5532f28e9d5a71326a370c3dd696d6c8f065a88cad3a8a177bfb595bb1045cecb1e58d0fb97832bf2985b711fdf8c1af588af2b33", + "incomingViewKey": "4c655a8dd1e0cc0e5d1ef68c6cb668fb6925d0ef74d90d45148790e5eefb4106", + "outgoingViewKey": "2107e5b9122e77c45b82296972e3af01cb1fd4c3f06652a7f603855eebad2ed8", + "publicAddress": "72bfe2ea5f5ebf9395cbb2fdbd728ee8e0ed01fc94199bf18e5cec11843a1f4a" }, { "header": { @@ -14,15 +16,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:/itGrXdTLV4rYEcqqccaFFV195gm8u6EaSNYiwNz0R8=" + "data": "base64:gL2vqzdihQY8Ggj4jKZrLorcYF4TE1gI1I7cd1D2e24=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:uJHuxc/fO2nUEYmjaVJPloMboRM2QeV5uGvnvaQ7j0k=" + "data": "base64:BV8ycvuHz1WGGh30OHL/upu9olNdJmjbtpFDqfT8JYM=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1671511065581, + "timestamp": 1676573486882, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -30,23 +32,21 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAfW3R0evSlBPsslSmilN3Bnfij0/Zqe1A3pIPtrMluF6vxrjUf9yTRSIjN3tLgwhCsZmdczZrWilCcX0lG3GySRFrxkChh2GuFrHdqqDdD2OgouWK9cfKlqgG3e9VOkpnEgiNj1SJ70d4wvWepSbZDRsoGejT0CLCJ+a6bhf9BzsDG1PQIVvMZDPOiNRt5N00QlcJJIwMNMzbMuw3s4V1oN12DA2coIzy2ET6BXkR46GKtvPSN0LiqVFjGRv8MoHei8+KM9VcO8bgedToVl9l7/Ars6FeLNi50eW6TI+0hrPwbWaeBQZkQWMI3cteZL6yr7iAxN9/rQC6XdyEzZvAxPnbai4Nixfmy7qRc3bYMwP/alcxThwDf2+5Njss/FAaq6LxdyS+2hDknGMGvmyFnAX0pkdsd53Yn8ikDyPEc7/meIe4XECGk8Z/OIMK8/zvp9G5od4y0tSELkqNV301UDcfnY4T4l15nsirtb7mZkzywJ15zSgyOHqnMVxY28tnrOXNWsvnmf3rJOhl/Q5BuYL3gsHgfOam/M8O+3Qtg28gbIDmtVde/z2azxQ5fltI9Y1rOSFWEzJjWoQ6YPlrDchPk2kbj7iiJutduCstB3p4LSpTnNV6UUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwvf1QCZXYiZN6/eOtsGXlLJcmXAbYpWmQxcN6b5ryHx2PH/FdoxJ97GG1SZvQQ0Zow6ZlnJNMxStB61nA60VTDA==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAuWC7c1RZ1ALjOhsrlRR/vKmz0ULYkzvpVufeEZ/SvAKkB9MQM3zTV4FdIwxtK0Y/1FteVnZBbmpRvfDkGdx5CT5+jiv2zGYdFwRqsvNxlNCDK9NNX5Dwbq1JaDjAHUMdgl9S3GRdeZLMr3bFxFNZTq1dN7ksIPqNKW15VjI/z1wRqHpa9xEcUCX2vWNtGwAh3ZL5U66OILHT1zgImJ0/tOaA0C596UBkbpTrRI/OB06jEPt95bX88h6/bTLRNtX6QRPskJSgY8TagyNVnt57r1oMZRgReB7ArJqxQKkA2OHFHzANz0FLKQov0jikhNmtiALAj14nF0d8WPDdCJFhn0VGZP6MZL20PzwwRaPWmLEGt70gF5hF/zFaz7nQE6kKBeMPYY37M4wSbbJnz4pTmXmWRLaJo1C59aLjTQLKCqjNchzZbzpJRFh9i/T18zOMAfgSV01+JMZU20oDHbByyFhVKaF4gSsVTV4/DobAmJ6NeDQHvK7Mv3bmTtFlio7+LXK92GX1NK1Q/cZQRdjLst6CRzOFwaxGLGWXkG4qYM+g6mJAAjivFcJ4O7QpkG06UeJ1qIaW1ksYnWr+oSVYSUoHEHF/15mmA3HLJ9XiaEixU4sQlooXmUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwgrAob0/cGJhiApNp/qGoJhaTjXWlEqga8pFDOey4JsEn/pzghwr8TZ29tRqJaO9zu0Ac7V+1izbcheU4OsKACw==" } ] - }, - { - "type": "Buffer", - "data": "base64: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" } ], "RawTransaction should throw an error if the max mint value is exceeded": [ { - "id": "ad5e47a1-ff63-4516-a3a5-08272f75ef1a", + "version": 1, + "id": "3aee2628-1f57-4afe-9dc3-3fd93833ee99", "name": "test", - "spendingKey": "28a8ad61284e8a6915607acddebb6b6e29a1e7f8736bc93abfdeec1852c7a72a", - "incomingViewKey": "0e85692068e43047851c64eae14e883b3449c5ca5056f9b344e1f3d10b502904", - "outgoingViewKey": "42cb5b427a5c6fa1f348423cf8597a0b038cffdccfaccc0ab43aa86d639623fc", - "publicAddress": "a46232c65f2b3737165006d17d312ef3267f13d2f00be2f1c39ce6d176d76aca" + "spendingKey": "bc08a1d862af250bd9a887001090ad191ed95b491392c9a2b250b94846935aaf", + "viewKey": "2bcc9439b1eae3b075bfe87affcf3066378105342f907eb04d3fe96ffb6584dc236e2ccf6e0d115acd9565bba19b38f68b00c1360608c2f88fceb230b5a18e23", + "incomingViewKey": "d480e28e7cd558bc19262cb56b34789442d0aa5237ec13d7090747e208ecd003", + "outgoingViewKey": "4b404ff82209cdb557711aacf1053328834887258892b30d1563171f9b7bdb74", + "publicAddress": "9bcd1adb6b5db734754974954c6df6f9eca8640b2f8e71ce8019417a89cd0465" }, { "header": { @@ -54,15 +54,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:4DQFus8mdaZam47v/0Df73GYh/yuoF8sgtEGxDJOGiU=" + "data": "base64:YGMgOocM/sgq9HXhyLZpYI4GtOGKIz2AS90OWiteQW8=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:JDBNWJXQdoZtU6dpqHkbqgzU0E2quFlDJeOEMmka2UE=" + "data": "base64:hUU6vNHso+gy6nBOmkukzMvOtr6y+9qvxJyd58dHbCM=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1674751027682, + "timestamp": 1676573489300, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -70,19 +70,21 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA47w6Vyp6A259cFxGWpvBVe4KSxUJoFgrYIq2qox3GMmL+CEO9ahb/M0JjcaxJ7HwZJ1diIAKq9M+hiJ3Slds4FBULFNVpCwNE/9JQpguy0yzzu0d9aPaP3XbpQs09D9bajTELaP4G0FFiH6Asj2Gj2CFw67buSfToXc94wGcnikZpaFszFgn2PBbMXOlnYM3F6mHhOO3xRv2ycp0gfF4hcfBerbWAv8Rr+HY39n9DKC2mE7EcW4nJBkWDjY95vW2ZUx5ZtF0iPEmBVxE9gT1iual9vNcIpOWD0RirVT+ZCoUH+UT+LaY2LzeFot7mD+mJxINwWdmXFkJQDx4Wbdh1tZPld7hyx8mtMVm4X4Nkf4+mYnZtLEKOXkB9s7Hat5CI23+h77+MuUFGhI1NI4bDuWffSSnD/lzklnD8g/24k5Lieh1XS/WoviS3cTiY7swKSLRlPihAKleBEKKlKaqV9w6DQE8aNJRdnywDcGS0V+VnZ9X4WUhy8vNGy102S3ifoMH2OXsAjqFXg/lCp14DFFY9FptqJ6bqwIsIgdyi6xxCv4x4dMVzcVWKBwLEzrEeNT1znNXdO5gy+9Dl7YX2xj5A6FnHLMz2F45ILD6D67R/rW6UFOgzElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw2H9K5ynm+kRfv3T1xL9UXBVRW9le5xeisEYEQuPSDdZ5l8MQM7lTwmwhsbtfJw6C4OocxDRIZv3zrsJlZ3eUDQ==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAANKVthTuVBr1/vYsr0jUUDwztwCulFi0uRqt8C1Lz2zq1r4LU5ifIXBkaHV7wIE73c0Cy3e0pI4USeppE232kBbY+Hs9LydD0fLVa4RMDER2xAiDQ8+ieK/oYJej5X0wFI7tWOqU5T8Irvj2iCzIkJjS+Y44tTXkP3cjP04YdeXYOOTj7hGIkJiMFqrWhhMbC5iqoG6L/02NF8Lxt7Mc0SvvrFGs6EwF2Xiw/GWzz/JuHxbHaVLSpm8hG/BFjqgEZUr1cgXDVQBVEv/Ib8imIChSErn/55P7n3+GIGZ8uvVQlGTiDGpSLevN6N05S8szL2XjBFA81OYo5eiaPrvcphs3BRU8EEVdgb12SmTigYvx0WZ8PCuFGRwQKPtLRj9UBJiQmqnYvcnro2LBHoyV1OCu0tIgUSP1h7V9OCkLU/j1nijbzXCj7cmuiy0+z4H/yW2RNUyGivCKgUEJR/k7MGQ5PghAKKXUy8RiWGdHiRwAi884rrSDSL+SBiQ6YJ4QYU7NJXPnV4NTZVJ5pOk0wDCLeDRGASbmb7Ebua+zwThS9hBvWVbiOLvUq5idLfS23B/TkomchdgRUcegxTZLwX1mI2hvzKT1pz91QpJu93AfNQnPrAZZlv0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw9BsJyPh4e3jhbr0ocF9yMBc/ePSbxpM+JHX2gMYRD84jl5upUd6SJsUOdQZuwmIgqeMjkypxc3CAkk2nsNtBCA==" } ] } ], "RawTransaction should throw an error if the max burn value is exceeded": [ { - "id": "6c277c70-d922-49f2-a052-f650ca5e71fe", + "version": 1, + "id": "94831d44-f5db-4054-8ed2-7705226db158", "name": "test", - "spendingKey": "ea84ecb473ef6811db2213865d7082cbfa84ed2080d3454886adbd787c942661", - "incomingViewKey": "f09a2fb392ab6a3c37cf85f7e20763fc6ab7c6dcbc237283c891930529ed6b02", - "outgoingViewKey": "100b1cfb9300bd4aad28501bab3089babbe27bcb9226ebde62cc93e3e9d1ffff", - "publicAddress": "c85dd50a8609696ccbca781944559bbf87bc4feed4e088d6dc95f819626b1406" + "spendingKey": "b4a6651e15f0374ac5e6ebf01034a2e090f21f62690a4182922ba192afdc1806", + "viewKey": "a84bb2455ca4a126ebc7c679cacb991c16b55769e755ad43623c51708c0f6ee401dac252941415b287a033da622aec7855a1d0078cfe23fef703a47420f9468f", + "incomingViewKey": "2f8499d764a7fc08f1f924b86c77833a9796e5b0f5fc61db7c6a794382920c01", + "outgoingViewKey": "803d51ab11ef36baff6329ebdcf408e01a414cdbb1c78ecdd10ee75cb7a1db0e", + "publicAddress": "1b4d6582a29633ebf86e477cd81aedfccf09fa506437ae39a75ee5dc366345f2" }, { "header": { @@ -90,15 +92,15 @@ "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", "noteCommitment": { "type": "Buffer", - "data": "base64:a5Pb/FsczYubxQv+DFrkCZ05ZEFirS9EsePpQlQD3ws=" + "data": "base64:adManZEvcIaQqLqtJmP4nK9sqOk5emtyKG+Q2rq2KwM=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:FKfiy4HOIseWd48dFRQ4bqzxqbX1yCscQ2JnrlFgQgc=" + "data": "base64:Xb6ZVGxl/EYXzs3lS7LDBd6EPoH2NqOY6A596BDEws4=" }, "target": "883423532389192164791648750371459257913741948437809479060803100646309888", "randomness": "0", - "timestamp": 1674751028219, + "timestamp": 1676573489716, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 4, "work": "0" @@ -106,29 +108,29 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA3pUemV248cZxQL1fcYhhf8ZG3ve5ezRIxVJDDFbyE5iD2Rxf3rEVvXYU7nZ86Io4u2s5iXhhnswz+IGuRn1iXHJsZHfgdj1dw315XBU22ueuL/z4Mo0XLCWYKhpK8Aq0gGRHPfCP54T+H7HT8ywHgLaKlTbHUirQZP5k0SWNt1ECXb9eB8ifOO9gAjtMdTiou7ASiuQNnynidOimMdoVM3KRr0dx2+9rIYdRmdoeeliR0GdWUS9iDHqVWTCWyK6VwZpS/1T7WaKezg98hD/mk8dsL986X1y1dnc44OjuR8qn1acbyPZYVWrMbBlEEjXqzMlNTXBlpaV/SPf6LA8B3m80UkM8TkjbFw/SkfT5R96WcJtFlQPBaRLnath+fc0+yI2vrHkbH9kQMWfUveoN4V3UyhlxKkKyGZXVvtPZwtqQJeuA1OnsP+rzTKNxAoTphxewzUT3BsRKJd3vwg+abCSg7Gl82WXqAk4jwDMD6detdRYsGPc8/JmASHTvO+SP/sl6GipMB6/eCq8XfnHx0Mx4FByEqxvtBxyNwdeO0eWPCcZq76i6nY/gSbs6HayuzaTF7R1dAWd0cMVpB4oR804jmgL37aQWr+AxuTK9yVafzc36A49mBklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwKnZ0W7GRhQl5bDw1Z8F09CZFzk/+7Hh/h9ERsMTQB984Xb1r0CSG6Q3pRrpAQ+TDldUPdJQzQlpOQ4fVDg1aDg==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA1V0XSkTMYCK/MfLtS/9ftyUtXF1Sx7nVUKJyO2eqgr+OV8ta+kz/8bNOOShrMJYCRSF189Fx2271l4V2rr41DB5TMQzXjfuVgVpRJwF3rIKzaDu4DzkDWpYhkdTPinMEpU0ARDCPxIqtL2Zp2FWeItNBz2+zMnJM1ZAFd1L+8tMJHB+YJAMYBFILL5U0OnczckZ0Y8P+B3yrxM8vbf5V2eYjZ/Ujopt5G7+BKH0xdgOMeuYilh0/3KEXDgnu/q8HtDzR+7eLfi+q4Q1dlqVQMpLwYZ2lPCNth+zij4ChekD7ZDG0uiiWV7b8WqV6X8wyZ0H7lZlctjc6CAyD4Gpl1lKPbnInG/nMESiTh79SRFrts5qFaJyfM1Us2gWG994501dT5to6Qi6ykAtBKel1xp2hvrZJyU1AHtQux7Z79Tip5p07SGnERH4w/DUXBW7PhW5jQqh7ruAa2zpswLklpcNcxXVUMAuP24apewGG/ezmElLgTjzJfJK5z19yzK7LKxQtgJVHTzBBSWvFx2HySt0nHsl4wWQNRgl4GoAY1dsG5Wlx2XReFVQLojEof5PqNZ+E3DPkE5MACpWEkY7DSe/OPfgZZZ3oelqfQ8o2ZFZAIMs9oDDfVUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwy8KVcl0oNhPsyND3t7n0Kuq3CyUh4cIyGi377lGx+uN+tJw1JDlqD3Ct5z0l9Upp9XtzF8VLFJ3mRho92DCbDQ==" } ] }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" }, { "header": { "sequence": 3, - "previousBlockHash": "C20807C105DECEF8E8ECF33235B9C406EAE290100FA0FC8DE268FC2AB6C2C20C", + "previousBlockHash": "F19427C9EABD85986F9E05EBF94650A2B2F521D5EB2C823BA34131116B354068", "noteCommitment": { "type": "Buffer", - "data": "base64:EJs1QXWLqcB6fnfSdzGgA/I/bLgI/vLI/ruapyh+iQA=" + "data": "base64:9Op9uGBLD1o2MkX8RMj6MuHMaV5qqa/icUZI8dy1hBg=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:t+V8lQlgj73sqqR0x/3ER0H0zlF+DE6J4+RITS4DwIs=" + "data": "base64:NxZhFs/teLmrO2Or1Prxq8VQppqb0IeUSnL5HM1eSys=" }, "target": "880842937844725196442695540779332307793253899902937591585455087694081134", "randomness": "0", - "timestamp": 1674751031007, + "timestamp": 1676573491681, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 7, "work": "0" @@ -136,33 +138,33 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAozqOv9iTVioM32h+i/xe6cjEpgzlEwDp6HpKzh1tM0OVMEqwwU/ZZQr7ESFgVJBxoDuBiOqWhjXkrlIBiyxoBz3Wz1mcLhm4wKUXbzqBJgepLcHQAP/qrygUaPWfPNQvsafzPM2HqDnHNjJqvp3ZKM3Z+Ggd5GLv5k5EAoI646cVlDyCMJKtYn55U8rz3QPfngHWSin0/ckWpvU2nd7hGpK2xiIsA0u3WsK8bhddsrmPcpwHePDz4ETvLBjYpLDrwOlR0LHZ3376Jjoz/ANsdvnSRrpuYjGPflNng0zt9eRjWwiwbgLYHGg7KVmuQJIEP9OYO8/1BoVXZWbhzQqmhk86nwFAMe1waAjgYuHVnUgntzGlqty23eOR7+myKGMW9LOS5SrREbBwHknDlga30IMayiQtd+oB9TZcWmIW2WvOQcvIhnXhMM4S1BZbOcSXIxCXIOWXM8h2rFLPdJiOuvbs7B8/x/OHwHfZZJ1O45n7eHzW/A5CUJMtLgVW7ryyu/Y90sE2JwmymhTq64gs+ngA76Ia1+fBa3/rDdNLE+ift/v+w8m3r15FsSZ/d+f2lDOfQPrsD+2w30FoFboHapA8Q6qTivSwYrzqnglmBPl3tccpMpChmElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwn2ayPOJx533/NU0j0Lk3QFg63AZ1mviidFwEGW0rjNAVCkGfFJSL4t+P3Rrb3mwDzAPUzAjf0qMmxd3yvFeBAw==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAWUhEiHaFf7kRLVHpWyrJocqcbhPQMXvyCHvAfb7xLzW0mxbKRnokbnAQ5B2iY9MeSafVDEONbmCKyhx6TZ6G9sGLZzmZoZnPcwBY0NCSY16jkand6NVpFaqdHPaA/3RKL+E9hfNyraNR8PUo6mj1xdo+dtZKjXtSDh/KGpmP/UYGMd2C59tq0dzxlGZ/1BhyKBynfUKTnqJDg8yAFLTb7IQPANuY6E2syH19rM8pFuGFhN8/pdRrhzN3mCU3JZlkWbADIFMzQNDsrSgvtt09DWS0REeKbuzdN7O8b0dj1rZQyy1cosTuVuw/SUa8tc2sOUKTbCRF6QqKsdwDPz9YqBKIih2NSoYOgq6gaa+6l+c/WJ/5JW+Dq8olsfohhc5ZW816nf7xV+MJh38Zlux/AXkKIAu4fmwNoXljoWIW6wmIiMZrLGdCNI+uHUuQjo2TNacjlSBkWj8r8hW7+K7uOulBm8z5Oxbc3vF+LKJtcaWSOIMHgVxJjADjY+I15MaklnpPo4aOLhWA1lbuHaoDo78iiRrr+nOgVqVDG1c2TPEtPk02jy081xAjikDn7qWgEas4lQYuKxltF2wfnsryj1BWitepzVrB7iRKcxqljpemiJJ8cyBgvElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwQQtJA/Gu9OQ8owGM19UGNmvEv7lIzT6LnJDoc/R21ScON/ngomAeujpgWZAoJ/+EZTSDtUZ8Wj3nkPYWPcaQCw==" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" } ] }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" }, { "header": { "sequence": 4, - "previousBlockHash": "722C4264E8BDD03A848F53A1FC0278193072F2A2AE778B2D38E9A022D88A0D37", + "previousBlockHash": "FA93E3CDCF144643443211E4F9A6CB27FE87C2F4D92372E2CCEF3136AABCCD31", "noteCommitment": { "type": "Buffer", - "data": "base64:vZ+k59zf2h7B2bU9ttiqA9vAXuczgxyIhqXs4QP2Uhw=" + "data": "base64:RC8TgUP/4gJORh3py40Db83mRNkaahm3xQVCwwQHmlE=" }, "transactionCommitment": { "type": "Buffer", - "data": "base64:GPuEWPkq81S9cp44w5CVVT61HcYFt3cfUz9DsbewHqM=" + "data": "base64:Z7HKX6yQeMIvin23tVNXwiEjPohVOvKviS6p2ezJJio=" }, "target": "878277375889837647326843029495509009809390053592540685978895509768758568", "randomness": "0", - "timestamp": 1674751033944, + "timestamp": 1676573493595, "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", "noteSize": 10, "work": "0" @@ -170,23 +172,25 @@ "transactions": [ { "type": "Buffer", - "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAKZ6v1GvxtvUYG8gChjAh39xRlHFAgBYP9wBDz0776hmRfUf7W7w+N2toP7AlaPtdrLNnR6kCtuMPN6KdIe8VGlJ5TICp7vWYXQncf8j6pZSBi1jWYetfLlx0PYwe8K9m0jsEWosBZbi0V2xMxMK8kAZODIK5thPgUqr8fUWypF4RLe3BLHGhDcYMoqSxWPTyoXRo4NAS0L+QPT/cj4cG5JZB6FC6fvkJt9ObIa266FSv5Dg0ur4ex2ouKGv/ShZGuiS2iHKqOz9oIq5NE3HyW+IZvbXIbi9BLIJ1T+RjZtHpsOCt/KkZMOqP7R/KteVOJq1GrkxImFv/49ZsZFcMvSL9TTuLlSjzWhMdJjf0gfw5AsVV5v0cb0wjUOohEgQbaN731DuPHwGFdW83LT0m2ouYOBo84HpmZ+Ggbx2EoSN1KoPX6+UugNUpm98VNwzWmLW9RaZ79FUnWR1oiO2JMpc50Dx9iMSEqKuv2wGBfVInVpKxY2dJpyMKn4tSoOCM7OI7KBLwIemUWM0mY9vR3+nUITpipd+xKkaTHybNZPYuUI5+c4fm0HhL8daER9ALV2m7um+PS+f9BKQ06HEhgGEH2JVoUisGBUjhMGoxR+jkbH5BAzo3wElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwdz37esuOWydL3vtftNCM+lzaM1VZBJ41wJe+HPRCdWrRRTqTJE0vkjPczc3Q0/cdK60azowzjJiTJhauDcOHBg==" + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAsFMftG0Q9xHVMDjKSQjZR7LUKxDC2Jbcb8dOueO6KyOF4qUTnwjQJDfTnq3VmoVdQhWifB3W31v9Wtt0CIPKfOA3Wi5S4wE1C9NxWoGCpUu0oxp8XCxQUwgpkJFfyA0uX/bKtOCxw3f+mHyArCqd+tkTke+P5kc/8kPkTGiNM0MDNchA/bUBGAjxPOT61wuOXK0IJBr23lJ91G2sokfJX75kbx3GtyreH6npwWIXpU+NTPw6naKmHNKgvwZzAWH+PpX9mbJxgJ+gw1LCMO4F7EEm8zUnWLkcQpUkP1aLtnW+uVw2nGtwWGdppay/lRUa7HAEUbtaICiWiVha5ae3CS89bYfgFr+6f2S/gOaoClvIdgqh5tHL7ypQW+mvvPNNwpiWI0MSaCeP48MRgf4U2i9xDZInlnqZtjnO8HKJ2cGyn1QPPMo7LmGgdrV5vWduKVVFfiwsukqCy0SF+p9lWwcZyPPz4EasfnZLQM1972+HeAifGZqG78ML+F9TUI0hQUEqdI8CQfWt5NxU7ckkbJoV4yW4vTPa/oIvEIPZnR0nVPk/XsDQQCoyPPUd4HTjWHIzPxnLqO7BAtXXXbPLVQR/3dHwtA+cYTyleJ/9TXVZ/D9cYwu0xUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwx+dV5k/3emf+j8cMpLOXbipYGxrSh4vow6+DVe6P3jHDbFW2n193Zzdo1BQGhpAzzUaiOZIn1WmFPGtIaZOADA==" }, { "type": "Buffer", - "data": "base64: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" + "data": "base64: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" } ] } ], "RawTransactionSerde serializes and deserializes a block": [ { - "id": "9cda7b3b-823b-4526-91f7-22be6fa37e96", + "version": 1, + "id": "58624054-7b6d-4fef-b1e2-a16de6710d46", "name": "test", - "spendingKey": "f2a38b2c995c0593a1c6c9bda0fe81f9547eeb098318afae194d1c81b581e842", - "incomingViewKey": "efd6e971c50efe3fbca599c5fe0d68c230fb4bdef61ecbfaf12ebc2b8acc5500", - "outgoingViewKey": "10a82a4a9e865c8441230f7ba7df945a67e607bdd23cc84bf7df64e250a36f36", - "publicAddress": "8d44386695dfb09c3466331b57f2ed16cc1b0e86f60b09bc750c8b440ab7f43d" + "spendingKey": "818158ede7e66268aff435004fa70a11929dc496579aacb7fce141ff872f505d", + "viewKey": "49fa30864be7c61c0ce3342bf8026754d20642cdba70454dee75f654b9343894a4738ce69666d3baf1b3e5efff74dc572d72d42da78ad0ba74e3a6bb931f6a2b", + "incomingViewKey": "23dda43cd0df740c81d345e711ef4469a607d74dc27cebdfbd73e3b116573907", + "outgoingViewKey": "1c090b76aec80cfc6ff7db08e62e19693bc355d52f52ba1f62df33b21db40b9e", + "publicAddress": "9c3c0bf9736e3f8ece96d4b163b5b09c0e30257ca31690cb45fdb7f6de1b4cd0" } ] } \ No newline at end of file diff --git a/ironfish/src/wallet/account.ts b/ironfish/src/wallet/account.ts index 55a65754bf..e8a29a7961 100644 --- a/ironfish/src/wallet/account.ts +++ b/ironfish/src/wallet/account.ts @@ -33,6 +33,7 @@ export class Account { readonly displayName: string name: string readonly spendingKey: string + readonly viewKey: string readonly incomingViewKey: string readonly outgoingViewKey: string readonly version: number @@ -44,6 +45,7 @@ export class Account { id, name, spendingKey, + viewKey, incomingViewKey, outgoingViewKey, publicAddress, @@ -53,6 +55,7 @@ export class Account { id: string name: string spendingKey: string + viewKey: string incomingViewKey: string outgoingViewKey: string publicAddress: string @@ -62,6 +65,7 @@ export class Account { this.id = id this.name = name this.spendingKey = spendingKey + this.viewKey = viewKey this.incomingViewKey = incomingViewKey this.outgoingViewKey = outgoingViewKey this.publicAddress = publicAddress @@ -81,6 +85,7 @@ export class Account { id: this.id, name: this.name, spendingKey: this.spendingKey, + viewKey: this.viewKey, incomingViewKey: this.incomingViewKey, outgoingViewKey: this.outgoingViewKey, publicAddress: this.publicAddress, diff --git a/ironfish/src/wallet/wallet.ts b/ironfish/src/wallet/wallet.ts index eabf0f8765..15324bd5ae 100644 --- a/ironfish/src/wallet/wallet.ts +++ b/ironfish/src/wallet/wallet.ts @@ -1259,6 +1259,7 @@ export class Wallet { outgoingViewKey: key.outgoing_view_key, publicAddress: key.public_address, spendingKey: key.spending_key, + viewKey: key.view_key, walletDb: this.walletDb, }) @@ -1302,6 +1303,7 @@ export class Wallet { ...toImport, version: ACCOUNT_SCHEMA_VERSION, id: uuid(), + viewKey: key.view_key, incomingViewKey: key.incoming_view_key, outgoingViewKey: key.outgoing_view_key, publicAddress: key.public_address, diff --git a/ironfish/src/wallet/walletdb/accountValue.test.ts b/ironfish/src/wallet/walletdb/accountValue.test.ts index 52b71dce37..0b29afdaae 100644 --- a/ironfish/src/wallet/walletdb/accountValue.test.ts +++ b/ironfish/src/wallet/walletdb/accountValue.test.ts @@ -16,6 +16,7 @@ describe('AccountValueEncoding', () => { outgoingViewKey: key.outgoing_view_key, publicAddress: key.public_address, spendingKey: key.spending_key, + viewKey: key.view_key, version: 1, } const buffer = encoder.serialize(value) diff --git a/ironfish/src/wallet/walletdb/accountValue.ts b/ironfish/src/wallet/walletdb/accountValue.ts index 68d3c188b7..c90a4eea7c 100644 --- a/ironfish/src/wallet/walletdb/accountValue.ts +++ b/ironfish/src/wallet/walletdb/accountValue.ts @@ -6,6 +6,7 @@ import bufio from 'bufio' import { IDatabaseEncoding } from '../../storage' const KEY_LENGTH = 32 +const VIEW_KEY_LENGTH = 64 const VERSION_LENGTH = 2 export interface AccountValue { @@ -13,6 +14,7 @@ export interface AccountValue { id: string name: string spendingKey: string + viewKey: string incomingViewKey: string outgoingViewKey: string publicAddress: string @@ -25,10 +27,10 @@ export class AccountValueEncoding implements IDatabaseEncoding { bw.writeVarString(value.id, 'utf8') bw.writeVarString(value.name, 'utf8') bw.writeBytes(Buffer.from(value.spendingKey, 'hex')) + bw.writeBytes(Buffer.from(value.viewKey, 'hex')) bw.writeBytes(Buffer.from(value.incomingViewKey, 'hex')) bw.writeBytes(Buffer.from(value.outgoingViewKey, 'hex')) bw.writeBytes(Buffer.from(value.publicAddress, 'hex')) - return bw.render() } @@ -38,6 +40,7 @@ export class AccountValueEncoding implements IDatabaseEncoding { const id = reader.readVarString('utf8') const name = reader.readVarString('utf8') const spendingKey = reader.readBytes(KEY_LENGTH).toString('hex') + const viewKey = reader.readBytes(VIEW_KEY_LENGTH).toString('hex') const incomingViewKey = reader.readBytes(KEY_LENGTH).toString('hex') const outgoingViewKey = reader.readBytes(KEY_LENGTH).toString('hex') const publicAddress = reader.readBytes(PUBLIC_ADDRESS_LENGTH).toString('hex') @@ -47,6 +50,7 @@ export class AccountValueEncoding implements IDatabaseEncoding { id, name, spendingKey, + viewKey, incomingViewKey, outgoingViewKey, publicAddress, @@ -59,6 +63,7 @@ export class AccountValueEncoding implements IDatabaseEncoding { size += bufio.sizeVarString(value.id, 'utf8') size += bufio.sizeVarString(value.name, 'utf8') size += KEY_LENGTH + size += VIEW_KEY_LENGTH size += KEY_LENGTH size += KEY_LENGTH size += PUBLIC_ADDRESS_LENGTH diff --git a/ironfish/src/wallet/walletdb/walletdb.ts b/ironfish/src/wallet/walletdb/walletdb.ts index 96a37368f3..daec062ece 100644 --- a/ironfish/src/wallet/walletdb/walletdb.ts +++ b/ironfish/src/wallet/walletdb/walletdb.ts @@ -34,7 +34,7 @@ import { HeadValue, NullableHeadValueEncoding } from './headValue' import { AccountsDBMeta, MetaValue, MetaValueEncoding } from './metaValue' import { TransactionValue, TransactionValueEncoding } from './transactionValue' -export const VERSION_DATABASE_ACCOUNTS = 21 +const VERSION_DATABASE_ACCOUNTS = 22 const getAccountsDBMetaDefaults = (): AccountsDBMeta => ({ defaultAccountId: null, @@ -143,7 +143,7 @@ export class WalletDB { }) this.accounts = this.db.addStore({ - name: 'a' + VERSION_DATABASE_ACCOUNTS.toString(), + name: 'a', keyEncoding: new StringEncoding(), valueEncoding: new AccountValueEncoding(), }) From 44f0f8fd31da05ddb2062141e6a4d148fee9b420 Mon Sep 17 00:00:00 2001 From: Jason Spafford Date: Thu, 16 Feb 2023 19:59:46 -0500 Subject: [PATCH 30/43] Add mempool to wallet constructor (#3456) --- ironfish/src/node.ts | 23 ++++++++++--------- .../src/primitives/transaction.test.slow.ts | 2 +- ironfish/src/rpc/routes/wallet/burnAsset.ts | 1 - .../wallet/createTransaction.test.slow.ts | 2 +- .../src/rpc/routes/wallet/mintAsset.test.ts | 2 +- ironfish/src/rpc/routes/wallet/mintAsset.ts | 2 +- .../src/rpc/routes/wallet/postTransaction.ts | 18 ++++++--------- .../rpc/routes/wallet/sendTransaction.test.ts | 2 -- .../src/rpc/routes/wallet/sendTransaction.ts | 1 - ironfish/src/testUtilities/fixtures/blocks.ts | 4 ++-- ironfish/src/wallet/wallet.test.slow.ts | 16 +++---------- ironfish/src/wallet/wallet.test.ts | 6 ++--- ironfish/src/wallet/wallet.ts | 22 ++++++++---------- 13 files changed, 41 insertions(+), 60 deletions(-) diff --git a/ironfish/src/node.ts b/ironfish/src/node.ts index ec8e824b26..bcac1ad822 100644 --- a/ironfish/src/node.ts +++ b/ironfish/src/node.ts @@ -245,6 +245,17 @@ export class IronfishNode { config, }) + const feeEstimator = new FeeEstimator({ + maxBlockHistory: config.get('feeEstimatorMaxBlockHistory'), + percentiles: { + low: config.get('feeEstimatorPercentileLow'), + medium: config.get('feeEstimatorPercentileMedium'), + high: config.get('feeEstimatorPercentileHigh'), + }, + }) + + const memPool = new MemPool({ chain, feeEstimator, metrics, logger }) + const walletDB = new WalletDB({ location: config.walletDatabasePath, workerPool, @@ -254,21 +265,11 @@ export class IronfishNode { const wallet = new Wallet({ chain, config, + memPool, database: walletDB, workerPool, }) - const feeEstimator = new FeeEstimator({ - maxBlockHistory: config.get('feeEstimatorMaxBlockHistory'), - percentiles: { - low: config.get('feeEstimatorPercentileLow'), - medium: config.get('feeEstimatorPercentileMedium'), - high: config.get('feeEstimatorPercentileHigh'), - }, - }) - - const memPool = new MemPool({ chain, feeEstimator, metrics, logger }) - return new IronfishNode({ pkg, chain, diff --git a/ironfish/src/primitives/transaction.test.slow.ts b/ironfish/src/primitives/transaction.test.slow.ts index cad14514c2..9ea1677e78 100644 --- a/ironfish/src/primitives/transaction.test.slow.ts +++ b/ironfish/src/primitives/transaction.test.slow.ts @@ -107,7 +107,7 @@ describe('Accounts', () => { expiration: 0, }) - const transaction = await nodeA.wallet.post(raw, nodeA.memPool, accountA.spendingKey) + const transaction = await nodeA.wallet.post(raw, accountA.spendingKey) expect(transaction.isMinersFee()).toBe(false) }) diff --git a/ironfish/src/rpc/routes/wallet/burnAsset.ts b/ironfish/src/rpc/routes/wallet/burnAsset.ts index b087e3f65d..11d1372cea 100644 --- a/ironfish/src/rpc/routes/wallet/burnAsset.ts +++ b/ironfish/src/rpc/routes/wallet/burnAsset.ts @@ -59,7 +59,6 @@ router.register( Assert.isNotNull(asset) const transaction = await node.wallet.burn( - node.memPool, account, assetId, value, diff --git a/ironfish/src/rpc/routes/wallet/createTransaction.test.slow.ts b/ironfish/src/rpc/routes/wallet/createTransaction.test.slow.ts index 4dbb848a3d..9ca842b3f6 100644 --- a/ironfish/src/rpc/routes/wallet/createTransaction.test.slow.ts +++ b/ironfish/src/rpc/routes/wallet/createTransaction.test.slow.ts @@ -39,7 +39,7 @@ describe('Route wallet/createTransaction', () => { expiration: 0, }) - return routeTest.node.wallet.post(raw, routeTest.node.memPool, sender.spendingKey) + return routeTest.node.wallet.post(raw, sender.spendingKey) }, ) diff --git a/ironfish/src/rpc/routes/wallet/mintAsset.test.ts b/ironfish/src/rpc/routes/wallet/mintAsset.test.ts index 60f8c0fe3e..b045f6360f 100644 --- a/ironfish/src/rpc/routes/wallet/mintAsset.test.ts +++ b/ironfish/src/rpc/routes/wallet/mintAsset.test.ts @@ -62,7 +62,7 @@ describe('mint', () => { fee: 0n, expiration: 0, }) - return wallet.post(raw, node.memPool, account.spendingKey) + return wallet.post(raw, account.spendingKey) }) jest.spyOn(wallet, 'mint').mockResolvedValueOnce(mintTransaction) diff --git a/ironfish/src/rpc/routes/wallet/mintAsset.ts b/ironfish/src/rpc/routes/wallet/mintAsset.ts index 0cc038164c..93e7cb58b1 100644 --- a/ironfish/src/rpc/routes/wallet/mintAsset.ts +++ b/ironfish/src/rpc/routes/wallet/mintAsset.ts @@ -88,7 +88,7 @@ router.register( } } - const transaction = await node.wallet.mint(node.memPool, account, options) + const transaction = await node.wallet.mint(account, options) Assert.isEqual(transaction.mints.length, 1) const mint = transaction.mints[0] diff --git a/ironfish/src/rpc/routes/wallet/postTransaction.ts b/ironfish/src/rpc/routes/wallet/postTransaction.ts index 2e592c691d..cf22dbe040 100644 --- a/ironfish/src/rpc/routes/wallet/postTransaction.ts +++ b/ironfish/src/rpc/routes/wallet/postTransaction.ts @@ -37,21 +37,17 @@ router.register( async (request, node): Promise => { const account = getAccount(node, request.data.account) - const rawTransactionBytes = Buffer.from(request.data.transaction, 'hex') - const rawTransaction = RawTransactionSerde.deserialize(rawTransactionBytes) + const bytes = Buffer.from(request.data.transaction, 'hex') + const raw = RawTransactionSerde.deserialize(bytes) + let postedTransaction: Transaction if (request.data.offline === true) { - postedTransaction = await node.wallet.postTransaction(rawTransaction, account.spendingKey) + postedTransaction = await node.wallet.postTransaction(raw, account.spendingKey) } else { - postedTransaction = await node.wallet.post( - rawTransaction, - node.memPool, - account.spendingKey, - ) + postedTransaction = await node.wallet.post(raw, account.spendingKey) } - const postedTransactionBytes = postedTransaction.serialize() - - request.end({ transaction: postedTransactionBytes.toString('hex') }) + const serialized = postedTransaction.serialize() + request.end({ transaction: serialized.toString('hex') }) }, ) diff --git a/ironfish/src/rpc/routes/wallet/sendTransaction.test.ts b/ironfish/src/rpc/routes/wallet/sendTransaction.test.ts index 1aa5ef02e1..19514791f5 100644 --- a/ironfish/src/rpc/routes/wallet/sendTransaction.test.ts +++ b/ironfish/src/rpc/routes/wallet/sendTransaction.test.ts @@ -239,7 +239,6 @@ describe('Transactions sendTransaction', () => { expect.anything(), expect.anything(), expect.anything(), - expect.anything(), routeTest.node.config.get('transactionExpirationDelta'), undefined, undefined, @@ -256,7 +255,6 @@ describe('Transactions sendTransaction', () => { expect.anything(), expect.anything(), expect.anything(), - expect.anything(), 12345, 1234, 10, diff --git a/ironfish/src/rpc/routes/wallet/sendTransaction.ts b/ironfish/src/rpc/routes/wallet/sendTransaction.ts index 7c2f406981..60639d1e14 100644 --- a/ironfish/src/rpc/routes/wallet/sendTransaction.ts +++ b/ironfish/src/rpc/routes/wallet/sendTransaction.ts @@ -110,7 +110,6 @@ router.register( try { const transaction = await node.wallet.send( - node.memPool, account, outputs, fee, diff --git a/ironfish/src/testUtilities/fixtures/blocks.ts b/ironfish/src/testUtilities/fixtures/blocks.ts index 0968f2248d..f835c31682 100644 --- a/ironfish/src/testUtilities/fixtures/blocks.ts +++ b/ironfish/src/testUtilities/fixtures/blocks.ts @@ -254,7 +254,7 @@ export async function useBlockWithTx( expirationDelta: 0, }) - const transaction = await node.wallet.post(raw, node.memPool, from.spendingKey) + const transaction = await node.wallet.post(raw, from.spendingKey) return node.chain.newBlock( [transaction], @@ -310,7 +310,7 @@ export async function useBlockWithTxs( expirationDelta: 0, }) - const transaction = await node.wallet.post(raw, node.memPool, from.spendingKey) + const transaction = await node.wallet.post(raw, from.spendingKey) await node.wallet.addPendingTransaction(transaction) transactions.push(transaction) diff --git a/ironfish/src/wallet/wallet.test.slow.ts b/ironfish/src/wallet/wallet.test.slow.ts index f510af57af..c8847a3527 100644 --- a/ironfish/src/wallet/wallet.test.slow.ts +++ b/ironfish/src/wallet/wallet.test.slow.ts @@ -106,7 +106,6 @@ describe('Accounts', () => { // Spend the balance const transaction = await node.wallet.send( - node.memPool, account, [ { @@ -175,7 +174,6 @@ describe('Accounts', () => { // Spend the balance const transaction = await node.wallet.send( - node.memPool, account, [ { @@ -246,7 +244,6 @@ describe('Accounts', () => { }) const transaction = await node.wallet.send( - node.memPool, account, [ { @@ -301,7 +298,6 @@ describe('Accounts', () => { // Spend the balance with an invalid expiration await expect( node.wallet.send( - node.memPool, account, [ { @@ -357,7 +353,6 @@ describe('Accounts', () => { // Spend the balance, setting expiry soon const transaction = await node.wallet.send( - node.memPool, account, [ { @@ -444,7 +439,6 @@ describe('Accounts', () => { // Spend the balance, setting expiry soon const transaction = await node.wallet.send( - node.memPool, account, [ { @@ -520,7 +514,7 @@ describe('Accounts', () => { expiration: 0, }) - const transaction = await nodeA.wallet.post(raw, nodeA.memPool, accountA.spendingKey) + const transaction = await nodeA.wallet.post(raw, accountA.spendingKey) // Create block 2 return nodeA.chain.newBlock( @@ -660,7 +654,7 @@ describe('Accounts', () => { expiration: 0, }) - const transaction = await nodeA.wallet.post(raw, nodeA.memPool, accountA.spendingKey) + const transaction = await nodeA.wallet.post(raw, accountA.spendingKey) // Create block A2 return nodeA.chain.newBlock( @@ -770,11 +764,7 @@ describe('Accounts', () => { expiration: 0, }) - const transaction = await nodeB.wallet.post( - raw, - nodeB.memPool, - accountANodeB.spendingKey, - ) + const transaction = await nodeB.wallet.post(raw, accountANodeB.spendingKey) // Create block A2 return nodeA.chain.newBlock( diff --git a/ironfish/src/wallet/wallet.test.ts b/ironfish/src/wallet/wallet.test.ts index ad8001cf2a..028465d3a1 100644 --- a/ironfish/src/wallet/wallet.test.ts +++ b/ironfish/src/wallet/wallet.test.ts @@ -1019,7 +1019,7 @@ describe('Accounts', () => { const assetId = Buffer.from('thisisafakeidentifier', 'hex') await expect( - node.wallet.mint(node.memPool, account, { + node.wallet.mint(account, { assetId, fee: BigInt(0), expirationDelta: node.config.get('transactionExpirationDelta'), @@ -1055,7 +1055,7 @@ describe('Accounts', () => { const mintValueB = BigInt(10) const transaction = await useTxFixture(node.wallet, account, account, () => { - return node.wallet.mint(node.memPool, account, { + return node.wallet.mint(account, { assetId: asset.id(), fee: BigInt(0), expirationDelta: node.config.get('transactionExpirationDelta'), @@ -1223,7 +1223,7 @@ describe('Accounts', () => { expiration: 0, }) - const transaction = await node.wallet.post(raw, node.memPool, account.spendingKey) + const transaction = await node.wallet.post(raw, account.spendingKey) return node.chain.newBlock( [transaction], diff --git a/ironfish/src/wallet/wallet.ts b/ironfish/src/wallet/wallet.ts index 15324bd5ae..dd8cd8bce4 100644 --- a/ironfish/src/wallet/wallet.ts +++ b/ironfish/src/wallet/wallet.ts @@ -85,6 +85,7 @@ export class Wallet { readonly workerPool: WorkerPool readonly chain: Blockchain readonly chainProcessor: ChainProcessor + readonly memPool: MemPool private readonly config: Config protected rebroadcastAfter: number @@ -100,6 +101,7 @@ export class Wallet { constructor({ chain, config, + memPool, database, logger = createRootLogger(), rebroadcastAfter, @@ -108,6 +110,7 @@ export class Wallet { chain: Blockchain config: Config database: WalletDB + memPool: MemPool logger?: Logger rebroadcastAfter?: number workerPool: WorkerPool @@ -115,6 +118,7 @@ export class Wallet { this.chain = chain this.config = config this.logger = logger.withTag('accounts') + this.memPool = memPool this.walletDb = database this.workerPool = workerPool this.rebroadcastAfter = rebroadcastAfter ?? 10 @@ -667,7 +671,6 @@ export class Wallet { } async send( - memPool: MemPool, account: Account, outputs: { publicAddress: string @@ -689,14 +692,10 @@ export class Wallet { confirmations: confirmations ?? undefined, }) - return this.post(raw, memPool, account.spendingKey) + return this.post(raw, account.spendingKey) } - async mint( - memPool: MemPool, - account: Account, - options: MintAssetOptions, - ): Promise { + async mint(account: Account, options: MintAssetOptions): Promise { let mintData: MintData if ('assetId' in options) { @@ -729,11 +728,10 @@ export class Wallet { confirmations: options.confirmations, }) - return this.post(raw, memPool, account.spendingKey) + return this.post(raw, account.spendingKey) } async burn( - memPool: MemPool, account: Account, assetId: Buffer, value: bigint, @@ -751,7 +749,7 @@ export class Wallet { confirmations, }) - return this.post(raw, memPool, account.spendingKey) + return this.post(raw, account.spendingKey) } async createTransaction(options: { @@ -857,7 +855,7 @@ export class Wallet { } } - async post(raw: RawTransaction, memPool: MemPool, spendingKey: string): Promise { + async post(raw: RawTransaction, spendingKey: string): Promise { const transaction = await this.postTransaction(raw, spendingKey) const verify = this.chain.verifier.verifyCreatedTransaction(transaction) @@ -866,7 +864,7 @@ export class Wallet { } await this.addPendingTransaction(transaction) - memPool.acceptTransaction(transaction) + this.memPool.acceptTransaction(transaction) this.broadcastTransaction(transaction) this.onTransactionCreated.emit(transaction) From bcbb47b0f44e98f725617a73c3cbb251113582f6 Mon Sep 17 00:00:00 2001 From: mat-if <97762857+mat-if@users.noreply.github.com> Date: Thu, 16 Feb 2023 18:07:07 -0700 Subject: [PATCH 31/43] refactor: remove unused blockchain util fn (#3454) `isBlockMine` was a wrapper around a test utilitiy function. It doesn't seem like a great idea to expose test utility functions as "normal" code path functions. Given that, and that the function was unused, removing it seems like a decent option. --- ironfish/src/utils/blockchain.ts | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/ironfish/src/utils/blockchain.ts b/ironfish/src/utils/blockchain.ts index 9bb3358db0..58d3f39ed8 100644 --- a/ironfish/src/utils/blockchain.ts +++ b/ironfish/src/utils/blockchain.ts @@ -3,10 +3,8 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import { Blockchain } from '../blockchain' -import { Block, BlockHeader } from '../primitives' +import { BlockHeader } from '../primitives' import { GENESIS_BLOCK_SEQUENCE } from '../primitives/block' -import { isTransactionMine } from '../testUtilities/helpers/transaction' -import { Account } from '../wallet' export function getBlockRange( chain: Blockchain, @@ -40,10 +38,6 @@ export function getBlockRange( return { start, stop } } -export function isBlockMine(block: Block, account: Account): boolean { - return isTransactionMine(block.minersFee, account) -} - // Returns the block header at the given sequence or hash async function blockHeaderBySequenceOrHash( chain: Blockchain, @@ -56,4 +50,4 @@ async function blockHeaderBySequenceOrHash( return await chain.getHeaderAtSequence(start) } -export const BlockchainUtils = { isBlockMine, getBlockRange, blockHeaderBySequenceOrHash } +export const BlockchainUtils = { getBlockRange, blockHeaderBySequenceOrHash } From fb0385ca084de63ed563115485861bcee8ae20e2 Mon Sep 17 00:00:00 2001 From: jowparks Date: Thu, 16 Feb 2023 17:10:37 -0800 Subject: [PATCH 32/43] feat: verify nullifier with view key instead of spend key (#3455) --- ironfish-rust-nodejs/index.d.ts | 2 +- ironfish-rust-nodejs/src/structs/note.rs | 9 ++++---- ironfish-rust-nodejs/tests/demo.test.slow.ts | 2 +- ironfish/src/primitives/note.ts | 4 ++-- ironfish/src/wallet/wallet.ts | 2 +- ironfish/src/wallet/walletdb/accountValue.ts | 2 +- .../src/workerPool/tasks/decryptNotes.test.ts | 9 ++++---- ironfish/src/workerPool/tasks/decryptNotes.ts | 21 ++++++++----------- 8 files changed, 25 insertions(+), 26 deletions(-) diff --git a/ironfish-rust-nodejs/index.d.ts b/ironfish-rust-nodejs/index.d.ts index 7ef2b9ee96..e77ef70cc8 100644 --- a/ironfish-rust-nodejs/index.d.ts +++ b/ironfish-rust-nodejs/index.d.ts @@ -139,7 +139,7 @@ export class Note { * only at the time the note is spent. This key is collected in a massive * 'nullifier set', preventing double-spend. */ - nullifier(ownerPrivateKey: string, position: bigint): Buffer + nullifier(ownerViewKey: string, position: bigint): Buffer } export type NativeTransactionPosted = TransactionPosted export class TransactionPosted { diff --git a/ironfish-rust-nodejs/src/structs/note.rs b/ironfish-rust-nodejs/src/structs/note.rs index cd974395e2..275609b53f 100644 --- a/ironfish-rust-nodejs/src/structs/note.rs +++ b/ironfish-rust-nodejs/src/structs/note.rs @@ -5,11 +5,12 @@ use ironfish_rust::{ assets::asset::{asset_generator_from_id, ID_LENGTH as ASSET_ID_LENGTH}, note::{AMOUNT_VALUE_SIZE, GENERATOR_SIZE, MEMO_SIZE, SCALAR_SIZE}, + ViewKey, }; use napi::{bindgen_prelude::*, JsBuffer}; use napi_derive::napi; -use ironfish_rust::{Note, SaplingKey}; +use ironfish_rust::Note; use ironfish_rust::keys::PUBLIC_ADDRESS_SIZE; @@ -145,12 +146,12 @@ impl NativeNote { /// only at the time the note is spent. This key is collected in a massive /// 'nullifier set', preventing double-spend. #[napi] - pub fn nullifier(&self, owner_private_key: String, position: BigInt) -> Result { + pub fn nullifier(&self, owner_view_key: String, position: BigInt) -> Result { let position_u64 = position.get_u64().1; - let private_key = SaplingKey::from_hex(&owner_private_key).map_err(to_napi_err)?; + let view_key = ViewKey::from_hex(&owner_view_key).map_err(to_napi_err)?; - let nullifier: &[u8] = &self.note.nullifier(private_key.view_key(), position_u64).0; + let nullifier: &[u8] = &self.note.nullifier(&view_key, position_u64).0; Ok(Buffer::from(nullifier)) } diff --git a/ironfish-rust-nodejs/tests/demo.test.slow.ts b/ironfish-rust-nodejs/tests/demo.test.slow.ts index 9ebc128edd..671e953ab9 100644 --- a/ironfish-rust-nodejs/tests/demo.test.slow.ts +++ b/ironfish-rust-nodejs/tests/demo.test.slow.ts @@ -88,7 +88,7 @@ describe('Demonstrate the Sapling API', () => { // Null characters are included in the memo string expect(decryptedNote.memo().replace(/\0/g, '')).toEqual('test') expect(decryptedNote.value()).toEqual(BigInt(20)) - expect(decryptedNote.nullifier(key.spending_key, BigInt(0)).byteLength).toBeGreaterThan(BigInt(0)) + expect(decryptedNote.nullifier(key.view_key, BigInt(0)).byteLength).toBeGreaterThan(BigInt(0)) }) it(`Should create a standard transaction`, () => { diff --git a/ironfish/src/primitives/note.ts b/ironfish/src/primitives/note.ts index 86dfeec86d..7701f9238c 100644 --- a/ironfish/src/primitives/note.ts +++ b/ironfish/src/primitives/note.ts @@ -89,8 +89,8 @@ export class Note { return this._assetId } - nullifier(ownerPrivateKey: string, position: bigint): Buffer { - const buf = this.takeReference().nullifier(ownerPrivateKey, position) + nullifier(ownerViewKey: string, position: bigint): Buffer { + const buf = this.takeReference().nullifier(ownerViewKey, position) this.returnReference() return buf } diff --git a/ironfish/src/wallet/wallet.ts b/ironfish/src/wallet/wallet.ts index dd8cd8bce4..40dab143a7 100644 --- a/ironfish/src/wallet/wallet.ts +++ b/ironfish/src/wallet/wallet.ts @@ -330,7 +330,7 @@ export class Wallet { serializedNote: note.serialize(), incomingViewKey: account.incomingViewKey, outgoingViewKey: account.outgoingViewKey, - spendingKey: account.spendingKey, + viewKey: account.viewKey, currentNoteIndex, decryptForSpender, }) diff --git a/ironfish/src/wallet/walletdb/accountValue.ts b/ironfish/src/wallet/walletdb/accountValue.ts index c90a4eea7c..dd3be6c9c0 100644 --- a/ironfish/src/wallet/walletdb/accountValue.ts +++ b/ironfish/src/wallet/walletdb/accountValue.ts @@ -6,7 +6,7 @@ import bufio from 'bufio' import { IDatabaseEncoding } from '../../storage' const KEY_LENGTH = 32 -const VIEW_KEY_LENGTH = 64 +export const VIEW_KEY_LENGTH = 64 const VERSION_LENGTH = 2 export interface AccountValue { diff --git a/ironfish/src/workerPool/tasks/decryptNotes.test.ts b/ironfish/src/workerPool/tasks/decryptNotes.test.ts index beb8c3165b..7c94ced4bf 100644 --- a/ironfish/src/workerPool/tasks/decryptNotes.test.ts +++ b/ironfish/src/workerPool/tasks/decryptNotes.test.ts @@ -10,6 +10,7 @@ import { useTxFixture, } from '../../testUtilities' import { ACCOUNT_KEY_LENGTH } from '../../wallet' +import { VIEW_KEY_LENGTH } from '../../wallet/walletdb/accountValue' import { DecryptNotesRequest, DecryptNotesResponse, DecryptNotesTask } from './decryptNotes' describe('DecryptNotesRequest', () => { @@ -20,7 +21,7 @@ describe('DecryptNotesRequest', () => { serializedNote: Buffer.alloc(ENCRYPTED_NOTE_LENGTH, 1), incomingViewKey: Buffer.alloc(ACCOUNT_KEY_LENGTH, 1).toString('hex'), outgoingViewKey: Buffer.alloc(ACCOUNT_KEY_LENGTH, 1).toString('hex'), - spendingKey: Buffer.alloc(ACCOUNT_KEY_LENGTH, 1).toString('hex'), + viewKey: Buffer.alloc(VIEW_KEY_LENGTH, 1).toString('hex'), currentNoteIndex: 2, decryptForSpender: true, }, @@ -69,7 +70,7 @@ describe('DecryptNotesTask', () => { serializedNote: transaction.getNote(0).serialize(), incomingViewKey: account.incomingViewKey, outgoingViewKey: account.outgoingViewKey, - spendingKey: account.spendingKey, + viewKey: account.viewKey, currentNoteIndex: 2, decryptForSpender: true, }, @@ -106,7 +107,7 @@ describe('DecryptNotesTask', () => { serializedNote: transaction.getNote(0).serialize(), incomingViewKey: accountA.incomingViewKey, outgoingViewKey: accountA.outgoingViewKey, - spendingKey: accountA.spendingKey, + viewKey: accountA.viewKey, currentNoteIndex: 3, decryptForSpender: true, }, @@ -130,7 +131,7 @@ describe('DecryptNotesTask', () => { serializedNote: transaction.getNote(0).serialize(), incomingViewKey: accountA.incomingViewKey, outgoingViewKey: accountA.outgoingViewKey, - spendingKey: accountA.spendingKey, + viewKey: accountA.viewKey, currentNoteIndex: 3, decryptForSpender: false, }, diff --git a/ironfish/src/workerPool/tasks/decryptNotes.ts b/ironfish/src/workerPool/tasks/decryptNotes.ts index f248109284..a0ad1e3a9e 100644 --- a/ironfish/src/workerPool/tasks/decryptNotes.ts +++ b/ironfish/src/workerPool/tasks/decryptNotes.ts @@ -5,6 +5,7 @@ import { DECRYPTED_NOTE_LENGTH, ENCRYPTED_NOTE_LENGTH } from '@ironfish/rust-nod import bufio from 'bufio' import { NoteEncrypted } from '../../primitives/noteEncrypted' import { ACCOUNT_KEY_LENGTH } from '../../wallet' +import { VIEW_KEY_LENGTH } from '../../wallet/walletdb/accountValue' import { WorkerMessage, WorkerMessageType } from './workerMessage' import { WorkerTask } from './workerTask' @@ -12,7 +13,7 @@ export interface DecryptNoteOptions { serializedNote: Buffer incomingViewKey: string outgoingViewKey: string - spendingKey: string + viewKey: string currentNoteIndex: number | null decryptForSpender: boolean } @@ -46,7 +47,7 @@ export class DecryptNotesRequest extends WorkerMessage { bw.writeBytes(payload.serializedNote) bw.writeBytes(Buffer.from(payload.incomingViewKey, 'hex')) bw.writeBytes(Buffer.from(payload.outgoingViewKey, 'hex')) - bw.writeBytes(Buffer.from(payload.spendingKey, 'hex')) + bw.writeBytes(Buffer.from(payload.viewKey, 'hex')) if (payload.currentNoteIndex) { bw.writeU32(payload.currentNoteIndex) @@ -68,20 +69,16 @@ export class DecryptNotesRequest extends WorkerMessage { const serializedNote = reader.readBytes(ENCRYPTED_NOTE_LENGTH) const incomingViewKey = reader.readBytes(ACCOUNT_KEY_LENGTH).toString('hex') const outgoingViewKey = reader.readBytes(ACCOUNT_KEY_LENGTH).toString('hex') - const spendingKey = reader.readBytes(ACCOUNT_KEY_LENGTH).toString('hex') - - let currentNoteIndex = null - if (hasCurrentNoteIndex) { - currentNoteIndex = reader.readU32() - } + const viewKey = reader.readBytes(VIEW_KEY_LENGTH).toString('hex') + const currentNoteIndex = hasCurrentNoteIndex ? reader.readU32() : null payloads.push({ serializedNote, incomingViewKey, outgoingViewKey, - spendingKey, currentNoteIndex, decryptForSpender, + viewKey, }) } @@ -95,7 +92,7 @@ export class DecryptNotesRequest extends WorkerMessage { size += ENCRYPTED_NOTE_LENGTH size += ACCOUNT_KEY_LENGTH size += ACCOUNT_KEY_LENGTH - size += +ACCOUNT_KEY_LENGTH + size += VIEW_KEY_LENGTH if (payload.currentNoteIndex) { size += 4 } @@ -223,7 +220,7 @@ export class DecryptNotesTask extends WorkerTask { serializedNote, incomingViewKey, outgoingViewKey, - spendingKey, + viewKey, currentNoteIndex, decryptForSpender, } of payloads) { @@ -238,7 +235,7 @@ export class DecryptNotesTask extends WorkerTask { hash: note.hash(), nullifier: currentNoteIndex !== null - ? receivedNote.nullifier(spendingKey, BigInt(currentNoteIndex)) + ? receivedNote.nullifier(viewKey, BigInt(currentNoteIndex)) : null, serializedNote: receivedNote.serialize(), }) From 7e853304fd2832322cbb7dbd7378fa46edabdb7e Mon Sep 17 00:00:00 2001 From: Jason Spafford Date: Fri, 17 Feb 2023 11:31:54 -0500 Subject: [PATCH 33/43] Convert wallet.post() to use options (#3460) I'm going to add more options to this --- .../src/primitives/transaction.test.slow.ts | 5 +++- .../wallet/createTransaction.test.slow.ts | 5 +++- .../src/rpc/routes/wallet/mintAsset.test.ts | 5 +++- .../src/rpc/routes/wallet/postTransaction.ts | 5 +++- ironfish/src/testUtilities/fixtures/blocks.ts | 10 +++++-- ironfish/src/wallet/wallet.test.slow.ts | 15 ++++++++--- ironfish/src/wallet/wallet.test.ts | 5 +++- ironfish/src/wallet/wallet.ts | 26 +++++++++++++++---- 8 files changed, 61 insertions(+), 15 deletions(-) diff --git a/ironfish/src/primitives/transaction.test.slow.ts b/ironfish/src/primitives/transaction.test.slow.ts index 9ea1677e78..65c7434d37 100644 --- a/ironfish/src/primitives/transaction.test.slow.ts +++ b/ironfish/src/primitives/transaction.test.slow.ts @@ -107,7 +107,10 @@ describe('Accounts', () => { expiration: 0, }) - const transaction = await nodeA.wallet.post(raw, accountA.spendingKey) + const transaction = await nodeA.wallet.post({ + transaction: raw, + account: accountA, + }) expect(transaction.isMinersFee()).toBe(false) }) diff --git a/ironfish/src/rpc/routes/wallet/createTransaction.test.slow.ts b/ironfish/src/rpc/routes/wallet/createTransaction.test.slow.ts index 9ca842b3f6..174d6a81a7 100644 --- a/ironfish/src/rpc/routes/wallet/createTransaction.test.slow.ts +++ b/ironfish/src/rpc/routes/wallet/createTransaction.test.slow.ts @@ -39,7 +39,10 @@ describe('Route wallet/createTransaction', () => { expiration: 0, }) - return routeTest.node.wallet.post(raw, sender.spendingKey) + return routeTest.node.wallet.post({ + transaction: raw, + account: sender, + }) }, ) diff --git a/ironfish/src/rpc/routes/wallet/mintAsset.test.ts b/ironfish/src/rpc/routes/wallet/mintAsset.test.ts index b045f6360f..41fdeaf77a 100644 --- a/ironfish/src/rpc/routes/wallet/mintAsset.test.ts +++ b/ironfish/src/rpc/routes/wallet/mintAsset.test.ts @@ -62,7 +62,10 @@ describe('mint', () => { fee: 0n, expiration: 0, }) - return wallet.post(raw, account.spendingKey) + return wallet.post({ + transaction: raw, + account, + }) }) jest.spyOn(wallet, 'mint').mockResolvedValueOnce(mintTransaction) diff --git a/ironfish/src/rpc/routes/wallet/postTransaction.ts b/ironfish/src/rpc/routes/wallet/postTransaction.ts index cf22dbe040..aca362dcb4 100644 --- a/ironfish/src/rpc/routes/wallet/postTransaction.ts +++ b/ironfish/src/rpc/routes/wallet/postTransaction.ts @@ -44,7 +44,10 @@ router.register( if (request.data.offline === true) { postedTransaction = await node.wallet.postTransaction(raw, account.spendingKey) } else { - postedTransaction = await node.wallet.post(raw, account.spendingKey) + postedTransaction = await node.wallet.post({ + transaction: raw, + account, + }) } const serialized = postedTransaction.serialize() diff --git a/ironfish/src/testUtilities/fixtures/blocks.ts b/ironfish/src/testUtilities/fixtures/blocks.ts index f835c31682..cf0b2f0ed9 100644 --- a/ironfish/src/testUtilities/fixtures/blocks.ts +++ b/ironfish/src/testUtilities/fixtures/blocks.ts @@ -254,7 +254,10 @@ export async function useBlockWithTx( expirationDelta: 0, }) - const transaction = await node.wallet.post(raw, from.spendingKey) + const transaction = await node.wallet.post({ + transaction: raw, + account: from, + }) return node.chain.newBlock( [transaction], @@ -310,7 +313,10 @@ export async function useBlockWithTxs( expirationDelta: 0, }) - const transaction = await node.wallet.post(raw, from.spendingKey) + const transaction = await node.wallet.post({ + transaction: raw, + account: from, + }) await node.wallet.addPendingTransaction(transaction) transactions.push(transaction) diff --git a/ironfish/src/wallet/wallet.test.slow.ts b/ironfish/src/wallet/wallet.test.slow.ts index c8847a3527..215efa6156 100644 --- a/ironfish/src/wallet/wallet.test.slow.ts +++ b/ironfish/src/wallet/wallet.test.slow.ts @@ -514,7 +514,10 @@ describe('Accounts', () => { expiration: 0, }) - const transaction = await nodeA.wallet.post(raw, accountA.spendingKey) + const transaction = await nodeA.wallet.post({ + transaction: raw, + account: accountA, + }) // Create block 2 return nodeA.chain.newBlock( @@ -654,7 +657,10 @@ describe('Accounts', () => { expiration: 0, }) - const transaction = await nodeA.wallet.post(raw, accountA.spendingKey) + const transaction = await nodeA.wallet.post({ + transaction: raw, + account: accountA, + }) // Create block A2 return nodeA.chain.newBlock( @@ -764,7 +770,10 @@ describe('Accounts', () => { expiration: 0, }) - const transaction = await nodeB.wallet.post(raw, accountANodeB.spendingKey) + const transaction = await nodeB.wallet.post({ + transaction: raw, + account: accountANodeB, + }) // Create block A2 return nodeA.chain.newBlock( diff --git a/ironfish/src/wallet/wallet.test.ts b/ironfish/src/wallet/wallet.test.ts index 028465d3a1..f640917d5d 100644 --- a/ironfish/src/wallet/wallet.test.ts +++ b/ironfish/src/wallet/wallet.test.ts @@ -1223,7 +1223,10 @@ describe('Accounts', () => { expiration: 0, }) - const transaction = await node.wallet.post(raw, account.spendingKey) + const transaction = await node.wallet.post({ + transaction: raw, + account, + }) return node.chain.newBlock( [transaction], diff --git a/ironfish/src/wallet/wallet.ts b/ironfish/src/wallet/wallet.ts index 40dab143a7..71757422dc 100644 --- a/ironfish/src/wallet/wallet.ts +++ b/ironfish/src/wallet/wallet.ts @@ -692,7 +692,10 @@ export class Wallet { confirmations: confirmations ?? undefined, }) - return this.post(raw, account.spendingKey) + return this.post({ + transaction: raw, + account, + }) } async mint(account: Account, options: MintAssetOptions): Promise { @@ -728,7 +731,10 @@ export class Wallet { confirmations: options.confirmations, }) - return this.post(raw, account.spendingKey) + return this.post({ + transaction: raw, + account, + }) } async burn( @@ -749,7 +755,10 @@ export class Wallet { confirmations, }) - return this.post(raw, account.spendingKey) + return this.post({ + transaction: raw, + account, + }) } async createTransaction(options: { @@ -855,8 +864,15 @@ export class Wallet { } } - async post(raw: RawTransaction, spendingKey: string): Promise { - const transaction = await this.postTransaction(raw, spendingKey) + async post(options: { + transaction: RawTransaction + spendingKey?: string + account?: Account + }): Promise { + const spendingKey = options.account?.spendingKey ?? options.spendingKey + Assert.isTruthy(spendingKey, `Spending key is required to post transaction`) + + const transaction = await this.postTransaction(options.transaction, spendingKey) const verify = this.chain.verifier.verifyCreatedTransaction(transaction) if (!verify.valid) { From 4d0d463cf5e9ad543af5fd978ffa18cd43879159 Mon Sep 17 00:00:00 2001 From: Jason Spafford Date: Fri, 17 Feb 2023 11:32:05 -0500 Subject: [PATCH 34/43] Add config:unset command (#3457) * Add config:unset command This new command will unset a config variable * Added test * Rename command --- ironfish-cli/src/commands/config/unset.ts | 39 +++++++++++++++++++ ironfish/src/fileStores/keyStore.ts | 16 ++++++++ ironfish/src/rpc/clients/client.ts | 10 +++++ ironfish/src/rpc/routes/config/index.ts | 1 + .../src/rpc/routes/config/unsetConfig.test.ts | 26 +++++++++++++ ironfish/src/rpc/routes/config/unsetConfig.ts | 29 ++++++++++++++ .../src/rpc/routes/config/uploadConfig.ts | 7 +++- 7 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 ironfish-cli/src/commands/config/unset.ts create mode 100644 ironfish/src/rpc/routes/config/unsetConfig.test.ts create mode 100644 ironfish/src/rpc/routes/config/unsetConfig.ts diff --git a/ironfish-cli/src/commands/config/unset.ts b/ironfish-cli/src/commands/config/unset.ts new file mode 100644 index 0000000000..0a9d4f712e --- /dev/null +++ b/ironfish-cli/src/commands/config/unset.ts @@ -0,0 +1,39 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +import { Flags } from '@oclif/core' +import { IronfishCommand } from '../../command' +import { RemoteFlags } from '../../flags' + +export class UnsetCommand extends IronfishCommand { + static description = `Unset a value in the config and fall back to default` + + static args = [ + { + name: 'name', + parse: (input: string): Promise => Promise.resolve(input.trim()), + required: true, + description: 'Name of the config item', + }, + ] + + static flags = { + ...RemoteFlags, + local: Flags.boolean({ + default: false, + description: 'Dont connect to the node when updating the config', + }), + } + + static examples = ['$ ironfish config:unset blockGraffiti'] + + async start(): Promise { + const { args, flags } = await this.parse(UnsetCommand) + const name = args.name as string + + const client = await this.sdk.connectRpc(flags.local) + await client.unsetConfig({ name }) + + this.exit(0) + } +} diff --git a/ironfish/src/fileStores/keyStore.ts b/ironfish/src/fileStores/keyStore.ts index 73c8a8b0b5..2c91f0169e 100644 --- a/ironfish/src/fileStores/keyStore.ts +++ b/ironfish/src/fileStores/keyStore.ts @@ -96,6 +96,22 @@ export class KeyStore> { await this.storage.save(save) } + clear(key: T): void { + const previousValue = this.config[key] + + delete this.loaded[key] + this.keysLoaded.delete(key) + + if (Object.prototype.hasOwnProperty.call(this.overrides, key)) { + delete this.overrides[key] + } + + const newValue = this.get(key) + if (previousValue !== newValue) { + this.onConfigChange.emit(key, newValue) + } + } + set(key: T, value: TSchema[T]): void { const schema = this.schema?.fields[key] diff --git a/ironfish/src/rpc/clients/client.ts b/ironfish/src/rpc/clients/client.ts index 6951981007..41354e586e 100644 --- a/ironfish/src/rpc/clients/client.ts +++ b/ironfish/src/rpc/clients/client.ts @@ -76,6 +76,7 @@ import { FollowChainStreamRequest, FollowChainStreamResponse, } from '../routes/chain/followChain' +import { UnsetConfigRequest, UnsetConfigResponse } from '../routes/config/unsetConfig' import { OnGossipRequest, OnGossipResponse } from '../routes/events/onGossip' import { GetBannedPeersRequest, GetBannedPeersResponse } from '../routes/peers/getBannedPeers' import { GetPeerRequest, GetPeerResponse } from '../routes/peers/getPeer' @@ -506,6 +507,15 @@ export abstract class RpcClient { ).waitForEnd() } + async unsetConfig( + params: UnsetConfigRequest, + ): Promise> { + return this.request( + `${ApiNamespace.config}/unsetConfig`, + params, + ).waitForEnd() + } + async uploadConfig( params: UploadConfigRequest, ): Promise> { diff --git a/ironfish/src/rpc/routes/config/index.ts b/ironfish/src/rpc/routes/config/index.ts index 2855b5c591..2184582d79 100644 --- a/ironfish/src/rpc/routes/config/index.ts +++ b/ironfish/src/rpc/routes/config/index.ts @@ -4,4 +4,5 @@ export * from './getConfig' export * from './setConfig' +export * from './unsetConfig' export * from './uploadConfig' diff --git a/ironfish/src/rpc/routes/config/unsetConfig.test.ts b/ironfish/src/rpc/routes/config/unsetConfig.test.ts new file mode 100644 index 0000000000..05461020a7 --- /dev/null +++ b/ironfish/src/rpc/routes/config/unsetConfig.test.ts @@ -0,0 +1,26 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +import { createRouteTest } from '../../../testUtilities/routeTest' + +jest.mock('axios') + +describe('Route config/unsetConfig', () => { + const routeTest = createRouteTest() + + it('should error if the config name does not exist', async () => { + await expect(routeTest.client.unsetConfig({ name: 'asdf' })).rejects.toThrow() + }) + + it('handles clear values values', async () => { + routeTest.sdk.config.set('blockGraffiti', 'bar') + routeTest.sdk.config.setOverride('blockGraffiti', 'foo') + expect(routeTest.sdk.config.get('blockGraffiti')).toEqual('foo') + + await routeTest.client.unsetConfig({ + name: 'blockGraffiti', + }) + + expect(routeTest.sdk.config.get('blockGraffiti')).toEqual('') + }) +}) diff --git a/ironfish/src/rpc/routes/config/unsetConfig.ts b/ironfish/src/rpc/routes/config/unsetConfig.ts new file mode 100644 index 0000000000..8f2ebd2e0c --- /dev/null +++ b/ironfish/src/rpc/routes/config/unsetConfig.ts @@ -0,0 +1,29 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +import * as yup from 'yup' +import { ConfigOptions, ConfigOptionsSchema } from '../../../fileStores/config' +import { ApiNamespace, router } from '../router' +import { setUnknownConfigValue } from './uploadConfig' + +export type UnsetConfigRequest = { name: string } +export type UnsetConfigResponse = Partial + +export const UnsetConfigRequestSchema: yup.ObjectSchema = yup + .object({ + name: yup.string().defined(), + }) + .defined() + +export const UnsetConfigResponseSchema: yup.ObjectSchema = + ConfigOptionsSchema + +router.register( + `${ApiNamespace.config}/unsetConfig`, + UnsetConfigRequestSchema, + async (request, node): Promise => { + setUnknownConfigValue(node.config, request.data.name) + await node.config.save() + request.end() + }, +) diff --git a/ironfish/src/rpc/routes/config/uploadConfig.ts b/ironfish/src/rpc/routes/config/uploadConfig.ts index 16f973b214..c076b03833 100644 --- a/ironfish/src/rpc/routes/config/uploadConfig.ts +++ b/ironfish/src/rpc/routes/config/uploadConfig.ts @@ -43,7 +43,7 @@ function clearConfig(config: Config): void { export function setUnknownConfigValue( config: Config, unknownKey: string, - unknownValue: unknown, + unknownValue?: unknown, ignoreUnknownKey = false, ): void { if (unknownKey && !(unknownKey in config.defaults)) { @@ -68,6 +68,11 @@ export function setUnknownConfigValue( sourceValue = sourceValue.trim() } + if (value === undefined) { + config.clear(sourceKey) + return + } + if (typeof sourceValue !== typeof targetValue) { value = convertValue(sourceKey, sourceValue, targetValue) } From b43bcf90fd4bbdc253410580f3206f5ca3e4c8a2 Mon Sep 17 00:00:00 2001 From: lwisne Date: Fri, 17 Feb 2023 09:37:24 -0700 Subject: [PATCH 35/43] add eligibility check to mint (#3417) * add eligibility check to mint * better wording * changes to match API changes * is_verified -> verified * PR feedback --------- Co-authored-by: mat-if <97762857+mat-if@users.noreply.github.com> Co-authored-by: Daniel Cogan Co-authored-by: Jason Spafford Co-authored-by: Rohan Jadvani <5459049+rohanjadvani@users.noreply.github.com> --- ironfish-cli/src/commands/testnet.ts | 11 ++++++-- ironfish-cli/src/commands/wallet/mint.ts | 34 ++++++++++++++++++++++++ ironfish/src/webApi.ts | 3 +++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/ironfish-cli/src/commands/testnet.ts b/ironfish-cli/src/commands/testnet.ts index 9f05cd2f08..92eaa3700a 100644 --- a/ironfish-cli/src/commands/testnet.ts +++ b/ironfish-cli/src/commands/testnet.ts @@ -92,7 +92,7 @@ export default class Testnet extends IronfishCommand { } else { // Fetch by graffiti if (!userArg || userArg.length === 0) { - this.log(`Could not figure out testnet user, graffiti was not provided`) + this.log(`ERROR: Could not figure out testnet user, graffiti was not provided`) return this.exit(1) } @@ -102,7 +102,14 @@ export default class Testnet extends IronfishCommand { const user = await api.findUser({ graffiti: userArg }) if (!user) { - this.log(`Could not find a user with graffiti ${userArg}`) + this.log(`ERROR: Could not find a user with graffiti ${userArg}`) + return this.exit(1) + } + + if (!user.verified) { + this.log( + `ERROR: You must verify your Iron Fish email. Visit https://ironfish.network and click "Log In" to do so.`, + ) return this.exit(1) } diff --git a/ironfish-cli/src/commands/wallet/mint.ts b/ironfish-cli/src/commands/wallet/mint.ts index 620a5862e0..e63065a5c0 100644 --- a/ironfish-cli/src/commands/wallet/mint.ts +++ b/ironfish-cli/src/commands/wallet/mint.ts @@ -9,6 +9,7 @@ import { RawTransactionSerde, RpcResponseEnded, Transaction, + WebApi, } from '@ironfish/sdk' import { CliUx, Flags } from '@oclif/core' import inquirer from 'inquirer' @@ -108,6 +109,8 @@ export class Mint extends IronfishCommand { account = defaultAccount.name } + await this.doElegibilityCheck() + let assetId = flags.assetId let metadata = flags.metadata let name = flags.name @@ -340,4 +343,35 @@ Find the transaction on https://explorer.ironfish.network/transaction/${transact this.exit(2) } } + + async doElegibilityCheck(): Promise { + const api = new WebApi() + // Connect to node + const node = await this.sdk.connectRpc() + const graffiti = (await node.getConfig({ name: 'blockGraffiti' })).content.blockGraffiti + if (graffiti) { + const user = await api.findUser({ graffiti: graffiti }) + if (!user) { + this.log(`WARNING: Could not find a user with graffiti ${graffiti}`) + } else { + if (!user.verified) { + this.log( + `WARNING: No verified email on account for graffiti ${graffiti}. You need this email to claim testnet rewards. Visit https://testnet.ironfish.network/login to verify.`, + ) + } + if (user.node_uptime_count < user.node_uptime_threshold) { + const threshold_days = user.node_uptime_threshold / 2 + this.log( + `WARNING: ${threshold_days} days (${ + threshold_days * 24 + } hours) of hosting a node is needed to qualify for Phase 3 points. You currently have ${ + user.node_uptime_count * 12 + } hours.`, + ) + } + } + } else { + this.log(`WARNING: Graffiti not set. Testnet points will not be recorded.`) + } + } } diff --git a/ironfish/src/webApi.ts b/ironfish/src/webApi.ts index add497f7ef..dfdce56f52 100644 --- a/ironfish/src/webApi.ts +++ b/ironfish/src/webApi.ts @@ -43,6 +43,9 @@ type ApiUser = { id: number country_code: string graffiti: string + verified: boolean + node_uptime_count: number + node_uptime_threshold: number total_points: number rank: number } From fd091657106b3b503aa36dbc55d03b197109798e Mon Sep 17 00:00:00 2001 From: Jason Spafford Date: Fri, 17 Feb 2023 15:32:12 -0500 Subject: [PATCH 36/43] Remove use of routeTest.client.request (#3458) * Remove use of routeTest.client.request We don't need to use this unless you want a raw untyped request. Most of these tests only want the typed request, and in fact typing these found some bugs in the tests.:wq * Fix test --- .../routes/chain/getTransactionStream.test.ts | 23 ++++++++----------- .../src/rpc/routes/config/getConfig.test.ts | 4 +--- .../src/rpc/routes/faucet/getFunds.test.ts | 12 +++++----- .../src/rpc/routes/node/getStatus.test.ts | 2 +- ironfish/src/rpc/routes/node/stopNode.test.ts | 2 +- .../src/rpc/routes/wallet/create.test.slow.ts | 20 +++------------- 6 files changed, 22 insertions(+), 41 deletions(-) diff --git a/ironfish/src/rpc/routes/chain/getTransactionStream.test.ts b/ironfish/src/rpc/routes/chain/getTransactionStream.test.ts index 68e9c45601..0e6b20c13b 100644 --- a/ironfish/src/rpc/routes/chain/getTransactionStream.test.ts +++ b/ironfish/src/rpc/routes/chain/getTransactionStream.test.ts @@ -4,6 +4,7 @@ import '../../../testUtilities/matchers' import { Asset } from '@ironfish/rust-nodejs' +import { Assert } from '../../../assert' import { BlockHashSerdeInstance } from '../../../serde' import { useAccountFixture, @@ -11,17 +12,11 @@ import { useMintBlockFixture, } from '../../../testUtilities/fixtures' import { createRouteTest } from '../../../testUtilities/routeTest' -import { GetTransactionStreamResponse } from './getTransactionStream' +import { MemoryResponse } from '../../adapters' describe('Route chain.getTransactionStream', () => { const routeTest = createRouteTest() - it('should fail if no incoming view key is specified', async () => { - await expect( - routeTest.client.request('chain/getTransactionStream', {}).waitForEnd(), - ).rejects.toThrow('Request failed (400) validation: incomingViewKey is a required field') - }) - it(`should fail if block can't be found with hash`, async () => { const hash = BlockHashSerdeInstance.serialize(Buffer.alloc(32, 'blockhashnotfound')) const wallet = routeTest.node.wallet @@ -43,10 +38,10 @@ describe('Route chain.getTransactionStream', () => { const wallet = routeTest.node.wallet const account = await useAccountFixture(wallet) const asset = new Asset(account.spendingKey, 'customasset', 'metadata') - const response = routeTest.client.request( - 'chain/getTransactionStream', - { incomingViewKey: account.incomingViewKey }, - ) + const response = routeTest.client.getTransactionStream({ + incomingViewKey: account.incomingViewKey, + }) + Assert.isInstanceOf(response, MemoryResponse) await response.contentStream().next() // Mint so we have an existing asset const mintValue = BigInt(10) @@ -57,9 +52,10 @@ describe('Route chain.getTransactionStream', () => { asset, value: mintValue, }) + await expect(routeTest.node.chain).toAddBlock(mintBlock) // validate mint block - expect(await (await response.contentStream().next()).value).toEqual( + expect((await response.contentStream().next()).value).toEqual( expect.objectContaining({ transactions: expect.arrayContaining([ expect.objectContaining({ @@ -80,8 +76,9 @@ describe('Route chain.getTransactionStream', () => { value: mintValue, }) await expect(routeTest.node.chain).toAddBlock(burnBlock) + // validate burn block - expect(await (await response.contentStream().next()).value).toEqual( + expect((await response.contentStream().next()).value).toEqual( expect.objectContaining({ transactions: expect.arrayContaining([ expect.objectContaining({ diff --git a/ironfish/src/rpc/routes/config/getConfig.test.ts b/ironfish/src/rpc/routes/config/getConfig.test.ts index 2b1ccf060c..a01c42b0cf 100644 --- a/ironfish/src/rpc/routes/config/getConfig.test.ts +++ b/ironfish/src/rpc/routes/config/getConfig.test.ts @@ -7,9 +7,7 @@ describe('Route config/getConfig', () => { const routeTest = createRouteTest() it('should error if the config name does not exist', async () => { - await expect( - routeTest.client.request('config/getConfig', { name: 'asdf' }).waitForEnd(), - ).rejects.toThrow() + await expect(routeTest.client.getConfig({ name: 'asdf' })).rejects.toThrow() }) it('returns value of the requested ConfigOptions', async () => { diff --git a/ironfish/src/rpc/routes/faucet/getFunds.test.ts b/ironfish/src/rpc/routes/faucet/getFunds.test.ts index 48b3eaa666..aa3f979112 100644 --- a/ironfish/src/rpc/routes/faucet/getFunds.test.ts +++ b/ironfish/src/rpc/routes/faucet/getFunds.test.ts @@ -59,9 +59,9 @@ describe('Route faucet.getFunds', () => { }, } }) - await expect( - routeTest.client.request('faucet/getFunds', { accountName, email }).waitForEnd(), - ).rejects.toThrow(RpcRequestError) + await expect(routeTest.client.getFunds({ account: accountName, email })).rejects.toThrow( + RpcRequestError, + ) }) }) @@ -69,9 +69,9 @@ describe('Route faucet.getFunds', () => { it('throws an error', async () => { const apiResponse = new Error('API failure') as AxiosError axios.post = jest.fn().mockRejectedValueOnce(apiResponse) - await expect( - routeTest.client.request('faucet/getFunds', { accountName, email }).waitForEnd(), - ).rejects.toThrow('API failure') + await expect(routeTest.client.getFunds({ account: accountName, email })).rejects.toThrow( + 'API failure', + ) }) }) }) diff --git a/ironfish/src/rpc/routes/node/getStatus.test.ts b/ironfish/src/rpc/routes/node/getStatus.test.ts index e407f63447..b22e9dabf3 100644 --- a/ironfish/src/rpc/routes/node/getStatus.test.ts +++ b/ironfish/src/rpc/routes/node/getStatus.test.ts @@ -7,7 +7,7 @@ describe('Route node/getStatus', () => { const routeTest = createRouteTest() it('should get status', async () => { - const response = await routeTest.client.request('node/getStatus').waitForEnd() + const response = await routeTest.client.getNodeStatus() expect(response.status).toBe(200) diff --git a/ironfish/src/rpc/routes/node/stopNode.test.ts b/ironfish/src/rpc/routes/node/stopNode.test.ts index 08116e4246..015361355f 100644 --- a/ironfish/src/rpc/routes/node/stopNode.test.ts +++ b/ironfish/src/rpc/routes/node/stopNode.test.ts @@ -9,7 +9,7 @@ describe('Route node.getStatus', () => { it('should get status', async () => { routeTest.node.shutdown = jest.fn() - const response = await routeTest.client.request('node/stopNode').waitForEnd() + const response = await routeTest.client.stopNode() expect(response.status).toBe(200) expect(response.content).toBe(undefined) expect(routeTest.node.shutdown).toHaveBeenCalled() diff --git a/ironfish/src/rpc/routes/wallet/create.test.slow.ts b/ironfish/src/rpc/routes/wallet/create.test.slow.ts index 39c546c092..e96021a6d6 100644 --- a/ironfish/src/rpc/routes/wallet/create.test.slow.ts +++ b/ironfish/src/rpc/routes/wallet/create.test.slow.ts @@ -18,7 +18,7 @@ describe('Route wallet/create', () => { const name = uuid() - const response = await routeTest.client.request('wallet/create', { name }).waitForEnd() + const response = await routeTest.client.createAccount({ name }) expect(response.status).toBe(200) expect(response.content).toMatchObject({ name: name, @@ -38,7 +38,7 @@ describe('Route wallet/create', () => { const name = uuid() - const response = await routeTest.client.request('wallet/create', { name }).waitForEnd() + const response = await routeTest.client.createAccount({ name }) expect(response.content).toMatchObject({ name: name, publicAddress: expect.any(String), @@ -47,20 +47,6 @@ describe('Route wallet/create', () => { expect(routeTest.node.wallet.getDefaultAccount()?.name).toBe(name) }) - it('should validate request', async () => { - try { - expect.assertions(3) - await routeTest.client.request('wallet/create').waitForEnd() - } catch (e: unknown) { - if (!(e instanceof RpcRequestError)) { - throw e - } - expect(e.status).toBe(400) - expect(e.code).toBe(ERROR_CODES.VALIDATION) - expect(e.message).toContain('name') - } - }) - it('should fail if name already exists', async () => { const name = uuid() @@ -68,7 +54,7 @@ describe('Route wallet/create', () => { try { expect.assertions(2) - await routeTest.client.request('wallet/create', { name: name }).waitForEnd() + await routeTest.client.createAccount({ name: name }) } catch (e: unknown) { if (!(e instanceof RpcRequestError)) { throw e From 194ff0739a09b407438c04a289f2d4de6efa6139 Mon Sep 17 00:00:00 2001 From: Jason Spafford Date: Fri, 17 Feb 2023 16:01:14 -0500 Subject: [PATCH 37/43] Allow config:get allow plaintext output (#3465) --- ironfish-cli/src/commands/config/get.ts | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/ironfish-cli/src/commands/config/get.ts b/ironfish-cli/src/commands/config/get.ts index 6489bdfa71..7d2d960ddc 100644 --- a/ironfish-cli/src/commands/config/get.ts +++ b/ironfish-cli/src/commands/config/get.ts @@ -33,6 +33,11 @@ export class GetCommand extends IronfishCommand { allowNo: true, description: 'Should colorize the output', }), + json: Flags.boolean({ + default: false, + allowNo: true, + description: 'Output the config value as json', + }), } async start(): Promise { @@ -51,9 +56,16 @@ export class GetCommand extends IronfishCommand { this.exit(0) } - let output = JSON.stringify(response.content[key], undefined, ' ') - if (flags.color) { - output = jsonColorizer(output) + let output = '' + + if (flags.json) { + output = JSON.stringify(response.content[key], undefined, ' ') + + if (flags.color) { + output = jsonColorizer(output) + } + } else { + output = String(response.content[key]) } this.log(output) From 96ca0fe83dbeab39e951a6b9099b715263c3256a Mon Sep 17 00:00:00 2001 From: mat-if <97762857+mat-if@users.noreply.github.com> Date: Fri, 17 Feb 2023 15:15:26 -0700 Subject: [PATCH 38/43] feat(ironfish): improve the limits of GetBlockHeaders (#3431) * feat(ironfish): improve the limits of GetBlockHeaders This introduces a limit of 1024 headers that can be requested per GetBlockHeaders request. A block header is currently ~180 bytes, which would make the max message size around 185kb. This also introduces a limit to the number of total block headers that can be looked up from disk, given that GetBlockHeaders can use a `skip` amount to potentially use an excessive amount of disk usage. * fix: off-by-1 error when counting lookups and include tests * move header lookup into a const in versions --- .../__fixtures__/peerNetwork.test.ts.fixture | 736 ++++++++++++++++++ ironfish/src/network/peerNetwork.test.ts | 112 +++ ironfish/src/network/peerNetwork.ts | 21 +- ironfish/src/network/version.ts | 2 + 4 files changed, 868 insertions(+), 3 deletions(-) diff --git a/ironfish/src/network/__fixtures__/peerNetwork.test.ts.fixture b/ironfish/src/network/__fixtures__/peerNetwork.test.ts.fixture index ed8b6aa775..eeffafb1d8 100644 --- a/ironfish/src/network/__fixtures__/peerNetwork.test.ts.fixture +++ b/ironfish/src/network/__fixtures__/peerNetwork.test.ts.fixture @@ -1854,5 +1854,741 @@ } ] } + ], + "PeerNetwork handles requests for block headers responds with CannotSatisfy when requesting too many headers": [ + { + "header": { + "sequence": 2, + "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", + "noteCommitment": { + "type": "Buffer", + "data": "base64:zUiHYM/T0qEtp8UkrA+yHzMgXEZruSTLc0sq8TnEmAk=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:JAtin0YY+PErZGwEpAu2OjQrFzubxvLrrRiKy/11g8s=" + }, + "target": "883423532389192164791648750371459257913741948437809479060803100646309888", + "randomness": "0", + "timestamp": 1676496532984, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 4, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAD7ylv1otfAbEPSNKU2zwMNIgz1a8pMiRKhZ8n4YWu56Ey4wA/lYgYzgfwCRwgucRtQAEfQ6ln5ggUklo9+UtxMvCKrtpLQ8f5yx2lN+jsmiXczWeDa11VS3eHSpxKY2EX7YMZCYI+q7333tMPTFObe+VcEmrdXiq9GM/8He+BE8MdYNAcFirhEma/zZUSm+z7f76VeOwDiRVt4oUjPH0O6+wO63c49kbn7zml3ABUlq2N2oM1A6bV7Y/wB7hfRu56ohkditL8Y/C+iJFhA8c5ANA0JDbmVb5JQGBneiCYeYA4uao2Jgi6YnoWZGiVC0xkxa1NHRmWW8t8lOiM7oXAKOajVe3gjREjNHVm4Xh+nxsl0ecJ4yqMofrb5pe7IBwGVEWNHm8tpjXcf0bkOVwU4JacnDAKi934b+OZlXspfCm4Uo1miQvTbIcQuR5ADqJmfqekNQBycQLGA/djY+tv8WMsFImV/f2tS/LSL2tzPbYawSfN5z5WQBFjS77WIEVQ4G/OJBc7CBpGza+heOfOFGicmVTzJ5fqr8P3yTMFVCfxsI3LUrdbu9vls6oeIi6UIRekrZm0PZp82JOQGTreQoJkRKDMkmPzh8NiU9J7ShT+2ZUZaFwe0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAwjCfm0nXljVSKa5YABkNihkdYeOIw5mSLJKtgDprpYtrzHIW5+1sHej0CidoPc0y4PqEMjLlFB56qTg/w65CQ==" + } + ] + } + ], + "PeerNetwork handles requests for block headers only iterates headers up to the lookup limit": [ + { + "header": { + "sequence": 2, + "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", + "noteCommitment": { + "type": "Buffer", + "data": "base64:ADT9PJpdOIrtO89whudYzBFXQy4QaGlsvZDCqlokjyY=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:NIm18gf38Zj7cNH/sMoTt17SEL78d3jtObD6Riyi+io=" + }, + "target": "883423532389192164791648750371459257913741948437809479060803100646309888", + "randomness": "0", + "timestamp": 1676496533290, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 4, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA80ukLKeUru9TTODKhTLj1TpdJPOc0QOmRG10VvZHUwSuehaQjHXfLRyMh2EGDGf4958vsWU72SGCLTdhUgSaxO9Qusm7jgcmlOYMBog35yyUu/A1DnRBfXZfwU81Qw8nlbIssthxBj3E2L1oPBSmabgQ8UfYxM5HbPjeQtgGZ7AQ976ClHUVrVuz5MS3f0iyRzNgr5eFpxJ436cYXW0kqqiqaHp8NIFQ8gLklb2vqxStNPNegK780Gg0Lo51DX2vaWkclx5nnBB9N6LssilrXvjtmVnq7xu7HjH+qw+aPaqga7EWgfX5Rj0UWr9db1cSLTajWlLmrsXlYy9rjWjzUe2umPZoW4/coI+sFb9sOT+jSXzpRH0Wzsu4lbb/oUBR8Ekg/0Q1pbnnEErWSUhvmP/Yj0P5/lncoMGEbaMGPpn7reRH9MkT2XQr9FROk43az4os24uwtDsXrYvnJgWstse9axwOCefKEys9jZaYPpjr+VM7e5oosM/tvS/pfR9K00u7FLtjSKY5jT8TEJSPvqMtCROWc+OaoqJ91WZ8jr+f0wvRptev8/O5MIygFk9HCzKuVt/zM3DFxS7lR8mHutv6M55kzNcDMwzfEK1OvIn29j33/CTIn0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwtmTBmsFT2xViReHU/IawbWQu6CIiui7Hh6JaDOxAuiQ2L8o6+ZEPCKOrPygsTZn4oOSFr2Yc+0ycsG9qUDN+CA==" + } + ] + }, + { + "header": { + "sequence": 3, + "previousBlockHash": "40B2EF62BF5714D7D6093D59363008D38A273150D28AF862A60FEAA7A1BB173D", + "noteCommitment": { + "type": "Buffer", + "data": "base64:uMdY1DtRNBmAN2Bt8ZspBQrm4fyV+c5goTNJNx21sQg=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:vLri2EPNcq+u2xuFuUzoQm4MZbELu652CFWHS0/zRFk=" + }, + "target": "880842937844725196442695540779332307793253899902937591585455087694081134", + "randomness": "0", + "timestamp": 1676496533585, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 5, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAtX9pFDPKHqCPktiiQ9lKThbbqDT0eepzdCMtCpkGmqiCgr5KFew0wNOGuOQLLlmY1xxFSTgq/TsKFwEIDUXWa0t7qWYuCNTu1hw5Z5yDxa+W4FGtAuJvm542HaZPASDQTy3OGNd4NmsS83BY9Yy8+2ZMJevXKaRwvLsZUoZnqZoLlikG/dcS77Ht0eNXeoAIJzXJrRTe02AykICHCSQ91vpdx1RwN0uuI9jWtlfJhTSXfmTMITxyXgP2rqfj601Rhfq9w2032SOHzLJz4dz6hjpzudo4XuMAdud+K03IQ/EQ6Sp2lah0UWHCsIXCJZIDsd+OemymwSsK+ymnncnJQGGUaGVhDrUM+kiN5A3pUakMfm1L4tdPxLJCu0+Fm4lBkaek5ELcSWdO1nd2VP0V+G0JVaJTp3JZc3Y4IopOoKCqH18Hr7I1IYLBNR2WPsOsXUSZoYiwXt3KrRP+KJVYPtT+9Uvtjqqmw5X+djaq/yXZCLhGEsf1cYnBhm7Qu6MLb370x9jLchhyZkqvGeuarAaudqtwt06miDvm0QaTkZX8yZNtRAKTZt8L16dFtR8wWsN1g+TCMWVAHLhAOegCX8ALdCgdPaiZwaZ2v4IONWRpAyfdy8E9Mklyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwcMa/tTBFkqIFjCI51HW1ScNVV6qVA5KCGkiBzV6fupFntah2RoYpB2UsPp7GRu8dr+rnzSUdFXM5zJhBC1jfBA==" + } + ] + }, + { + "header": { + "sequence": 4, + "previousBlockHash": "801C19E6450F773C82EBDBA9183968C5F1102E43E4715FF00B0A5B14A5FF6556", + "noteCommitment": { + "type": "Buffer", + "data": "base64:ml0id5CdYMfhDHo/kIttOCkstHJ8rRUo1mefRIYoxU0=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:REMMAKlaX5sGkVEfc9R8/SDUDkX2HzR3OFmc90fcA/c=" + }, + "target": "878277375889837647326843029495509009809390053592540685978895509768758568", + "randomness": "0", + "timestamp": 1676496533875, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 6, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAALUfbv3j5wv/ZG9Txqxm7lSxcjGiW4+wjo4zGN7+IMxWlL3GXNUiUhPwi4DJhCy7MlEX/sN/pX0c3w3Cvu3pWRuX7w312EEIW54ThebWmbvKKDXnaQqub7fnmiP6G2VXgwzTjJ8gpglq8umVZnBXWRzyACgkkaZfOFIyDDKQC0kkP/DG1ph2JsPWOLA1fA5oF1Bdf5uEXtynNAQPOolyFce7/e7e5sRm9rNxxphoNFa+pmGrG5h1BnOcTBqqVKZv8hLG6EhCWyjp6AcTzEkXvgoGl8s0Ef33XlTqshMEv4pelAStaqvNqSIn0BBgNZPljNMNg4ZVlm15I1bIo2E2p0X4ry8xs7a6LRDGYjt5ebse97PCp0mbAqPgsrZFF6ZMEhBaiuv83FMtNXLPsT+JABE8pUcstqdvXKAOrAB9HnmkHfgtNZpomKqLnKV/YyqSxQh4AeXKkvMUaitpUtSHaLd3Qurl7tRK1byMhux3qoapZxGBoRY/zZb8py5jcVj0eMI6yitjbNBGzpPNr3jyyrpPO+OD4ifO/Syx4/JaUUgK9Of7qLAOC28fN5RElApsv3QHCLJ8DokBB76QOQA8OPStSB7sZy2IsSvHj09IraG7zNgpTLdEvbUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwbROA8cleBcQIl+PpODweLlSqxY88IGlKl8/Qw4UKx0jymK8YcXOtGmMMHRHSejoaq9b6LNCGc8WopE+hlCWHAw==" + } + ] + }, + { + "header": { + "sequence": 5, + "previousBlockHash": "F847FFB4CCDD0AA5A8849E6252634C024AB0E54B1E863D3E897D07ABCCF2A5A9", + "noteCommitment": { + "type": "Buffer", + "data": "base64:xjmTOvfduXbxy/AKhinWCPxdFZQM8YZZpgf7C/5tbkE=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:xIsZ5sQiP3BkW7U33olv9x3V5S9z57Nz2LxN13nr+Lg=" + }, + "target": "875726715553274711274586950997458160797358911132930209640137826778142618", + "randomness": "0", + "timestamp": 1676496534156, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 7, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA49oLzqDL94fRmZauaz/f4HCTcCjSUoV801qhDW6+TSOu0yFTAkr1wosTFsFzTMCMEXCnn0pDDlNJ1kZ+jVlC5OGIIA3ayYr+kqQ6YJd3z5O5zkCmR/pnmkYieIDYFNPP6UNXJbg+anGlQB3XsuKEJZEirTaqOKC5Ymi7f/GH2oMA69tU72tR/k+BjC5oH4QBmy7O6gsN03w14Qt1IQ7p536k899ihfxP3U0cMeNCvS2R1B8z4B+ASXFE94NodgIyDMGzQDrL6OsSHnOPwczoky+fQXzJ6vIyelBHNtFFNWovDhfA0Q+biUSMKoF2OeVm5i2TFPwWHNQQpXgmDCG46tMelTHrK32KTnxyXjQMEXB7CMIK5Kv+2MAIKJmKTTMfQohJWA7qKz/zoRyEDjqiZHCJWV2fd8HY9hIOX9983eXt7UGLOAMaLnaP5JBMcj4QtAPIxog6ar8O1RczcwTWdMGNeffiNRf+rT3QM1EiWwZgidAlU+YfpsYiuM/8mE2khKZEw4Hz4qhDLcNKLV3TX/It3PrO/kRmlF7ic3rXR83kvYW4jABPcEsrwvfsIvSo7WliIPqAUlwC8xBPeU418+sI67al/XNzYt61HNKRJ7yWO+AgPk07XUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwjaPFoMxvSb+hU5yA6bVggJ1JIDVoHGRm+sZ3/NxS1TgZG3fzGarHLfTjUYDowD90k3f0FZlCRdiyO8NfvpsWCw==" + } + ] + }, + { + "header": { + "sequence": 6, + "previousBlockHash": "E5AC9CB59F76DFBE3FBCB21A7249582167B9A2CB6FCD14CE7C00F7298B02AA0A", + "noteCommitment": { + "type": "Buffer", + "data": "base64:7w2hq3cPY38iEnNKwcR2nJws0SoYlZ1BN86NZStPXHA=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:hx3CZKMnJtxVCGvMiKwzqGIy7XbooWjBXLpdHM5OkBA=" + }, + "target": "873190827380823143577845869093025366895436057143163037218399975928398962", + "randomness": "0", + "timestamp": 1676496534435, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 8, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAlaVouw0jvE9PIlN5u/lrkuOTkVEUnBMi5nkw9f+T6DeA4wJtX7btiOO6u+gqa95ZLhD5mWtBnIPLQ53zYaLyCFC4eM3JGfw704EWk3dWi3iQVnzbEP0murHRC9FYRCk5dtPf3QgVggY7/IFtMzAcLw+WVN+KcZRdnEnwGmMZbrsN38zbHakJ5F3ZsRXslCQdE5Q4qUsE7VGPvQgD9drnjF95wWga2sNpYwv8WUCsxL2qK5PhCBPWZ3ADl0a6BzCqOsHH1YP+j3ryV13JLVzUqWTGjlxLT2gjyDrvaD1fALlZwdhhcLyesPTBqAEZoQqm/RaSTxnStQlRCrY/SZ8vCZLFOstSa4I+lP8Z94JPeOJUlQtJnVCI6QyQLeId9/oOSQIQChiA3GRtb4LdNgPMdQraWwmxvDskEvsST6HlDELsUxkgl1FkouIKhrlI9JyTNs+BpouQZHKgN61DZThX6xCE2F4g2o1g4kVV+HbU4IkwOEteVxDka2qsKqA6RvTm7xYQ8xZIcCy0JqOQte0/M9Hc22xRSS1KbWFLFiAzMawzO98rY7k2GBOvt1JSacxN7Mpk54eAzN8NTkt1v+NG8L5l+pIz+CTAv+ihPhHC5be8GtVs150MGElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw7rDUPgqCs5Bc+jdupBXjNm8Tt8Vfuk9kx2q7gx+KIVtTTRAS+6o4qzLyos5GMXUJqHtFAGT4IrR7solPIY7vCA==" + } + ] + }, + { + "header": { + "sequence": 7, + "previousBlockHash": "7826288AF15B7C04CEB577F818E3FF43602D8F17D353A1EA77E5529DF37D27B7", + "noteCommitment": { + "type": "Buffer", + "data": "base64:lkkdcN2lf+W4EUHZqzzszYWhC3hkcDzH5fsxFbuztB0=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:e9cY3RlMDdZ11YmfRPmRCqGsCmSmLCnRgSDCFvUUdXE=" + }, + "target": "870669583413409794751345832897376592977547406352566801307278513052763546", + "randomness": "0", + "timestamp": 1676496534711, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 9, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAHy5jarDkB3DIE+wAqeopnkih/0zNfT0NmOLGZuI+8COrVMqV0kcbLrIAnT3moQ4Y3rpBNA/K+YWvJ9MlSmIY6XNuVGHEyz5M1x5+x4WJ9jyi5d6S/JQKHNk5khplT+0y3UdhC8U7wULNa/k+r3rhufQJp+dkqpMee8X8EEzv2H8HCmWwMOKuatqzpk4cs3rM4E/9DmayYEPS+krEBqI5LMO37whsjDbTTxStLveaQQ2tQOZmHlnGytth1AtUvKHN5ao/rI9facCW6xxE3G+240K9UQfrHI07k2MYbR9TW51lpnv364DSqSDI5H9Jjl9zciu9LMsK4rD+0bh70M4O0xQRQhaWtucqBl33cGwcdxdFX3aD3ykOEzowjrsXTMwP6b4QyTriSFf3vasHA+rwVa+zX0DLC8Sd2yavf7iBOzHoPzkiHGW+6/UwLmEHkTLhbcCewapcq9YbEDAS1Vu6l9RHEtiqcDBGaiiGaXnuoxVDyGf3eexXhKc2bk3r+a2Kqvy6NrF4V7UbsfH/R535Im5ZqSSMlaizhgCaWyhCh+JZPzt1r6KjTDdvkkFQQOPpuVOgKdVKd3ozrAQR3Qky/AQ0YIr4wut5RX2Qca1bxuEBnUYxugQuJ0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw6uVI7GHQ8cnguYGi0/TTq+uQOennNHEqBZcxpHeq499Rdh8nBh2QoExYHbmTuy7Th779zrjWBGOlpb11+LCWAw==" + } + ] + }, + { + "header": { + "sequence": 8, + "previousBlockHash": "A24F94A754588B266E2852C3779EDD2702943AAFE7572F2F717ABB20883285B3", + "noteCommitment": { + "type": "Buffer", + "data": "base64:LBfhZlUrZUzIxtq+U/eLR+mefw2szTsOnijTUNuR8XA=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:JA8feosLeXFwEih/LHf4ZtibjcANrGVaCBEN31DBuXw=" + }, + "target": "868162857165578480563002226852566487623485369674008547560712452074684573", + "randomness": "0", + "timestamp": 1676496534988, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 10, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAXSyXMPg5J0CIjfdQpetA+sIUyfGUJCPIHhM7lJx51uCyO3hBTwl9VWzwezo5F7qIBEmP0o/NrCExZC/biNhkP4ESb7MwCmiykuv2CXceqoK58FkTl46Txm22/5CcniG47S4jSOD+arkdQlIs+sEeGI5tPcyMsTR2E+rOiMV0qVIP1z8aK6do+6S2sgBhF3PjJq44E6uMNuACaolvkq0la/pYRE8KO8Ocaa0aTdNWagqvag3ECYTZZq3UnW4jGUhRbbMT64+EYXsC0T1P+mpq8sotVHlwoY/LqxmiYCECDuh2XI908k7TAbEdwSy+OUSVjVhI2ZTopYdgLIaoQy5URMhr5VT9xxwWyB0m+HkL9NjYGI+Wi1T0tmRDmxzLfa8veC6T9LJsGXs+B/nf9EkQal7XLW6RHkizrSEGpiCgtArlthhuqtMJnE8qvU68MEwDy3GwYnTmMRzKnnppOQ3MLzPU+HGlIlcFzfeMslEYBq57qFdLaY297GcA7/AzxHFPupg8D16w4qNgkWfs0CLJ2lK5U64AOQWGYPnyG5aIc6AbE/hjnscS6EUgUf0F8r6FTaU5jnTbnCDaRDiDAETHhmWx3q2sV+Gk/N9Va2z01LhOVVjFpjeoHElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAweTGmQZmCqAVt2ZeeLq4AZMnL1jci3NUCByJRNtVHEkXVKxckGouFNrqqITrdEqVoSNxpkqqGf1Qwz/X0/yTgDQ==" + } + ] + }, + { + "header": { + "sequence": 9, + "previousBlockHash": "69E20BD87FBAFC151BFEA7EB4D516DF68A04C2643BEF54C5DD57592C4E6FF1E3", + "noteCommitment": { + "type": "Buffer", + "data": "base64:aQh4zwOVLTckEVfmLGNwZXVeTc75k6/Ogtae7mgy+mk=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:QH5ntot4PAv1S4yFWB5LDbs8bYdYiq2jceUpD+N+Qf4=" + }, + "target": "865631694431441438209791613778448244346620102758851756346587204580484799", + "randomness": "0", + "timestamp": 1676496535265, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 11, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAPmD8gJZryDrR3GcjUMfXPrtOSZwhV4MtKABWTzVkVM+jcLqE5bSEO19GF6xsV+gx3B8cKJaF7S9mmtxpbDmgC65qOQSzN9h1vYfsrNtdqFG1Wk7KQoKKWMWPeicwRdjISdTpGIMLQX9gE8LK0WddVMgoGUzITo6B88wEpjDB5CIUMrjP3Hpz4oYC47ybRJwJVEm8DsJcZeu7Yoh45vhte2ZqQOJhsXAkKblalNhoXS2gTT9WpspxhFE2w/eKP2W1iMFlayCz9Ls6/ZI4Udni4Tx/TXCLjBY9tIgqbTsWPStpN+3wt+u2/adrC3NcPqEIxCgk2zapms8Jrj34Qn1613Q9R3j8OlPPJBYXUzKHQKEafcg6B1A7Ik87seGSfokgObaIqkkZx2b2uwK9bk/aPOfQZkk1YnywNDBPEr3xZSVThbia8tY97htJIq28nEQVJfnYuGW1BBCan2bRX27nQ+MjJNQbIZExynQm49DNzuQcHpQep0u5eQEWYr6haT/cIi4XVpyAQzRzHJImhI0589sH+S13KVjrZtX1PK4kr9AWi9yiD03wfAUdRQs9HiyP6Fr4CFbsFeovD40HQyZ/6wON/owoMwilmow46fFOU0SskerP8OQMK0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwj3G+2Tjgxjj7smsPn6Ht1ZUR4dgmlHlHqjBZk4/lGdDUtrxGZujYZFf+sS2Uf9EivpyRsS07ui+qiT0sYc2ZCg==" + } + ] + }, + { + "header": { + "sequence": 10, + "previousBlockHash": "0936254208CC8FEF8683384A33E00C6E6EC757879F8F617D212497F8BA22E6B5", + "noteCommitment": { + "type": "Buffer", + "data": "base64:rnHnUMrrqjbeBKU/TFCNmRJYSmTV6cKUIDWCZOoMomI=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:/AFzMDjrTaMKKPactQvqpnlFo7cTR9OuO/Nb1m7sT6U=" + }, + "target": "863115248198486802107777401000983242294567404108951996477664688928658648", + "randomness": "0", + "timestamp": 1676496535544, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 12, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAh/mir30O4BWD/YlF1kVQQ8Ik2NZ0/TichmTJyZ0Gv5SylH3XajTlYi6vNTNnGtG0MV0PWL94818dFHgpabU239+xBv2koArfoMnzyMOno+2C1qsaQWhRvFB60K4Kz61C48zGs+w6+CHjCruNnX+B3Rdy9O4CHVRmu0+u++03xuwOjKPfakaQhyegjXdqGk3RREIikjSMiqUSW84Ctx3phaYmkdI5Si2RogD0UGCYI8+E6xFe2dngd5lWxmdpIF99cClDCkzJvVmLET0pvkCVBNUzEEVXoAGqnBr7yQQ3JCmmlNx6sy96X04AILk7iSEspESl0snMnY7wHI6SNOYx5Awpab6KfD/hp160dkX3O7OvJIO7A6YLZIf/II+x91czYdiorktnZVeKIxvVS9YEmn4N0TTT1LK7fL5kbQj7sd+L2qsGcdqqBwME1+c/SklgSj3JH9yxqFwMPxPLZkl70E6n3amPMJEq6t29vLdCFRsYErVspPrpxUuOi1c3VS1ssOGH0MOk0QM6/E3BE9vegYyfVOlKcc0y5uzO0VVbjVyOzJEoPHZYQa/+IuIqv5HnxEcWMtIRc/0RAT3EJbYOMBKh+IBPRvjk714gmihVsx83unMRlfDKiUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAqyJOvsxvtvVvR+B4PYkPL69DraNbx7pLEVBuSBKdL+/SWhihTc7nhiu0wWEw7dcoooz1l2NvNuimvEcd2wQCQ==" + } + ] + } + ], + "PeerNetwork handles requests for block headers lookup limit includes headers within the limit": [ + { + "header": { + "sequence": 2, + "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", + "noteCommitment": { + "type": "Buffer", + "data": "base64:t2a1lVPbLNlgvG8CFQ1w3orhmHtTPhfXbfKdNjEuYDQ=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:4Ym1lDh++p0jS3nGEUtgJBGJAbj9zWioX8ZYRt+TjJU=" + }, + "target": "883423532389192164791648750371459257913741948437809479060803100646309888", + "randomness": "0", + "timestamp": 1676496737244, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 4, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAQtOP1INd6+JqVL04YMGYquQg7uLh1Ok5KLe3OThE19GYclYeVhLxlU44RGlW1+YKmHho21u4wT2t2xz7q2kWl9iU70EtEQgp6tJCRlTzCrazuZ1tM2PPrh+bwwR1MEX32FoJZ2mps8P2wZb+EU8d3UeiNiBKaNkvtX7JmWYRfyEOmX4knWVHQrJlAXNIac3OqE5lCvE5FVRTQVD/mi6MI3jHLNIDZue/85eONSFivQ22/XhUL+LZnsp7euzkzzrgAWfoGpDmKyAekcfdPYSvk5dnEEMAfQmlcA2Hx74gtAsrqRNSi3AzcTHIWXvVpG/giKttKnOtcK+3EO33C5qllRx4RljaXDuGwFcEA5AdSK5+oJ7K+pKVf0uCzTyBj3MVdOSPtUiCOJftPOOMMaUe8yBgEE+8Zc8C+MoNb45k965IYmxub7CMOjP+FiI9OHemS6bMV7FKLNempk5hZvz8CBm6EECwp7Hfsq/amqyEofBG79fO0fI1e2IQVvO+KKomrXCL76YIuSzLpORIhRdckgloJNb8SGkXeFrJpoVPZBvx24B1yegTuDei9L/ogwHn67B6oNLAHoholDqZCw5NCpYFGkRpUxNSK7rWKD3EV53ItVr2fVEyZ0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwQW9uHUJ+IhL0kCpjdWPtJ2Ehh1z/Y2JhKZ5p5yUEXgIfAwXEmzd/Syph7Hc+uLL2mJNqxHc7d0l8dreo9VF7Bw==" + } + ] + }, + { + "header": { + "sequence": 3, + "previousBlockHash": "D9989A57460EC9CB82FBE690CD27E66C8AD2F4D174B660CA154535F39BE041DF", + "noteCommitment": { + "type": "Buffer", + "data": "base64:WsR6VhvZ8OzykSx3ys45vNC7/wXM+Pg1USn/eVNttAg=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:sPIvoTZD6GFkFNTzJYXiOBrtovpuZaQUyGIWAy446Y4=" + }, + "target": "880842937844725196442695540779332307793253899902937591585455087694081134", + "randomness": "0", + "timestamp": 1676496737633, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 5, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA92RCJovMXVE8rLXwX/kS/xSPzPHsDFaIsl+L3WkAooyJ5PgHyX0+wRCWc9dn1RxBXLIhvvXcpzXKOwwZ2z2dKUIU7ug+OusndV5/Qb1KWzGDsFoJBwfGvOxXqdLWi8lutNwmmop+L7nCoATYcPJETFDdy9fACJLxrMhfH/Dj4z0R2QyvpXBAxNjoeVO59SoWnJ0nl6aeUGT4JKSaEuZ7sUEV5hx7ZHcq+SKSOvfuPveltju8zt+a8W4Ddo0L8vb4zrm2F8St+9zQTZnCt8SGhJ8/0XlKuWwtokULdJ7S6Ou6a69bUsFOWWLci6v1zWzI6pF6RVK4ZRtSlEzZYSvFXU/Qly7EkqbDSwpj04JWyfSLb3CSH5O1Buqoen4Qaf09uWd29P0zQaCu0jCWP5cXBDm+94QXiaoVHhKgyFeqiMHu/gcQq8ZD2W4DYTrWCa3IusM5JwBFoizAEnXPCdBTiA2Z1ZKKfTBmZqmiJeOhlfC9nrPFDspGeQPKeI7yHqyUbMMqmegHlWKX7Kv+40zFB5QkfjCSDclq8ePsQToFCgV02zhQdJ9BQsWhevxx9iWF8gSCBLtpLGccsqM8NsTIoenBdh3x89ATjtvWcsvBcIYGDUkbfY9z1Ulyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwmZjHz15puN6UZLR3yzsMDfU85e/vXom55P3MuVoZTWtAKK154g6T/enrE/NQvJYNAB2X3pNMSu8HQVNfFA4/Bw==" + } + ] + }, + { + "header": { + "sequence": 4, + "previousBlockHash": "0557B1000742FB2A4D351F6269B335DC6EA996E95DB9A1E896AA85128AE7DE30", + "noteCommitment": { + "type": "Buffer", + "data": "base64:KwFO0/ymnWtLu3VhHo9SZiGbMx5sXFZMLKAaJtkDRUA=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:RSJ6qg3goBLG6FFfWCCLooJWqg33mMj9ifndVnWQn4Q=" + }, + "target": "878277375889837647326843029495509009809390053592540685978895509768758568", + "randomness": "0", + "timestamp": 1676496737958, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 6, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAApowmHRZNd3HxjKpKWWVM9xiqlDSxv6DGSsmlJ4MTq52oo43SkqPWZ7wFLd1r2ebg8eBiL/J6snsKpMQ070/hYZFJWClF0I0lIGfWMq8Z3gmPgmIchE3kfs7JlpWRJBjnzj/mg5w9w8T55dy3ch7gwQuJhZ9D3VoWck7Rlxm/7gIXmBjmKLtLC1djdsGKuU+DD4CzOOvBHcpoITsS3xwY8fnX6vZ5NUk09XhqzxuTuy+2xULIC2kMFLBWxiuiTBK9dnfaMsoy+RLoRSMnqJoIniIJmBFM9oUqzJGHWUavTo6pFCtKCMirpFZ4lZXx8vZRC9Q6TEBeAgWJBYtSKjV7FhULCCOSVvgkMLaLZiusNyEXGICAgsPXhYMGTbTK6VlI6ur0PQooX4eXokoC2hstmTBjcOODz3lEu7NoFJ4mmUUzDQMZh8hwgdX4Wpi0WDk+jtYOARENV6NNWN0HveQgwHQZC5b7tMgHgQVqMIMx2zU12G0l6wr7aPG8RsZKo+EpE7LJCHlvMOPgvgiYgiURRyC/rrtNQJ2OYagboCtpQO8WzOF0GGdW+RRM/ZBvyd5bz3ptkvLlT8dm0FiKxEE42LU4SYOyR+ZWg8LT8TTDZ4bwgUQ6sQpdA0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwdVOng4CZy5TtsNxno+os5diwC1OkZnXAN6c9vUeG3mGwMsjDfyVGLp20wEP5H4nGGHwt8zS900oCfORECMRdAw==" + } + ] + }, + { + "header": { + "sequence": 5, + "previousBlockHash": "73BFFF16678452C83F8F8C280B0859DDB4BF34A714687E3CD85440463FA2A613", + "noteCommitment": { + "type": "Buffer", + "data": "base64:1TZg7BqlBDH0kIfFaJ+ARLkhjmstHPX5CzxDn8ADvwU=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:feq7zRqnFK7E7ZP1HOWLyrZkW4cvsN9+U0GNZej4ZCg=" + }, + "target": "875726715553274711274586950997458160797358911132930209640137826778142618", + "randomness": "0", + "timestamp": 1676496738260, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 7, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAV0w80A17mAmKOs+3nKJsUAtN7VnEYOm8wglZq6cfCCqqNZbHX/Z+Kbwa/JORDy3z7KbD7j1Tx+ziec/qdWRKCK0d470Qpr6Nd77gRpxz0ziCS0Hpmyw7W5Sz06/PkpvWefHxjuRh2louu/uRAn+8f8J/Nh/WxvWGj8EXe/LHLo8JKuNEFmiEe948VKKsgw+qC6Luwv9cod6K8gezFi8KJUgwnFmZKlmgoYZ763kkEqqlqsbX/rtl0GkQdCVdAgH5IB/ZEBAgZkP76ADTF759j4wn7ygFFuUSmICwJID8qBpxo64lNRiA5ztqEsMK3ChQXDAh5tnRm7LeoBbmYNF6yOUiDGRcZBNAalMBqxs5SnyVLTrGAGx0phXjWZesTcRv3/VoP6VPHiAykAIa3mHBN7/JuxqkGPrsY4rWwEANSL57vOqEDMGniNvOe4Sxu7EB5Txlj36LUBQZZmFqub8oA8j2LyAlNTdEM9R7ZfrcnALv33FxAOwoe7OUaSCWIhGol+j4qjBgycTF/OeT6VrJ1Qe0ibAgbntvgB0pn9qR0VAr5aGW5NnJYr6TMR+MkBR/Vl2Lvj6NEKmmKb15EUMoYQqkgOxhGXs104TIDtAqsc7sngGHaczA+klyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwWxI65vAqFwpQGzkQvyUdQ47IS3+liDdes/XbnYcNLZwJJqdR117ICHxuqyccr16gH0m1T72XXHcL/qk5UKGaCA==" + } + ] + }, + { + "header": { + "sequence": 6, + "previousBlockHash": "0A6B039EA7AE12CD6FF295B6B68AC153C29F7A996AE1BF7F6A56270CB8424144", + "noteCommitment": { + "type": "Buffer", + "data": "base64:7qmkZYMrT7uDzpgJ2ztEvOcVVoohyMLFYGyp6nI6SVY=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:TkAct/e3eUWM0QiQlQ0RGlXIjbsFdbkCeexy/EQUGhY=" + }, + "target": "873190827380823143577845869093025366895436057143163037218399975928398962", + "randomness": "0", + "timestamp": 1676496738621, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 8, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAKlvyUZNc0g3PldcM/pUyN84vzzuL3BltJkzN7uFeyNCFlNKhIddf96QwhkeodVZ+/XLzalxVIz5eU95FiwVc9n3fqu79cI/0bpAZKtBrIg6lBqFs0PY8S1Zk5mrtGPAImTVOMy8A9sc3Xo2sDyIt7rZMmnXMYah0olbOxnPtXiQPdL/oD3ec1m2A8sZ6BEKph5ZKxODBgzx5tFDN3CqxL28I5hRspNLphPHhTQkceRiUHwbbWkspsYc7bWbgkdxx9xFINzGxQC5ApIxbIKLc9vasOyScIMTLqtJ22xc08JtnjICACwml0VBGlnPnEmapnM4a2O0EaETL5qBYf/PzDMaOwnfCkeq72CbuJsi132DXMUPUQQ9Y6YAb+GRIA29yX3H0veDUFiYbEDbmRldWtRBJa2SOVM6IsAoQ755M7HMREWls3jTbv421Fp0GmItFg8c2xuwXxkBiciyEoN65D5EBOzv6rkTwFTXTCd2t9ejtLwrU91wH6pYl2i8gHIG/yoX5uJWaTA9NWs1kKfw14IyWFvn6v4emuLBD5IOt3Ex3yXhWSpM/JazmEQ06goYNAe8D+rWZqefifKUIuUiHw0gsDt8EKF6r2YEh4AGSITRRlLAqQVBP20lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwOqdxdN1J6R1taqfACk5fi8lav7bQCosPhs9m9n3N36cztO1CUSW7U9Xqht0VhJ3R6I8+6FK3gwZY2T4Jl92QCQ==" + } + ] + }, + { + "header": { + "sequence": 7, + "previousBlockHash": "D7C63282C52A2EA2B010B3B5D21BF64CB817605EEC79E8A827C13DF4CB174AAE", + "noteCommitment": { + "type": "Buffer", + "data": "base64:NNp8sFIxtkTd2HvBA5Mi0ZUBLz0rSF1BaC1HPbf/12I=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:SWNK+BWyOxYGZ+sSbI1+pEL1AnvUctHPhdMtS2hjMvA=" + }, + "target": "870669583413409794751345832897376592977547406352566801307278513052763546", + "randomness": "0", + "timestamp": 1676496738910, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 9, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA5D2LPuAfabtYP1E2SkTofclTH9+YOs/n+HNu1ja7FmuDM1vTBVaOtsDVw3n7RoEdaBikx9zBVd5QCVgA9bHFGoppjh8z6HOSRuDKOqlS8hiOWIm/a4G9NAAEPSAWB0Y09UzM9jGj3Rvo9bftjEyaCRufPmQBUKzRdZ3CoO42+JMAM0QL08IwjyYfjSLAGardXBSvoR164EUX70d3EpRwyBsDk/peCgsUUq6RFWoUEnKObcAf1/9oGEvazsK8cUln1iNdW7GAhxq8a+oxH/NfdCqVEO7rJnOwC1RLEAusYQ1hdEofXd367GacV/6GAUcAUiTb955ghsnSckpeH3OFRK0fvUd2H0EnHNvz+f2vpSsmbnM8YAjjn9GcX2iUIdNRdxT6CAyFjg+WC65DOKH1+D76rBNNxZAOxW4Dcd5GhqoKXgD6a2z5+AxhU/rZQ7atJz7eW6hizTA43vxNMfSQh6sgBVEbljUBrye+zIr/JsDFK++XsU4P8r3Lm0NCwoKO8LaXd1mpGfX2tLq08PLCCcSeA5KR4lVS26Hqh2ZYvh+c0lrFFdwl6r2XN8urqlFjz+A5sI9joEIv8huYAbsrItBiVKbaQhyR8OG1s6+zoMpHufRlKI9H1Elyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNDggZUIxqLuta1+l+4/fmRVAd3BAErSoy1PWkBGknWYFlFBvomJHq6c3JYYDy4iL2ErqKaEJfJ7upde+84NJAQ==" + } + ] + }, + { + "header": { + "sequence": 8, + "previousBlockHash": "43303E439A58677BFE19648ED10D1C0243486AFC3B19B99E7E09E6A47E56EA07", + "noteCommitment": { + "type": "Buffer", + "data": "base64:J5cXN4LYiKjxnFEfYiHA7gibda/ixbfIS20R38SEWks=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:WpFjqATUO5OsF1vXai91K9+jbSa8otnD8/6i9n2gct0=" + }, + "target": "868162857165578480563002226852566487623485369674008547560712452074684573", + "randomness": "0", + "timestamp": 1676496739203, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 10, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAnhgk6qpMSBXb+1VvRn7Mu0ZHKIlN7fSsibiO78mgcTaXQ9lj/nf0kFyGnE4RqZHzefaTOg+gotxa/OALYfGN1M9Hwkw8hZzospUhlo40uQyIHnGgpWCA2GtZ8hmigeKppNMGJxL69yzzRjV/WSEdR+Y3q2zXtdImJRdsWZDN4fYImxCjLzjBCN8d43iWAqL2DqpmK4pf7d5VubhOiAleQL4r+MFR1llaN9Iis0HE7pWYuw4pbH9dIiRcxnlcPNuFQujmaqWaYDep0sqTMMSVTt4iVuzR3EKk1n2qpeGuOebgbpR1oVNN4vZt9ekX/BBbvQZcIUvMoq01pNotS5/TWbPrW7eF2gt/jqkGuQGwJyUNHJGqYY9biLs1uB+hyb1slXvtUtUVETs4ruhFCFZQKNo5Po7Hs9CkLqpn+444d0uXrJzcE97VndkbRISLnkhWDhZ5j+RxL0rbRck2pEmxuU4QUWsQG9VLbRFL0lxLHWUpwgdFwn2FlKDDLLXqH8BNd3eITHzAvOPad78bT3u4XSl7tLwQ0uBlbYogkpMnuLuTQSK/M+vKbVZQMTORdahwKEglBECASPDQcjt/EoA62rJPOmDcHBkoCKW9g1UgpYdQTJ1usdnR3Ulyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwsRxi8wbDkkmZ2O08Wdw8LCkDrpi9fC44RTOj1L8ILufG7i9ZnSYkKdq9HJ3SJsswcE9n+KsVcDgJisbAW/L0Cw==" + } + ] + }, + { + "header": { + "sequence": 9, + "previousBlockHash": "98D9DCDE28C9AA9E878CD3A4426EAE1C32291DE25EA3A6DF067C4C1BA71A79D7", + "noteCommitment": { + "type": "Buffer", + "data": "base64:OwYSB4gVGRzNHrVEbbmJsZ3GQiHfRam+ML3enQz4xlU=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:8JMIlrCNn+cWt44DulAUUIUdrW4d0eBIiJHvHy7i9T4=" + }, + "target": "865631694431441438209791613778448244346620102758851756346587204580484799", + "randomness": "0", + "timestamp": 1676496739518, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 11, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAeaNMAXi6mtZctWJiS128sMp4+VRxjEGwCaLCI7mptZCgp7fNhV045icLcQrYy+0fRjCg31fCtb/P0Z3DSqA4//lw4nRTwz9334uYVs1Nt8OvmmxtJDvAnZ1KFTp8WG6I8TVhNKp8etnnh+mLFHZxi7oym7YppREoA7FqWOnZFYwZu317HAjrllBH/eoh2jW1ixhibUubD0qx6kkuvBZr/Ph1MTlNiPEILDwJYc/tXW6hwJp6rw6TKAtPNa4pxUchU6xuNlxYayeyNJo5xC5Orgwk9nI/YPdy2EMYtJcy1cZbH+moOrOjbE/Cr6R2KqL88vzATX/0IE3PAd4f7gx5QQrni4D50TZr3Jl5bEtmZ4zyzb4yC7YqpobB55mRycMeFis/iUhMNp9lHrrc+xdAxnCLtFtUoEF0Pf4WeYd0WgHrNew3BDoe42rUPHpZuvdOnlxDwyCdOaV2P30kjhQUGyxoX4OweUnk+bMkm9jcG9eMzfkoEWTwvuAtThQ2Lz28EYQ0lhy8XCC9vIrHimURy9q4AdSdp1TR2fkvaZ7a8xEkil8ev4skfw768BDnJ3Bspn39A6Ldf+aFTsWrcOogBimIEfdHm+OKTD48nW2P9njojUV2/UvmXUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAweB6okD5jXKCeElZEhjJuzOX4f8SDsVpN5HWWSkBFUuYKPff8GSJgNVUABG0maz8c7kYFbug6XU8Zxy7FhBhDCw==" + } + ] + }, + { + "header": { + "sequence": 10, + "previousBlockHash": "41654CADED33E9665C6C78A24C89A6AE649C7C9545E6CCD1927D90505F9A5AAE", + "noteCommitment": { + "type": "Buffer", + "data": "base64:3qHig8+Ftv4X9rMI1NHynOc8rJfeV4o8tMYjZx7tChQ=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:mNftZoFayp1h74+dBwu7xO/1MyuzQwSksXuJp4M1ql0=" + }, + "target": "863115248198486802107777401000983242294567404108951996477664688928658648", + "randomness": "0", + "timestamp": 1676496739798, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 12, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAluc4P/sfl9mLdshF3ATqp7MFIkGJ8PB102G+uSRj3r2rTkbfEZXUQ8pKJxzPSCNu+TJK8f3O8MKQdr9BdyhP6Ev18/8IRnfj6C20V09CLySyBa/JadwJIlLOr+SKCwlSxn4CRV7ft/wHaCj9wLGhNzQc5wfaIHiuj+Q4DulXBA4WQnqOSjspjBd7vv+/lJDdXcdeE+fgfZhs9p7cE28kvow3EONv3mi8QcKAgQZkie2vgUFklnr0X4X8oBHbzHQTVPOoPGQw5gqfIPfsklh2NDYKGl8hTPBD37SpsRoH+BXlhE47Q3ThRjtnF7Sx2CNOCL/ie+BOCgvePBaNjozb5p6A3lSATdO77ChggupuoRvV9my3kKSmei1H4PsYcXJn9g/EAfr8jQ8ZxVW1Ar4pf8B3GGATmau56tJm2PWsUxTeXEXbkrFrjZB/i8ZKlNVAHkIApcirfddEmDYyypijj1Ml3EDnz2L1MxOHq3rwsbFR5YVzkULAUltUY4QK+/CIt5gvA6ZUZEuqWwQPZ853pCzrd4K7aRxQ6STE+UfaFnDJkS9W6frZRJAlUlWwPTxUoJD6OzgqLIkVOgtVVIMnA3kao5qPunwEqBz4jDwtTYtMNo3icQeAHUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw9BMspUQySxKUBexsGhWIkQcNRSfCNfwf3j3YPPE0tu0zkAmJNuOdeuu+5jx4SCsPUAx/RX4cZAVOsqpMdC9DAw==" + } + ] + } + ], + "PeerNetwork handles requests for block headers lookup limit does not include headers beyond the limit": [ + { + "header": { + "sequence": 2, + "previousBlockHash": "D179D8B74987D6617267D46F4958554BA0DF02D7E5E6117DB02D6FF38FD0F6DA", + "noteCommitment": { + "type": "Buffer", + "data": "base64:J58Hf4m8P6lUXm9S9LMhgwgoAqlCa8LeYqX2nt0wQwA=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:5cqj7sYDkdhCD3IVafWXtT+86QCSktFvvXZQMPfKf9g=" + }, + "target": "883423532389192164791648750371459257913741948437809479060803100646309888", + "randomness": "0", + "timestamp": 1676496740115, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 4, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAhjDtHPjPRZFvOZe0o3rQhWyDa85ntlKE0vHAGdueGBesgTRlLDxdl2ya3zeeHqX3jFiTrwHOkMQCYMp9Vbp9tLN1dB3ZHAWS5XORgP5okd2X64OgSKmWkVDTb82IC8XnhWrzJWTfK3mmOP3x5Ue4KGWK9lpE6u9nw79D7KiLDPEH0Ykko03kEqoJcJ7LT+c3HT5igloRCLm+D6BAq6ReEAod2hgMJx2jKnO616aGma2oriO8BOlh3FZ4rCkIsjm+E0VIXCU2vH6G5Xd++I79Ivqj/9J3WIgPIk0VPnLDcIJYOk06wksFSEA2nBsfKbVEzxnorVGeGfy/dLFnL7GwxB2aEeUhCFrNVSaMj5K6A3rlNThgA50VWe5UbwokkGMBWj5WqEJLdhBVCOGJCL/c1PaVZbg4TfPNF2D+ISxxulPcLVV6XVMzDxgD5f5B9SH/Wxcvs7h48s6mN3E/G6qcUSTlnHX1V3eBwGw0Z1ku476bDqH7iBW352TElh18dvVta+dI0mjgtYBXLVs4dTnRhvsDgj74OpM9RBm5/YleR4GC5ay4mlZql1uhKwmF7NaITKkgI2X6eOfcMcXMAMoVYdoLx9zRZ5JezFE0+RC3+chJbB13no6TSUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwcMEXRBjoXO3iKYVyO0qI/OETvfa1V40VdMfuT3GaxE7Y81CalR4EQuCWElH9HDzb3Jmh6QqzBfrSoryXtvriAw==" + } + ] + }, + { + "header": { + "sequence": 3, + "previousBlockHash": "856D867CCF5FDFF3C2913CEAEBA8DCFC354539E453CBB4F4BD4E2DFDF879D329", + "noteCommitment": { + "type": "Buffer", + "data": "base64:FAAqgdnGfBbO7Hp0daTvB2BWNUHKvVfQP7BrkArblWw=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:nzcfc4bXxc/85GXpGOvUmwwaN54wrFA6mIPmy3GdztE=" + }, + "target": "880842937844725196442695540779332307793253899902937591585455087694081134", + "randomness": "0", + "timestamp": 1676496740389, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 5, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAOHkB9MS9Ac6rF2k34Arplry+flkqI99SCtVERM/Wo4SoK8VgEU7Rodzx5MIjY1BOvKBCgfHdtodBYQ/q5dvjRVU0nCNuXIVWJn3hYluK5Aukb7k5lnBQxURIvsmJjRtMNVgt+qbOfxw3YCaCNp778p2gGRzbxb1SX0QMUmJ6roYB4EQULFv8eNKJD9CBhPxcUyH1tcLNRECSMRab4QJ8++pt74EDo+NGAxAK3DWo0vOrrJ17aB5EY0yjTRyXWUgvbWJcKX9YhLu5JLLhe13fB/Mq3Fb5rRmVrAfCovvk+zrOygjSPGEdGTVzpnrFHH/VTG2HpBknvfy/TbY6vtMLIHEgLxJiOEDQyRy2/b0M1q+S/rwNk5VDu3O+n0ximbZggCPYJTzpU9omN30dhP0j5Z+Dxsp3pdcWw4ItRL3LalSW0HKYbIpXU5ml5K81BxnUpAN5s7TeJT0g5vM5z5KRSvPn7SXij2KK4HPtaJCZRtd1L29e8G7Key53vhmmtW86Ps/N1i3gLle4esICeAVouiWWQZFg7UMNQ1JHOsufj1J6hN47am4p7tpdsxNXi+6HPRY08J2Svlk0t1GAQ4YUUcwfrs4LHgYEMrbZeMhAyqHsWoE3+ecEhUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwzJ9VCHF4Qx072B46p+5apAkf6UYCK6LU9U5oH1FJSB0/Iec4v602x5O+FFMgPV4H+mABmDNazM9aIQuMvqEJBw==" + } + ] + }, + { + "header": { + "sequence": 4, + "previousBlockHash": "D57590AE98CFCB6665C238DF0662685AD2C71A6054D3B0A3FB46C8555D75FB62", + "noteCommitment": { + "type": "Buffer", + "data": "base64:d0C8yTs3IkuJS71CzVlcz1rIAb5hkUxj//6DRlrTmmQ=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:g0rkmFnz1icfGxLL1A/lEXSRRdDcliuTNRYLVUtSgwc=" + }, + "target": "878277375889837647326843029495509009809390053592540685978895509768758568", + "randomness": "0", + "timestamp": 1676496740697, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 6, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAfCeZN9M2/7EKD1Mz8fq/YWRZphFYxSzz9r+QZlQLzUWTpKQBwTMdn0r9Ed8UHcLYDqaFVXIYvIAazyDfRZbD+VaeuqHWelbjx+dw9xSTlyK0cws7eXz1lIrZzELlp3Jd7Hkra6NWD9+0+wHPSnnjNo4F8fLzFJgLUQtLXPvNgoUNYOqdci/5c1QX/CQ+CsWQcWZ+LCTZgEifM1mVbgkcO6Dcw+l4VdfppCWNjdEaDjqQXBzqhyHOEuca633/qUhcxTpHlDRkuJEoSWfy+yvIWNBTh4QOjP0ofbcNyoobdJyTOKSo699FVTvnQU/qb8yyRO2IpTrKc5oR3u7eIlhSBgTHJnRsHQM0UidQjyRNbJoAIOocPFeaUCwWX2mnP9EGWrHGf8YtxjTThHXqXLB/tIdS+qCM2wKPVTr4HjaA/dU+uDYf33ySVvhnuqEDCSWsIueYoYDk97QT+Hfl/DxDXs20bD6gOX3Fd9+b8bbyUfLs2mTrtF7T+H0+4Xl2433ZzGf1V7HY2U4CUp1oRCgkk3WMUMiiKknUzNzss/b4XOSPWSh5LRBvsCXN/eiC1zFewYauy6+hyiPA4YlVrPXlN7ibOHB9QRYShnqi6M/Dw/N8+6+yHh8VhUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwShk8oRQHK2bn3ptMsDEdpp6/sej2po+dMpwKcPh0HRASqrlGDPd+leeBSu0CVBCRKxf21NiY1AoFDESomrrcAg==" + } + ] + }, + { + "header": { + "sequence": 5, + "previousBlockHash": "961AD3CF427CF9AB2E92895492BBB085CF75D28503CDD2AD2D48EDA3491798E0", + "noteCommitment": { + "type": "Buffer", + "data": "base64:m9t1fXfqkIo4U/cA1xVgdYu/S70gVcHSbusZ0lYicw8=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:nk0+793pLezxzZxCzCFQYPVRzBQMFOfITaq4L9lxREg=" + }, + "target": "875726715553274711274586950997458160797358911132930209640137826778142618", + "randomness": "0", + "timestamp": 1676496740979, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 7, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAJtQG87XCwGyXp+ycAn6ia2dQYcjzZc5KVzL1SkZ0VZGs4eu1jn8ux4HlF7xfuXt65txomHb9AqlGNpdjCjUDkPYV4E0CJYDutVs96GOh8ZetthGjkjaru7rgHUUDg0Q/NlbosIYqjoGablxD4/bzILM5prQrQ5zLM0QhhDM+wrcNIJZEWl97qFLjphEEe7z+PTJKGoeTVSQPhj9r1Jj1bkHKQqOAqx008P+p8kNbshuhLZDF5EXbj4RssQYnSOv5mIlT3kqpZlnKKUzqdYDwpi89vvBxspV9PnLHj2b0u1H18bhdkYDAPLYTsA8Gfv2oD6jf4iFwzuWM/+HL60HtKz+vk1S3WUdy7a2FdXQ9Yt31y7ToajM1DwKOMapGj65bcKYFTt6Hcnv17qmzLyf9ouh5O24CqENj/wOby3m+QysLDTZ0gXco7BD9SlmQ9R3u2yd5bAh+sfVcSa2weKOW9XrcxCemIUB4tAqPr5LVgGW6RIRF6pyOwWxrVoRtkK+iFafQd18LRJWeVvDBaWn9YJHG8G2j78/vI1dXjPf73fYBbhbQFlPGOh+g2XO9XEhnelJMeaSzGj5/HRGwwAqhB7I4U7thyrK0/1HhuHbt/pe6uVEHSNYXWUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwcvVwtvcRHVJwcaq4jdG3/wFXXCePvD5HS7WM+sNfMIHKMPgp2crDDC5Re0Balxu2i5ZIqmuy4BxqGz50zcX3AQ==" + } + ] + }, + { + "header": { + "sequence": 6, + "previousBlockHash": "3C347F18DD87315BF816FB93B44F533AE80060102922D0CAB82C00C2DC2BA331", + "noteCommitment": { + "type": "Buffer", + "data": "base64:xgELRkwsg2+f0wejyuy3BP3pcSkp0IGzKqMGM/w48AQ=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:CSGfOK/hyNwErr+goAroPBClsAoPwzi7ktv4ZSAuRzw=" + }, + "target": "873190827380823143577845869093025366895436057143163037218399975928398962", + "randomness": "0", + "timestamp": 1676496741259, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 8, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAxTwLJx/fCqDyou5wYpH9x7UXtKo6H2stZEZ87BxOUau1tRkoZwmuHFZvWyE2+qdWCdyMAZFR/ENXjyDCp2XKX7XPLzF2L/PIuA8kRZuAQ6aZ6qiACcv3FKzvj/8TGYDlSVR005ojMW08L1SJACntEN8rY0f/LM6hUu5bad7EJvsI3a+gLwh9RliMMPhu9BVWlG3uBZcUoipZ9wzJrHY+lqxze/aVNq9MLj+nQW+49PeXf9rahGmRgdXueJQP+awqRZjSe7JawfSvsVAMS+a1wgG3BvwkyLws2CR1WOTWM6Ij+Ab9ewvPu7olVsFUyYrUW8LitxsxRpYVZESAL/RqODxWJNcFiBEAFFRbvmzU5WQUxWZB2Z2bgZOl/VIjerRGTpDgLhM2Uuj9M8qGvT+cGY3IVKmNS5bIVSY4rIZ0o4PZShWLpT1XPc63dKFPnXyN1jnKCJ8wJ+nMPbAPYS8xx50A796rky37OmfCoFcVSdZyM3nsRbKLYirBeB7MFII3UX/Aig6C/vWP14ntLLbS5qrvMNSUFAGOjidFUEfU4+/xUYr146hIVwE6PX9dETLwas9f4reDerZOPATQfl5wcXOAdGfcOCHJixxke7ZEJAhC72T72kj42klyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw7muU6zoRS9nMMVbziDjgfozQMwKRFmLtNb8wsIq+m7YhAHHCWVyk3DaMXQYReG3U/nMJNohCt/K4FqHUSwSUCQ==" + } + ] + }, + { + "header": { + "sequence": 7, + "previousBlockHash": "049E0BAA0A1BDA0DB3B92F05AA741651B072E7693E75863C71BC24DCF9D0E591", + "noteCommitment": { + "type": "Buffer", + "data": "base64:N6GRBCak6+lnq+hQo319frhUrdlTnIgzlqodpMTJtWc=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:Ffu13oGWvNtZalblFtHnj/Hr1eXkMaJ6GQeabSmBTEs=" + }, + "target": "870669583413409794751345832897376592977547406352566801307278513052763546", + "randomness": "0", + "timestamp": 1676496741538, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 9, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAIFB2i1UwNYDYhgsR/nR4H6ivJQzj6Y9tqEbeIr7QCYGsgNrPzSZweBZZJL0H0Wwkt+NBcvGHa3Q26xQvrEMOq1NX10kQj1BNwsjZuGnkuIGoyJ9oUhQKveT5oM38v0FAJodEIw6sU2nOftkhDpTlqOdkJ4hyNFsUJcTbruD/tp8QwhgdSu2vABIQB+PLZE0f9OnJ1iVQRE6syQINI0Njk3j6+9BAgjKv6BTrapzqlNmL9nqy3Zn04m2m5xK/C4Hl/XaKgF5icJ8YFBZZxvLC70LJkzhIjIGGTXYKqVSy/YkcBd/4+pzBWmwJwEz8u23hT6DJN7swrqIZ6HiXBDraWipJtDjUOaDpwvSOplxtnfVNRKC1MfXemE7DqvKlNI9DAoEViA6obim2cWX8LQ+aD4RjaV+0jhnYFLC2XlTACIXgZochkIUK8yZ7jydXzJvfS/LuHZEciEuE7xsskRicLF/cgm/yeq0DPxtjA7IoqdzCh+xc2VT5Dr2DI+qC1cfxM7UZSUSZJuXWEiO/T9RimLZa9UxkopXFVdveBbdYo5Pj+BAVwlva1pCqD3VNsVvmVw28Uprupo5Du1jHSo4vtPpdKrFRLmTHXdDQU/TCxq77buNF/JCEK0lyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw1bCIwE89NtU41Mv/RRECrMLQhOIWdD44t6gCee/E2DsFRIRPTEDrRfV4WL2jnGfvHAHirbT/qw3YShLubKqFDA==" + } + ] + }, + { + "header": { + "sequence": 8, + "previousBlockHash": "52AA8AA14C3E7785A1C67275AE93939C318863B11B0963C06C9487C1D63B565B", + "noteCommitment": { + "type": "Buffer", + "data": "base64:YO8fPCCYi1d/4/Esrn4rVBU0ahQ/z0hyzH6eWPG9hmQ=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:UX58aXdK2jYiIoyMpXxFhX1i4Nv5RptYNZ2Vl63xZ6g=" + }, + "target": "868162857165578480563002226852566487623485369674008547560712452074684573", + "randomness": "0", + "timestamp": 1676496741818, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 10, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAA/P4rkwBQ6Iu48T7tWRnMGxnvnlI9fmBVVUjx38F/cuu23D8rBvc16N8DNF4hWtTp4uPIsdjkmbufM+6xyGs6jJZntt3i6vsgyNJygzmedM22vzC3TT65TWjDitcw1UTuloXFa/yYfTQZi1WMlGuK/Oi3YpXA5OWf2KrIyLR30eIWFPrOv7FYC8Oek2ikIzkoMc61cyP/sALs3+BcLEaZa4IWzOXdzaOmL0kInYmXBuiXtmDJdROMHODXtdv/QDUjRv9ThgUa/iN1bYCtPwfjEOMoEBW5kbi1HAtXKcucRjHtrjeYOYzPU7W4dKIRHi2jhPbeQvksXuhRo2767wLTvwiI0Uxc8wk3JPnfRo01t3B/TTrgNncn4pOj1tkJTdNXIVXVKv7p1S4gI7ab7+k2Kjoz80FJAEWHCjDboh4LrU7vjzAqLuQGm3FQcCZJgnNQNYpQfqsEYag6cTzKDJnuwK/AqCtBgIqU3UvIotFrv7Q3sP0iY4EQ4P/eEjK8QghDt98b6v8lKeOS6PYKB7uTa1hmDy325YZQA8BZAORxlu076Q+TJTgiICsq3+nh1XywDRss4CGFCVcsqUtHNlFGXPM6SGxrZBE+yDCzU6FXNNIw2IxsuncrDUlyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwO2aViVwdNmZpspdTqqKfMh4JEbz9Pc0S1GWsGu+lPucjFqwzi6rrjg47UG8Bso2gIRd2R766tTwNUgsW/u8MDA==" + } + ] + }, + { + "header": { + "sequence": 9, + "previousBlockHash": "46A926FEDAB336BBDA8D6B999D2F90F4A61D96BA44D08F2F6B86977BC2DFF599", + "noteCommitment": { + "type": "Buffer", + "data": "base64:XhfT+DqQkqaHDviplyL6CfwcjDghdwafL//Qf2i7DCM=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:b2b6TEpybFJx7f6bH1oO75GCKcheywVZQ5DIeJBVmtI=" + }, + "target": "865631694431441438209791613778448244346620102758851756346587204580484799", + "randomness": "0", + "timestamp": 1676496742098, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 11, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAtrVSwHRUMEWxIk56asw0Wgq9MTf4Cb9GjASNadSkPGuDpUnBwCSqNdJ4BoSWbDoORo4JhpysXtbcxKqSUm2RDLs10cVCXT/pgR+WUMWSqUugL5RayqrzjXHoe5AjRrdiduyPkR1gCJQzATDPyUzsgNNhl3XyK67rRCoLNa684cgDRUgxIOLK/Tu8jLu48qW0+0iiZ2Ae2DhNTPfJbupRNSEGxbuQmjHLI+7JC7bN9qCH3W3e5jjYb95A0fxWbWnhLqgAJmzPaYd3VgPgg2ubOcd019zmJcSjerpVBfh7MTJr28V1W6AGEGiyKBbSIROQ9fimiGsZgZFISxP9yPU7g7O8R2/jJzG9mfengl2tPu6H9TKqF09u2DB/zzhAbyxHeHLxwptR9nfPHp/93aKil8NbvRNkBXurZ8eU8SaccXMPDv7zyD6s7TeuAVYnLCVr5KC2y2+C1OKfJa2YGagzEeJU7lnTpqolz9mw0smgB78It5Q6DXKjsmTNU08o46svAdphBSVM/Nr+nr71n+cVbwg6tRNz3aQ+njEUmU6uAshmCcIb53vLBzEVv0bCJVurGpRg2IuxHA28zo0eB7qouCO+ooV7UmGlqpFwaz2aNjSoRy48pF2RMElyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwx8mub2LifftDhrRyRL9GNg0rTA8YFSSvV2U+LN241uBW91fob4R14H6bv7iSFRCYwWViIPvwHUs41zBghIrWDQ==" + } + ] + }, + { + "header": { + "sequence": 10, + "previousBlockHash": "1682689BECDC16F0CB0F5501786A8F05E7D87DFCE1D83CEBCD670F5A000E134A", + "noteCommitment": { + "type": "Buffer", + "data": "base64:l7HXD2akrR661uJWtZVnl8OYBdiNtUI5f/MbHzKbnzI=" + }, + "transactionCommitment": { + "type": "Buffer", + "data": "base64:LeMku7714XV8umeAzcqz9kKpShYBMRct2NFT8tUrld0=" + }, + "target": "863115248198486802107777401000983242294567404108951996477664688928658648", + "randomness": "0", + "timestamp": 1676496742377, + "graffiti": "0000000000000000000000000000000000000000000000000000000000000000", + "noteSize": 12, + "work": "0" + }, + "transactions": [ + { + "type": "Buffer", + "data": "base64:AQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzKiP////8AAAAAi2OrAtfLj4cjKvvI12KozPx4l0xbbKamLFiknecJNUSZ6550Bjh5RWd7KPKDwZsegHHV7xvcC5I43sFQ2Q1bnbaT/LjiEfoMvjpLexm+VfqDIPYndIOeVg4ne5RSqE7T4w9f6eGMICcZDhE70BSSTn7uN/HN4c3RUaI3yIDtBagWQ4Ql0g4zBMTdTPkai+bmGky2WHznxMU97HRwfSu9eTbFdlpsMmLX+JceaYp+vi6Z1Epyi9tSjDdGO+bP1XSFMepC5OPxnGevUFie0/QWEaflendqg+zoGrSFHlGrBpGv7pqLtby9oWGyR2nTzQ0o/2sHfEmjCpBhaJ7Y++9Uq8FXNJwN8GbF9/BXRVyw5/OH9jrBxz8+ojmcJkW+1StQajyEKxN6Dfv97LLWELAooAHIPUzIEHrHYMlFjMcMeW/zmwxHyea0eYmRyoi3+SOWmdbvG1LpRZZwz4BT0Aa5bjkZRkTAu18JHgEy2hdo7uh6u+BMGL9CmBpzPAXZjrMufMjpfcsDOv4gsEJafS4SbY1SVcKI4DMMfQLfL3F+AbLq6yCUugQgpdgpoiJ/SCq5qNmJ9dS09dzyjZTUb5b5xnRu3o2xDewYkjKx93by9FeraW8R1Uue1Ulyb24gRmlzaCBub3RlIGVuY3J5cHRpb24gbWluZXIga2V5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw08/N8vc8+3zbocG8x7jGpq1L1hdva72c9UgVPcc9s6ePz93JFp9if/E8m5KZP0yFVhEi3+UhX246pGarBVGhDA==" + } + ] + } ] } \ No newline at end of file diff --git a/ironfish/src/network/peerNetwork.test.ts b/ironfish/src/network/peerNetwork.test.ts index 445eabce6b..aece1e3c84 100644 --- a/ironfish/src/network/peerNetwork.test.ts +++ b/ironfish/src/network/peerNetwork.test.ts @@ -53,6 +53,15 @@ import { import { NetworkMessageType } from './types' import { VERSION_PROTOCOL } from './version' +jest.mock('./version', () => { + const moduleMock = jest.requireActual('./version') + return { + ...moduleMock, + MAX_REQUESTED_HEADERS: 4, + MAX_HEADER_LOOKUPS: 8, + } +}) + jest.useFakeTimers() describe('PeerNetwork', () => { @@ -534,6 +543,109 @@ describe('PeerNetwork', () => { response, ) }) + + it('responds with CannotSatisfy when requesting too many headers', async () => { + const { node, peerNetwork } = nodeTest + const block2 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block2) + + const { peer } = getConnectedPeer(peerNetwork.peerManager) + const peerIdentity = peer.getIdentityOrThrow() + + const sendSpy = jest.spyOn(peer, 'send') + + const rpcId = 432 + const message = new GetBlockHeadersRequest(block2.header.hash, 5, 1, false, rpcId) + + await peerNetwork.peerManager.onMessage.emitAsync(peer, { peerIdentity, message }) + + expect(sendSpy.mock.calls[0][0]).toBeInstanceOf(CannotSatisfyRequest) + }) + + describe('lookup limit', () => { + it('includes headers within the limit', async () => { + const { node, peerNetwork } = nodeTest + const block2 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block2) + const block3 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block3) + const block4 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block4) + const block5 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block5) + const block6 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block6) + const block7 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block7) + const block8 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block8) + const block9 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block9) + const block10 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block10) + + const { peer } = getConnectedPeer(peerNetwork.peerManager) + const peerIdentity = peer.getIdentityOrThrow() + + const sendSpy = jest.spyOn(peer, 'send') + + const rpcId = 432 + const message = new GetBlockHeadersRequest(block2.header.sequence, 4, 6, false, rpcId) + // The start header, block2, is the first lookup. Then we skip 6, + // resulting in 7 lookups. The 8th and final lookup is block9. + const response = new GetBlockHeadersResponse([block2.header, block9.header], rpcId) + + await peerNetwork.peerManager.onMessage.emitAsync(peer, { peerIdentity, message }) + + expect(sendSpy.mock.calls[0][0]).toBeInstanceOf(GetBlockHeadersResponse) + expectGetBlockHeadersResponseToMatch( + sendSpy.mock.calls[0][0] as GetBlockHeadersResponse, + response, + ) + }) + + it('does not include headers beyond the limit', async () => { + const { node, peerNetwork } = nodeTest + const block2 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block2) + const block3 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block3) + const block4 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block4) + const block5 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block5) + const block6 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block6) + const block7 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block7) + const block8 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block8) + const block9 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block9) + const block10 = await useMinerBlockFixture(node.chain) + await expect(node.chain).toAddBlock(block10) + + const { peer } = getConnectedPeer(peerNetwork.peerManager) + const peerIdentity = peer.getIdentityOrThrow() + + const sendSpy = jest.spyOn(peer, 'send') + + const rpcId = 432 + const message = new GetBlockHeadersRequest(block2.header.sequence, 4, 7, false, rpcId) + // The start header, block2, is the first lookup. Then we skip 7, + // resulting in 8 lookups. Thus, the header from block10 is not included + // since it would be the 9th lookup. + const response = new GetBlockHeadersResponse([block2.header], rpcId) + + await peerNetwork.peerManager.onMessage.emitAsync(peer, { peerIdentity, message }) + + expect(sendSpy.mock.calls[0][0]).toBeInstanceOf(GetBlockHeadersResponse) + expectGetBlockHeadersResponseToMatch( + sendSpy.mock.calls[0][0] as GetBlockHeadersResponse, + response, + ) + }) + }) }) describe('when enable syncing is true', () => { diff --git a/ironfish/src/network/peerNetwork.ts b/ironfish/src/network/peerNetwork.ts index 422a0bf579..ac486ebb29 100644 --- a/ironfish/src/network/peerNetwork.ts +++ b/ironfish/src/network/peerNetwork.ts @@ -65,7 +65,12 @@ import { PeerManager } from './peers/peerManager' import { TransactionFetcher } from './transactionFetcher' import { IsomorphicWebSocketConstructor } from './types' import { parseUrl } from './utils/parseUrl' -import { MAX_REQUESTED_BLOCKS, VERSION_PROTOCOL } from './version' +import { + MAX_HEADER_LOOKUPS, + MAX_REQUESTED_BLOCKS, + MAX_REQUESTED_HEADERS, + VERSION_PROTOCOL, +} from './version' import { WebSocketServer } from './webSocketServer' /** @@ -1027,12 +1032,14 @@ export class PeerNetwork { return new GetBlockHeadersResponse([], rpcId) } - if (request.message.limit > MAX_REQUESTED_BLOCKS) { + if (request.message.limit > MAX_REQUESTED_HEADERS) { peer.punish( BAN_SCORE.MAX, `Peer sent GetBlockHeaders with limit of ${request.message.limit}`, ) - const error = new CannotSatisfyRequestError(`Requested more than ${MAX_REQUESTED_BLOCKS}`) + const error = new CannotSatisfyRequestError( + `Requested more than ${MAX_REQUESTED_HEADERS}`, + ) throw error } @@ -1050,6 +1057,9 @@ export class PeerNetwork { const headers = [] let skipCounter = skip + // Limit the total number of lookups to avoid excessive disk usage + let remainingLookups = MAX_HEADER_LOOKUPS + // If `reverse` is true, we iterate in descending order, using `start` as the // highest sequence. Otherwise, we iterate in ascending order, using // `start` as the lowest sequence. @@ -1058,6 +1068,11 @@ export class PeerNetwork { : (from: BlockHeader) => this.chain.iterateTo(from) for await (const header of iterationFunction(from)) { + if (remainingLookups === 0) { + break + } + remainingLookups -= 1 + if (skip) { if (skipCounter < skip) { skipCounter += 1 diff --git a/ironfish/src/network/version.ts b/ironfish/src/network/version.ts index d82f7a21db..fda1fecb78 100644 --- a/ironfish/src/network/version.ts +++ b/ironfish/src/network/version.ts @@ -6,4 +6,6 @@ export const VERSION_PROTOCOL = 20 export const VERSION_PROTOCOL_MIN = 19 export const MAX_REQUESTED_BLOCKS = 50 +export const MAX_REQUESTED_HEADERS = 1024 +export const MAX_HEADER_LOOKUPS = MAX_REQUESTED_HEADERS * 2 export const MAX_MESSAGE_SIZE = 256 * 1024 * 1024 From 5a582cd9ebf3a7f91c46aa10282012a1f853e266 Mon Sep 17 00:00:00 2001 From: jowparks Date: Fri, 17 Feb 2023 15:24:53 -0800 Subject: [PATCH 39/43] chore: snake case to camel case returned for rust Key (#3467) --- ironfish-cli/src/commands/wallet/import.ts | 2 +- ironfish-rust-nodejs/index.d.ts | 10 ++--- ironfish-rust-nodejs/src/lib.rs | 5 --- ironfish-rust-nodejs/tests/demo.test.slow.ts | 44 +++++++++---------- ironfish/src/blockchain/blockchain.test.ts | 2 +- ironfish/src/consensus/verifier.test.ts | 4 +- ironfish/src/genesis/genesis.test.slow.ts | 6 +-- ironfish/src/genesis/makeGenesisBlock.ts | 14 +++--- .../data/022-add-view-key-account.ts | 2 +- .../src/primitives/rawTransaction.test.ts | 2 +- ironfish/src/strategy.test.slow.ts | 30 ++++++------- ironfish/src/testUtilities/fixtures/blocks.ts | 6 +-- ironfish/src/wallet/wallet.test.slow.ts | 36 +++++++-------- ironfish/src/wallet/wallet.test.ts | 4 +- ironfish/src/wallet/wallet.ts | 18 ++++---- .../src/wallet/walletdb/accountValue.test.ts | 10 ++--- ironfish/src/workerPool/job.test.slow.ts | 2 +- .../src/workerPool/tasks/createMinersFee.ts | 2 +- 18 files changed, 97 insertions(+), 102 deletions(-) diff --git a/ironfish-cli/src/commands/wallet/import.ts b/ironfish-cli/src/commands/wallet/import.ts index 1c99fe7c88..057cf45363 100644 --- a/ironfish-cli/src/commands/wallet/import.ts +++ b/ironfish-cli/src/commands/wallet/import.ts @@ -99,7 +99,7 @@ export class ImportCommand extends IronfishCommand { static verifySpendingKey(spendingKey: string): string | null { try { - return generateKeyFromPrivateKey(spendingKey)?.spending_key + return generateKeyFromPrivateKey(spendingKey)?.spendingKey } catch (e) { return null } diff --git a/ironfish-rust-nodejs/index.d.ts b/ironfish-rust-nodejs/index.d.ts index e77ef70cc8..a2bbc47521 100644 --- a/ironfish-rust-nodejs/index.d.ts +++ b/ironfish-rust-nodejs/index.d.ts @@ -52,11 +52,11 @@ export const enum LanguageCode { Spanish = 7 } export interface Key { - spending_key: string - view_key: string - incoming_view_key: string - outgoing_view_key: string - public_address: string + spendingKey: string + viewKey: string + incomingViewKey: string + outgoingViewKey: string + publicAddress: string } export function generateKey(): Key export function spendingKeyToWords(privateKey: string, languageCode: LanguageCode): string diff --git a/ironfish-rust-nodejs/src/lib.rs b/ironfish-rust-nodejs/src/lib.rs index b4a31da816..ba96451a13 100644 --- a/ironfish-rust-nodejs/src/lib.rs +++ b/ironfish-rust-nodejs/src/lib.rs @@ -55,15 +55,10 @@ impl From for Language { #[napi(object)] pub struct Key { - #[napi(js_name = "spending_key")] pub spending_key: String, - #[napi(js_name = "view_key")] pub view_key: String, - #[napi(js_name = "incoming_view_key")] pub incoming_view_key: String, - #[napi(js_name = "outgoing_view_key")] pub outgoing_view_key: String, - #[napi(js_name = "public_address")] pub public_address: String, } diff --git a/ironfish-rust-nodejs/tests/demo.test.slow.ts b/ironfish-rust-nodejs/tests/demo.test.slow.ts index 671e953ab9..d7d0a9c7a9 100644 --- a/ironfish-rust-nodejs/tests/demo.test.slow.ts +++ b/ironfish-rust-nodejs/tests/demo.test.slow.ts @@ -21,17 +21,17 @@ describe('Demonstrate the Sapling API', () => { it('Should generate a key', () => { const key = generateKey() - expect(typeof key.incoming_view_key).toBe('string') - expect(typeof key.outgoing_view_key).toBe('string') - expect(typeof key.public_address).toBe('string') - expect(typeof key.spending_key).toBe('string') + expect(typeof key.incomingViewKey).toBe('string') + expect(typeof key.outgoingViewKey).toBe('string') + expect(typeof key.publicAddress).toBe('string') + expect(typeof key.spendingKey).toBe('string') }) it('Should be able to convert hex key to words, and reverse', () => { const hexKey = 'd56b241ca965b3997485ccf06421740c1d61163922ad1c02ee69fbe09253daf7' const hexKeyWords = 'step float already fan forest smile spirit ridge vacant canal fringe blouse stock mention tonight fiber bright blast omit water ankle clarify hint turn' const key = generateKeyFromPrivateKey(hexKey) - const words = spendingKeyToWords(key.spending_key, LanguageCode.English); + const words = spendingKeyToWords(key.spendingKey, LanguageCode.English); expect(words).toEqual(hexKeyWords) const hexKeyGenerated = wordsToSpendingKey(words, LanguageCode.English); @@ -42,24 +42,24 @@ describe('Demonstrate the Sapling API', () => { const hexSpendingKey = 'd96dc74bbca05dffb14a5631024588364b0cc9f583b5c11908b6ea98a2b778f7' const key = generateKeyFromPrivateKey(hexSpendingKey) // concatenated bytes of authorizing_key and nullifier_deriving_key - expect(key.view_key).toEqual('498b5103a72c41237c3f2bca96f20100f5a3a8a17c6b8366a485fd16e8931a5d2ff2eb8f991032c815414ff0ae2d8bc3ea3b56bffc481db3f28e800050244463') + expect(key.viewKey).toEqual('498b5103a72c41237c3f2bca96f20100f5a3a8a17c6b8366a485fd16e8931a5d2ff2eb8f991032c815414ff0ae2d8bc3ea3b56bffc481db3f28e800050244463') }) it('Should generate a new public address given a spending key', () => { const key = generateKey() - const newKey = generateKeyFromPrivateKey(key.spending_key) + const newKey = generateKeyFromPrivateKey(key.spendingKey) - expect(key.incoming_view_key).toEqual(newKey.incoming_view_key) - expect(key.outgoing_view_key).toEqual(newKey.outgoing_view_key) - expect(typeof newKey.public_address).toBe('string') - expect(key.spending_key).toEqual(newKey.spending_key) + expect(key.incomingViewKey).toEqual(newKey.incomingViewKey) + expect(key.outgoingViewKey).toEqual(newKey.outgoingViewKey) + expect(typeof newKey.publicAddress).toBe('string') + expect(key.spendingKey).toEqual(newKey.spendingKey) }) it(`Should create a miner's fee transaction`, () => { const key = generateKey() - const transaction = new Transaction(key.spending_key) - const note = new Note(key.public_address, BigInt(20), 'test', Asset.nativeId(), key.public_address) + const transaction = new Transaction(key.spendingKey) + const note = new Note(key.publicAddress, BigInt(20), 'test', Asset.nativeId(), key.publicAddress) transaction.output(note) const serializedPostedTransaction = transaction.post_miners_fee() @@ -76,11 +76,11 @@ describe('Demonstrate the Sapling API', () => { expect(encryptedNote.hash().byteLength).toBe(32) expect(encryptedNote.equals(encryptedNote)).toBe(true) - const decryptedNoteBuffer = encryptedNote.decryptNoteForOwner(key.incoming_view_key) + const decryptedNoteBuffer = encryptedNote.decryptNoteForOwner(key.incomingViewKey) expect(decryptedNoteBuffer).toBeInstanceOf(Buffer) expect(decryptedNoteBuffer!.byteLength).toBe(DECRYPTED_NOTE_LENGTH) - const decryptedSpenderNote = encryptedNote.decryptNoteForSpender(key.outgoing_view_key) + const decryptedSpenderNote = encryptedNote.decryptNoteForSpender(key.outgoingViewKey) expect(decryptedSpenderNote).toBe(null) const decryptedNote = Note.deserialize(decryptedNoteBuffer!) @@ -88,24 +88,24 @@ describe('Demonstrate the Sapling API', () => { // Null characters are included in the memo string expect(decryptedNote.memo().replace(/\0/g, '')).toEqual('test') expect(decryptedNote.value()).toEqual(BigInt(20)) - expect(decryptedNote.nullifier(key.view_key, BigInt(0)).byteLength).toBeGreaterThan(BigInt(0)) + expect(decryptedNote.nullifier(key.viewKey, BigInt(0)).byteLength).toBeGreaterThan(BigInt(0)) }) it(`Should create a standard transaction`, () => { const key = generateKey() const recipientKey = generateKey() - const minersFeeTransaction = new Transaction(key.spending_key) - const minersFeeNote = new Note(key.public_address, BigInt(20), 'miner', Asset.nativeId(), key.public_address) + const minersFeeTransaction = new Transaction(key.spendingKey) + const minersFeeNote = new Note(key.publicAddress, BigInt(20), 'miner', Asset.nativeId(), key.publicAddress) minersFeeTransaction.output(minersFeeNote) const postedMinersFeeTransaction = new TransactionPosted(minersFeeTransaction.post_miners_fee()) - const transaction = new Transaction(key.spending_key) + const transaction = new Transaction(key.spendingKey) transaction.setExpiration(10) const encryptedNote = new NoteEncrypted(postedMinersFeeTransaction.getNote(0)) - const decryptedNote = Note.deserialize(encryptedNote.decryptNoteForOwner(key.incoming_view_key)!) - const newNote = new Note(recipientKey.public_address, BigInt(15), 'receive', Asset.nativeId(), minersFeeNote.owner()) + const decryptedNote = Note.deserialize(encryptedNote.decryptNoteForOwner(key.incomingViewKey)!) + const newNote = new Note(recipientKey.publicAddress, BigInt(15), 'receive', Asset.nativeId(), minersFeeNote.owner()) let currentHash = encryptedNote.hash() let authPath = Array.from({ length: 32 }, (_, depth) => { @@ -128,7 +128,7 @@ describe('Demonstrate the Sapling API', () => { transaction.spend(decryptedNote, witness) transaction.output(newNote) - const postedTransaction = new TransactionPosted(transaction.post(key.public_address, BigInt(5))) + const postedTransaction = new TransactionPosted(transaction.post(key.publicAddress, BigInt(5))) expect(postedTransaction.expiration()).toEqual(10) expect(postedTransaction.fee()).toEqual(BigInt(5)) diff --git a/ironfish/src/blockchain/blockchain.test.ts b/ironfish/src/blockchain/blockchain.test.ts index 42250fbd4e..e86df93be5 100644 --- a/ironfish/src/blockchain/blockchain.test.ts +++ b/ironfish/src/blockchain/blockchain.test.ts @@ -1430,7 +1430,7 @@ describe('Blockchain', () => { return node.chain.newBlock( [burnTransaction, spendTransaction], - await node.strategy.createMinersFee(fee, 3, generateKey().spending_key), + await node.strategy.createMinersFee(fee, 3, generateKey().spendingKey), ) }) diff --git a/ironfish/src/consensus/verifier.test.ts b/ironfish/src/consensus/verifier.test.ts index 818f0ed328..61793e8597 100644 --- a/ironfish/src/consensus/verifier.test.ts +++ b/ironfish/src/consensus/verifier.test.ts @@ -182,7 +182,7 @@ describe('Verifier', () => { () => { const key = generateKey() const reward = nodeTest.strategy.miningReward(minersBlock.header.sequence) - const owner = key.public_address + const owner = key.publicAddress const minerNote1 = new NativeNote( owner, BigInt(reward / 2), @@ -197,7 +197,7 @@ describe('Verifier', () => { Asset.nativeId(), owner, ) - const transaction = new NativeTransaction(key.spending_key) + const transaction = new NativeTransaction(key.spendingKey) transaction.output(minerNote1) transaction.output(minerNote2) return new Transaction(transaction._postMinersFeeUnchecked()) diff --git a/ironfish/src/genesis/genesis.test.slow.ts b/ironfish/src/genesis/genesis.test.slow.ts index 5a69df2f44..9e51514271 100644 --- a/ironfish/src/genesis/genesis.test.slow.ts +++ b/ironfish/src/genesis/genesis.test.slow.ts @@ -31,7 +31,7 @@ describe('Read genesis block', () => { const minersfee = await nodeTest.strategy.createMinersFee( BigInt(0), nodeTest.chain.head.sequence + 1, - generateKey().spending_key, + generateKey().spendingKey, ) const newBlock = await nodeTest.chain.newBlock([], minersfee) expect(newBlock).toBeTruthy() @@ -106,7 +106,7 @@ describe('Create genesis block', () => { const minersfee = await strategy.createMinersFee( BigInt(0), block.header.sequence + 1, - generateKey().spending_key, + generateKey().spendingKey, ) const additionalBlock = await chain.newBlock([], minersfee) expect(additionalBlock).toBeTruthy() @@ -144,7 +144,7 @@ describe('Create genesis block', () => { const newMinersfee = await strategy.createMinersFee( BigInt(0), deserializedBlock.header.sequence + 1, - generateKey().spending_key, + generateKey().spendingKey, ) const newBlock = await newChain.newBlock([], newMinersfee) expect(newBlock).toBeTruthy() diff --git a/ironfish/src/genesis/makeGenesisBlock.ts b/ironfish/src/genesis/makeGenesisBlock.ts index dc9c243029..7e75d496ae 100644 --- a/ironfish/src/genesis/makeGenesisBlock.ts +++ b/ironfish/src/genesis/makeGenesisBlock.ts @@ -54,11 +54,11 @@ export async function makeGenesisBlock( const genesisKey = generateKey() // Create a genesis note granting the genesisKey allocationSum coins. const genesisNote = new NativeNote( - genesisKey.public_address, + genesisKey.publicAddress, allocationSum, '', Asset.nativeId(), - genesisKey.public_address, + genesisKey.publicAddress, ) // Create a miner's fee transaction for the block. @@ -70,14 +70,14 @@ export async function makeGenesisBlock( logger.info(`Generating a miner's fee transaction for the block...`) const minersFeeKey = generateKey() const note = new NativeNote( - minersFeeKey.public_address, + minersFeeKey.publicAddress, BigInt(0), '', Asset.nativeId(), - minersFeeKey.public_address, + minersFeeKey.publicAddress, ) - const minersFeeTransaction = new NativeTransaction(minersFeeKey.spending_key) + const minersFeeTransaction = new NativeTransaction(minersFeeKey.spendingKey) minersFeeTransaction.output(note) const postedMinersFeeTransaction = new Transaction(minersFeeTransaction.post_miners_fee()) @@ -88,7 +88,7 @@ export async function makeGenesisBlock( * */ logger.info(`Generating an initial transaction with ${allocationSumInIron} coins...`) - const initialTransaction = new NativeTransaction(genesisKey.spending_key) + const initialTransaction = new NativeTransaction(genesisKey.spendingKey) logger.info(' Generating the output...') initialTransaction.output(genesisNote) @@ -124,7 +124,7 @@ export async function makeGenesisBlock( * */ logger.info('Generating a transaction for distributing allocations...') - const transaction = new NativeTransaction(genesisKey.spending_key) + const transaction = new NativeTransaction(genesisKey.spendingKey) logger.info(` Generating a spend for ${allocationSumInIron} coins...`) transaction.spend(genesisNote, witness) diff --git a/ironfish/src/migrations/data/022-add-view-key-account.ts b/ironfish/src/migrations/data/022-add-view-key-account.ts index 1eefdb5944..540e110a9f 100644 --- a/ironfish/src/migrations/data/022-add-view-key-account.ts +++ b/ironfish/src/migrations/data/022-add-view-key-account.ts @@ -34,7 +34,7 @@ export class Migration022 extends Migration { const migrated = { ...account, - viewKey: key.view_key, + viewKey: key.viewKey, } await stores.new.accounts.put(account.id, migrated, tx) diff --git a/ironfish/src/primitives/rawTransaction.test.ts b/ironfish/src/primitives/rawTransaction.test.ts index 7e94a2dcd0..5fa9cc3d20 100644 --- a/ironfish/src/primitives/rawTransaction.test.ts +++ b/ironfish/src/primitives/rawTransaction.test.ts @@ -186,7 +186,7 @@ describe('RawTransactionSerde', () => { const note = new Note( new NativeNote( - generateKey().public_address, + generateKey().publicAddress, 5n, 'memo', asset.id(), diff --git a/ironfish/src/strategy.test.slow.ts b/ironfish/src/strategy.test.slow.ts index 16e58b47f9..cf4a2454a1 100644 --- a/ironfish/src/strategy.test.slow.ts +++ b/ironfish/src/strategy.test.slow.ts @@ -93,11 +93,11 @@ describe('Demonstrate the Sapling API', () => { describe('Can transact between two accounts', () => { it('Can create a miner reward', () => { - const owner = generateKeyFromPrivateKey(spenderKey.spending_key).public_address + const owner = generateKeyFromPrivateKey(spenderKey.spendingKey).publicAddress minerNote = new NativeNote(owner, BigInt(42), '', Asset.nativeId(), owner) - const transaction = new NativeTransaction(spenderKey.spending_key) + const transaction = new NativeTransaction(spenderKey.spendingKey) transaction.output(minerNote) minerTransaction = new NativeTransactionPosted(transaction.post_miners_fee()) expect(minerTransaction).toBeTruthy() @@ -123,7 +123,7 @@ describe('Demonstrate the Sapling API', () => { }) it('Can create a simple transaction', () => { - transaction = new NativeTransaction(spenderKey.spending_key) + transaction = new NativeTransaction(spenderKey.spendingKey) expect(transaction).toBeTruthy() }) @@ -137,7 +137,7 @@ describe('Demonstrate the Sapling API', () => { // Add an output to the transaction receiverKey = generateKey() const outputNote = new NativeNote( - receiverKey.public_address, + receiverKey.publicAddress, BigInt(40), '', Asset.nativeId(), @@ -175,7 +175,7 @@ describe('Demonstrate the Sapling API', () => { workerPool, consensus: new TestnetConsensus(consensusParameters), }) - const minersFee = await strategy.createMinersFee(BigInt(0), 0, generateKey().spending_key) + const minersFee = await strategy.createMinersFee(BigInt(0), 0, generateKey().spendingKey) expect(minersFee['transactionPosted']).toBeNull() expect(await workerPool.verify(minersFee, { verifyFees: false })).toEqual({ valid: true }) @@ -189,7 +189,7 @@ describe('Demonstrate the Sapling API', () => { consensus: new TestnetConsensus(consensusParameters), }) - const minersFee = await strategy.createMinersFee(BigInt(0), 0, generateKey().spending_key) + const minersFee = await strategy.createMinersFee(BigInt(0), 0, generateKey().spendingKey) await minersFee.withReference(async () => { expect(minersFee['transactionPosted']).not.toBeNull() @@ -212,7 +212,7 @@ describe('Demonstrate the Sapling API', () => { workerPool: new WorkerPool(), consensus: new TestnetConsensus(consensusParameters), }) - const minersFee = await strategy.createMinersFee(BigInt(0), 0, key.spending_key) + const minersFee = await strategy.createMinersFee(BigInt(0), 0, key.spendingKey) expect(minersFee['transactionPosted']).toBeNull() @@ -223,7 +223,7 @@ describe('Demonstrate the Sapling API', () => { } expect(note['noteEncrypted']).toBeNull() - const decryptedNote = note.decryptNoteForOwner(key.incoming_view_key) + const decryptedNote = note.decryptNoteForOwner(key.incomingViewKey) expect(decryptedNote).toBeDefined() expect(note['noteEncrypted']).toBeNull() @@ -249,7 +249,7 @@ describe('Demonstrate the Sapling API', () => { expect(leaf.merkleHash.equals(latestNote.hash())).toBe(true) // We should be able to decrypt the note as owned by the receiver - const decryptedNote = latestNote.decryptNoteForOwner(receiverKey.incoming_view_key) + const decryptedNote = latestNote.decryptNoteForOwner(receiverKey.incomingViewKey) expect(decryptedNote).toBeTruthy() if (!decryptedNote) { throw new Error('DecryptedNote should be truthy') @@ -257,17 +257,17 @@ describe('Demonstrate the Sapling API', () => { receiverNote = decryptedNote // If we can decrypt a note as owned by the receiver, the spender should not be able to decrypt it as owned - expect(latestNote.decryptNoteForOwner(spenderKey.incoming_view_key)).toBeUndefined() + expect(latestNote.decryptNoteForOwner(spenderKey.incomingViewKey)).toBeUndefined() // Nor should the receiver be able to decrypt it as spent - expect(latestNote.decryptNoteForSpender(receiverKey.outgoing_view_key)).toBeUndefined() + expect(latestNote.decryptNoteForSpender(receiverKey.outgoingViewKey)).toBeUndefined() // However, the spender should be able to decrypt it as spent - expect(latestNote.decryptNoteForSpender(spenderKey.outgoing_view_key)).toBeTruthy() + expect(latestNote.decryptNoteForSpender(spenderKey.outgoingViewKey)).toBeTruthy() }) it('Can create and post a transaction', async () => { - transaction = new NativeTransaction(receiverKey.spending_key) + transaction = new NativeTransaction(receiverKey.spendingKey) const witness = await tree.witness(receiverWitnessIndex) if (witness === null) { @@ -280,9 +280,9 @@ describe('Demonstrate the Sapling API', () => { transaction.spend(note, witness) receiverNote.returnReference() - const receiverAddress = receiverKey.public_address + const receiverAddress = receiverKey.publicAddress const noteForSpender = new NativeNote( - spenderKey.public_address, + spenderKey.publicAddress, BigInt(10), '', Asset.nativeId(), diff --git a/ironfish/src/testUtilities/fixtures/blocks.ts b/ironfish/src/testUtilities/fixtures/blocks.ts index cf0b2f0ed9..44e0bdbc0e 100644 --- a/ironfish/src/testUtilities/fixtures/blocks.ts +++ b/ironfish/src/testUtilities/fixtures/blocks.ts @@ -72,7 +72,7 @@ export async function useMinerBlockFixture( addTransactionsTo?: Wallet, transactions: Transaction[] = [], ): Promise { - const spendingKey = account ? account.spendingKey : generateKey().spending_key + const spendingKey = account ? account.spendingKey : generateKey().spendingKey const transactionFees = transactions.reduce((a, t) => a + t.fee(), BigInt(0)) return await useBlockFixture( @@ -261,7 +261,7 @@ export async function useBlockWithTx( return node.chain.newBlock( [transaction], - await node.strategy.createMinersFee(transaction.fee(), 3, generateKey().spending_key), + await node.strategy.createMinersFee(transaction.fee(), 3, generateKey().spendingKey), ) }) @@ -328,7 +328,7 @@ export async function useBlockWithTxs( return node.chain.newBlock( transactions, - await node.strategy.createMinersFee(transactionFees, 3, generateKey().spending_key), + await node.strategy.createMinersFee(transactionFees, 3, generateKey().spendingKey), ) }) diff --git a/ironfish/src/wallet/wallet.test.slow.ts b/ironfish/src/wallet/wallet.test.slow.ts index 215efa6156..0732d23302 100644 --- a/ironfish/src/wallet/wallet.test.slow.ts +++ b/ironfish/src/wallet/wallet.test.slow.ts @@ -109,7 +109,7 @@ describe('Accounts', () => { account, [ { - publicAddress: generateKey().public_address, + publicAddress: generateKey().publicAddress, amount: BigInt(2), memo: '', assetId: Asset.nativeId(), @@ -124,7 +124,7 @@ describe('Accounts', () => { const minersfee2 = await strategy.createMinersFee( transaction.fee(), newBlock.header.sequence + 1, - generateKey().spending_key, + generateKey().spendingKey, ) const newBlock2 = await chain.newBlock([transaction], minersfee2) const addResult2 = await chain.addBlock(newBlock2) @@ -177,7 +177,7 @@ describe('Accounts', () => { account, [ { - publicAddress: generateKey().public_address, + publicAddress: generateKey().publicAddress, amount: BigInt(2), memo: '', assetId: Asset.nativeId(), @@ -195,7 +195,7 @@ describe('Accounts', () => { const minersfee2 = await strategy.createMinersFee( transaction.fee(), newBlock.header.sequence + 1, - generateKey().spending_key, + generateKey().spendingKey, ) const newBlock2 = await chain.newBlock([transaction], minersfee2) const addResult2 = await chain.addBlock(newBlock2) @@ -247,19 +247,19 @@ describe('Accounts', () => { account, [ { - publicAddress: generateKey().public_address, + publicAddress: generateKey().publicAddress, amount: BigInt(2), memo: 'recipient 1', assetId: Asset.nativeId(), }, { - publicAddress: generateKey().public_address, + publicAddress: generateKey().publicAddress, amount: BigInt(2), memo: 'recipient 2', assetId: Asset.nativeId(), }, { - publicAddress: generateKey().public_address, + publicAddress: generateKey().publicAddress, amount: BigInt(2), memo: 'recipient 3', assetId: Asset.nativeId(), @@ -277,7 +277,7 @@ describe('Accounts', () => { const minersfee2 = await strategy.createMinersFee( transaction.fee(), newBlock.header.sequence + 1, - generateKey().spending_key, + generateKey().spendingKey, ) const newBlock2 = await chain.newBlock([transaction], minersfee2) const addResult2 = await chain.addBlock(newBlock2) @@ -301,7 +301,7 @@ describe('Accounts', () => { account, [ { - publicAddress: generateKey().public_address, + publicAddress: generateKey().publicAddress, amount: BigInt(2), memo: '', assetId: Asset.nativeId(), @@ -356,7 +356,7 @@ describe('Accounts', () => { account, [ { - publicAddress: generateKey().public_address, + publicAddress: generateKey().publicAddress, amount: BigInt(2), memo: '', assetId: Asset.nativeId(), @@ -383,7 +383,7 @@ describe('Accounts', () => { const minersfee2 = await strategy.createMinersFee( transaction.fee(), newBlock.header.sequence + 1, - generateKey().spending_key, + generateKey().spendingKey, ) const newBlock2 = await chain.newBlock([], minersfee2) const addResult2 = await chain.addBlock(newBlock2) @@ -442,7 +442,7 @@ describe('Accounts', () => { account, [ { - publicAddress: generateKey().public_address, + publicAddress: generateKey().publicAddress, amount: BigInt(2), memo: '', assetId: Asset.nativeId(), @@ -466,7 +466,7 @@ describe('Accounts', () => { const minersfee2 = await strategy.createMinersFee( transaction.fee(), newBlock.header.sequence + 1, - generateKey().spending_key, + generateKey().spendingKey, ) const newBlock2 = await chain.newBlock([], minersfee2) const addResult2 = await chain.addBlock(newBlock2) @@ -522,7 +522,7 @@ describe('Accounts', () => { // Create block 2 return nodeA.chain.newBlock( [transaction], - await nodeA.strategy.createMinersFee(transaction.fee(), 3, generateKey().spending_key), + await nodeA.strategy.createMinersFee(transaction.fee(), 3, generateKey().spendingKey), ) }) @@ -665,7 +665,7 @@ describe('Accounts', () => { // Create block A2 return nodeA.chain.newBlock( [transaction], - await nodeA.strategy.createMinersFee(BigInt(0), 3, generateKey().spending_key), + await nodeA.strategy.createMinersFee(BigInt(0), 3, generateKey().spendingKey), ) }, nodeA.wallet, @@ -778,7 +778,7 @@ describe('Accounts', () => { // Create block A2 return nodeA.chain.newBlock( [transaction], - await nodeA.strategy.createMinersFee(BigInt(0), 3, generateKey().spending_key), + await nodeA.strategy.createMinersFee(BigInt(0), 3, generateKey().spendingKey), ) }, nodeB.wallet, @@ -791,7 +791,7 @@ describe('Accounts', () => { const blockB2 = await useBlockFixture(nodeB.chain, async () => nodeB.chain.newBlock( [], - await nodeB.strategy.createMinersFee(BigInt(0), 3, generateKey().spending_key), + await nodeB.strategy.createMinersFee(BigInt(0), 3, generateKey().spendingKey), ), ) addedBlock = await nodeB.chain.addBlock(blockB2) @@ -801,7 +801,7 @@ describe('Accounts', () => { const blockB3 = await useBlockFixture(nodeB.chain, async () => nodeB.chain.newBlock( [], - await nodeB.strategy.createMinersFee(BigInt(0), 4, generateKey().spending_key), + await nodeB.strategy.createMinersFee(BigInt(0), 4, generateKey().spendingKey), ), ) addedBlock = await nodeB.chain.addBlock(blockB3) diff --git a/ironfish/src/wallet/wallet.test.ts b/ironfish/src/wallet/wallet.test.ts index f640917d5d..ae4eb0e0a3 100644 --- a/ironfish/src/wallet/wallet.test.ts +++ b/ironfish/src/wallet/wallet.test.ts @@ -1065,7 +1065,7 @@ describe('Accounts', () => { const mintBlock = await node.chain.newBlock( [transaction], - await node.strategy.createMinersFee(transaction.fee(), 4, generateKey().spending_key), + await node.strategy.createMinersFee(transaction.fee(), 4, generateKey().spendingKey), ) await expect(node.chain).toAddBlock(mintBlock) await node.wallet.updateHead() @@ -1230,7 +1230,7 @@ describe('Accounts', () => { return node.chain.newBlock( [transaction], - await node.strategy.createMinersFee(transaction.fee(), 3, generateKey().spending_key), + await node.strategy.createMinersFee(transaction.fee(), 3, generateKey().spendingKey), ) }) await expect(node.chain).toAddBlock(blockB) diff --git a/ironfish/src/wallet/wallet.ts b/ironfish/src/wallet/wallet.ts index 71757422dc..d5a9f624fa 100644 --- a/ironfish/src/wallet/wallet.ts +++ b/ironfish/src/wallet/wallet.ts @@ -1269,11 +1269,11 @@ export class Wallet { version: ACCOUNT_SCHEMA_VERSION, id: uuid(), name, - incomingViewKey: key.incoming_view_key, - outgoingViewKey: key.outgoing_view_key, - publicAddress: key.public_address, - spendingKey: key.spending_key, - viewKey: key.view_key, + incomingViewKey: key.incomingViewKey, + outgoingViewKey: key.outgoingViewKey, + publicAddress: key.publicAddress, + spendingKey: key.spendingKey, + viewKey: key.viewKey, walletDb: this.walletDb, }) @@ -1317,10 +1317,10 @@ export class Wallet { ...toImport, version: ACCOUNT_SCHEMA_VERSION, id: uuid(), - viewKey: key.view_key, - incomingViewKey: key.incoming_view_key, - outgoingViewKey: key.outgoing_view_key, - publicAddress: key.public_address, + viewKey: key.viewKey, + incomingViewKey: key.incomingViewKey, + outgoingViewKey: key.outgoingViewKey, + publicAddress: key.publicAddress, } validateAccount(accountValue) diff --git a/ironfish/src/wallet/walletdb/accountValue.test.ts b/ironfish/src/wallet/walletdb/accountValue.test.ts index 0b29afdaae..7d34d302b7 100644 --- a/ironfish/src/wallet/walletdb/accountValue.test.ts +++ b/ironfish/src/wallet/walletdb/accountValue.test.ts @@ -12,11 +12,11 @@ describe('AccountValueEncoding', () => { const value: AccountValue = { id: 'id', name: 'foobar๐Ÿ‘๏ธ๐Ÿƒ๐ŸŸ', - incomingViewKey: key.incoming_view_key, - outgoingViewKey: key.outgoing_view_key, - publicAddress: key.public_address, - spendingKey: key.spending_key, - viewKey: key.view_key, + incomingViewKey: key.incomingViewKey, + outgoingViewKey: key.outgoingViewKey, + publicAddress: key.publicAddress, + spendingKey: key.spendingKey, + viewKey: key.viewKey, version: 1, } const buffer = encoder.serialize(value) diff --git a/ironfish/src/workerPool/job.test.slow.ts b/ironfish/src/workerPool/job.test.slow.ts index 81885ac29f..a6685e33d2 100644 --- a/ironfish/src/workerPool/job.test.slow.ts +++ b/ironfish/src/workerPool/job.test.slow.ts @@ -16,7 +16,7 @@ describe('Worker Pool', () => { expect(workerPool.workers.length).toBe(1) expect(workerPool.completed).toBe(0) - const minersFee = await strategy.createMinersFee(BigInt(0), 0, generateKey().spending_key) + const minersFee = await strategy.createMinersFee(BigInt(0), 0, generateKey().spendingKey) expect(minersFee.serialize()).toBeInstanceOf(Buffer) expect(workerPool.completed).toBe(1) diff --git a/ironfish/src/workerPool/tasks/createMinersFee.ts b/ironfish/src/workerPool/tasks/createMinersFee.ts index e30f46c84b..fc812d9571 100644 --- a/ironfish/src/workerPool/tasks/createMinersFee.ts +++ b/ironfish/src/workerPool/tasks/createMinersFee.ts @@ -77,7 +77,7 @@ export class CreateMinersFeeTask extends WorkerTask { execute({ amount, memo, spendKey, jobId }: CreateMinersFeeRequest): CreateMinersFeeResponse { // Generate a public address from the miner's spending key - const minerPublicAddress = generateKeyFromPrivateKey(spendKey).public_address + const minerPublicAddress = generateKeyFromPrivateKey(spendKey).publicAddress const minerNote = new Note( minerPublicAddress, amount, From 96feb91f1d27dc0dc80f2f9e18a6cd6f961cdd67 Mon Sep 17 00:00:00 2001 From: Jason Spafford Date: Sat, 18 Feb 2023 10:27:41 -0500 Subject: [PATCH 40/43] Change eligibiliy check (#3468) - Called from mint / burn / send - Colorized output to be yellow - Skip in case API is unreachable - Allow user to disable eligibility check for offline signing --- ironfish-cli/package.json | 1 + ironfish-cli/src/commands/wallet/burn.ts | 10 +++++ ironfish-cli/src/commands/wallet/mint.ts | 44 +++++--------------- ironfish-cli/src/commands/wallet/send.ts | 10 +++++ ironfish-cli/src/utils/testnet.ts | 51 ++++++++++++++++++++++++ yarn.lock | 16 ++++---- 6 files changed, 90 insertions(+), 42 deletions(-) create mode 100644 ironfish-cli/src/utils/testnet.ts diff --git a/ironfish-cli/package.json b/ironfish-cli/package.json index 140dcfb2ca..2f41c1bda3 100644 --- a/ironfish-cli/package.json +++ b/ironfish-cli/package.json @@ -70,6 +70,7 @@ "blessed": "0.1.81", "blru": "0.1.6", "buffer-map": "0.0.7", + "chalk": "4.1.2", "inquirer": "8.2.5", "json-colorizer": "2.2.2", "segfault-handler": "1.3.0", diff --git a/ironfish-cli/src/commands/wallet/burn.ts b/ironfish-cli/src/commands/wallet/burn.ts index 6102bfaeee..230a5f52bd 100644 --- a/ironfish-cli/src/commands/wallet/burn.ts +++ b/ironfish-cli/src/commands/wallet/burn.ts @@ -16,6 +16,7 @@ import { IronfishCommand } from '../../command' import { IronFlag, parseIron, RemoteFlags } from '../../flags' import { ProgressBar } from '../../types' import { selectAsset } from '../../utils/asset' +import { doEligibilityCheck } from '../../utils/testnet' export class Burn extends IronfishCommand { static description = 'Burn tokens and decrease supply for a given asset' @@ -67,12 +68,21 @@ export class Burn extends IronfishCommand { description: 'The block sequence that the transaction can not be mined after. Set to 0 for no expiration.', }), + eligibility: Flags.boolean({ + default: true, + allowNo: true, + description: 'check testnet eligibility', + }), } async start(): Promise { const { flags } = await this.parse(Burn) const client = await this.sdk.connectRpc(false, true) + if (flags.eligibility) { + await doEligibilityCheck(client, this.logger) + } + const status = await client.getNodeStatus() if (!status.content.blockchain.synced) { this.log( diff --git a/ironfish-cli/src/commands/wallet/mint.ts b/ironfish-cli/src/commands/wallet/mint.ts index e63065a5c0..aa6ec0e25f 100644 --- a/ironfish-cli/src/commands/wallet/mint.ts +++ b/ironfish-cli/src/commands/wallet/mint.ts @@ -9,7 +9,6 @@ import { RawTransactionSerde, RpcResponseEnded, Transaction, - WebApi, } from '@ironfish/sdk' import { CliUx, Flags } from '@oclif/core' import inquirer from 'inquirer' @@ -17,6 +16,7 @@ import { IronfishCommand } from '../../command' import { IronFlag, parseIron, RemoteFlags } from '../../flags' import { ProgressBar } from '../../types' import { selectAsset } from '../../utils/asset' +import { doEligibilityCheck } from '../../utils/testnet' export class Mint extends IronfishCommand { static description = 'Mint tokens and increase supply for a given asset' @@ -80,12 +80,21 @@ export class Mint extends IronfishCommand { description: 'The block sequence that the transaction can not be mined after. Set to 0 for no expiration.', }), + eligibility: Flags.boolean({ + default: true, + allowNo: true, + description: 'check testnet eligibility', + }), } async start(): Promise { const { flags } = await this.parse(Mint) const client = await this.sdk.connectRpc(false, true) + if (flags.eligibility) { + await doEligibilityCheck(client, this.logger) + } + const status = await client.getNodeStatus() if (!status.content.blockchain.synced) { this.log( @@ -109,8 +118,6 @@ export class Mint extends IronfishCommand { account = defaultAccount.name } - await this.doElegibilityCheck() - let assetId = flags.assetId let metadata = flags.metadata let name = flags.name @@ -343,35 +350,4 @@ Find the transaction on https://explorer.ironfish.network/transaction/${transact this.exit(2) } } - - async doElegibilityCheck(): Promise { - const api = new WebApi() - // Connect to node - const node = await this.sdk.connectRpc() - const graffiti = (await node.getConfig({ name: 'blockGraffiti' })).content.blockGraffiti - if (graffiti) { - const user = await api.findUser({ graffiti: graffiti }) - if (!user) { - this.log(`WARNING: Could not find a user with graffiti ${graffiti}`) - } else { - if (!user.verified) { - this.log( - `WARNING: No verified email on account for graffiti ${graffiti}. You need this email to claim testnet rewards. Visit https://testnet.ironfish.network/login to verify.`, - ) - } - if (user.node_uptime_count < user.node_uptime_threshold) { - const threshold_days = user.node_uptime_threshold / 2 - this.log( - `WARNING: ${threshold_days} days (${ - threshold_days * 24 - } hours) of hosting a node is needed to qualify for Phase 3 points. You currently have ${ - user.node_uptime_count * 12 - } hours.`, - ) - } - } - } else { - this.log(`WARNING: Graffiti not set. Testnet points will not be recorded.`) - } - } } diff --git a/ironfish-cli/src/commands/wallet/send.ts b/ironfish-cli/src/commands/wallet/send.ts index 4750de695d..da9fadb2d3 100644 --- a/ironfish-cli/src/commands/wallet/send.ts +++ b/ironfish-cli/src/commands/wallet/send.ts @@ -17,6 +17,7 @@ import { IronfishCommand } from '../../command' import { IronFlag, parseIron, RemoteFlags } from '../../flags' import { ProgressBar } from '../../types' import { selectAsset } from '../../utils/asset' +import { doEligibilityCheck } from '../../utils/testnet' import { watchTransaction } from '../../utils/transaction' export class Send extends IronfishCommand { @@ -87,6 +88,11 @@ export class Send extends IronfishCommand { description: 'Return raw transaction. Use it to create a transaction but not post to the network', }), + eligibility: Flags.boolean({ + default: true, + allowNo: true, + description: 'check testnet eligibility', + }), } async start(): Promise { @@ -103,6 +109,10 @@ export class Send extends IronfishCommand { const client = await this.sdk.connectRpc(false, true) + if (flags.eligibility) { + await doEligibilityCheck(client, this.logger) + } + const status = await client.getNodeStatus() if (!status.content.blockchain.synced) { this.log( diff --git a/ironfish-cli/src/utils/testnet.ts b/ironfish-cli/src/utils/testnet.ts new file mode 100644 index 0000000000..4505a23e19 --- /dev/null +++ b/ironfish-cli/src/utils/testnet.ts @@ -0,0 +1,51 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +import { ErrorUtils, Logger, RpcClient, WebApi } from '@ironfish/sdk' +import chalk from 'chalk' + +export async function doEligibilityCheck(client: RpcClient, logger: Logger): Promise { + const graffiti = (await client.getConfig({ name: 'blockGraffiti' })).content.blockGraffiti + + if (!graffiti) { + logger.warn(chalk.yellow(`WARNING: Graffiti not set. Testnet points will not be recorded.`)) + return + } + + const api = new WebApi() + + let user + try { + user = await api.findUser({ graffiti: graffiti }) + } catch (e) { + logger.debug(`Failed to fetch API user: ${ErrorUtils.renderError(e)}`) + return + } + + if (!user) { + logger.warn(chalk.yellow(`WARNING: Could not find a user with graffiti ${graffiti}`)) + return + } + + if (!user.verified) { + logger.warn( + chalk.yellow( + `WARNING: No verified email on account for graffiti ${graffiti}. You need this email to claim testnet rewards. Visit https://testnet.ironfish.network/login to verify.`, + ), + ) + } + + if (user.node_uptime_count < user.node_uptime_threshold) { + const threshold_days = user.node_uptime_threshold / 2 + + logger.warn( + chalk.yellow( + `WARNING: ${threshold_days} days (${ + threshold_days * 24 + } hours) of hosting a node is needed to qualify for Phase 3 points. You currently have ${ + user.node_uptime_count * 12 + } hours.`, + ), + ) + } +} diff --git a/yarn.lock b/yarn.lock index 49e17cb7b6..4e167b69fe 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5048,6 +5048,14 @@ chai@4.2.0: pathval "^1.1.0" type-detect "^4.0.5" +chalk@4.1.2, chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + chalk@^1.0.0: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -5068,14 +5076,6 @@ chalk@^2.0.0, chalk@^2.4.1: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - char-regex@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" From 91c6ec492a0f67725cb1a4360d0cfb5fe5d48ee8 Mon Sep 17 00:00:00 2001 From: jowparks Date: Sat, 18 Feb 2023 09:42:06 -0800 Subject: [PATCH 41/43] chore: move account import to rpc and use account value in Account.importAccount (#3469) --- ironfish/src/rpc/routes/wallet/importAccount.ts | 12 ++++++++++-- ironfish/src/wallet/account.ts | 2 -- ironfish/src/wallet/wallet.ts | 4 ++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/ironfish/src/rpc/routes/wallet/importAccount.ts b/ironfish/src/rpc/routes/wallet/importAccount.ts index f5cc6182df..a92668c147 100644 --- a/ironfish/src/rpc/routes/wallet/importAccount.ts +++ b/ironfish/src/rpc/routes/wallet/importAccount.ts @@ -1,10 +1,13 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +import { generateKeyFromPrivateKey } from '@ironfish/rust-nodejs' +import { v4 as uuid } from 'uuid' import * as yup from 'yup' -import { AccountImport } from '../../../wallet/account' import { ApiNamespace, router } from '../router' +export type AccountImport = { name: string; spendingKey: string; version: number } + export type ImportAccountRequest = { account: AccountImport rescan?: boolean @@ -39,7 +42,12 @@ router.register( `${ApiNamespace.wallet}/importAccount`, ImportAccountRequestSchema, async (request, node): Promise => { - const account = await node.wallet.importAccount(request.data.account) + const accountValue = { + id: uuid(), + ...request.data.account, + ...generateKeyFromPrivateKey(request.data.account.spendingKey), + } + const account = await node.wallet.importAccount(accountValue) if (request.data.rescan) { void node.wallet.scanTransactions() diff --git a/ironfish/src/wallet/account.ts b/ironfish/src/wallet/account.ts index e8a29a7961..aefc084d77 100644 --- a/ironfish/src/wallet/account.ts +++ b/ironfish/src/wallet/account.ts @@ -24,8 +24,6 @@ export const ACCOUNT_KEY_LENGTH = 32 export const ACCOUNT_SCHEMA_VERSION = 1 -export type AccountImport = { name: string; spendingKey: string; version: number } - export class Account { private readonly walletDb: WalletDB diff --git a/ironfish/src/wallet/wallet.ts b/ironfish/src/wallet/wallet.ts index d5a9f624fa..226484426c 100644 --- a/ironfish/src/wallet/wallet.ts +++ b/ironfish/src/wallet/wallet.ts @@ -36,7 +36,7 @@ import { } from '../utils' import { WorkerPool } from '../workerPool' import { DecryptedNote, DecryptNoteOptions } from '../workerPool/tasks/decryptNotes' -import { Account, ACCOUNT_SCHEMA_VERSION, AccountImport } from './account' +import { Account, ACCOUNT_SCHEMA_VERSION } from './account' import { AssetBalances } from './assetBalances' import { NotEnoughFundsError } from './errors' import { MintAssetOptions } from './interfaces/mintAssetOptions' @@ -1302,7 +1302,7 @@ export class Wallet { } } - async importAccount(toImport: AccountImport): Promise { + async importAccount(toImport: AccountValue): Promise { if (toImport.name && this.getAccountByName(toImport.name)) { throw new Error(`Account already exists with the name ${toImport.name}`) } From 2fc908f6f32c1be7af6ed1f355f18d677a8e7573 Mon Sep 17 00:00:00 2001 From: Hugh Cunningham <57735705+hughy@users.noreply.github.com> Date: Tue, 21 Feb 2023 08:03:15 -0800 Subject: [PATCH 42/43] fixes walletdb migrations that rely on old accounts (#3487) we've recently made changes to the way that accounts are stored in the walletdb. it's possible that a user may have a database that needs to apply migrations that rely on the old AccountValue encoding before applying the migration to the new encoding. this results in an encoding error when an older migration (pre-021) attempts to read from the accounts store, which has not yet been migrated. adds a function, GetOldAccounts, to simplify reading accounts from the old accounts store in older migrations. uses this function for loading accounts in all migrations before Migration021. --- .../src/migrations/data/016-sequence-to-tx.ts | 13 ++----- .../migrations/data/017-sequence-encoding.ts | 21 ++--------- .../data/018-backfill-wallet-assets.ts | 12 ++----- .../019-backfill-wallet-assets-from-chain.ts | 12 ++----- .../data/020-backfill-null-asset-supplies.ts | 12 ++----- .../021-add-version-to-accounts/schemaOld.ts | 36 +++++++++++++++++-- 6 files changed, 45 insertions(+), 61 deletions(-) diff --git a/ironfish/src/migrations/data/016-sequence-to-tx.ts b/ironfish/src/migrations/data/016-sequence-to-tx.ts index c4bfd6aa0c..281d730940 100644 --- a/ironfish/src/migrations/data/016-sequence-to-tx.ts +++ b/ironfish/src/migrations/data/016-sequence-to-tx.ts @@ -5,8 +5,8 @@ import { Logger } from '../../logger' import { IronfishNode } from '../../node' import { IDatabase, IDatabaseTransaction } from '../../storage' -import { Account } from '../../wallet' import { Migration } from '../migration' +import { GetOldAccounts } from './021-add-version-to-accounts/schemaOld' export class Migration016 extends Migration { path = __filename @@ -21,16 +21,7 @@ export class Migration016 extends Migration { tx: IDatabaseTransaction | undefined, logger: Logger, ): Promise { - const accounts = [] - - for await (const accountValue of node.wallet.walletDb.loadAccounts()) { - accounts.push( - new Account({ - ...accountValue, - walletDb: node.wallet.walletDb, - }), - ) - } + const accounts = await GetOldAccounts(node, db, tx) logger.info(`Indexing on-chain transactions for ${accounts.length} accounts`) diff --git a/ironfish/src/migrations/data/017-sequence-encoding.ts b/ironfish/src/migrations/data/017-sequence-encoding.ts index 81bda6f212..312f83b059 100644 --- a/ironfish/src/migrations/data/017-sequence-encoding.ts +++ b/ironfish/src/migrations/data/017-sequence-encoding.ts @@ -14,8 +14,8 @@ import { PrefixEncoding, U32_ENCODING_BE, } from '../../storage' -import { Account } from '../../wallet' import { Migration } from '../migration' +import { GetOldAccounts } from './021-add-version-to-accounts/schemaOld' export class Migration017 extends Migration { path = __filename @@ -30,7 +30,7 @@ export class Migration017 extends Migration { tx: IDatabaseTransaction | undefined, logger: Logger, ): Promise { - const accounts = await this.getAccounts(node) + const accounts = await GetOldAccounts(node, db, tx) logger.info(`Re-indexing transactions for ${accounts.length} accounts`) logger.info('') @@ -63,7 +63,7 @@ export class Migration017 extends Migration { } async backward(node: IronfishNode, db: IDatabase): Promise { - const accounts = await this.getAccounts(node) + const accounts = await GetOldAccounts(node, db) const { sequenceToNoteHash, sequenceToTransactionHash, pendingTransactionHashes } = this.getOldStores(db) @@ -103,21 +103,6 @@ export class Migration017 extends Migration { await node.wallet.walletDb.pendingTransactionHashes.clear() } - async getAccounts(node: IronfishNode): Promise { - const accounts = [] - - for await (const accountValue of node.wallet.walletDb.loadAccounts()) { - accounts.push( - new Account({ - ...accountValue, - walletDb: node.wallet.walletDb, - }), - ) - } - - return accounts - } - getOldStores(db: IDatabase): { sequenceToNoteHash: IDatabaseStore sequenceToTransactionHash: IDatabaseStore diff --git a/ironfish/src/migrations/data/018-backfill-wallet-assets.ts b/ironfish/src/migrations/data/018-backfill-wallet-assets.ts index a8de432b5e..2d841a491f 100644 --- a/ironfish/src/migrations/data/018-backfill-wallet-assets.ts +++ b/ironfish/src/migrations/data/018-backfill-wallet-assets.ts @@ -4,8 +4,8 @@ import { Logger } from '../../logger' import { IronfishNode } from '../../node' import { IDatabase, IDatabaseTransaction } from '../../storage' -import { Account } from '../../wallet' import { Migration } from '../migration' +import { GetOldAccounts } from './021-add-version-to-accounts/schemaOld' export class Migration018 extends Migration { path = __filename @@ -24,15 +24,7 @@ export class Migration018 extends Migration { // running this migration await node.wallet.walletDb.assets.clear() - const accounts = [] - for await (const accountValue of node.wallet.walletDb.loadAccounts(tx)) { - accounts.push( - new Account({ - ...accountValue, - walletDb: node.wallet.walletDb, - }), - ) - } + const accounts = await GetOldAccounts(node, _db, tx) logger.info(`Backfilling assets for ${accounts.length} accounts`) diff --git a/ironfish/src/migrations/data/019-backfill-wallet-assets-from-chain.ts b/ironfish/src/migrations/data/019-backfill-wallet-assets-from-chain.ts index 3ae7515848..0dd6139599 100644 --- a/ironfish/src/migrations/data/019-backfill-wallet-assets-from-chain.ts +++ b/ironfish/src/migrations/data/019-backfill-wallet-assets-from-chain.ts @@ -9,8 +9,8 @@ import { IronfishNode } from '../../node' import { BUFFER_ENCODING, IDatabase, IDatabaseStore, IDatabaseTransaction } from '../../storage' import { createDB } from '../../storage/utils' import { BufferUtils } from '../../utils' -import { Account } from '../../wallet' import { Migration } from '../migration' +import { GetOldAccounts } from './021-add-version-to-accounts/schemaOld' export class Migration019 extends Migration { path = __filename @@ -34,15 +34,7 @@ export class Migration019 extends Migration { valueEncoding: new AssetValueEncoding(), }) - const accounts = [] - for await (const accountValue of node.wallet.walletDb.loadAccounts(tx)) { - accounts.push( - new Account({ - ...accountValue, - walletDb: node.wallet.walletDb, - }), - ) - } + const accounts = await GetOldAccounts(node, _db, tx) logger.info(`Backfilling assets for ${accounts.length} accounts`) diff --git a/ironfish/src/migrations/data/020-backfill-null-asset-supplies.ts b/ironfish/src/migrations/data/020-backfill-null-asset-supplies.ts index a3ac7f5237..c044ff61b6 100644 --- a/ironfish/src/migrations/data/020-backfill-null-asset-supplies.ts +++ b/ironfish/src/migrations/data/020-backfill-null-asset-supplies.ts @@ -5,8 +5,8 @@ import { Logger } from '../../logger' import { IronfishNode } from '../../node' import { IDatabase, IDatabaseTransaction } from '../../storage' import { BufferUtils } from '../../utils' -import { Account } from '../../wallet' import { Migration } from '../migration' +import { GetOldAccounts } from './021-add-version-to-accounts/schemaOld' export class Migration020 extends Migration { path = __filename @@ -21,15 +21,7 @@ export class Migration020 extends Migration { tx: IDatabaseTransaction | undefined, logger: Logger, ): Promise { - const accounts = [] - for await (const accountValue of node.wallet.walletDb.loadAccounts(tx)) { - accounts.push( - new Account({ - ...accountValue, - walletDb: node.wallet.walletDb, - }), - ) - } + const accounts = await GetOldAccounts(node, _db, tx) logger.info(`Backfilling assets for ${accounts.length} accounts`) diff --git a/ironfish/src/migrations/data/021-add-version-to-accounts/schemaOld.ts b/ironfish/src/migrations/data/021-add-version-to-accounts/schemaOld.ts index 4c4e0af6a4..fcb5dd7b18 100644 --- a/ironfish/src/migrations/data/021-add-version-to-accounts/schemaOld.ts +++ b/ironfish/src/migrations/data/021-add-version-to-accounts/schemaOld.ts @@ -1,9 +1,17 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -import { PUBLIC_ADDRESS_LENGTH } from '@ironfish/rust-nodejs' +import { generateKeyFromPrivateKey, PUBLIC_ADDRESS_LENGTH } from '@ironfish/rust-nodejs' import bufio from 'bufio' -import { IDatabase, IDatabaseEncoding, IDatabaseStore, StringEncoding } from '../../../storage' +import { IronfishNode } from '../../../node' +import { + IDatabase, + IDatabaseEncoding, + IDatabaseStore, + IDatabaseTransaction, + StringEncoding, +} from '../../../storage' +import { Account } from '../../../wallet' const KEY_LENGTH = 32 @@ -75,3 +83,27 @@ export function GetOldStores(db: IDatabase): { return { accounts } } + +export async function GetOldAccounts( + node: IronfishNode, + db: IDatabase, + tx?: IDatabaseTransaction, +): Promise { + const accounts = [] + const oldStores = GetOldStores(db) + + for await (const account of oldStores.accounts.getAllValuesIter(tx)) { + const key = generateKeyFromPrivateKey(account.spendingKey) + + accounts.push( + new Account({ + ...account, + version: undefined, + viewKey: key.viewKey, + walletDb: node.wallet.walletDb, + }), + ) + } + + return accounts +} From e1b443913f1b333105650a2ca070bf270cc876a1 Mon Sep 17 00:00:00 2001 From: Jason Spafford Date: Tue, 21 Feb 2023 11:43:15 -0500 Subject: [PATCH 43/43] Version bump for release 0.1.68 (#3497) --- ironfish-cli/package.json | 6 +++--- ironfish-rust-nodejs/npm/darwin-arm64/package.json | 2 +- ironfish-rust-nodejs/npm/darwin-x64/package.json | 2 +- ironfish-rust-nodejs/npm/linux-arm64-gnu/package.json | 2 +- ironfish-rust-nodejs/npm/linux-arm64-musl/package.json | 2 +- ironfish-rust-nodejs/npm/linux-x64-gnu/package.json | 2 +- ironfish-rust-nodejs/npm/linux-x64-musl/package.json | 2 +- ironfish-rust-nodejs/npm/win32-x64-msvc/package.json | 2 +- ironfish-rust-nodejs/package.json | 2 +- ironfish/package.json | 4 ++-- 10 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ironfish-cli/package.json b/ironfish-cli/package.json index 2f41c1bda3..d789927b4d 100644 --- a/ironfish-cli/package.json +++ b/ironfish-cli/package.json @@ -1,6 +1,6 @@ { "name": "ironfish", - "version": "0.1.67", + "version": "0.1.68", "description": "CLI for running and interacting with an Iron Fish node", "author": "Iron Fish (https://ironfish.network)", "main": "build/src/index.js", @@ -59,8 +59,8 @@ "@aws-sdk/s3-request-presigner": "3.127.0", "@aws-sdk/client-cognito-identity": "3.215.0", "@aws-sdk/client-s3": "3.127.0", - "@ironfish/rust-nodejs": "0.1.26", - "@ironfish/sdk": "0.0.44", + "@ironfish/rust-nodejs": "0.1.27", + "@ironfish/sdk": "0.0.45", "@oclif/core": "1.23.1", "@oclif/plugin-help": "5.1.12", "@oclif/plugin-not-found": "2.3.1", diff --git a/ironfish-rust-nodejs/npm/darwin-arm64/package.json b/ironfish-rust-nodejs/npm/darwin-arm64/package.json index a3cd00cd25..0802490509 100644 --- a/ironfish-rust-nodejs/npm/darwin-arm64/package.json +++ b/ironfish-rust-nodejs/npm/darwin-arm64/package.json @@ -1,6 +1,6 @@ { "name": "@ironfish/rust-nodejs-darwin-arm64", - "version": "0.1.26", + "version": "0.1.27", "os": [ "darwin" ], diff --git a/ironfish-rust-nodejs/npm/darwin-x64/package.json b/ironfish-rust-nodejs/npm/darwin-x64/package.json index d94e6dacec..f8c9707d02 100644 --- a/ironfish-rust-nodejs/npm/darwin-x64/package.json +++ b/ironfish-rust-nodejs/npm/darwin-x64/package.json @@ -1,6 +1,6 @@ { "name": "@ironfish/rust-nodejs-darwin-x64", - "version": "0.1.26", + "version": "0.1.27", "os": [ "darwin" ], diff --git a/ironfish-rust-nodejs/npm/linux-arm64-gnu/package.json b/ironfish-rust-nodejs/npm/linux-arm64-gnu/package.json index 5cfada4e62..8131c5bd81 100644 --- a/ironfish-rust-nodejs/npm/linux-arm64-gnu/package.json +++ b/ironfish-rust-nodejs/npm/linux-arm64-gnu/package.json @@ -1,6 +1,6 @@ { "name": "@ironfish/rust-nodejs-linux-arm64-gnu", - "version": "0.1.26", + "version": "0.1.27", "os": [ "linux" ], diff --git a/ironfish-rust-nodejs/npm/linux-arm64-musl/package.json b/ironfish-rust-nodejs/npm/linux-arm64-musl/package.json index d236ecb0f6..bb9a4dac72 100644 --- a/ironfish-rust-nodejs/npm/linux-arm64-musl/package.json +++ b/ironfish-rust-nodejs/npm/linux-arm64-musl/package.json @@ -1,6 +1,6 @@ { "name": "@ironfish/rust-nodejs-linux-arm64-musl", - "version": "0.1.26", + "version": "0.1.27", "os": [ "linux" ], diff --git a/ironfish-rust-nodejs/npm/linux-x64-gnu/package.json b/ironfish-rust-nodejs/npm/linux-x64-gnu/package.json index 99585b4ef6..c58700e4ef 100644 --- a/ironfish-rust-nodejs/npm/linux-x64-gnu/package.json +++ b/ironfish-rust-nodejs/npm/linux-x64-gnu/package.json @@ -1,6 +1,6 @@ { "name": "@ironfish/rust-nodejs-linux-x64-gnu", - "version": "0.1.26", + "version": "0.1.27", "os": [ "linux" ], diff --git a/ironfish-rust-nodejs/npm/linux-x64-musl/package.json b/ironfish-rust-nodejs/npm/linux-x64-musl/package.json index d94f559a6e..44f81aa397 100644 --- a/ironfish-rust-nodejs/npm/linux-x64-musl/package.json +++ b/ironfish-rust-nodejs/npm/linux-x64-musl/package.json @@ -1,6 +1,6 @@ { "name": "@ironfish/rust-nodejs-linux-x64-musl", - "version": "0.1.26", + "version": "0.1.27", "os": [ "linux" ], diff --git a/ironfish-rust-nodejs/npm/win32-x64-msvc/package.json b/ironfish-rust-nodejs/npm/win32-x64-msvc/package.json index f92ee4222a..5e13baef18 100644 --- a/ironfish-rust-nodejs/npm/win32-x64-msvc/package.json +++ b/ironfish-rust-nodejs/npm/win32-x64-msvc/package.json @@ -1,6 +1,6 @@ { "name": "@ironfish/rust-nodejs-win32-x64-msvc", - "version": "0.1.26", + "version": "0.1.27", "os": [ "win32" ], diff --git a/ironfish-rust-nodejs/package.json b/ironfish-rust-nodejs/package.json index a3d62fe335..f4b01a527e 100644 --- a/ironfish-rust-nodejs/package.json +++ b/ironfish-rust-nodejs/package.json @@ -1,6 +1,6 @@ { "name": "@ironfish/rust-nodejs", - "version": "0.1.26", + "version": "0.1.27", "description": "Node.js bindings for Rust code required by the Iron Fish SDK", "main": "index.js", "types": "index.d.ts", diff --git a/ironfish/package.json b/ironfish/package.json index b846a1fd16..a6cacd6010 100644 --- a/ironfish/package.json +++ b/ironfish/package.json @@ -1,6 +1,6 @@ { "name": "@ironfish/sdk", - "version": "0.0.44", + "version": "0.0.45", "description": "SDK for running and interacting with an Iron Fish node", "author": "Iron Fish (https://ironfish.network)", "main": "build/src/index.js", @@ -18,7 +18,7 @@ ], "dependencies": { "@ethersproject/bignumber": "5.7.0", - "@ironfish/rust-nodejs": "0.1.26", + "@ironfish/rust-nodejs": "0.1.27", "@napi-rs/blake-hash": "1.3.1", "axios": "0.21.4", "blru": "0.1.6",