Skip to content

Commit

Permalink
refactor: align info host-call with the latest PVM api changes
Browse files Browse the repository at this point in the history
  • Loading branch information
danielvladco committed Oct 28, 2024
1 parent a4d35d3 commit 6b70192
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 139 deletions.
22 changes: 11 additions & 11 deletions internal/polkavm/abi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

func Test_memoryMap(t *testing.T) {
maxSize := uint32(AddressSpaceSize - uint64(VmMaxPageSize)*4)
maxSize := uint32(AddressSpaceSize - uint64(VmMaxPageSize)*5)
tests := []struct {
expectError bool
pageSize, roDataSize, rwDataSize, stackSize uint32
Expand All @@ -22,19 +22,19 @@ func Test_memoryMap(t *testing.T) {
expectedRWDataSize: 0x4000,
expectedStackSize: 0x4000,
expectedRWDataAddress: 0x30000,
expectedStackAddressHigh: 0xffff0000,
expectedStackAddressLow: 0xfffec000,
expectedStackAddressHigh: 0xfffe0000,
expectedStackAddressLow: 0xfffdc000,
expectedHeapBase: 0x30001,
expectedMaxHeapSize: AddressSpaceSize - uint64(VmMaxPageSize)*3 - uint64(0x30001),
expectedMaxHeapSize: AddressSpaceSize - uint64(VmMaxPageSize)*4 - uint64(0x30001),
}, {
pageSize: 0x4000, roDataSize: maxSize, rwDataSize: 0, stackSize: 0,
expectedRODataAddress: 0x10000,
expectedRODataSize: maxSize,
expectedRWDataAddress: 0x10000 + VmMaxPageSize + maxSize,
expectedRWDataSize: 0,
expectedStackAddressHigh: VmAddressSpaceTop - VmMaxPageSize,
expectedStackAddressLow: VmAddressSpaceTop - VmMaxPageSize,
expectedStackSize: 0,
expectedStackAddressHigh: VmAddressSpaceTop,
expectedStackAddressLow: VmAddressSpaceTop,
expectedHeapBase: 0x10000 + VmMaxPageSize + maxSize,
expectedMaxHeapSize: 0,
}, {
Expand All @@ -52,8 +52,8 @@ func Test_memoryMap(t *testing.T) {
expectedRODataSize: 0,
expectedRWDataAddress: VmMaxPageSize * 2,
expectedRWDataSize: maxSize,
expectedStackAddressHigh: VmAddressSpaceTop,
expectedStackAddressLow: VmAddressSpaceTop,
expectedStackAddressHigh: VmAddressSpaceTop - VmMaxPageSize,
expectedStackAddressLow: VmAddressSpaceTop - VmMaxPageSize,
expectedStackSize: 0,
expectedHeapBase: VmMaxPageSize*2 + maxSize,
expectedMaxHeapSize: 0,
Expand All @@ -63,15 +63,15 @@ func Test_memoryMap(t *testing.T) {
expectedRODataSize: 0,
expectedRWDataAddress: VmMaxPageSize * 2,
expectedRWDataSize: 0,
expectedStackAddressHigh: VmAddressSpaceTop,
expectedStackAddressLow: VmAddressSpaceTop - maxSize,
expectedStackAddressHigh: VmAddressSpaceTop - VmMaxPageSize,
expectedStackAddressLow: VmAddressSpaceTop - VmMaxPageSize - maxSize,
expectedStackSize: maxSize,
expectedHeapBase: VmMaxPageSize * 2,
expectedMaxHeapSize: 0,
}}
for _, tc := range tests {
t.Run("", func(t *testing.T) {
m, err := NewMemoryMap(tc.pageSize, tc.roDataSize, tc.rwDataSize, tc.stackSize, 0)
m, err := NewMemoryMap(uint(tc.pageSize), uint(tc.roDataSize), uint(tc.rwDataSize), uint(tc.stackSize), 0)
if err != nil {
if tc.expectError {
return
Expand Down
130 changes: 52 additions & 78 deletions internal/polkavm/host_call/general_functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type AccountInfo struct {
TotalItems uint32 // ti
}

// GasRemaining ΩG
// GasRemaining ΩG(ξ, ω, ...)
func GasRemaining(gas polkavm.Gas, regs polkavm.Registers) (polkavm.Gas, polkavm.Registers, error) {
if gas < GasRemainingCost {
return gas, regs, polkavm.ErrOutOfGas
Expand All @@ -45,8 +45,8 @@ func GasRemaining(gas polkavm.Gas, regs polkavm.Registers) (polkavm.Gas, polkavm
return gas, regs, nil
}

// Lookup ΩL
func Lookup(gas polkavm.Gas, regs polkavm.Registers, mem polkavm.Memory, serviceId block.ServiceId, serviceState state.ServiceState) (polkavm.Gas, polkavm.Registers, polkavm.Memory, error) {
// Lookup ΩL(ξ, ω, μ, s, s, d)
func Lookup(gas polkavm.Gas, regs polkavm.Registers, mem polkavm.Memory, s state.ServiceAccount, serviceId block.ServiceId, serviceState state.ServiceState) (polkavm.Gas, polkavm.Registers, polkavm.Memory, error) {
if gas < LookupCost {
return gas, regs, mem, polkavm.ErrOutOfGas
}
Expand All @@ -55,23 +55,15 @@ func Lookup(gas polkavm.Gas, regs polkavm.Registers, mem polkavm.Memory, service
sID := regs[polkavm.A0]

// Determine the lookup key 'a'
var a state.ServiceAccount
if sID == uint32(serviceId) || sID == math.MaxUint32 {
a := s
if sID != math.MaxUint32 && sID != uint32(serviceId) {
var exists bool
// Lookup service account by serviceId in the serviceState
serviceAccount, serviceExists := serviceState[serviceId]
if !serviceExists {
regs[polkavm.A0] = uint32(polkavm.HostCallResultNone)
return gas, regs, mem, nil
}

a = serviceAccount
} else {
storedService, exists := serviceState[block.ServiceId(sID)]
a, exists = serviceState[serviceId]
if !exists {
regs[polkavm.A0] = uint32(polkavm.HostCallResultNone)
return gas, regs, mem, nil
}
a = storedService
}

ho := regs[polkavm.A1]
Expand Down Expand Up @@ -112,8 +104,8 @@ func Lookup(gas polkavm.Gas, regs polkavm.Registers, mem polkavm.Memory, service
return gas, regs, mem, err
}

// Read ΩR
func Read(gas polkavm.Gas, regs polkavm.Registers, mem polkavm.Memory, serviceId block.ServiceId, serviceState state.ServiceState) (polkavm.Gas, polkavm.Registers, polkavm.Memory, error) {
// Read ΩR(ξ, ω, μ, s, s, d)
func Read(gas polkavm.Gas, regs polkavm.Registers, mem polkavm.Memory, s state.ServiceAccount, serviceId block.ServiceId, serviceState state.ServiceState) (polkavm.Gas, polkavm.Registers, polkavm.Memory, error) {
if gas < ReadCost {
return gas, regs, mem, polkavm.ErrOutOfGas
}
Expand All @@ -125,14 +117,13 @@ func Read(gas polkavm.Gas, regs polkavm.Registers, mem polkavm.Memory, serviceId
bo := regs[polkavm.A3]
bz := regs[polkavm.A4]

if sID == math.MaxUint32 {
sID = uint32(serviceId)
}

// account 'a'
storedService, exists := serviceState[block.ServiceId(sID)]
if !exists {
return gas, regs, mem, polkavm.ErrAccountNotFound
a := s
if sID != math.MaxUint32 && sID != uint32(serviceId) {
var exists bool
a, exists = serviceState[block.ServiceId(sID)]
if !exists {
return gas, regs, mem, polkavm.ErrAccountNotFound
}
}

// read key data from memory at ko..ko+kz
Expand All @@ -157,7 +148,7 @@ func Read(gas polkavm.Gas, regs polkavm.Registers, mem polkavm.Memory, serviceId
// Compute the hash H(E4(s) + keyData)
k := blake2b.Sum256(hashInput)

v, exists := storedService.Storage[k]
v, exists := a.Storage[k]
if !exists {
regs[polkavm.A0] = uint32(polkavm.HostCallResultNone)
return gas, regs, mem, nil
Expand All @@ -179,7 +170,7 @@ func Read(gas polkavm.Gas, regs polkavm.Registers, mem polkavm.Memory, serviceId
return gas, regs, mem, nil
}

// Write ΩW
// Write ΩW (ξ, ω, μ, s, s)
func Write(gas polkavm.Gas, regs polkavm.Registers, mem polkavm.Memory, serviceId block.ServiceId, s state.ServiceAccount) (polkavm.Gas, polkavm.Registers, polkavm.Memory, state.ServiceAccount, error) {
if gas < WriteCost {
return gas, regs, mem, s, polkavm.ErrOutOfGas
Expand Down Expand Up @@ -235,65 +226,48 @@ func Write(gas polkavm.Gas, regs polkavm.Registers, mem polkavm.Memory, serviceI
return gas, regs, mem, a, err // return service account 'a' as opposed to 's' for not successful paths
}

func MakeInfoFunc(
serviceId block.ServiceId,
serviceState state.ServiceState,
memoryMap *polkavm.MemoryMap,
) polkavm.HostFunc {
return func(instance polkavm.Instance) (uint32, error) {
if err := deductGas(instance, InfoCost); err != nil {
return 0, err
}

sID := instance.GetReg(polkavm.A0)
omega1 := instance.GetReg(polkavm.A1)
// Info ΩI(ξ, ω, μ, s, s, d)
func Info(gas polkavm.Gas, regs polkavm.Registers, mem polkavm.Memory, s state.ServiceAccount, serviceId block.ServiceId, serviceState state.ServiceState) (polkavm.Gas, polkavm.Registers, polkavm.Memory, error) {
if gas < InfoCost {
return gas, regs, mem, polkavm.ErrOutOfGas
}
gas -= InfoCost

if sID == math.MaxUint32 {
sID = uint32(serviceId)
}
sID := regs[polkavm.A0]
omega1 := regs[polkavm.A1]

t, exists := serviceState[block.ServiceId(sID)]
t := s
if sID != math.MaxUint32 && sID != uint32(serviceId) {
var exists bool
t, exists = serviceState[block.ServiceId(sID)]
if !exists {
return uint32(polkavm.HostCallResultNone), nil
}

accountInfo := AccountInfo{
CodeHash: t.CodeHash,
Balance: t.Balance,
ThresholdBalance: t.ThresholdBalance(),
GasLimitForAccumulator: t.GasLimitForAccumulator,
GasLimitOnTransfer: t.GasLimitOnTransfer,
TotalStorageSize: t.TotalStorageSize(),
TotalItems: t.TotalItems(),
}

serializer := serialization.NewSerializer(codec.NewJamCodec())
// E(tc, tb, tt, tg , tm, tl, ti)
m, err := serializer.Encode(accountInfo)
if err != nil {
return 0, err
}

end := omega1 + uint32(len(m))
if end > memoryMap.RWDataAddress+memoryMap.RWDataSize {
return uint32(polkavm.HostCallResultOob), nil
}

err = instance.SetMemory(memoryMap, omega1, m)
if err != nil {
return uint32(polkavm.HostCallResultOob), nil
regs[polkavm.A0] = uint32(polkavm.HostCallResultNone)
return gas, regs, mem, nil
}
}

return uint32(polkavm.HostCallResultOk), nil
accountInfo := AccountInfo{
CodeHash: t.CodeHash,
Balance: t.Balance,
ThresholdBalance: t.ThresholdBalance(),
GasLimitForAccumulator: t.GasLimitForAccumulator,
GasLimitOnTransfer: t.GasLimitOnTransfer,
TotalStorageSize: t.TotalStorageSize(),
TotalItems: t.TotalItems(),
}
}

func deductGas(instance polkavm.Instance, gasCost int64) error {
if instance.GasRemaining() < gasCost {
return polkavm.ErrOutOfGas
serializer := serialization.NewSerializer(codec.NewJamCodec())
// E(tc, tb, tt, tg , tm, tl, ti)
m, err := serializer.Encode(accountInfo)
if err != nil {
return gas, regs, mem, polkavm.ErrPanicf(err.Error())
}

instance.DeductGas(gasCost)
if err := mem.Write(omega1, m); err != nil {
regs[polkavm.A0] = uint32(polkavm.HostCallResultOob)
return gas, regs, mem, nil
}

return nil
regs[polkavm.A0] = uint32(polkavm.HostCallResultOk)
return gas, regs, mem, nil
}
Loading

0 comments on commit 6b70192

Please sign in to comment.