Skip to content

Commit 118af43

Browse files
authored
data store (#286)
* data store * fix * update delay * fix
1 parent 8472c2f commit 118af43

File tree

31 files changed

+273
-201
lines changed

31 files changed

+273
-201
lines changed

.swiftformat

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
--maxwidth 140
33
--asynccapturing debugCheck
44
--closurevoid preserve
5+
--disable typeSugar
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import Utils
2+
3+
enum DataStoreError: Error {
4+
case invalidPackageHash(Data32)
5+
case invalidSegmentRoot(Data32)
6+
}
7+
8+
public final class DataStore: Sendable {
9+
private let impl: DataStoreProtocol
10+
private let network: DataStoreNetworkProtocol
11+
12+
public init(_ impl: DataStoreProtocol, _ network: DataStoreNetworkProtocol) {
13+
self.impl = impl
14+
self.network = network
15+
}
16+
17+
public func fetchSegment(segments: [WorkItem.ImportedDataSegment]) async throws -> [Data4104] {
18+
var result: [Data4104] = []
19+
20+
for segment in segments {
21+
let segmentRoot = switch segment.root {
22+
case let .segmentRoot(root):
23+
root
24+
case let .workPackageHash(hash):
25+
try await impl.getSegmentRoot(forWorkPackageHash: hash).unwrap(orError: DataStoreError.invalidPackageHash(hash))
26+
}
27+
let erasureRoot = try await impl.getEasureRoot(forSegmentRoot: segmentRoot)
28+
.unwrap(orError: DataStoreError.invalidSegmentRoot(segmentRoot))
29+
30+
if let localData = try await impl.get(erasureRoot: erasureRoot, index: segment.index) {
31+
result.append(localData)
32+
} else {
33+
// TODO: use network for fetch shards and reconstruct the segment
34+
fatalError("not implemented")
35+
}
36+
}
37+
38+
return result
39+
}
40+
41+
public func set(data: Data4104, erasureRoot: Data32, index: UInt16) async throws {
42+
try await impl.set(data: data, erasureRoot: erasureRoot, index: index)
43+
44+
// TODO; erasure code the data and store each chunk
45+
// so assurer can query them later with CE137
46+
}
47+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import Utils
2+
3+
public protocol DataStoreProtocol: Sendable {
4+
// segment root => erasure root
5+
func getEasureRoot(forSegmentRoot: Data32) async throws -> Data32?
6+
func set(erasureRoot: Data32, forSegmentRoot: Data32) async throws
7+
func delete(erasureRoot: Data32) async throws
8+
9+
// work package hash => segment root
10+
func getSegmentRoot(forWorkPackageHash: Data32) async throws -> Data32?
11+
func set(segmentRoot: Data32, forWorkPackageHash: Data32) async throws
12+
func delete(segmentRoot: Data32) async throws
13+
14+
// erasure root + index => segment data
15+
func get(erasureRoot: Data32, index: UInt16) async throws -> Data4104?
16+
func set(data: Data4104, erasureRoot: Data32, index: UInt16) async throws
17+
}
18+
19+
public protocol DataStoreNetworkProtocol: Sendable {
20+
// Use CE139/CE140 to fetch remote chunk
21+
func fetchRemoteChunk(erasureRoot: Data32, shardIndex: UInt16, segmentIndices: [UInt16]) async throws -> Data12?
22+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import Utils
2+
3+
public actor InMemoryDataStoreBackend {
4+
// segment root => erasure root
5+
private var erasureRootBySegmentRoot: [Data32: Data32] = [:]
6+
7+
// work package hash => segment root
8+
private var segmentRootByWorkPackageHash: [Data32: Data32] = [:]
9+
10+
// erasure root + index => segment data
11+
private var chunks: [Data32: [UInt16: Data4104]] = [:]
12+
13+
public init() {}
14+
}
15+
16+
extension InMemoryDataStoreBackend: DataStoreProtocol {
17+
public func getEasureRoot(forSegmentRoot: Data32) async throws -> Data32? {
18+
erasureRootBySegmentRoot[forSegmentRoot]
19+
}
20+
21+
public func set(erasureRoot: Data32, forSegmentRoot: Data32) async throws {
22+
erasureRootBySegmentRoot[forSegmentRoot] = erasureRoot
23+
}
24+
25+
public func delete(erasureRoot: Data32) async throws {
26+
erasureRootBySegmentRoot.removeValue(forKey: erasureRoot)
27+
}
28+
29+
public func getSegmentRoot(forWorkPackageHash: Data32) async throws -> Data32? {
30+
segmentRootByWorkPackageHash[forWorkPackageHash]
31+
}
32+
33+
public func set(segmentRoot: Data32, forWorkPackageHash: Data32) async throws {
34+
segmentRootByWorkPackageHash[forWorkPackageHash] = segmentRoot
35+
}
36+
37+
public func delete(segmentRoot: Data32) async throws {
38+
segmentRootByWorkPackageHash.removeValue(forKey: segmentRoot)
39+
}
40+
41+
public func get(erasureRoot: Data32, index: UInt16) async throws -> Data4104? {
42+
chunks[erasureRoot]?[index]
43+
}
44+
45+
public func set(data: Data4104, erasureRoot: Data32, index: UInt16) async throws {
46+
chunks[erasureRoot, default: [:]][index] = data
47+
}
48+
}
49+
50+
extension InMemoryDataStoreBackend: DataStoreNetworkProtocol {
51+
public func fetchRemoteChunk(erasureRoot _: Data32, shardIndex _: UInt16, segmentIndices _: [UInt16]) async throws -> Data12? {
52+
nil
53+
}
54+
}

Blockchain/Sources/Blockchain/BlockchainServices.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ public class BlockchainServices {
3232
self.genesisBlock = genesisBlock
3333
self.genesisState = genesisState
3434
dataProvider = try! await BlockchainDataProvider(InMemoryDataProvider(genesisState: genesisState, genesisBlock: genesisBlock))
35-
dataStore = DataStore(InMemoryDataStore(), basePath: URL(fileURLWithPath: "/tmp/boka-test-data"))
35+
let dataStoreBackend = InMemoryDataStoreBackend()
36+
dataStore = DataStore(dataStoreBackend, dataStoreBackend)
3637

3738
storeMiddleware = StoreMiddleware()
3839
eventBus = EventBus(eventMiddleware: .serial(Middleware(storeMiddleware), .noError), handlerMiddleware: .noError)

Blockchain/Sources/Blockchain/Config/ProtocolConfig.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,7 @@ public struct ProtocolConfig: Sendable, Codable, Equatable {
8585
/// WM = 2^11: The maximum number of entries in a work-package manifest.
8686
public var maxWorkPackageManifestEntries: Int
8787

88-
/// WB = 12 * 2^20: The maximum size of an encoded work-package together with its extrinsic data and import impli-
89-
/// cations, in octets.
88+
/// WB = 12 * 2^20: The maximum size of an encoded work-package together with its extrinsic data and import implications, in octets.
9089
public var maxEncodedWorkPackageSize: Int
9190

9291
/// WG = WP*WE = 4104: The size of a segment in octets.

Blockchain/Sources/Blockchain/DataStore/DataStore.swift

Lines changed: 0 additions & 46 deletions
This file was deleted.

Blockchain/Sources/Blockchain/DataStore/FilesystemDataStore.swift

Lines changed: 0 additions & 23 deletions
This file was deleted.

Blockchain/Sources/Blockchain/DataStore/InMemoryDataStore.swift

Lines changed: 0 additions & 19 deletions
This file was deleted.

Blockchain/Sources/Blockchain/Types/WorkPackageBundle.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ import Utils
55
public struct WorkPackageBundle: Sendable, Equatable, Codable {
66
public var workPackage: WorkPackage
77
public var extrinsic: [Data]
8-
public var importSegments: [[Data]]
9-
public var justifications: [[Data]]
8+
public var importSegments: [Data4104]
9+
public var justifications: [Data]
1010
}

0 commit comments

Comments
 (0)