Skip to content

Commit

Permalink
Merge branch 'main' into feat/codec-buff-decoder-bitsequence
Browse files Browse the repository at this point in the history
  • Loading branch information
danielvladco committed Feb 4, 2025
2 parents 01ab09c + e035c67 commit 44bca51
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 155 deletions.
4 changes: 2 additions & 2 deletions internal/polkavm/host_call/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const (
ForgetCost
YieldCost
HistoricalLookupCost
ImportCost
FetchCost
ExportCost
MachineCost
PeekCost
Expand Down Expand Up @@ -56,7 +56,7 @@ const (
ForgetID
YieldID
HistoricalLookupID
ImportID
FetchID
ExportID
MachineID
PeekID
Expand Down
33 changes: 9 additions & 24 deletions internal/polkavm/host_call/refine_functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,40 +76,25 @@ func HistoricalLookup(
return gas, regs, mem, ctxPair, nil
}

// Import ΩY(ϱ, ω, µ, (m, e), i)
func Import(
// Fetch ΩY(ϱ, ω, µ, (m, e), i, p, o, i)
func Fetch(
gas Gas,
regs Registers,
mem Memory,
ctxPair RefineContextPair,
itemIndex uint32,
workPackage work.Package,
authorizerHashOutput []byte,
importedSegments []work.Segment,
) (Gas, Registers, Memory, RefineContextPair, error) {
if gas < ImportCost {
if gas < FetchCost {
return gas, regs, mem, ctxPair, ErrOutOfGas
}
gas -= ImportCost
gas -= FetchCost

index := regs[A0] // ω7
offset := regs[A1] // ω8
length := regs[A2] // ω9
//TODO implement

// v = ∅
if index >= uint64(len(importedSegments)) {
// v = ∅, return NONE
return gas, withCode(regs, NONE), mem, ctxPair, nil
}

// v = i[ω7]
v := importedSegments[index][:]

l := min(length, common.SizeOfSegment)

segmentToWrite := v[:l]
if err := mem.Write(uint32(offset), segmentToWrite); err != nil {
return gas, withCode(regs, OOB), mem, ctxPair, nil
}

return gas, withCode(regs, OK), mem, ctxPair, nil
return gas, regs, mem, ctxPair, nil
}

// Export ΩE(ϱ, ω, µ, (m, e), ς)
Expand Down
62 changes: 0 additions & 62 deletions internal/polkavm/host_call/refine_functions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,68 +112,6 @@ func TestHistoricalLookup(t *testing.T) {
assert.Equal(t, expectedGasRemaining, gasRemaining)
}

func TestImport(t *testing.T) {
pp := &polkavm.Program{
ProgramMemorySizes: polkavm.ProgramMemorySizes{
RWDataSize: 256,
StackSize: 512,
InitialHeapPages: 10,
},
CodeAndJumpTable: polkavm.CodeAndJumpTable{
Instructions: []polkavm.Instruction{
{Opcode: polkavm.Ecalli, Imm: []uint32{0}, Offset: 0, Length: 1},
{Opcode: polkavm.JumpIndirect, Imm: []uint32{0}, Reg: []polkavm.Reg{polkavm.RA}, Offset: 1, Length: 2},
},
},
}

mem, initialRegs, err := polkavm.InitializeStandardProgram(pp, nil)
require.NoError(t, err)

segmentData := [common.SizeOfSegment]byte{}
for i := range segmentData {
segmentData[i] = byte('A')
}
importedSegments := []work.Segment{segmentData}

bo := polkavm.RWAddressBase + 100
bz := uint32(50)

initialRegs[polkavm.A0] = uint64(0)
initialRegs[polkavm.A1] = uint64(bo)
initialRegs[polkavm.A2] = uint64(bz)

hostCall := func(hostCall uint32, gasCounter polkavm.Gas, regs polkavm.Registers, mem polkavm.Memory, x service.ServiceAccount) (polkavm.Gas, polkavm.Registers, polkavm.Memory, service.ServiceAccount, error) {
gasCounterOut, regsOut, memOut, _, err := host_call.Import(
gasCounter,
regs,
mem,
polkavm.RefineContextPair{},
importedSegments,
)
require.NoError(t, err)
return gasCounterOut, regsOut, memOut, x, err
}

gasRemaining, regsOut, memOut, _, err := interpreter.InvokeHostCall(pp, 0, initialGas, initialRegs, mem, hostCall, service.ServiceAccount{})
require.ErrorIs(t, err, polkavm.ErrHalt)

actualValue := make([]byte, bz)
err = memOut.Read(bo, actualValue)
require.NoError(t, err)

expectedData := make([]byte, bz)
for i := range expectedData {
expectedData[i] = 'A'
}

assert.Equal(t, expectedData, actualValue)
assert.Equal(t, uint64(host_call.OK), regsOut[polkavm.A0])

expectedGasRemaining := polkavm.Gas(initialGas) - host_call.ImportCost - polkavm.GasCosts[polkavm.Ecalli] - polkavm.GasCosts[polkavm.JumpIndirect]
assert.Equal(t, expectedGasRemaining, gasRemaining)
}

func TestExport(t *testing.T) {
pp := &polkavm.Program{
ProgramMemorySizes: polkavm.ProgramMemorySizes{
Expand Down
67 changes: 35 additions & 32 deletions internal/refine/refine.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,45 +22,48 @@ var (
ErrBig = errors.New("code beyond the maximum size allowed") // BIG
)

type RefineImpl struct {
type Refine struct {
state state.State
}

// InvokePVM ΨR(H, NG, NS , H, Y, X, H, Y, ⟦G⟧, ⟦Y⟧, N) → (Y ∪ J, ⟦Y⟧)
func (r *RefineImpl) InvokePVM(
serviceCodePredictionHash crypto.Hash, gas uint64, serviceIndex block.ServiceId,
workPackageHash crypto.Hash, workPayload []byte, refinementContext block.RefinementContext,
authorizerHash crypto.Hash, authorizerHashOutput []byte, importedSegments []work.Segment,
extrinsicDataBlobs [][]byte, exportOffset uint64,
// InvokePVM ΨR(N,P,Y, ⟦⟦G⟧⟧, N) → (Y ∪ J, ⟦Y⟧)
func (r *Refine) InvokePVM(
itemIndex uint32, // i
workPackage work.Package, // p
authorizerHashOutput []byte, // o
importedSegments []work.Segment, // i
exportOffset uint64, // ς
) ([]byte, []work.Segment, error) {
// let a = E(s, y, p, c, a, ↕o, ↕[↕x | x <− x])
args, err := jam.Marshal(struct {
ServiceIndex block.ServiceId
WorkPayload []byte
WorkPackageHash crypto.Hash
RefinementContext block.RefinementContext
AuthorizerHash crypto.Hash
AuthorizerHashOutput []byte
ExtrinsicDataBlobs [][]byte
}{
ServiceIndex: serviceIndex,
WorkPayload: workPayload,
WorkPackageHash: workPackageHash,
RefinementContext: refinementContext,
AuthorizerHash: authorizerHash,
AuthorizerHashOutput: authorizerHashOutput,
ExtrinsicDataBlobs: extrinsicDataBlobs, // we assume the extrinsic data is a ordered sequence
})
// w = p_w[i]
w := workPackage.WorkItems[itemIndex]

packageBytes, err := jam.Marshal(workPackage)
if err != nil {
return nil, nil, err
}

// let a = E(ws, wy, H(p), px, pa)
args, err := jam.Marshal(struct {
ServiceIndex block.ServiceId
WorkPayload []byte
WorkPackageHash crypto.Hash
RefinementContext block.RefinementContext
AuthorizerHash crypto.Hash
}{
ServiceIndex: w.ServiceId,
WorkPayload: w.Payload,
WorkPackageHash: crypto.HashData(packageBytes),
RefinementContext: workPackage.Context,
AuthorizerHash: workPackage.AuthCodeHash,
})

// if s ∉ K(δ) ∨ Λ(δ[s], ct, c) = ∅ then (BAD, [])
service, ok := r.state.Services[serviceIndex]
service, ok := r.state.Services[w.ServiceId]
if !ok {
return nil, nil, ErrBad
}
code := service.LookupPreimage(refinementContext.LookupAnchor.Timeslot, serviceCodePredictionHash)

code := service.LookupPreimage(workPackage.Context.LookupAnchor.Timeslot, w.CodeHash)
if code == nil {
return nil, nil, ErrBad
}
Expand All @@ -74,9 +77,9 @@ func (r *RefineImpl) InvokePVM(
hostCall := func(hostCall uint32, gasCounter polkavm.Gas, regs polkavm.Registers, mem polkavm.Memory, ctxPair polkavm.RefineContextPair) (polkavm.Gas, polkavm.Registers, polkavm.Memory, polkavm.RefineContextPair, error) {
switch hostCall {
case host_call.HistoricalLookupID:
gasCounter, regs, mem, ctxPair, err = host_call.HistoricalLookup(gasCounter, regs, mem, ctxPair, serviceIndex, r.state.Services, refinementContext.LookupAnchor.Timeslot)
case host_call.ImportID:
gasCounter, regs, mem, ctxPair, err = host_call.Import(gasCounter, regs, mem, ctxPair, importedSegments)
gasCounter, regs, mem, ctxPair, err = host_call.HistoricalLookup(gasCounter, regs, mem, ctxPair, w.ServiceId, r.state.Services, workPackage.Context.LookupAnchor.Timeslot)
case host_call.FetchID:
gasCounter, regs, mem, ctxPair, err = host_call.Fetch(gasCounter, regs, mem, ctxPair, itemIndex, workPackage, authorizerHashOutput, importedSegments)
case host_call.ExportID:
gasCounter, regs, mem, ctxPair, err = host_call.Export(gasCounter, regs, mem, ctxPair, exportOffset)
case host_call.GasID:
Expand All @@ -103,8 +106,8 @@ func (r *RefineImpl) InvokePVM(
return gasCounter, regs, mem, ctxPair, nil
}

// (g, r, (m, e)) = ΨM(Λ(δ[s], ct, c), 0, g, a, F, (∅, []))∶
_, result, ctxPair, err := interpreter.InvokeWholeProgram(code, 0, gas, args, hostCall, polkavm.RefineContextPair{
// (g, r, (m, e)) = ΨM(Λ(δ[w_s], (p_x)t, w_c), 0, w_g, a, F, (∅, []))∶
_, result, ctxPair, err := interpreter.InvokeWholeProgram(code, 0, w.GasLimitRefine, args, hostCall, polkavm.RefineContextPair{
IntegratedPVMMap: make(map[uint64]polkavm.IntegratedPVM),
Segments: []work.Segment{},
})
Expand Down
4 changes: 2 additions & 2 deletions internal/work/item.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type Extrinsic struct {

// Item represents I (14.2 v0.5.4)
type Item struct {
ServiceId uint32 // s ∈ N_S
ServiceId block.ServiceId // s ∈ N_S
CodeHash crypto.Hash // c ∈ H
Payload []byte // y ∈ Y
GasLimitRefine uint64 // g ∈ N_G
Expand Down Expand Up @@ -51,7 +51,7 @@ func (w *Item) ToWorkResult(o block.WorkResultOutputOrError) block.WorkResult {
}

return block.WorkResult{
ServiceId: block.ServiceId(w.ServiceId),
ServiceId: w.ServiceId,
ServiceHashCode: w.CodeHash,
PayloadHash: payloadHash,
GasPrioritizationRatio: gasPrioritizationRatio,
Expand Down
29 changes: 6 additions & 23 deletions internal/work/results/compute.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,10 @@ type AuthPVMInvoker interface {

type RefinePVMInvoker interface {
InvokePVM(
serviceCodePredictionHash crypto.Hash,
gas uint64,
serviceIndex block.ServiceId,
workPackageHash crypto.Hash,
workPayload []byte,
refinementContext block.RefinementContext,
authorizerHash crypto.Hash,
itemIndex uint32,
workPackage work.Package,
authorizerHashOutput []byte,
importedSegments []work.Segment,
extrinsicData [][]byte,
exportOffset uint64,
) ([]byte, []work.Segment, error)
}
Expand Down Expand Up @@ -288,29 +282,18 @@ func (c *Computation) EvaluateWorkPackage(
var allExportedSegments []work.Segment
exportOffset := uint64(0)

for _, item := range wp.WorkItems {
for index, item := range wp.WorkItems {
importedSegs, _, err := c.buildImportedSegments(item)
if err != nil {
return nil, fmt.Errorf("importedSegments: %w", err)
}

extrinsicData, err := c.buildExtrinsicData(item)
if err != nil {
return nil, fmt.Errorf("extrinsicData: %w", err)
}

// ΨR(wc, wg, ws, h, wy, px, pa, o, S(w,l), X(w), l) (14.11 v0.5.4)
// ΨR(j, p, o, i, ℓ) (14.11 v0.6.0)
refineOut, exported, refineErr := c.Refine.InvokePVM(
item.CodeHash,
item.GasLimitRefine,
block.ServiceId(item.ServiceId),
crypto.HashData(wp.Parameterization),
item.Payload,
wp.Context,
wp.AuthCodeHash,
uint32(index),
wp,
authOutput,
importedSegs,
extrinsicData,
exportOffset,
)

Expand Down
11 changes: 2 additions & 9 deletions internal/work/results/compute_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/eigerco/strawberry/internal/block"
"github.com/eigerco/strawberry/internal/crypto"
"github.com/eigerco/strawberry/internal/work"
)
Expand Down Expand Up @@ -247,16 +246,10 @@ func (m mockAuthorizationInvoker) InvokePVM(workPackage work.Package, coreIndex
type mockRefineInvoker struct{}

func (m mockRefineInvoker) InvokePVM(
serviceCodePredictionHash crypto.Hash,
gas uint64,
serviceIndex block.ServiceId,
workPackageHash crypto.Hash,
workPayload []byte,
refinementContext block.RefinementContext,
authorizerHash crypto.Hash,
itemIndex uint32,
workPackage work.Package,
authorizerHashOutput []byte,
importedSegments []work.Segment,
extrinsicData [][]byte,
exportOffset uint64,
) ([]byte, []work.Segment, error) {
out := []byte("RefineOutput")
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/codec_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ func compareExtrinsicFields(t *testing.T, expected ExpectedExtrinsic, actual blo
}

func compareWorkItemFields(t *testing.T, expected ExpectedWorkItem, actual work.Item) {
require.Equal(t, expected.Service, actual.ServiceId)
require.Equal(t, expected.Service, uint32(actual.ServiceId))
require.Equal(t, expected.CodeHash, toHex(actual.CodeHash))
require.Equal(t, expected.Payload, toHex(actual.Payload))
require.Equal(t, expected.RefineGasLimit, actual.GasLimitRefine)
Expand Down

0 comments on commit 44bca51

Please sign in to comment.