Skip to content

Commit

Permalink
0.5.0 pvm updates (#232)
Browse files Browse the repository at this point in the history
* update instructions

* fix decode imm

* fix decode imm

* updates

* disable pvm test
  • Loading branch information
qiweiii authored Nov 27, 2024
1 parent e50528b commit 329a86f
Show file tree
Hide file tree
Showing 19 changed files with 1,100 additions and 568 deletions.
12 changes: 6 additions & 6 deletions Blockchain/Sources/Blockchain/Config/ProtocolConfig+Preset.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ extension Ref where T == ProtocolConfig {
ticketSubmissionEndSlot: 2,
pvmDynamicAddressAlignmentFactor: 2,
pvmProgramInitInputDataSize: 1 << 24,
pvmProgramInitPageSize: 1 << 14,
pvmProgramInitSegmentSize: 1 << 16
pvmProgramInitZoneSize: 1 << 16,
pvmMemoryPageSize: 1 << 12
))

// TODO: pick some good numbers for dev env
Expand Down Expand Up @@ -77,8 +77,8 @@ extension Ref where T == ProtocolConfig {
ticketSubmissionEndSlot: 10,
pvmDynamicAddressAlignmentFactor: 2,
pvmProgramInitInputDataSize: 1 << 24,
pvmProgramInitPageSize: 1 << 14,
pvmProgramInitSegmentSize: 1 << 16
pvmProgramInitZoneSize: 1 << 16,
pvmMemoryPageSize: 1 << 12
))

