Skip to content

Commit

Permalink
refactor: use x64 everywhere for PVM
Browse files Browse the repository at this point in the history
  • Loading branch information
danielvladco committed Feb 18, 2025
1 parent 13de0f6 commit 2443abd
Show file tree
Hide file tree
Showing 15 changed files with 135 additions and 135 deletions.
72 changes: 36 additions & 36 deletions internal/polkavm/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,37 +27,37 @@ type Memory struct {
}

type memorySegment struct {
address uint32
address uint64
data []byte
access MemoryAccess
}

// Read reads from the set of readable indices (Vμ) (implements eq. A.8)
func (m *Memory) Read(address uint32, data []byte) error {
func (m *Memory) Read(address uint64, data []byte) error {
// ☇ if min(x) mod 2^32 < 2^16
if address < 1<<16 {
return ErrPanicf("forbidden memory access")
}
var memoryData []byte
access := Inaccessible
if address >= m.stack.address && address+uint32(len(data)) <= m.stack.address+uint32(len(m.stack.data)) {
memoryData = m.stack.data[address-m.stack.address : address-m.stack.address+uint32(len(data))]
if address >= m.stack.address && address+uint64(len(data)) <= m.stack.address+uint64(len(m.stack.data)) {
memoryData = m.stack.data[address-m.stack.address : address-m.stack.address+uint64(len(data))]
access = m.stack.access
} else if address >= m.rw.address && address+uint32(len(data)) <= m.rw.address+uint32(len(m.rw.data)) {
memoryData = m.rw.data[address-m.rw.address : address-m.rw.address+uint32(len(data))]
} else if address >= m.rw.address && address+uint64(len(data)) <= m.rw.address+uint64(len(m.rw.data)) {
memoryData = m.rw.data[address-m.rw.address : address-m.rw.address+uint64(len(data))]
access = m.rw.access
} else if address >= m.ro.address && address+uint32(len(data)) <= m.ro.address+uint32(len(m.ro.data)) {
memoryData = m.ro.data[address-m.ro.address : address-m.ro.address+uint32(len(data))]
} else if address >= m.ro.address && address+uint64(len(data)) <= m.ro.address+uint64(len(m.ro.data)) {
memoryData = m.ro.data[address-m.ro.address : address-m.ro.address+uint64(len(data))]
access = m.ro.access
} else if address >= m.args.address && address+uint32(len(data)) <= m.args.address+uint32(len(m.args.data)) {
memoryData = m.args.data[address-m.args.address : address-m.args.address+uint32(len(data))]
} else if address >= m.args.address && address+uint64(len(data)) <= m.args.address+uint64(len(m.args.data)) {
memoryData = m.args.data[address-m.args.address : address-m.args.address+uint64(len(data))]
access = m.args.access
}

// F × ZP ⌊ min(x) mod 2^32 ÷ ZP ⌋
if access == Inaccessible {
// find the minimum page that is not readable
for i := address / PageSize; i <= (address+uint32(len(data)))/PageSize; i++ {
for i := address / PageSize; i <= (address+uint64(len(data)))/PageSize; i++ {
access := m.GetAccess(i)
if access == Inaccessible {
return &ErrPageFault{Reason: "inaccessible memory", Address: i * PageSize}
Expand All @@ -70,32 +70,32 @@ func (m *Memory) Read(address uint32, data []byte) error {
}

// Write writes to the set of writeable indices (Vμ*) (implements eq. A.8)
func (m *Memory) Write(address uint32, data []byte) error {
func (m *Memory) Write(address uint64, data []byte) error {
// ☇ if min(x) mod 2^32 < 2^16
if address < 1<<16 {
return ErrPanicf("forbidden memory access")
}

var memoryData []byte
access := Inaccessible
if address >= m.stack.address && address+uint32(len(data)) <= m.stack.address+uint32(len(m.stack.data)) {
memoryData = m.stack.data[address-m.stack.address : address-m.stack.address+uint32(len(data))]
if address >= m.stack.address && address+uint64(len(data)) <= m.stack.address+uint64(len(m.stack.data)) {
memoryData = m.stack.data[address-m.stack.address : address-m.stack.address+uint64(len(data))]
access = m.stack.access
} else if address >= m.rw.address && address+uint32(len(data)) <= m.rw.address+uint32(len(m.rw.data)) {
memoryData = m.rw.data[address-m.rw.address : address-m.rw.address+uint32(len(data))]
} else if address >= m.rw.address && address+uint64(len(data)) <= m.rw.address+uint64(len(m.rw.data)) {
memoryData = m.rw.data[address-m.rw.address : address-m.rw.address+uint64(len(data))]
access = m.rw.access
} else if address >= m.ro.address && address+uint32(len(data)) <= m.ro.address+uint32(len(m.ro.data)) {
memoryData = m.ro.data[address-m.ro.address : address-m.ro.address+uint32(len(data))]
} else if address >= m.ro.address && address+uint64(len(data)) <= m.ro.address+uint64(len(m.ro.data)) {
memoryData = m.ro.data[address-m.ro.address : address-m.ro.address+uint64(len(data))]
access = m.ro.access
} else if address >= m.args.address && address+uint32(len(data)) <= m.args.address+uint32(len(m.args.data)) {
memoryData = m.args.data[address-m.args.address : address-m.args.address+uint32(len(data))]
} else if address >= m.args.address && address+uint64(len(data)) <= m.args.address+uint64(len(m.args.data)) {
memoryData = m.args.data[address-m.args.address : address-m.args.address+uint64(len(data))]
access = m.args.access
}

// F × ZP ⌊ min(x) mod 2^32 ÷ ZP ⌋
if access != ReadWrite {
// find the minimum page that is not writeable
for i := address / PageSize; i <= (address+uint32(len(data)))/PageSize; i++ {
for i := address / PageSize; i <= (address+uint64(len(data)))/PageSize; i++ {
access := m.GetAccess(i)
if access != ReadWrite { // return min(page) where the issue was found
return &ErrPageFault{Reason: "memory at address is not writeable", Address: i * PageSize}
Expand All @@ -107,8 +107,8 @@ func (m *Memory) Write(address uint32, data []byte) error {
return nil
}

func (m *Memory) Sbrk(size uint32) (uint32, error) {
currentHeapPointer := m.rw.address + uint32(len(m.rw.data)) // h
func (m *Memory) Sbrk(size uint64) (uint64, error) {
currentHeapPointer := m.rw.address + uint64(len(m.rw.data)) // h
if size == 0 {
return currentHeapPointer, nil
}
Expand All @@ -122,40 +122,40 @@ func (m *Memory) Sbrk(size uint32) (uint32, error) {
m.rw.data = make([]byte, alignToPage(newHeapPointer))
}

return m.rw.address + uint32(len(m.rw.data)), nil
return m.rw.address + uint64(len(m.rw.data)), nil
}

// SetAccess updates the access mode
func (m *Memory) SetAccess(pageIndex uint32, access MemoryAccess) error {
func (m *Memory) SetAccess(pageIndex uint64, access MemoryAccess) error {
address := pageIndex * PageSize

if address >= m.stack.address && address < m.stack.address+uint32(len(m.stack.data)) {
if address >= m.stack.address && address < m.stack.address+uint64(len(m.stack.data)) {
m.stack.access = access
return nil
} else if address >= m.rw.address && address < m.rw.address+uint32(len(m.rw.data)) {
} else if address >= m.rw.address && address < m.rw.address+uint64(len(m.rw.data)) {
m.rw.access = access
return nil
} else if address >= m.ro.address && address < m.ro.address+uint32(len(m.ro.data)) {
} else if address >= m.ro.address && address < m.ro.address+uint64(len(m.ro.data)) {
m.ro.access = access
return nil
} else if address >= m.args.address && address < m.args.address+uint32(len(m.args.data)) {
} else if address >= m.args.address && address < m.args.address+uint64(len(m.args.data)) {
m.args.access = access
return nil
}

return &ErrPageFault{Reason: "page out of valid range", Address: address}
}

func (m *Memory) GetAccess(pageIndex uint32) MemoryAccess {
func (m *Memory) GetAccess(pageIndex uint64) MemoryAccess {
address := pageIndex * PageSize

if address >= m.stack.address && address < m.stack.address+uint32(len(m.stack.data)) {
if address >= m.stack.address && address < m.stack.address+uint64(len(m.stack.data)) {
return m.stack.access
} else if address >= m.rw.address && address < m.rw.address+uint32(len(m.rw.data)) {
} else if address >= m.rw.address && address < m.rw.address+uint64(len(m.rw.data)) {
return m.rw.access
} else if address >= m.ro.address && address < m.ro.address+uint32(len(m.ro.data)) {
} else if address >= m.ro.address && address < m.ro.address+uint64(len(m.ro.data)) {
return m.ro.access
} else if address >= m.args.address && address < m.args.address+uint32(len(m.args.data)) {
} else if address >= m.args.address && address < m.args.address+uint64(len(m.args.data)) {
return m.args.access
}

Expand All @@ -167,7 +167,7 @@ type Registers [13]uint64
type Gas int64

// HostCall the generic Ω function definition Ωx(n, ϱ, ω, μ, x) defined in section A.6
type HostCall[X any] func(hostCall uint32, gasCounter Gas, regs Registers, mem Memory, x X) (Gas, Registers, Memory, X, error)
type HostCall[X any] func(hostCall uint64, gasCounter Gas, regs Registers, mem Memory, x X) (Gas, Registers, Memory, X, error)

type Mutator interface {
Trap() error
Expand Down Expand Up @@ -343,7 +343,7 @@ type AccumulateContextPair struct {
type IntegratedPVM struct {
Code []byte //p program code
Ram Memory //u RAM
InstructionCounter uint32 //i instruction counter
InstructionCounter uint64 //i instruction counter
}

type RefineContextPair struct {
Expand Down
2 changes: 1 addition & 1 deletion internal/polkavm/exit_reason.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ var ErrOutOfGas = fmt.Errorf("out of gas")
// ErrPageFault a page fault (attempt to data some address in RAM which is not accessible). This includes the address at fault. (F)
type ErrPageFault struct {
Reason string
Address uint32
Address uint64
}

func (e *ErrPageFault) Error() string {
Expand Down
26 changes: 13 additions & 13 deletions internal/polkavm/host_call/accumulate_functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ func Bless(gas Gas, regs Registers, mem Memory, ctxPair AccumulateContextPair) (
// let [m, a, v, o, n] = ω7...12
managerServiceId, assignServiceId, designateServiceId, addr, servicesNr := regs[A0], regs[A1], regs[A2], regs[A3], regs[A4]
// let g = {(s ↦ g) where E4(s) ⌢ E8(g) = μ_o+12i⋅⋅⋅+12 | i ∈ Nn} if Zo⋅⋅⋅+12n ⊂ Vμ otherwise ∇
for i := range uint32(servicesNr) {
serviceId, err := readNumber[block.ServiceId](mem, uint32(addr)+(12*i), 4)
for i := range servicesNr {
serviceId, err := readNumber[block.ServiceId](mem, addr+(12*i), 4)
if err != nil {
return gas, regs, mem, ctxPair, ErrPanicf(err.Error())
}
serviceGas, err := readNumber[uint64](mem, uint32(addr)+(12*i)+4, 8)
serviceGas, err := readNumber[uint64](mem, addr+(12*i)+4, 8)
if err != nil {
return gas, regs, mem, ctxPair, ErrPanicf(err.Error())
}
Expand Down Expand Up @@ -59,7 +59,7 @@ func Assign(gas Gas, regs Registers, mem Memory, ctxPair AccumulateContextPair)
}
for i := 0; i < state.PendingAuthorizersQueueSize; i++ {
bytes := make([]byte, 32)
if err := mem.Read(uint32(addr)+uint32(32*i), bytes); err != nil {
if err := mem.Read(addr+uint64(32*i), bytes); err != nil {
return gas, regs, mem, ctxPair, ErrPanicf(err.Error())
}
ctxPair.RegularCtx.AccumulationState.PendingAuthorizersQueues[core][i] = crypto.Hash(bytes)
Expand All @@ -84,7 +84,7 @@ func Designate(gas Gas, regs Registers, mem Memory, ctxPair AccumulateContextPai
addr := regs[A0]
for i := 0; i < common.NumberOfValidators; i++ {
bytes := make([]byte, 336)
if err := mem.Read(uint32(addr)+uint32(336*i), bytes); err != nil {
if err := mem.Read(addr+uint64(336*i), bytes); err != nil {
return gas, regs, mem, ctxPair, ErrPanicf(err.Error())
}

Expand Down Expand Up @@ -126,7 +126,7 @@ func New(gas Gas, regs Registers, mem Memory, ctxPair AccumulateContextPair) (Ga

// c = μo⋅⋅⋅+32 if No⋅⋅⋅+32 ⊂ Vμ otherwise ∇
codeHashBytes := make([]byte, 32)
if err := mem.Read(uint32(addr), codeHashBytes); err != nil {
if err := mem.Read(addr, codeHashBytes); err != nil {
return gas, regs, mem, ctxPair, ErrPanicf(err.Error())
}

Expand Down Expand Up @@ -185,7 +185,7 @@ func Upgrade(gas Gas, regs Registers, mem Memory, ctxPair AccumulateContextPair)

// c = μo⋅⋅⋅+32 if No⋅⋅⋅+32 ⊂ Vμ otherwise ∇
codeHash := make([]byte, 32)
if err := mem.Read(uint32(addr), codeHash); err != nil {
if err := mem.Read(addr, codeHash); err != nil {
return gas, regs, mem, ctxPair, ErrPanicf(err.Error())
}

Expand All @@ -212,7 +212,7 @@ func Transfer(gas Gas, regs Registers, mem Memory, ctxPair AccumulateContextPair

// m = μo⋅⋅⋅+M if No⋅⋅⋅+WT ⊂ Vμ otherwise ∇
m := make([]byte, service.TransferMemoSizeBytes)
if err := mem.Read(uint32(o), m); err != nil {
if err := mem.Read(o, m); err != nil {
return gas, regs, mem, ctxPair, ErrPanicf(err.Error())
}

Expand Down Expand Up @@ -260,7 +260,7 @@ func Eject(gas Gas, regs Registers, mem Memory, ctxPair AccumulateContextPair, t

// let h = μo..o+32 if Zo..o+32 ⊂ Vμ
h := make([]byte, 32)
if err := mem.Read(uint32(o), h); err != nil {
if err := mem.Read(o, h); err != nil {
// otherwise ∇
return gas, regs, mem, ctxPair, ErrPanicf(err.Error())
}
Expand Down Expand Up @@ -326,7 +326,7 @@ func Query(gas Gas, regs Registers, mem Memory, ctxPair AccumulateContextPair) (

// let h = μo..o+32 if Zo..o+32 ⊂ Vμ
h := make([]byte, 32)
if err := mem.Read(uint32(addr), h); err != nil {
if err := mem.Read(addr, h); err != nil {
// otherwise ∇ => panic
return gas, regs, mem, ctxPair, ErrPanicf(err.Error())
}
Expand Down Expand Up @@ -373,7 +373,7 @@ func Solicit(gas Gas, regs Registers, mem Memory, ctxPair AccumulateContextPair,
addr, preimageLength := regs[A0], regs[A1]
// let h = μo⋅⋅⋅+32 if Zo⋅⋅⋅+32 ⊂ Vμ otherwise ∇
preimageHashBytes := make([]byte, 32)
if err := mem.Read(uint32(addr), preimageHashBytes); err != nil {
if err := mem.Read(addr, preimageHashBytes); err != nil {
return gas, regs, mem, ctxPair, ErrPanicf(err.Error())
}

Expand Down Expand Up @@ -414,7 +414,7 @@ func Forget(gas Gas, regs Registers, mem Memory, ctxPair AccumulateContextPair,

// let h = μo⋅⋅⋅+32 if Zo⋅⋅⋅+32 ⊂ Vμ otherwise ∇
preimageHashBytes := make([]byte, 32)
if err := mem.Read(uint32(addr), preimageHashBytes); err != nil {
if err := mem.Read(addr, preimageHashBytes); err != nil {
return gas, regs, mem, ctxPair, ErrPanicf(err.Error())
}

Expand Down Expand Up @@ -479,7 +479,7 @@ func Yield(gas Gas, regs Registers, mem Memory, ctxPair AccumulateContextPair) (

// let h = μo..o+32 if Zo..o+32 ⊂ Vμ otherwise ∇
hBytes := make([]byte, 32)
if err := mem.Read(uint32(addr), hBytes); err != nil {
if err := mem.Read(addr, hBytes); err != nil {
// (ε', ω′7, x′_y) = (panic, ω7, x_y) if h = ∇
return gas, regs, mem, ctxPair, ErrPanicf(err.Error())
}
Expand Down
4 changes: 2 additions & 2 deletions internal/polkavm/host_call/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func (r Code) String() string {
return "unknown"
}

func readNumber[U interface{ ~uint32 | ~uint64 | ~int64 }](mem Memory, addr uint32, length int) (u U, err error) {
func readNumber[U interface{ ~uint32 | ~uint64 | ~int64 }](mem Memory, addr uint64, length int) (u U, err error) {
b := make([]byte, length)
if err = mem.Read(addr, b); err != nil {
return
Expand Down Expand Up @@ -146,7 +146,7 @@ func writeFromOffset(

if l > 0 {
sliceToWrite := data[f : f+l]
if err := mem.Write(uint32(addressToWrite), sliceToWrite); err != nil {
if err := mem.Write(addressToWrite, sliceToWrite); err != nil {
return ErrPanicf("out-of-bounds write at address %d", addressToWrite)
}
}
Expand Down
10 changes: 5 additions & 5 deletions internal/polkavm/host_call/general_functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func Lookup(gas polkavm.Gas, regs polkavm.Registers, mem polkavm.Memory, s servi
h, o := regs[polkavm.A1], regs[polkavm.A2]

key := make([]byte, 32)
if err := mem.Read(uint32(h), key); err != nil {
if err := mem.Read(h, key); err != nil {
return gas, regs, mem, polkavm.ErrPanicf(err.Error())
}

Expand Down Expand Up @@ -105,7 +105,7 @@ func Read(gas polkavm.Gas, regs polkavm.Registers, mem polkavm.Memory, s service

// read key data from memory at ko..ko+kz
keyData := make([]byte, kz)
err := mem.Read(uint32(ko), keyData)
err := mem.Read(ko, keyData)
if err != nil {
return gas, regs, mem, polkavm.ErrPanicf(err.Error())
}
Expand Down Expand Up @@ -150,7 +150,7 @@ func Write(gas polkavm.Gas, regs polkavm.Registers, mem polkavm.Memory, s servic
vz := regs[polkavm.A3]

keyData := make([]byte, kz)
err := mem.Read(uint32(ko), keyData)
err := mem.Read(ko, keyData)
if err != nil {
return gas, regs, mem, s, polkavm.ErrPanicf(err.Error())
}
Expand All @@ -167,7 +167,7 @@ func Write(gas polkavm.Gas, regs polkavm.Registers, mem polkavm.Memory, s servic
delete(a.Storage, k)
} else {
valueData := make([]byte, vz)
err = mem.Read(uint32(vo), valueData)
err = mem.Read(vo, valueData)
if err != nil {
return gas, regs, mem, s, polkavm.ErrPanicf(err.Error())
}
Expand Down Expand Up @@ -223,7 +223,7 @@ func Info(gas polkavm.Gas, regs polkavm.Registers, mem polkavm.Memory, serviceId
return gas, regs, mem, err
}

if err = mem.Write(uint32(omega8), m); err != nil {
if err = mem.Write(omega8, m); err != nil {
return gas, regs, mem, polkavm.ErrPanicf(err.Error())
}

Expand Down
Loading

0 comments on commit 2443abd

Please sign in to comment.