Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

State serialization to 0.5.0 #147

Merged
merged 6 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 20 additions & 38 deletions internal/polkavm/host_call/accumulate_functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ import (
"github.com/eigerco/strawberry/internal/state"
)

// Empower ΩE(ϱ, ω, μ, (x, y))
func Empower(gas Gas, regs Registers, mem Memory, ctxPair AccumulateContextPair) (Gas, Registers, Memory, AccumulateContextPair, error) {
if gas < EmpowerCost {
// Bless ΩB(ϱ, ω, μ, (x, y))
func Bless(gas Gas, regs Registers, mem Memory, ctxPair AccumulateContextPair) (Gas, Registers, Memory, AccumulateContextPair, error) {
if gas < BlessCost {
return gas, regs, mem, ctxPair, ErrOutOfGas
}
gas -= EmpowerCost
gas -= BlessCost

// let [m, a, v, o, n] = ω7...12
managerServiceId, assignServiceId, designateServiceId, addr, servicesNr := regs[A0], regs[A1], regs[A2], regs[A3], regs[A4]
Expand Down Expand Up @@ -108,9 +108,8 @@ func Checkpoint(gas Gas, regs Registers, mem Memory, ctxPair AccumulateContextPa

ctxPair.ExceptionalCtx = ctxPair.RegularCtx

// Split the new ϱ' value into its lower and upper parts.
// Set the new ϱ' value into ω′7
regs[A0] = uint32(gas & ((1 << 32) - 1))
regs[A1] = uint32(gas >> 32)

return gas, regs, mem, ctxPair, nil
}
Expand All @@ -122,19 +121,14 @@ func New(gas Gas, regs Registers, mem Memory, ctxPair AccumulateContextPair) (Ga
}
gas -= NewCost

// let [o, l, gl, gh, ml, mh] = ω7..13
addr, preimageLength, gl, gh, ml, mh := regs[A0], regs[A1], regs[A2], regs[A3], regs[A4], regs[A5]
// let [o, l, g, m] = ω7..11
addr, preimageLength, gasLimitAccumulator, gasLimitTransfer := regs[A0], regs[A1], regs[A2], regs[A3]

// c = μo⋅⋅⋅+32 if No⋅⋅⋅+32 ⊂ Vμ otherwise ∇
codeHashBytes := make([]byte, 32)
if err := mem.Read(addr, codeHashBytes); err != nil {
return gas, withCode(regs, OOB), mem, ctxPair, nil
}
// let g = 2^32 ⋅ gh + gl
gasLimitAccumulator := uint64(gh)<<32 | uint64(gl)

// let m = 2^32 ⋅ mh + ml
gasLimitTransfer := uint64(mh)<<32 | uint64(ml)

codeHash := crypto.Hash(codeHashBytes)

Expand All @@ -145,8 +139,8 @@ func New(gas Gas, regs Registers, mem Memory, ctxPair AccumulateContextPair) (Ga
{Hash: codeHash, Length: service.PreimageLength(preimageLength)}: {},
},
CodeHash: codeHash,
GasLimitForAccumulator: gasLimitAccumulator,
GasLimitOnTransfer: gasLimitTransfer,
GasLimitForAccumulator: uint64(gasLimitAccumulator),
GasLimitOnTransfer: uint64(gasLimitTransfer),
}
account.Balance = account.ThresholdBalance()

Expand Down Expand Up @@ -177,47 +171,35 @@ func Upgrade(gas Gas, regs Registers, mem Memory, ctxPair AccumulateContextPair)
return gas, regs, mem, ctxPair, ErrOutOfGas
}
gas -= UpgradeCost
// let [o, gh, gl, mh, ml] = ω7...12
addr, gl, gh, ml, mh := regs[A0], regs[A1], regs[A2], regs[A3], regs[A4]
// let [o, g, m] = ω7...10
addr, gasLimitAccumulator, gasLimitTransfer := regs[A0], regs[A1], regs[A2]

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

// let g = 2^32 ⋅ gh + gl
gasLimitAccumulator := uint64(gh)<<32 | uint64(gl)

// let m = 2^32 ⋅ mh + ml
gasLimitTransfer := uint64(mh)<<32 | uint64(ml)

// (ω′7, (X′s)c, (X′s)g , (X′s)m) = (OK, c, g, m) if c ≠ ∇
currentService := ctxPair.RegularCtx.ServiceAccount()
currentService.CodeHash = crypto.Hash(codeHash)
currentService.GasLimitForAccumulator = gasLimitAccumulator
currentService.GasLimitOnTransfer = gasLimitTransfer
currentService.GasLimitForAccumulator = uint64(gasLimitAccumulator)
currentService.GasLimitOnTransfer = uint64(gasLimitTransfer)
ctxPair.RegularCtx.ServiceState[ctxPair.RegularCtx.ServiceId] = currentService
return gas, withCode(regs, OK), mem, ctxPair, nil
}