public static let mainnet = Ref(ProtocolConfig(
Expand Down Expand Up @@ -116,7 +116,7 @@ extension Ref where T == ProtocolConfig {
ticketSubmissionEndSlot: 500,
pvmDynamicAddressAlignmentFactor: 2,
pvmProgramInitInputDataSize: 1 << 24,
pvmProgramInitPageSize: 1 << 14,
pvmProgramInitSegmentSize: 1 << 16
pvmProgramInitZoneSize: 1 << 16,
pvmMemoryPageSize: 1 << 12
))
}
36 changes: 18 additions & 18 deletions Blockchain/Sources/Blockchain/Config/ProtocolConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,11 @@ public struct ProtocolConfig: Sendable, Codable, Equatable {
// ZI = 2^24: The standard pvm program initialization input data size.
public var pvmProgramInitInputDataSize: Int

// ZG = 2^14: The standard pvm program initialization page size.
public var pvmProgramInitPageSize: Int
// ZZ = 2^16: The standard pvm program initialization zone size.
public var pvmProgramInitZoneSize: Int

// ZQ = 2^16: The standard pvm program initialization segment size.
public var pvmProgramInitSegmentSize: Int
// ZP = 2^12: The pvm memory page size.
public var pvmMemoryPageSize: Int

public init(
auditTranchePeriod: Int,
Expand Down Expand Up @@ -148,8 +148,8 @@ public struct ProtocolConfig: Sendable, Codable, Equatable {
ticketSubmissionEndSlot: Int,
pvmDynamicAddressAlignmentFactor: Int,
pvmProgramInitInputDataSize: Int,
pvmProgramInitPageSize: Int,
pvmProgramInitSegmentSize: Int
pvmProgramInitZoneSize: Int,
pvmMemoryPageSize: Int
) {
self.auditTranchePeriod = auditTranchePeriod
self.additionalMinBalancePerStateItem = additionalMinBalancePerStateItem
Expand Down Expand Up @@ -185,8 +185,8 @@ public struct ProtocolConfig: Sendable, Codable, Equatable {
self.ticketSubmissionEndSlot = ticketSubmissionEndSlot
self.pvmDynamicAddressAlignmentFactor = pvmDynamicAddressAlignmentFactor
self.pvmProgramInitInputDataSize = pvmProgramInitInputDataSize
self.pvmProgramInitPageSize = pvmProgramInitPageSize
self.pvmProgramInitSegmentSize = pvmProgramInitSegmentSize
self.pvmProgramInitZoneSize = pvmProgramInitZoneSize
self.pvmMemoryPageSize = pvmMemoryPageSize
}
}

Expand All @@ -197,8 +197,8 @@ extension ProtocolConfig: PvmConfig {}
extension Ref: @retroactive PvmConfig where T == ProtocolConfig {
public var pvmDynamicAddressAlignmentFactor: Int { value.pvmDynamicAddressAlignmentFactor }
public var pvmProgramInitInputDataSize: Int { value.pvmProgramInitInputDataSize }
public var pvmProgramInitPageSize: Int { value.pvmProgramInitPageSize }
public var pvmProgramInitSegmentSize: Int { value.pvmProgramInitSegmentSize }
public var pvmProgramInitZoneSize: Int { value.pvmProgramInitZoneSize }
public var pvmMemoryPageSize: Int { value.pvmMemoryPageSize }
}

extension ProtocolConfig {
Expand Down Expand Up @@ -270,10 +270,10 @@ extension ProtocolConfig {
? other.pvmDynamicAddressAlignmentFactor : pvmDynamicAddressAlignmentFactor,
pvmProgramInitInputDataSize: other.pvmProgramInitInputDataSize != 0
? other.pvmProgramInitInputDataSize : pvmProgramInitInputDataSize,
pvmProgramInitPageSize: other.pvmProgramInitPageSize != 0
? other.pvmProgramInitPageSize : pvmProgramInitPageSize,
pvmProgramInitSegmentSize: other.pvmProgramInitSegmentSize != 0
? other.pvmProgramInitSegmentSize : pvmProgramInitSegmentSize
pvmProgramInitZoneSize: other.pvmProgramInitZoneSize != 0
? other.pvmProgramInitZoneSize : pvmProgramInitZoneSize,
pvmMemoryPageSize: other.pvmMemoryPageSize != 0
? other.pvmMemoryPageSize : pvmMemoryPageSize
)
}

Expand Down Expand Up @@ -362,11 +362,11 @@ extension ProtocolConfig {
pvmProgramInitInputDataSize = try decode(
.pvmProgramInitInputDataSize, defaultValue: 0, required: required
)
pvmProgramInitPageSize = try decode(
.pvmProgramInitPageSize, defaultValue: 0, required: required
pvmProgramInitZoneSize = try decode(
.pvmProgramInitZoneSize, defaultValue: 0, required: required
)
pvmProgramInitSegmentSize = try decode(
.pvmProgramInitSegmentSize, defaultValue: 0, required: required
pvmMemoryPageSize = try decode(
.pvmMemoryPageSize, defaultValue: 0, required: required
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ public class GasFn: HostCall {
public static var identifier: UInt8 { 0 }

public func _callImpl(config _: ProtocolConfigRef, state: VMState) async throws {
state.writeRegister(Registers.Index(raw: 7), UInt32(bitPattern: Int32(state.getGas().value & 0xFFFF_FFFF)))
state.writeRegister(Registers.Index(raw: 8), UInt32(bitPattern: Int32(state.getGas().value >> 32)))
state.writeRegister(Registers.Index(raw: 7), UInt64(bitPattern: state.getGas().value))
}
}

Expand All @@ -29,14 +28,14 @@ public class Lookup: HostCall {

public func _callImpl(config _: ProtocolConfigRef, state: VMState) async throws {
var service: ServiceIndex
let reg = state.readRegister(Registers.Index(raw: 7))
if reg == serviceIndex || reg == Int32.max {
let reg: UInt64 = state.readRegister(Registers.Index(raw: 7))
if reg == serviceIndex || reg == Int64.max {
service = serviceIndex
} else {
service = reg
service = ServiceIndex(truncatingIfNeeded: reg)
}

let regs = state.readRegisters(in: 8 ..< 11)
let regs: [UInt32] = state.readRegisters(in: 8 ..< 11)

let preimageHash = try? Blake2b256.hash(state.readMemory(address: regs[0], length: 32))

Expand Down Expand Up @@ -78,14 +77,14 @@ public class Read: HostCall {

public func _callImpl(config _: ProtocolConfigRef, state: VMState) async throws {
var service: ServiceIndex
let reg = state.readRegister(Registers.Index(raw: 7))
if reg == serviceIndex || reg == Int32.max {
let reg: UInt64 = state.readRegister(Registers.Index(raw: 7))
if reg == serviceIndex || reg == Int64.max {
service = serviceIndex
} else {
service = reg
service = ServiceIndex(truncatingIfNeeded: reg)
}

let regs = state.readRegisters(in: 8 ..< 12)
let regs: [UInt32] = state.readRegisters(in: 8 ..< 12)

let key = try? Blake2b256.hash(serviceIndex.encode(), state.readMemory(address: regs[0], length: Int(regs[1])))

Expand Down Expand Up @@ -126,7 +125,7 @@ public class Write: HostCall {
}

public func _callImpl(config: ProtocolConfigRef, state: VMState) async throws {
let regs = state.readRegisters(in: 7 ..< 11)
let regs: [UInt32] = state.readRegisters(in: 7 ..< 11)

let key = try? Blake2b256.hash(serviceIndex.encode(), state.readMemory(address: regs[0], length: Int(regs[1])))

Expand All @@ -137,7 +136,7 @@ public class Write: HostCall {
}

let len = if let key, let value = try await serviceAccounts.get(serviceAccount: service!, storageKey: key) {
UInt32(value.count)
UInt64(value.count)
} else {
HostCallResultCode.NONE.rawValue
}
Expand Down Expand Up @@ -176,14 +175,14 @@ public class Info: HostCall {

public func _callImpl(config: ProtocolConfigRef, state: VMState) async throws {
var service: ServiceIndex
let reg = state.readRegister(Registers.Index(raw: 7))
if reg == Int32.max {
let reg: UInt64 = state.readRegister(Registers.Index(raw: 7))
if reg == Int64.max {
service = serviceIndex
} else {
service = reg
service = ServiceIndex(truncatingIfNeeded: reg)
}

let o = state.readRegister(Registers.Index(raw: 8))
let o: UInt32 = state.readRegister(Registers.Index(raw: 8))

let m: Data?
let account = try await serviceAccounts.get(serviceAccount: service)
Expand Down Expand Up @@ -217,7 +216,7 @@ public class Info: HostCall {
// MARK: - Accumulate

/// Set privileged services details
public class Empower: HostCall {
public class Bless: HostCall {
public static var identifier: UInt8 { 5 }

public var x: AccumlateResultContext
Expand All @@ -227,7 +226,7 @@ public class Empower: HostCall {
}

public func _callImpl(config _: ProtocolConfigRef, state: VMState) async throws {
let regs = state.readRegisters(in: 7 ..< 12)
let regs: [UInt32] = state.readRegisters(in: 7 ..< 12)

var basicGas: [ServiceIndex: Gas] = [:]
let length = 12 * Int(regs[4])
Expand Down Expand Up @@ -263,7 +262,7 @@ public class Assign: HostCall {
}

public func _callImpl(config: ProtocolConfigRef, state: VMState) async throws {
let (targetCoreIndex, startAddr) = state.readRegister(Registers.Index(raw: 7), Registers.Index(raw: 8))
let (targetCoreIndex, startAddr): (UInt32, UInt32) = state.readRegister(Registers.Index(raw: 7), Registers.Index(raw: 8))

var authorizationQueue: [Data32] = []
let length = 32 * config.value.maxAuthorizationsQueueItems
Expand Down Expand Up @@ -296,7 +295,7 @@ public class Designate: HostCall {
}

public func _callImpl(config: ProtocolConfigRef, state: VMState) async throws {
let startAddr = state.readRegister(Registers.Index(raw: 7))
let startAddr: UInt32 = state.readRegister(Registers.Index(raw: 7))

var validatorQueue: [ValidatorKey] = []
let length = 336 * config.value.totalNumberOfValidators
Expand Down Expand Up @@ -329,8 +328,7 @@ public class Checkpoint: HostCall {
}

public func _callImpl(config _: ProtocolConfigRef, state: VMState) async throws {
state.writeRegister(Registers.Index(raw: 7), UInt32(bitPattern: Int32(state.getGas().value & 0xFFFF_FFFF)))
state.writeRegister(Registers.Index(raw: 8), UInt32(bitPattern: Int32(state.getGas().value >> 32)))
state.writeRegister(Registers.Index(raw: 7), UInt64(bitPattern: state.getGas().value))

y = x
}
Expand All @@ -351,18 +349,18 @@ public class New: HostCall {
}

public func _callImpl(config: ProtocolConfigRef, state: VMState) async throws {
let regs = state.readRegisters(in: 7 ..< 13)
let regs: [UInt64] = state.readRegisters(in: 7 ..< 11)

let codeHash: Data32? = try? Data32(state.readMemory(address: regs[0], length: 32))
let minAccumlateGas = Gas(0x1_0000_0000) * Gas(regs[3]) + Gas(regs[2])
let minOnTransferGas = Gas(0x1_0000_0000) * Gas(regs[5]) + Gas(regs[4])
let minAccumlateGas = Gas(regs[2])
let minOnTransferGas = Gas(regs[3])

var newAccount: ServiceAccount?
if let codeHash {
newAccount = ServiceAccount(
storage: [:],
preimages: [:],
preimageInfos: [HashAndLength(hash: codeHash, length: regs[1]): []],
preimageInfos: [HashAndLength(hash: codeHash, length: UInt32(truncatingIfNeeded: regs[1])): []],
codeHash: codeHash,
balance: Balance(0),
minAccumlateGas: minAccumlateGas,
Expand Down Expand Up @@ -400,16 +398,14 @@ public class Upgrade: HostCall {
}

public func _callImpl(config _: ProtocolConfigRef, state: VMState) async throws {
let regs = state.readRegisters(in: 7 ..< 12)
let regs: [UInt64] = state.readRegisters(in: 7 ..< 10)

let codeHash: Data32? = try? Data32(state.readMemory(address: regs[0], length: 32))
let minAccumlateGas = Gas(0x1_0000_0000) * Gas(regs[1]) + Gas(regs[2])
let minOnTransferGas = Gas(0x1_0000_0000) * Gas(regs[3]) + Gas(regs[4])

if let codeHash, var acc = try await x.serviceAccounts.get(serviceAccount: x.serviceIndex) {
acc.codeHash = codeHash
acc.minAccumlateGas = minAccumlateGas
acc.minOnTransferGas = minOnTransferGas
acc.minAccumlateGas = Gas(regs[1])
acc.minOnTransferGas = Gas(regs[2])
x.serviceAccounts.set(serviceAccount: x.serviceIndex, account: acc)
state.writeRegister(Registers.Index(raw: 7), HostCallResultCode.OK.rawValue)
} else {
Expand All @@ -429,16 +425,16 @@ public class Transfer: HostCall {
}

public func gasCost(state: VMState) -> Gas {
let (reg8, reg9) = state.readRegister(Registers.Index(raw: 8), Registers.Index(raw: 9))
let (reg8, reg9): (UInt32, UInt32) = state.readRegister(Registers.Index(raw: 8), Registers.Index(raw: 9))
return Gas(10) + Gas(reg8) + Gas(0x1_0000_0000) * Gas(reg9)
}

public func _callImpl(config: ProtocolConfigRef, state: VMState) async throws {
let regs = state.readRegisters(in: 0 ..< 6)
let amount = Balance(0x1_0000_0000) * Balance(regs[2]) + Balance(regs[1])
let gasLimit = Gas(0x1_0000_0000) * Gas(regs[4]) + Gas(regs[3])
let regs: [UInt64] = state.readRegisters(in: 7 ..< 11)
let amount = Balance(regs[1])
let gasLimit = Gas(regs[2])
let memo = try? state.readMemory(address: regs[5], length: config.value.transferMemoSize)
let dest = regs[0]
let dest = UInt32(truncatingIfNeeded: regs[0])

let acc = try await x.serviceAccounts.get(serviceAccount: x.serviceIndex)

Expand Down Expand Up @@ -486,19 +482,20 @@ public class Quit: HostCall {
}

public func _callImpl(config: ProtocolConfigRef, state: VMState) async throws {
let (dest, startAddr) = state.readRegister(Registers.Index(raw: 7), Registers.Index(raw: 8))
let (dest, startAddr): (UInt64, UInt64) = state.readRegister(Registers.Index(raw: 7), Registers.Index(raw: 8))
let acc = try await x.serviceAccounts.get(serviceAccount: x.serviceIndex).expect("service account not found")
let amount = acc.balance - acc.thresholdBalance(config: config) + Balance(config.value.serviceMinBalance)
let gasLimit = Gas(state.getGas())

let isValidDest = dest == x.serviceIndex || dest == Int32.max
let isValidDest = dest == x.serviceIndex || dest == UInt64.max
let memoData = try? state.readMemory(address: startAddr, length: config.value.transferMemoSize)
let memo = memoData != nil ? try JamDecoder.decode(Data128.self, from: memoData!) : nil
let destination = ServiceIndex(truncatingIfNeeded: dest)

let destAcc: ServiceAccountDetails? = if try await x.serviceAccounts.get(serviceAccount: dest) != nil {
try await x.serviceAccounts.get(serviceAccount: dest)
} else if x.accumulateState.serviceAccounts[dest] != nil {
x.accumulateState.serviceAccounts[dest]?.toDetails()
let destAcc: ServiceAccountDetails? = if try await x.serviceAccounts.get(serviceAccount: destination) != nil {
try await x.serviceAccounts.get(serviceAccount: destination)
} else if x.accumulateState.serviceAccounts[destination] != nil {
x.accumulateState.serviceAccounts[destination]?.toDetails()
} else {
nil
}
Expand All @@ -519,7 +516,7 @@ public class Quit: HostCall {
x.serviceAccounts.set(serviceAccount: x.serviceIndex, account: nil)
x.transfers.append(DeferredTransfers(
sender: x.serviceIndex,
destination: dest,
destination: destination,
amount: amount,
memo: memo!,
gasLimit: gasLimit
Expand All @@ -542,7 +539,7 @@ public class Solicit: HostCall {
}

public func _callImpl(config: ProtocolConfigRef, state: VMState) async throws {
let (startAddr, length) = state.readRegister(Registers.Index(raw: 7), Registers.Index(raw: 8))
let (startAddr, length): (UInt32, UInt32) = state.readRegister(Registers.Index(raw: 7), Registers.Index(raw: 8))
let hash = try? state.readMemory(address: startAddr, length: 32)

let preimageInfo = try await x.serviceAccounts.get(serviceAccount: x.serviceIndex, preimageHash: Data32(hash!)!, length: length)
Expand Down Expand Up @@ -582,7 +579,7 @@ public class Forget: HostCall {
}

public func _callImpl(config: ProtocolConfigRef, state: VMState) async throws {
let (startAddr, length) = state.readRegister(Registers.Index(raw: 7), Registers.Index(raw: 8))
let (startAddr, length): (UInt32, UInt32) = state.readRegister(Registers.Index(raw: 7), Registers.Index(raw: 8))
let hash = try? state.readMemory(address: startAddr, length: 32)
let minHoldPeriod = TimeslotIndex(config.value.preimagePurgePeriod)

Expand Down
Loading

0 comments on commit 329a86f

Please sign in to comment.