Metal worker compiles a class v3 program from the pack a prepare line names; igneum-pow chain_dataset_day seam; pow_genesis_dataset_log2 in the override files
main.swift: servePackProgram reads program.h with the packfile.h checks (generator 2 or 3, the class line against the generator, the seed bytes, IGNEUM_SEEDW_INIT against attempt_words, class and era against the line) and compiles program_bound.metal; the program store keys on (seed, class, era); a v3 job with no resident v3 pack program answers need + error; v2 lines unchanged (Swift generation, the variant race); a pack program never races. verify.rs: Epoch::chain_dataset_day(day, class, days_since_genesis, genesis_dataset_log2) and days_since_genesis, the entry the node builds every day cache through (the ca2-mixer growth rule fills the body). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
804f62834f
commit
d1a8a7fc0e
4 changed files with 120 additions and 25 deletions
|
|
@ -417,6 +417,11 @@ pub struct Epoch {
|
|||
/// Default dataset size: 2^28 words = 1 GiB.
|
||||
pub const DEFAULT_DATASET_LOG2: u32 = 28;
|
||||
|
||||
/// Days a day index lies after the network's genesis day (0 for the genesis day and any day before it).
|
||||
pub fn days_since_genesis(day_index: u64, genesis_day_index: u64) -> u64 {
|
||||
day_index.saturating_sub(genesis_day_index)
|
||||
}
|
||||
|
||||
impl Epoch {
|
||||
pub fn new(seed: &str, day: &str, mode: DatasetMode, dataset_log2: u32) -> Self {
|
||||
Self { program: generate(seed), dataset: DatasetSource::new(day, mode, dataset_log2) }
|
||||
|
|
@ -467,9 +472,18 @@ impl Epoch {
|
|||
/// construction (the mixer multiplier) and cache size schedule (ca2-mixer); today both classes build the day of
|
||||
/// [`Epoch::from_seed_bytes`], and the engine keys its day caches on `(day, class)` so the two never share one.
|
||||
pub fn chain_dataset(day_bytes: &[u8], class: ProgramClass) -> DatasetSource {
|
||||
let _ = class;
|
||||
Self::chain_dataset_day(day_bytes, class, 0, DEFAULT_DATASET_LOG2)
|
||||
}
|
||||
|
||||
/// [`Epoch::chain_dataset`] with the day's position since genesis and the network's genesis dataset size: the
|
||||
/// entry the node's engine and the miner's export build every day cache through, so the cache growth schedule
|
||||
/// of spec 01 section 1.13.3 has one place to act. SEAM (ca2-node, 5 October 2026): the body here builds the
|
||||
/// genesis-size cache for every day; the ca2-mixer branch fills the growth rule (`growth_doublings`) and the
|
||||
/// class v3 item construction, keeping this signature.
|
||||
pub fn chain_dataset_day(day_bytes: &[u8], class: ProgramClass, days_since_genesis: u64, genesis_dataset_log2: u32) -> DatasetSource {
|
||||
let _ = (class, days_since_genesis);
|
||||
let key = crate::seed::seed_words_from_bytes(day_bytes);
|
||||
let mut dataset = DatasetSource::from_key(key, DatasetMode::MemoryHard, DEFAULT_DATASET_LOG2);
|
||||
let mut dataset = DatasetSource::from_key(key, DatasetMode::MemoryHard, genesis_dataset_log2);
|
||||
dataset.key_bytes = day_bytes.to_vec();
|
||||
dataset
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@
|
|||
"proving_v0_activation_daa": 18446744073709551615,
|
||||
"finality_v3_activation_daa": 18446744073709551615,
|
||||
"program_class_v3_activation_daa": 18446744073709551615,
|
||||
"pow_genesis_dataset_log2": 28,
|
||||
"fees_v1_activation_daa": 0,
|
||||
"fees": {"pgas": {"version": 1, "cycles_per_pgas": 1000, "intrinsic_pgas_per_tx": 300, "modexp_base": 10, "modexp_per_byte_numer": 1, "modexp_per_byte_denom": 10}, "block_proving_gas_limit": 120000, "shard_proving_gas_budget": 30000, "min_execution_base_fee_wei": 100000000000, "min_proving_base_fee_wei": 10000000000000, "initial_execution_base_fee_wei": 100000000000, "initial_proving_base_fee_wei": 10000000000000, "base_fee_change_denominator": 8}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2781,13 +2781,32 @@ func blockInitWords(prehash: [UInt8], nonceHi: UInt32) -> [UInt32] {
|
|||
|
||||
final class ServeProgram {
|
||||
let seedHex: String
|
||||
let program: Program
|
||||
/// The Swift-generated program (class v2); nil for a program compiled from a pack (class v3, Counter ASIC 2.0),
|
||||
/// which has no Swift instruction list and so never races variants
|
||||
let program: Program?
|
||||
/// Counter ASIC 2.0: the class ("v2" or "v3") and, for a pack program, its era seed hex and loads per hash
|
||||
let programClass: String
|
||||
let eraHex: String
|
||||
let loadsPerHash: Int
|
||||
private var slot: CompiledHash
|
||||
private let lock = NSLock()
|
||||
/// true until a race ran for this program (an inline compile races after the first job on it)
|
||||
var raceDue = true
|
||||
var raceLine = ""
|
||||
init(seedHex: String, program: Program, compiled: CompiledHash) { self.seedHex = seedHex; self.program = program; self.slot = compiled }
|
||||
init(seedHex: String, program: Program, compiled: CompiledHash) {
|
||||
self.seedHex = seedHex; self.program = program; self.slot = compiled
|
||||
self.programClass = "v2"; self.eraHex = ""; self.loadsPerHash = program.loadsPerHash
|
||||
}
|
||||
init(seedHex: String, packClass: String, eraHex: String, loadsPerHash: Int, compiled: CompiledHash) {
|
||||
self.seedHex = seedHex; self.program = nil; self.slot = compiled
|
||||
self.programClass = packClass; self.eraHex = eraHex; self.loadsPerHash = loadsPerHash; self.raceDue = false
|
||||
}
|
||||
/// Whether this program is the one a line naming `cls` (and `era`) wants; empty names accept any (class v2 lines).
|
||||
func matches(cls: String, era: String) -> Bool {
|
||||
if cls != "" && cls != programClass { return false }
|
||||
if era != "" && programClass == "v3" && era.lowercased() != eraHex.lowercased() { return false }
|
||||
return true
|
||||
}
|
||||
var compiled: CompiledHash { lock.lock(); defer { lock.unlock() }; return slot }
|
||||
func install(_ c: CompiledHash) { lock.lock(); slot = c; lock.unlock() }
|
||||
}
|
||||
|
|
@ -2873,7 +2892,8 @@ func raceProgram(_ gpu: GPU, _ program: ServeProgram, dataset: MTLBuffer, datase
|
|||
// Compile (the base is already compiled)
|
||||
for i in 1..<entries.count {
|
||||
if nowNs() > deadline { entries[i].note = "not compiled: the race budget ran out"; continue }
|
||||
do { entries[i].compiled = try compileBound(gpu, msl: generateMSL(program.program, datasetLog2: datasetLog2, source: .stored, bound: true, variant: entries[i].v), variant: entries[i].v) }
|
||||
guard let swiftProgram = program.program else { return "race \(program.seedHex.prefix(16)) skipped: a pack program (class \(program.programClass)) has no variants to race" }
|
||||
do { entries[i].compiled = try compileBound(gpu, msl: generateMSL(swiftProgram, datasetLog2: datasetLog2, source: .stored, bound: true, variant: entries[i].v), variant: entries[i].v) }
|
||||
catch { entries[i].note = "compile: \(error)".prefix(200).description }
|
||||
}
|
||||
let compileMs = ms(t0, nowNs())
|
||||
|
|
@ -2926,7 +2946,7 @@ func raceProgram(_ gpu: GPU, _ program: ServeProgram, dataset: MTLBuffer, datase
|
|||
if win != 0, let k = entries[win].compiled { program.install(k) }
|
||||
let total = ms(t0, nowNs())
|
||||
let os = ProcessInfo.processInfo.operatingSystemVersion
|
||||
var line = "race \(program.seedHex.prefix(16)) device \(device) driver macos-\(os.majorVersion).\(os.minorVersion).\(os.patchVersion) arch metal loads \(program.program.loadsPerHash) wide \(program.program.wideLoadsPerHash) variants \(entries.count)"
|
||||
var line = "race \(program.seedHex.prefix(16)) device \(device) driver macos-\(os.majorVersion).\(os.minorVersion).\(os.patchVersion) arch metal loads \(program.loadsPerHash) wide \(program.program?.wideLoadsPerHash ?? 0) variants \(entries.count)"
|
||||
for e in entries { line += e.ok && (e.mhs > 0 || pinnedOnly) ? " \(e.v.name)=\(fmt(e.mhs, 3))/\(e.compiled!.pipeline.maxTotalThreadsPerThreadgroup)t/\(e.v.groupWidth)w" : " \(e.v.name)=-" }
|
||||
let gain = baseMhs > 0 ? (winMhs / baseMhs - 1) * 100 : 0
|
||||
line += " winner \(entries[win].v.name) \(fmt(winMhs, 3)) base \(fmt(baseMhs, 3)) gain \(gain >= 0 ? "+" : "")\(fmt(gain, 2))% compile \(fmt(compileMs, 0)) bench \(fmt(total - compileMs, 0)) total \(fmt(total, 0)) ms"
|
||||
|
|
@ -2957,14 +2977,14 @@ final class ServeStore {
|
|||
/// The pair of the last job (epoch seed hex, day seed hex); never evicted
|
||||
var current: (String, String)? = nil
|
||||
|
||||
func program(_ seedHex: String) -> ServeProgram? { lock.lock(); defer { lock.unlock() }; return programs.first { $0.seedHex == seedHex } }
|
||||
func program(_ seedHex: String, cls: String = "", era: String = "") -> ServeProgram? { lock.lock(); defer { lock.unlock() }; return programs.first { $0.seedHex == seedHex && $0.matches(cls: cls, era: era) } }
|
||||
func dataset(_ dayHex: String) -> ServeDataset? { lock.lock(); defer { lock.unlock() }; return datasets.first { $0.dayHex == dayHex } }
|
||||
func counts() -> (Int, Int) { lock.lock(); defer { lock.unlock() }; return (programs.count, datasets.count) }
|
||||
|
||||
/// Adds a program; with more than two resident, the oldest one that is not the current job's goes.
|
||||
func add(_ p: ServeProgram) {
|
||||
lock.lock(); defer { lock.unlock() }
|
||||
if programs.contains(where: { $0.seedHex == p.seedHex }) { return }
|
||||
if programs.contains(where: { $0.seedHex == p.seedHex && $0.programClass == p.programClass && $0.eraHex == p.eraHex }) { return }
|
||||
programs.append(p)
|
||||
while programs.count > 2, let i = programs.firstIndex(where: { $0.seedHex != current?.0 && $0.seedHex != p.seedHex }) { programs.remove(at: i) }
|
||||
}
|
||||
|
|
@ -3011,6 +3031,51 @@ func serveProgram(_ gpu: GPU, _ store: ServeStore, seedHex: String, seed: [UInt8
|
|||
return (sp, ms(t0, nowNs()))
|
||||
}
|
||||
|
||||
// Counter ASIC 2.0 (5 October 2026): a class v3 program comes from the pack igneum-miner export-pack / --prepare-packs
|
||||
// wrote (program_bound.metal, the Rust emitter's text; program.h for the identity), never from the Swift generator.
|
||||
// The pack is checked the way the one-click workers check it (proto-cuda/nvrtc/packfile.h): IGNEUM_GENERATOR 2 or 3,
|
||||
// the class line against the generator, the seed bytes against the line's epoch seed, IGNEUM_SEEDW_INIT against the
|
||||
// words of IGNEUM_PROGRAM_ATTEMPT of that seed, and the class and era against what the line names.
|
||||
func servePackProgram(_ gpu: GPU, _ store: ServeStore, seedHex: String, seed: [UInt8], dir: String, wantClass: String, wantEra: String) throws -> (ServeProgram, Double) {
|
||||
if let p = store.program(seedHex, cls: wantClass, era: wantEra) { return (p, 0) }
|
||||
let t0 = nowNs()
|
||||
guard let programH = try? String(contentsOfFile: dir + "/program.h", encoding: .utf8) else { throw NSError(domain: "pack", code: 1, userInfo: [NSLocalizedDescriptionKey: "cannot read \(dir)/program.h"]) }
|
||||
func defineU32(_ name: String) -> UInt32? {
|
||||
guard let re = try? NSRegularExpression(pattern: "#define \(name) ([0-9a-fA-Fx]+)"), let m = re.firstMatch(in: programH, range: NSRange(programH.startIndex..., in: programH)) else { return nil }
|
||||
let v = String(programH[Range(m.range(at: 1), in: programH)!]).replacingOccurrences(of: "u", with: "")
|
||||
return v.hasPrefix("0x") ? UInt32(v.dropFirst(2), radix: 16) : UInt32(v)
|
||||
}
|
||||
func defineStr(_ name: String) -> String? {
|
||||
guard let re = try? NSRegularExpression(pattern: "#define \(name) \"([^\"]*)\""), let m = re.firstMatch(in: programH, range: NSRange(programH.startIndex..., in: programH)) else { return nil }
|
||||
return String(programH[Range(m.range(at: 1), in: programH)!])
|
||||
}
|
||||
func defineWords(_ name: String) -> [UInt32]? {
|
||||
guard let re = try? NSRegularExpression(pattern: "#define \(name) \\{([^}]*)\\}"), let m = re.firstMatch(in: programH, range: NSRange(programH.startIndex..., in: programH)) else { return nil }
|
||||
let body = String(programH[Range(m.range(at: 1), in: programH)!])
|
||||
let words = body.split(separator: ",").compactMap { t -> UInt32? in let v = t.trimmingCharacters(in: .whitespaces).replacingOccurrences(of: "u", with: ""); return v.hasPrefix("0x") ? UInt32(v.dropFirst(2), radix: 16) : UInt32(v) }
|
||||
return words.count == 8 ? words : nil
|
||||
}
|
||||
func refuse(_ why: String) -> NSError { NSError(domain: "pack", code: 2, userInfo: [NSLocalizedDescriptionKey: "pack \(dir): \(why)"]) }
|
||||
let generator = defineU32("IGNEUM_GENERATOR") ?? 1
|
||||
guard generator == 2 || generator == 3 else { throw refuse("program pack generator \(generator) is not a generator version this worker runs (2 or 3)") }
|
||||
let packClass = generator == 3 ? "v3" : "v2"
|
||||
if let named = defineStr("IGNEUM_PROGRAM_CLASS"), named != packClass { throw refuse("program pack IGNEUM_PROGRAM_CLASS \"\(named)\" does not match IGNEUM_GENERATOR \(generator)") }
|
||||
let eraHex = defineStr("IGNEUM_ERA_SEED_HEX") ?? ""
|
||||
if wantClass != "" && wantClass != packClass { throw refuse("program class mismatch: this pack is class \(packClass), the line names class \(wantClass) (export the pack again)") }
|
||||
if wantEra != "" && packClass == "v3" && wantEra.lowercased() != eraHex.lowercased() { throw refuse("era seed mismatch: this pack was drawn under era \(eraHex.isEmpty ? "(none)" : String(eraHex.prefix(16))), the line names era \(wantEra.prefix(16)) (export the pack again)") }
|
||||
if let packSeed = defineStr("IGNEUM_SEED_BYTES_HEX"), packSeed.lowercased() != seedHex.lowercased() { throw refuse("the pack is for epoch \(packSeed.prefix(16)), not \(seedHex.prefix(16))") }
|
||||
let attempt = defineU32("IGNEUM_PROGRAM_ATTEMPT") ?? 0
|
||||
guard let seedw = defineWords("IGNEUM_SEEDW_INIT") else { throw refuse("program.h has no IGNEUM_SEEDW_INIT with 8 words") }
|
||||
let want = attemptWords(seed, attempt)
|
||||
if want != seedw { throw refuse("program pack and its seeds disagree: IGNEUM_SEEDW_INIT is not attempt \(attempt) of the epoch seed \(seedHex.prefix(16))") }
|
||||
let loads = Int(defineU32("IGNEUM_LOADS_PER_HASH") ?? 128)
|
||||
guard let msl = try? String(contentsOfFile: dir + "/program_bound.metal", encoding: .utf8) else { throw refuse("cannot read program_bound.metal") }
|
||||
let c = try compileBound(gpu, msl: msl)
|
||||
let sp = ServeProgram(seedHex: seedHex, packClass: packClass, eraHex: eraHex, loadsPerHash: loads, compiled: c)
|
||||
store.add(sp)
|
||||
return (sp, ms(t0, nowNs()))
|
||||
}
|
||||
|
||||
// Builds the cache and dataset for a day seed (hex) unless resident. Returns (dataset, build ms).
|
||||
func serveDataset(_ gpu: GPU, _ store: ServeStore, dayHex: String, day: [UInt8], datasetLog2: Int) -> (ServeDataset, Double) {
|
||||
if let d = store.dataset(dayHex) { return (d, 0) }
|
||||
|
|
@ -3036,19 +3101,19 @@ func runServe(_ opts: Options) -> Never {
|
|||
var f = line.split(separator: " ").map(String.init)
|
||||
if f.isEmpty { continue }
|
||||
if f[0] == "quit" { break }
|
||||
// Counter ASIC 2.0 (5 October 2026): a job or prepare line of a class v3 epoch ends with `class=v3 era=<hex>`.
|
||||
// This worker regenerates programs from the seed with the Swift version 2 generator, so it refuses every
|
||||
// class v3 line until the integration branch adds generator 3 here (the one-click workers build from packs
|
||||
// and take v3 packs).
|
||||
var wantClass = ""
|
||||
// Counter ASIC 2.0 (5 October 2026): a job or prepare line of a class v3 epoch ends with `class=v3 era=<hex>`
|
||||
// (a class v2 line is the line of before). A class v2 program is generated here from the seed (the Swift
|
||||
// version 2 generator); a class v3 program is compiled from the pack the prepare line names (servePackProgram),
|
||||
// so a v3 job on seeds with no prepared v3 pack asks for one (`need`) instead of mining the wrong program.
|
||||
var wantClass = "", wantEra = ""
|
||||
while let last = f.last, last.hasPrefix("class=") || last.hasPrefix("era=") {
|
||||
if last.hasPrefix("class=") { wantClass = String(last.dropFirst(6)) }
|
||||
if last.hasPrefix("class=") { wantClass = String(last.dropFirst(6)) } else { wantEra = String(last.dropFirst(4)) }
|
||||
f.removeLast()
|
||||
}
|
||||
if wantClass != "" && wantClass != "v2" {
|
||||
if wantClass != "" && wantClass != "v2" && wantClass != "v3" {
|
||||
let id = f.count > 1 ? f[1] : "0"
|
||||
if f[0] == "prepare" { emit("prepare-failed \(id) \(f.count > 2 ? f[2] : "0") program class \(wantClass) is not implemented by this worker (Swift generator version 2 only)") }
|
||||
else { emit("error \(id) program class \(wantClass) is not implemented by this worker (Swift generator version 2 only); use the CUDA or OpenCL worker with a class \(wantClass) pack") }
|
||||
if f[0] == "prepare" { emit("prepare-failed \(id) \(f.count > 2 ? f[2] : "0") program class \(wantClass) is not one this worker runs (v2 or v3)") }
|
||||
else { emit("error \(id) program class \(wantClass) is not one this worker runs (v2 or v3)") }
|
||||
continue
|
||||
}
|
||||
if f[0] == "prepare" {
|
||||
|
|
@ -3058,12 +3123,16 @@ func runServe(_ opts: Options) -> Never {
|
|||
emit("prepare-failed \(f[1]) \(f[2]) bad field (epoch_seed 64 hex, day_seed hex)"); continue
|
||||
}
|
||||
let (epochHex, dayHex) = (f[1], f[2])
|
||||
let have = (store.program(epochHex) != nil, store.dataset(dayHex) != nil)
|
||||
let have = (store.program(epochHex, cls: wantClass, era: wantEra) != nil, store.dataset(dayHex) != nil)
|
||||
if have.0 && have.1 { emit("prepared \(epochHex) \(dayHex) 0 program 0 dataset 0 (already resident)"); continue }
|
||||
let packDir = f.count > 3 ? f[3...].joined(separator: " ") : ""
|
||||
if wantClass == "v3" && packDir.isEmpty { emit("prepare-failed \(epochHex) \(dayHex) a class v3 program is compiled from a pack: send prepare with a pack directory (igneum-miner --prepare-packs <dir>)"); continue }
|
||||
prepareQueue.async {
|
||||
let t0 = nowNs()
|
||||
do {
|
||||
let (sp, progMs) = try serveProgram(gpu, store, seedHex: epochHex, seed: epochSeed, datasetLog2: datasetLog2)
|
||||
let (sp, progMs) = wantClass == "v3"
|
||||
? try servePackProgram(gpu, store, seedHex: epochHex, seed: epochSeed, dir: packDir, wantClass: wantClass, wantEra: wantEra)
|
||||
: try serveProgram(gpu, store, seedHex: epochHex, seed: epochSeed, datasetLog2: datasetLog2)
|
||||
let (sd, dsMs) = serveDataset(gpu, store, dayHex: dayHex, day: daySeed, datasetLog2: datasetLog2)
|
||||
// The race: the prepared program against its own dataset, exclusive windows between jobs
|
||||
var raceMs = 0.0
|
||||
|
|
@ -3073,8 +3142,8 @@ func runServe(_ opts: Options) -> Never {
|
|||
raceMs = ms(r0, nowNs())
|
||||
}
|
||||
let (np, nd) = store.counts()
|
||||
emit("prepared \(epochHex) \(dayHex) \(fmt(ms(t0, nowNs()), 1)) program \(fmt(progMs, 1)) dataset \(fmt(dsMs, 1)) race \(fmt(raceMs, 1)) variant \(sp.compiled.variant) loads/hash \(sp.program.loadsPerHash) cache-fill \(fmt(sd.ctx.cacheFillGPUms, 1)) resident \(np) programs \(nd) datasets")
|
||||
} catch { emit("prepare-failed \(epochHex) \(dayHex) Metal compile failed: \(error)") }
|
||||
emit("prepared \(epochHex) \(dayHex) \(fmt(ms(t0, nowNs()), 1)) program \(fmt(progMs, 1)) dataset \(fmt(dsMs, 1)) race \(fmt(raceMs, 1)) variant \(sp.compiled.variant) class \(sp.programClass) loads/hash \(sp.loadsPerHash) cache-fill \(fmt(sd.ctx.cacheFillGPUms, 1)) resident \(np) programs \(nd) datasets")
|
||||
} catch { emit("prepare-failed \(epochHex) \(dayHex) \(wantClass == "v3" ? "" : "Metal compile failed: ")\(error.localizedDescription)") }
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
|
@ -3096,9 +3165,20 @@ func runServe(_ opts: Options) -> Never {
|
|||
let program: ServeProgram
|
||||
let dataset: ServeDataset
|
||||
do {
|
||||
if store.program(pair.0) == nil || store.dataset(pair.1) == nil { prepareQueue.sync {} }
|
||||
let (sp, progMs) = try serveProgram(gpu, store, seedHex: pair.0, seed: epochSeed, datasetLog2: datasetLog2)
|
||||
if progMs > 0 { emit("info program epoch \(pair.0.prefix(16)) loads/hash \(sp.program.loadsPerHash) compiled inline in \(fmt(progMs, 1)) ms (not prepared)") }
|
||||
if store.program(pair.0, cls: wantClass, era: wantEra) == nil || store.dataset(pair.1) == nil { prepareQueue.sync {} }
|
||||
let sp: ServeProgram
|
||||
if wantClass == "v3" {
|
||||
guard let resident = store.program(pair.0, cls: wantClass, era: wantEra) else {
|
||||
emit("need \(pair.0) \(pair.1)")
|
||||
emit("error \(jobId) pack (metal): program class mismatch: no class v3 program for epoch \(pair.0.prefix(16)) is resident (this worker compiles v3 from a pack); send prepare with a pack directory")
|
||||
continue
|
||||
}
|
||||
sp = resident
|
||||
} else {
|
||||
let (p, progMs) = try serveProgram(gpu, store, seedHex: pair.0, seed: epochSeed, datasetLog2: datasetLog2)
|
||||
if progMs > 0 { emit("info program epoch \(pair.0.prefix(16)) loads/hash \(p.loadsPerHash) compiled inline in \(fmt(progMs, 1)) ms (not prepared)") }
|
||||
sp = p
|
||||
}
|
||||
let (sd, dsMs) = serveDataset(gpu, store, dayHex: pair.1, day: daySeed, datasetLog2: datasetLog2)
|
||||
if dsMs > 0 { emit("info dataset day \(pair.1) built inline in \(fmt(dsMs, 1)) ms (cache fill \(fmt(sd.ctx.cacheFillGPUms, 1)) ms, build \(fmt(sd.ctx.lastBuildGPUms, 1)) ms GPU; not prepared)") }
|
||||
program = sp; dataset = sd
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"timestamp_deviation_tolerance": 132, "past_median_time_window_size": 27, "difficulty_window_size": 661, "min_difficulty_window_size": 150, "difficulty_rule": "igneum-dual", "coinbase_payload_script_public_key_max_len": 150, "max_coinbase_payload_len": 16384, "max_tx_inputs": 1000, "max_tx_outputs": 1000, "max_signature_script_len": 250000, "max_script_public_key_len": 10000, "mass_per_tx_byte": 1, "mass_per_script_pub_key_byte": 10, "mass_per_sig_op": 1000, "block_mass_limits": {"compute": 500000, "storage": 500000, "transient": 1000000}, "block_lane_limits": {"lanes_per_block": 50, "gas_per_lane": 1000000000}, "storage_mass_parameter": 1000000000000, "deflationary_phase_daa_score": 0, "pre_deflationary_phase_base_subsidy": 50000000000, "skip_proof_of_work": false, "max_block_level": 250, "pruning_proof_m": 1000, "blockrate": {"target_time_per_block": 1000, "ghostdag_k": 18, "past_median_time_sample_rate": 10, "difficulty_sample_rate": 4, "max_block_parents": 10, "mergeset_size_limit": 180, "merge_depth": 60, "finality_depth": 720, "pruning_depth": 13838, "coinbase_maturity": 2}, "pre_crescendo_target_time_per_block": 1000, "crescendo_activation": 0, "genesis_bits": 487587840, "finality": {"checkpoint_interval": 30, "checkpoint_depth": 20, "weight_window": 120, "dust": 5, "presence_window": 1, "aggregators": 8, "equivocation_ban": 120, "min_daa": 120, "aggregator_fallback": 1}, "pow_epoch_blocks": 60, "pow_epoch_lead": 10, "pow_day_ms": 1440000, "finality_v3_activation_daa": 0, "program_class_v3_activation_daa": 18446744073709551615}
|
||||
{"timestamp_deviation_tolerance": 132, "past_median_time_window_size": 27, "difficulty_window_size": 661, "min_difficulty_window_size": 150, "difficulty_rule": "igneum-dual", "coinbase_payload_script_public_key_max_len": 150, "max_coinbase_payload_len": 16384, "max_tx_inputs": 1000, "max_tx_outputs": 1000, "max_signature_script_len": 250000, "max_script_public_key_len": 10000, "mass_per_tx_byte": 1, "mass_per_script_pub_key_byte": 10, "mass_per_sig_op": 1000, "block_mass_limits": {"compute": 500000, "storage": 500000, "transient": 1000000}, "block_lane_limits": {"lanes_per_block": 50, "gas_per_lane": 1000000000}, "storage_mass_parameter": 1000000000000, "deflationary_phase_daa_score": 0, "pre_deflationary_phase_base_subsidy": 50000000000, "skip_proof_of_work": false, "max_block_level": 250, "pruning_proof_m": 1000, "blockrate": {"target_time_per_block": 1000, "ghostdag_k": 18, "past_median_time_sample_rate": 10, "difficulty_sample_rate": 4, "max_block_parents": 10, "mergeset_size_limit": 180, "merge_depth": 60, "finality_depth": 720, "pruning_depth": 13838, "coinbase_maturity": 2}, "pre_crescendo_target_time_per_block": 1000, "crescendo_activation": 0, "genesis_bits": 487587840, "finality": {"checkpoint_interval": 30, "checkpoint_depth": 20, "weight_window": 120, "dust": 5, "presence_window": 1, "aggregators": 8, "equivocation_ban": 120, "min_daa": 120, "aggregator_fallback": 1}, "pow_epoch_blocks": 60, "pow_epoch_lead": 10, "pow_day_ms": 1440000, "finality_v3_activation_daa": 0, "program_class_v3_activation_daa": 18446744073709551615, "pow_genesis_dataset_log2": 28}
|
||||
Loading…
Reference in a new issue