Skip to content

Commit

Permalink
Implements JamCodec and replace with ScaleCodec (#68)
Browse files Browse the repository at this point in the history
* use Swift Codable

* Codec package

* implement codec

* more refactor

* fmt

* more fix

* disable safrole tests

* comment out safrole tests
  • Loading branch information
xlc authored Aug 21, 2024
1 parent faf31d8 commit 51bb692
Show file tree
Hide file tree
Showing 56 changed files with 1,729 additions and 1,376 deletions.
2 changes: 1 addition & 1 deletion .swiftformat
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
--extensionacl on-declarations
--maxwidth 150
--maxwidth 140
--asynccapturing debugCheck
1 change: 1 addition & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ disabled_rules:
- identifier_name
- function_parameter_count
- force_try
- force_cast

excluded:
- "**/.build"
Expand Down
137 changes: 1 addition & 136 deletions Blockchain/Package.resolved
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"originHash" : "a6bbe74d9b5891b7b3286ff9db782962187c36afbc7f0261e2d03479b2b04bf5",
"originHash" : "2a91ceec1663a1ed3fc9b58333d3d32c6ce1131b7d1874346655dbfae0af61f4",
"pins" : [
{
"identity" : "blake2.swift",
Expand All @@ -10,33 +10,6 @@
"version" : "0.2.0"
}
},
{
"identity" : "grpc-swift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/grpc/grpc-swift.git",
"state" : {
"revision" : "6a90b7e77e29f9bda6c2b3a4165a40d6c02cfda1",
"version" : "1.23.0"
}
},
{
"identity" : "scalecodec.swift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/AcalaNetwork/ScaleCodec.swift.git",
"state" : {
"branch" : "main",
"revision" : "dac3e7161de34c60c82794d031de0231b5a5746e"
}
},
{
"identity" : "swift-async-algorithms",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-async-algorithms.git",
"state" : {
"revision" : "6ae9a051f76b81cc668305ceed5b0e0a7fd93d20",
"version" : "1.0.1"
}
},
{
"identity" : "swift-atomics",
"kind" : "remoteSourceControl",
Expand All @@ -46,15 +19,6 @@
"version" : "1.2.0"
}
},
{
"identity" : "swift-collections",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-collections.git",
"state" : {
"revision" : "3d2dc41a01f9e49d84f0a3925fb858bed64f702d",
"version" : "1.1.2"
}
},
{
"identity" : "swift-crypto",
"kind" : "remoteSourceControl",
Expand All @@ -73,15 +37,6 @@
"version" : "1.1.1"
}
},
{
"identity" : "swift-http-types",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-http-types",
"state" : {
"revision" : "ae67c8178eb46944fd85e4dc6dd970e1f3ed6ccd",
"version" : "1.3.0"
}
},
{
"identity" : "swift-log",
"kind" : "remoteSourceControl",
Expand All @@ -100,69 +55,6 @@
"version" : "2.5.0"
}
},
{
"identity" : "swift-nio",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio.git",
"state" : {
"revision" : "4c4453b489cf76e6b3b0f300aba663eb78182fad",
"version" : "2.70.0"
}
},
{
"identity" : "swift-nio-extras",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-extras.git",
"state" : {
"revision" : "05c36b57453d23ea63785d58a7dbc7b70ba1745e",
"version" : "1.23.0"
}
},
{
"identity" : "swift-nio-http2",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-http2.git",
"state" : {
"revision" : "b5f7062b60e4add1e8c343ba4eb8da2e324b3a94",
"version" : "1.34.0"
}
},
{
"identity" : "swift-nio-ssl",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-ssl.git",
"state" : {
"revision" : "a9fa5efd86e7ce2e5c1b6de113262e58035ca251",
"version" : "2.27.1"
}
},
{
"identity" : "swift-nio-transport-services",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-transport-services.git",
"state" : {
"revision" : "38ac8221dd20674682148d6451367f89c2652980",
"version" : "1.21.0"
}
},
{
"identity" : "swift-otel",
"kind" : "remoteSourceControl",
"location" : "https://github.com/slashmo/swift-otel.git",
"state" : {
"revision" : "8c271c7fed34a39f29c728598b3358fbdddf8ff4",
"version" : "0.9.0"
}
},
{
"identity" : "swift-protobuf",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-protobuf.git",
"state" : {
"revision" : "e17d61f26df0f0e06f58f6977ba05a097a720106",
"version" : "1.27.1"
}
},
{
"identity" : "swift-service-context",
"kind" : "remoteSourceControl",
Expand All @@ -172,15 +64,6 @@
"version" : "1.1.0"
}
},
{
"identity" : "swift-service-lifecycle",
"kind" : "remoteSourceControl",
"location" : "https://github.com/swift-server/swift-service-lifecycle.git",
"state" : {
"revision" : "24c800fb494fbee6e42bc156dc94232dc08971af",
"version" : "2.6.1"
}
},
{
"identity" : "swift-syntax",
"kind" : "remoteSourceControl",
Expand All @@ -190,15 +73,6 @@
"version" : "600.0.0-prerelease-2024-06-12"
}
},
{
"identity" : "swift-system",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-system.git",
"state" : {
"revision" : "d2ba781702a1d8285419c15ee62fd734a9437ff5",
"version" : "1.3.2"
}
},
{
"identity" : "swift-testing",
"kind" : "remoteSourceControl",
Expand All @@ -207,15 +81,6 @@
"branch" : "0.10.0",
"revision" : "69d59cfc76e5daf498ca61f5af409f594768eef9"
}
},
{
"identity" : "tuples.swift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/tesseract-one/Tuples.swift.git",
"state" : {
"revision" : "4d2cf7c64443cdf4df833d0bedd767bf9dbc49d9",
"version" : "0.1.3"
}
}
],
"version" : 3
Expand Down
4 changes: 2 additions & 2 deletions Blockchain/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ let package = Package(
),
],
dependencies: [
.package(path: "../Codec"),
.package(path: "../Utils"),
.package(path: "../TracingUtils"),
.package(url: "https://github.com/AcalaNetwork/ScaleCodec.swift.git", branch: "main"),
.package(url: "https://github.com/apple/swift-testing.git", branch: "0.10.0"),
],
targets: [
Expand All @@ -27,9 +27,9 @@ let package = Package(
.target(
name: "Blockchain",
dependencies: [
"Codec",
"Utils",
"TracingUtils",
.product(name: "ScaleCodec", package: "ScaleCodec.swift"),
]
),
.testTarget(
Expand Down
2 changes: 1 addition & 1 deletion Blockchain/Sources/Blockchain/Runtime.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public final class Runtime {
newState.lastBlock = block

let res = newState.updateSafrole(
slot: block.header.timeslotIndex, entropy: newState.entropyPool.0, extrinsics: block.extrinsic.tickets
slot: block.header.timeslotIndex, entropy: newState.entropyPool.t0, extrinsics: block.extrinsic.tickets
)
switch res {
case let .success((state: postState, epochMark: _, ticketsMark: _)):
Expand Down
45 changes: 31 additions & 14 deletions Blockchain/Sources/Blockchain/Safrole.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Blake2
import Codec
import Foundation
import ScaleCodec
import Utils

public enum SafroleError: Error {
Expand All @@ -17,9 +17,23 @@ public enum SafroleError: Error {
case other(any Swift.Error)
}

public struct EntropyPool: Sendable, Equatable, Codable {
public var t0: Data32
public var t1: Data32
public var t2: Data32
public var t3: Data32

public init(_ entropyPool: (Data32, Data32, Data32, Data32)) {
t0 = entropyPool.0
t1 = entropyPool.1
t2 = entropyPool.2
t3 = entropyPool.3
}
}

public struct SafrolePostState: Sendable, Equatable {
public var timeslot: TimeslotIndex
public var entropyPool: (Data32, Data32, Data32, Data32)
public var entropyPool: EntropyPool
public var previousValidators: ConfigFixedSizeArray<
ValidatorKey, ProtocolConfig.TotalNumberOfValidators
>
Expand Down Expand Up @@ -51,7 +65,7 @@ public struct SafrolePostState: Sendable, Equatable {

public init(
timeslot: TimeslotIndex,
entropyPool: (Data32, Data32, Data32, Data32),
entropyPool: EntropyPool,
previousValidators: ConfigFixedSizeArray<
ValidatorKey, ProtocolConfig.TotalNumberOfValidators
>,
Expand Down Expand Up @@ -108,7 +122,7 @@ public struct SafrolePostState: Sendable, Equatable {
public protocol Safrole {
var config: ProtocolConfigRef { get }
var timeslot: TimeslotIndex { get }
var entropyPool: (Data32, Data32, Data32, Data32) { get }
var entropyPool: EntropyPool { get }
var previousValidators: ConfigFixedSizeArray<
ValidatorKey, ProtocolConfig.TotalNumberOfValidators
> { get }
Expand Down Expand Up @@ -172,15 +186,18 @@ func outsideInReorder<T>(_ array: [T]) -> [T] {
return reordered
}

func generateFallbackIndices(entropy: Data32, count: Int) throws -> [Int] {
func generateFallbackIndices(entropy: Data32, count: Int, length: Int) throws -> [Int] {
try (0 ..< count).map { i throws in
// convert i to little endian
let bytes = UInt32(i).data(littleEndian: true, trimmed: false)
let bytes = UInt32(i).encode()
let data = entropy.data + Data(bytes)
// TODO: use blake256 update directly to be more efficient
let hash = try blake2b256(data)
let hash4 = hash.data[0 ..< 4]
let idx = try decode(UInt32.self, from: hash4)
return Int(idx)
let idx: UInt32 = hash4.withUnsafeBytes { ptr in
ptr.loadUnaligned(as: UInt32.self)
}
return Int(idx % UInt32(length))
}
}

Expand All @@ -189,8 +206,8 @@ func pickFallbackValidators(
validators: ConfigFixedSizeArray<ValidatorKey, ProtocolConfig.TotalNumberOfValidators>,
count: Int
) throws -> [BandersnatchPublicKey] {
let indices = try generateFallbackIndices(entropy: entropy, count: count)
return indices.map { validators[$0 % validators.count].bandersnatch }
let indices = try generateFallbackIndices(entropy: entropy, count: count, length: validators.count)
return indices.map { validators[$0].bandersnatch }
}

extension Safrole {
Expand Down Expand Up @@ -245,11 +262,11 @@ extension Safrole {
)
: (nextValidators, currentValidators, previousValidators, ticketsVerifier)

let newRandomness = try blake2b256(entropyPool.0.data + entropy.data)
let newRandomness = try blake2b256(entropyPool.t0.data + entropy.data)

let newEntropyPool = isEpochChange
? (newRandomness, entropyPool.0, entropyPool.1, entropyPool.2)
: (newRandomness, entropyPool.1, entropyPool.2, entropyPool.3)
? (newRandomness, entropyPool.t0, entropyPool.t1, entropyPool.t2)
: (newRandomness, entropyPool.t1, entropyPool.t2, entropyPool.t3)

let newTicketsOrKeys: Either<
ConfigFixedSizeArray<
Expand Down Expand Up @@ -339,7 +356,7 @@ extension Safrole {

let postState = SafrolePostState(
timeslot: slot,
entropyPool: newEntropyPool,
entropyPool: EntropyPool(newEntropyPool),
previousValidators: newPreviousValidators,
currentValidators: newCurrentValidators,
nextValidators: newNextValidators,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import ScaleCodec
import Utils

public struct AvailabilitySpecifications: Sendable, Equatable {
public struct AvailabilitySpecifications: Sendable, Equatable, Codable {
// h
public var workPackageHash: Data32

Expand Down Expand Up @@ -38,21 +37,3 @@ extension AvailabilitySpecifications: Dummy {
)
}
}

extension AvailabilitySpecifications: ScaleCodec.Codable {
public init(from decoder: inout some ScaleCodec.Decoder) throws {
try self.init(
workPackageHash: decoder.decode(),
length: decoder.decode(),
erasureRoot: decoder.decode(),
segmentRoot: decoder.decode()
)
}

public func encode(in encoder: inout some ScaleCodec.Encoder) throws {
try encoder.encode(workPackageHash)
try encoder.encode(length)
try encoder.encode(erasureRoot)
try encoder.encode(segmentRoot)
}
}
Loading

0 comments on commit 51bb692

Please sign in to comment.