Skip to content

Commit

Permalink
Merge branch 'main' into feat/state-serialization-0.5.0
Browse files Browse the repository at this point in the history
  • Loading branch information
carlos-romano committed Nov 27, 2024
1 parent d0e50c2 commit ad9109e
Show file tree
Hide file tree
Showing 13 changed files with 116 additions and 157 deletions.
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

0 comments on commit ad9109e

Please sign in to comment.