From 218ce1d2c9a76c4da32ae73e09b64367f34c7cfb Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Wed, 11 Dec 2024 14:02:32 +1300 Subject: [PATCH] fix --- Database/Sources/Database/JamCoder.swift | 17 --- Database/Sources/Database/NoopCoder.swift | 19 ++++ .../Tests/DatabaseTests/DatabaseTests.swift | 0 .../DatabaseTests/RocksDBBackendTests.swift | 102 ++++++++++++++++++ .../RocksDBSwiftTests/RocksDBTests.swift | 11 -- 5 files changed, 121 insertions(+), 28 deletions(-) create mode 100644 Database/Sources/Database/NoopCoder.swift delete mode 100644 Database/Tests/DatabaseTests/DatabaseTests.swift create mode 100644 Database/Tests/DatabaseTests/RocksDBBackendTests.swift diff --git a/Database/Sources/Database/JamCoder.swift b/Database/Sources/Database/JamCoder.swift index cbaef623..8541d21a 100644 --- a/Database/Sources/Database/JamCoder.swift +++ b/Database/Sources/Database/JamCoder.swift @@ -29,20 +29,3 @@ struct JamCoder: StoreCoder { try JamDecoder.decode(Value.self, from: data, withConfig: config) } } - -struct NoopCoder: StoreCoder { - typealias Key = Data - typealias Value = Data - - func encode(key: Key) throws -> Data { - key - } - - func encode(value: Value) throws -> Data { - value - } - - func decode(data: Data) throws -> Value { - data - } -} diff --git a/Database/Sources/Database/NoopCoder.swift b/Database/Sources/Database/NoopCoder.swift new file mode 100644 index 00000000..e6f0b2ce --- /dev/null +++ b/Database/Sources/Database/NoopCoder.swift @@ -0,0 +1,19 @@ +import Foundation +import RocksDBSwift + +struct NoopCoder: StoreCoder { + typealias Key = Data + typealias Value = Data + + func encode(key: Key) throws -> Data { + key + } + + func encode(value: Value) throws -> Data { + value + } + + func decode(data: Data) throws -> Value { + data + } +} diff --git a/Database/Tests/DatabaseTests/DatabaseTests.swift b/Database/Tests/DatabaseTests/DatabaseTests.swift deleted file mode 100644 index e69de29b..00000000 diff --git a/Database/Tests/DatabaseTests/RocksDBBackendTests.swift b/Database/Tests/DatabaseTests/RocksDBBackendTests.swift new file mode 100644 index 00000000..79dc9dec --- /dev/null +++ b/Database/Tests/DatabaseTests/RocksDBBackendTests.swift @@ -0,0 +1,102 @@ +import Blockchain +import Database +import Foundation +import Testing +import Utils + +final class RocksDBBackendTests { + let path = { + let tmpDir = FileManager.default.temporaryDirectory + return tmpDir.appendingPathComponent("\(UUID().uuidString)") + }() + + let config: ProtocolConfigRef = .dev + let genesisBlock: BlockRef + var backend: RocksDBBackend! + + init() async throws { + genesisBlock = BlockRef.dummy(config: config) + + // Initialize backend with genesis block + backend = try await RocksDBBackend( + path: path, + config: config, + genesisBlock: genesisBlock, + genesisStateData: [:] + ) + } + + deinit { + backend = nil + try? FileManager.default.removeItem(at: path) + } + + @Test + func testGenesisBlockInitialization() async throws { + // Verify genesis block was properly stored + let exists = try await backend.hasBlock(hash: genesisBlock.hash) + #expect(exists == true) + + // Verify it's both a head and finalized head + let isHead = try await backend.isHead(hash: genesisBlock.hash) + #expect(isHead == true) + + let finalizedHead = try await backend.getFinalizedHead() + #expect(finalizedHead == genesisBlock.hash) + + // Verify block number + let blockNumber = try await backend.getBlockNumber(hash: genesisBlock.hash) + #expect(blockNumber == 0) + } + + @Test + func testBlockOperations() async throws { + // Create and add a new block + let block1 = BlockRef.dummy(config: config, parent: genesisBlock) + + try await backend.add(block: block1) + try await backend.updateHead(hash: block1.hash, parent: genesisBlock.hash) + + // Verify block was stored + let storedBlock = try await backend.getBlock(hash: block1.hash) + #expect(storedBlock == block1) + + // Verify block indexes + let blocksByTimeslot = try await backend.getBlockHash(byTimeslot: 1) + #expect(blocksByTimeslot.contains(block1.hash)) + + let blocksByNumber = try await backend.getBlockHash(byNumber: 1) + #expect(blocksByNumber.contains(block1.hash)) + + // Test block removal + try await backend.remove(hash: block1.hash) + let exists = try await backend.hasBlock(hash: block1.hash) + #expect(exists == false) + } + + @Test + func testChainReorganization() async throws { + // Create two competing chains + let block1 = BlockRef.dummy(config: config, parent: genesisBlock) + + let block2 = BlockRef.dummy(config: config, parent: genesisBlock).mutate { block in + block.header.unsigned.timeslot = 123 + } + + // Add both blocks and update heads + try await backend.add(block: block1) + try await backend.add(block: block2) + try await backend.updateHead(hash: block1.hash, parent: genesisBlock.hash) + try await backend.updateHead(hash: block2.hash, parent: genesisBlock.hash) + + // Verify both are heads + let heads = try await backend.getHeads() + #expect(heads.contains(block1.hash)) + #expect(heads.contains(block2.hash)) + + // Test finalization of one chain + try await backend.setFinalizedHead(hash: block1.hash) + let finalizedHead = try await backend.getFinalizedHead() + #expect(finalizedHead == block1.hash) + } +} diff --git a/Database/Tests/RocksDBSwiftTests/RocksDBTests.swift b/Database/Tests/RocksDBSwiftTests/RocksDBTests.swift index 44de8529..5d974dbc 100644 --- a/Database/Tests/RocksDBSwiftTests/RocksDBTests.swift +++ b/Database/Tests/RocksDBSwiftTests/RocksDBTests.swift @@ -107,17 +107,6 @@ final class RocksDBTests { #expect(retrieved?.isEmpty == true) } - @Test func testErrorConditions() throws { - // Test invalid operations - let invalidDB = try? RocksDB(path: URL(fileURLWithPath: "/nonexistent/path")) - #expect(invalidDB == nil) - - // Test deleting non-existent key - try rocksDB.delete(column: .col1, key: "nonexistent".data) - let value = try rocksDB.get(column: .col1, key: "nonexistent".data) - #expect(value == nil) - } - @Test func testIterator() throws { // Setup test data let testData = [