// Transfer ΩT(ϱ, ω, μ, (x, y))
func Transfer(gas Gas, regs Registers, mem Memory, ctxPair AccumulateContextPair) (Gas, Registers, Memory, AccumulateContextPair, error) {
// let (d, al, ah, gl, gh, o) = ω7..13
receiverId, al, ah, gl, gh, o := regs[A0], regs[A1], regs[A2], regs[A3], regs[A4], regs[A5]

// let a = 2^32 ⋅ ah + al
newBalance := uint64(ah)<<32 | uint64(al)
// let (d, a, g, o) = ω7..11
receiverId, newBalance, gasLimit, o := regs[A0], regs[A1], regs[A2], regs[A3]

transferCost := TransferBaseCost + Gas(newBalance)
if gas < transferCost {
return gas, regs, mem, ctxPair, ErrOutOfGas
}
gas -= transferCost

// let g = 2^32 ⋅ gh + gl
gasLimit := uint64(gh)<<32 | uint64(gl)

// m = μo⋅⋅⋅+M if No⋅⋅⋅+M ⊂ Vμ otherwise ∇
m := make([]byte, service.TransferMemoSizeBytes)
if err := mem.Read(o, m); err != nil {
Expand All @@ -228,9 +210,9 @@ func Transfer(gas Gas, regs Registers, mem Memory, ctxPair AccumulateContextPair
deferredTransfer := service.DeferredTransfer{
SenderServiceIndex: ctxPair.RegularCtx.ServiceId,
ReceiverServiceIndex: block.ServiceId(receiverId),
Balance: newBalance,
Balance: uint64(newBalance),
Memo: service.Memo(m),
GasLimit: gasLimit,
GasLimit: uint64(gasLimit),
}

// let d = xd ∪ (xu)d
Expand All @@ -244,7 +226,7 @@ func Transfer(gas Gas, regs Registers, mem Memory, ctxPair AccumulateContextPair
}

// if g < (δ ∪ xn)[d]m
if gasLimit < receiverService.GasLimitOnTransfer {
if uint64(gasLimit) < receiverService.GasLimitOnTransfer {
return gas, withCode(regs, LOW), mem, ctxPair, nil
}

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

// let b = (xs)b − a
// if b < (xs)t
if ctxPair.RegularCtx.ServiceAccount().Balance-newBalance < ctxPair.RegularCtx.ServiceAccount().ThresholdBalance() {
if ctxPair.RegularCtx.ServiceAccount().Balance-uint64(newBalance) < ctxPair.RegularCtx.ServiceAccount().ThresholdBalance() {
return gas, withCode(regs, CASH), mem, ctxPair, nil
}

Expand Down Expand Up @@ -286,7 +268,7 @@ func Quit(gas Gas, regs Registers, mem Memory, ctxPair AccumulateContextPair) (G
}

// if d ∈ {s, 2^32 − 1}
if block.ServiceId(receiverId) == ctxPair.RegularCtx.ServiceId || receiverId == math.MaxUint32 {
if block.ServiceId(receiverId) == ctxPair.RegularCtx.ServiceId || uint64(receiverId) == math.MaxUint64 {
delete(ctxPair.RegularCtx.AccumulationState.ServiceState, ctxPair.RegularCtx.ServiceId)
return gas, withCode(regs, OK), mem, ctxPair, ErrHalt
}
Expand Down
80 changes: 29 additions & 51 deletions internal/polkavm/host_call/accumulate_functions_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package host_call

import (
"maps"
"math"
"slices"
"testing"
"unsafe"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -75,15 +73,15 @@ func TestAccumulate(t *testing.T) {
}{
{
name: "empower",
fn: fnStd(Empower),
fn: fnStd(Bless),
alloc: alloc{
A3: slices.Concat(
encodeNumber(uint32(123)),
encodeNumber(uint64(12341234)),
encodeNumber(uint32(234)),
encodeNumber(uint64(23452345)),
encodeNumber(uint32(345)),
encodeNumber(uint64(34563456)),
encodeNumber(t, uint32(123)),
encodeNumber(t, uint64(12341234)),
encodeNumber(t, uint32(234)),
encodeNumber(t, uint64(23452345)),
encodeNumber(t, uint32(345)),
encodeNumber(t, uint64(34563456)),
),
},
initialRegs: deltaRegs{
Expand Down Expand Up @@ -159,17 +157,14 @@ func TestAccumulate(t *testing.T) {
expectedDeltaRegs: checkUint64(t, 89),
expectedX: checkpointCtx,
expectedY: checkpointCtx,
}, {
},
{
name: "new",
fn: fnStd(New),
alloc: alloc{
A0: hash2bytes(randomHash),
},
initialRegs: merge(
deltaRegs{A1: 123123},
storeUint64(123124123, A2, A3),
storeUint64(756846353, A4, A5),
),
initialRegs: deltaRegs{A1: 123123, A2: 123124123, A3: 756846353},
expectedDeltaRegs: deltaRegs{
A0: uint32(currentServiceID),
},
Expand Down Expand Up @@ -210,16 +205,14 @@ func TestAccumulate(t *testing.T) {
},
},
},
}, {
},
{
name: "upgrade",
fn: fnStd(Upgrade),
alloc: alloc{
A0: hash2bytes(randomHash),
},
initialRegs: merge(
storeUint64(345345345345, A1, A2),
storeUint64(456456456456, A3, A4),
),
initialRegs: deltaRegs{A1: 3453453453, A2: 456456456},
expectedDeltaRegs: deltaRegs{
A0: uint32(OK),
},
Expand All @@ -233,33 +226,31 @@ func TestAccumulate(t *testing.T) {
ServiceId: currentServiceID,
ServiceState: service.ServiceState{currentServiceID: {
CodeHash: randomHash,
GasLimitForAccumulator: 345345345345,
GasLimitOnTransfer: 456456456456,
GasLimitForAccumulator: 3453453453,
GasLimitOnTransfer: 456456456,
}},
},
}, {
name: "transfer",
fn: fnStd(Transfer),
alloc: alloc{
A5: fixedSizeBytes(service.TransferMemoSizeBytes, []byte("memo message")),
A3: fixedSizeBytes(service.TransferMemoSizeBytes, []byte("memo message")),
},
initialRegs: deltaRegs{
A0: 1234, // d: receiver
A1: 1000000000, // a
A2: 80, // g
},
initialRegs: merge(
deltaRegs{
A0: 1234, // d: receiver
},
storeUint64(100000000000, A1, A2), // a
storeUint64(80, A3, A4), // g
),
expectedDeltaRegs: deltaRegs{
A0: uint32(OK),
},
initialGas: 100000000100,
initialGas: 1000000100,
expectedGas: 88,
X: AccumulateContext{
ServiceId: block.ServiceId(123123123),
ServiceState: service.ServiceState{
block.ServiceId(123123123): {
Balance: 100000000100,
Balance: 1000000100,
},
},
AccumulationState: state.AccumulationState{
Expand All @@ -281,13 +272,13 @@ func TestAccumulate(t *testing.T) {
ServiceId: block.ServiceId(123123123),
ServiceState: service.ServiceState{
block.ServiceId(123123123): {
Balance: 100000000100,
Balance: 1000000100,
},
},
DeferredTransfers: []service.DeferredTransfer{{
SenderServiceIndex: block.ServiceId(123123123),
ReceiverServiceIndex: 1234,
Balance: 100000000000,
Balance: 1000000000,
Memo: service.Memo(fixedSizeBytes(service.TransferMemoSizeBytes, []byte("memo message"))),
GasLimit: 80,
}},
Expand Down Expand Up @@ -724,21 +715,6 @@ func checkUint64(t *testing.T, gas uint64) deltaRegs {
}
}

func storeUint64(i uint64, reg1, reg2 Reg) deltaRegs {
return deltaRegs{
reg1: uint32(math.Mod(float64(i), 1<<32)),
reg2: uint32(math.Floor(float64(i) / (1 << 32))),
}
}

func merge[M ~map[K]V, K comparable, V any](dd ...M) M {
result := make(M)
for _, d := range dd {
maps.Copy(result, d)
}
return result
}

func fnStd(fn func(Gas, Registers, Memory, AccumulateContextPair) (Gas, Registers, Memory, AccumulateContextPair, error)) hostCall {
return func(gas Gas, regs Registers, mem Memory, ctxPair AccumulateContextPair, timeslot jamtime.Timeslot) (Gas, Registers, Memory, AccumulateContextPair, error) {
return fn(gas, regs, mem, ctxPair)
Expand Down Expand Up @@ -775,6 +751,8 @@ func transform[S, S2 any](slice1 []S, fn func(S) S2) (slice []S2) {
return slice
}

func encodeNumber[T ~uint8 | ~uint16 | ~uint32 | ~uint64](v T) []byte {
return jam.SerializeTrivialNatural(v, uint8(unsafe.Sizeof(v)))
func encodeNumber[T ~uint8 | ~uint16 | ~uint32 | ~uint64](t *testing.T, v T) []byte {
res, err := jam.Marshal(v)
require.NoError(t, err)
return res
}
6 changes: 3 additions & 3 deletions internal/polkavm/host_call/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const (
ReadCost
WriteCost
InfoCost
EmpowerCost
BlessCost
AssignCost
DesignateCost
CheckpointCost
Expand All @@ -31,7 +31,7 @@ const (
ReadID = 2
WriteID = 3
InfoID = 4
EmpowerID = 5
BlessID = 5
AssignID = 6
DesignateID = 7
CheckpointID = 8
Expand Down Expand Up @@ -93,7 +93,7 @@ func readNumber[U interface{ ~uint32 | ~uint64 }](mem Memory, addr uint32, lengt
return
}

jam.DeserializeTrivialNatural(b, &u)
err = jam.Unmarshal(b, &u)
return
}

Expand Down
Loading
Loading