Skip to content

Commit 3f84c34

Browse files
authored
Merge pull request #4500 from onflow/supun/enable-rlp-tests
[Compiler] Run RLP tests with compiler/vm
2 parents 91ef416 + 0f2eb9f commit 3f84c34

2 files changed

Lines changed: 130 additions & 15 deletions

File tree

interpreter/computation_metering_test.go

Lines changed: 75 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3009,8 +3009,7 @@ func TestInterpretComputationMeteringRLP(t *testing.T) {
30093009

30103010
storage := NewUnmeteredInMemoryStorage()
30113011

3012-
// TODO: Also run with compiler
3013-
inter, err := parseCheckAndInterpretWithOptions(t, //nolint:staticcheck
3012+
inter, err := parseCheckAndPrepareWithOptions(t,
30143013
`
30153014
fun test() {
30163015
// "dog"
@@ -3046,8 +3045,24 @@ func TestInterpretComputationMeteringRLP(t *testing.T) {
30463045
_, err = inter.Invoke("test")
30473046
require.NoError(t, err)
30483047

3049-
AssertEqualWithDiff(t,
3050-
[]common.ComputationUsage{
3048+
var expectedUsages []common.ComputationUsage
3049+
if *compile {
3050+
// The compiler/VM meters the function invocation after the
3051+
// argument array has been constructed and transferred.
3052+
expectedUsages = []common.ComputationUsage{
3053+
{Kind: common.ComputationKindFunctionInvocation, Intensity: 1},
3054+
{Kind: common.ComputationKindStatement, Intensity: 1},
3055+
{Kind: common.ComputationKindCreateArrayValue, Intensity: 1},
3056+
{Kind: common.ComputationKindAtreeArrayBatchConstruction, Intensity: 4},
3057+
{Kind: common.ComputationKindTransferArrayValue, Intensity: 4},
3058+
{Kind: common.ComputationKindAtreeArraySingleSlabConstruction, Intensity: 4},
3059+
{Kind: common.ComputationKindFunctionInvocation, Intensity: 1},
3060+
{Kind: common.ComputationKindSTDLIBRLPDecodeString, Intensity: 4},
3061+
{Kind: common.ComputationKindCreateArrayValue, Intensity: 1},
3062+
{Kind: common.ComputationKindAtreeArraySingleSlabConstruction, Intensity: 3},
3063+
}
3064+
} else {
3065+
expectedUsages = []common.ComputationUsage{
30513066
{Kind: common.ComputationKindFunctionInvocation, Intensity: 1},
30523067
{Kind: common.ComputationKindStatement, Intensity: 1},
30533068
{Kind: common.ComputationKindFunctionInvocation, Intensity: 1},
@@ -3058,7 +3073,11 @@ func TestInterpretComputationMeteringRLP(t *testing.T) {
30583073
{Kind: common.ComputationKindSTDLIBRLPDecodeString, Intensity: 4},
30593074
{Kind: common.ComputationKindCreateArrayValue, Intensity: 1},
30603075
{Kind: common.ComputationKindAtreeArraySingleSlabConstruction, Intensity: 3},
3061-
},
3076+
}
3077+
}
3078+
3079+
AssertEqualWithDiff(t,
3080+
expectedUsages,
30623081
computationGauge.usages,
30633082
)
30643083
})
@@ -3076,8 +3095,7 @@ func TestInterpretComputationMeteringRLP(t *testing.T) {
30763095

30773096
storage := NewUnmeteredInMemoryStorage()
30783097

3079-
// TODO: Also run with compiler
3080-
inter, err := parseCheckAndInterpretWithOptions(t, //nolint:staticcheck
3098+
inter, err := parseCheckAndPrepareWithOptions(t,
30813099
`
30823100
fun test() {
30833101
// "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce porta malesuada imperdiet. Sed erat erat, aliquam sed volutpat sed, volutpat ac sapien. Pellentesque sit amet arcu ut magna vehicula finibus non eu felis. Etiam sed tellus congue, sodales ante eget, dictum eros. In at metus sapien fusce."
@@ -3113,8 +3131,25 @@ func TestInterpretComputationMeteringRLP(t *testing.T) {
31133131
_, err = inter.Invoke("test")
31143132
require.NoError(t, err)
31153133

3116-
AssertEqualWithDiff(t,
3117-
[]common.ComputationUsage{
3134+
var expectedUsages []common.ComputationUsage
3135+
if *compile {
3136+
// The compiler/VM meters the function invocation after the
3137+
// argument array has been constructed and transferred.
3138+
expectedUsages = []common.ComputationUsage{
3139+
{Kind: common.ComputationKindFunctionInvocation, Intensity: 1},
3140+
{Kind: common.ComputationKindStatement, Intensity: 1},
3141+
{Kind: common.ComputationKindCreateArrayValue, Intensity: 1},
3142+
{Kind: common.ComputationKindAtreeArrayBatchConstruction, Intensity: 303},
3143+
{Kind: common.ComputationKindTransferArrayValue, Intensity: 303},
3144+
{Kind: common.ComputationKindAtreeArrayBatchConstruction, Intensity: 303},
3145+
{Kind: common.ComputationKindAtreeArrayReadIteration, Intensity: 303},
3146+
{Kind: common.ComputationKindFunctionInvocation, Intensity: 1},
3147+
{Kind: common.ComputationKindSTDLIBRLPDecodeString, Intensity: 303},
3148+
{Kind: common.ComputationKindCreateArrayValue, Intensity: 1},
3149+
{Kind: common.ComputationKindAtreeArrayBatchConstruction, Intensity: 300},
3150+
}
3151+
} else {
3152+
expectedUsages = []common.ComputationUsage{
31183153
{Kind: common.ComputationKindFunctionInvocation, Intensity: 1},
31193154
{Kind: common.ComputationKindStatement, Intensity: 1},
31203155
{Kind: common.ComputationKindFunctionInvocation, Intensity: 1},
@@ -3126,7 +3161,11 @@ func TestInterpretComputationMeteringRLP(t *testing.T) {
31263161
{Kind: common.ComputationKindSTDLIBRLPDecodeString, Intensity: 303},
31273162
{Kind: common.ComputationKindCreateArrayValue, Intensity: 1},
31283163
{Kind: common.ComputationKindAtreeArrayBatchConstruction, Intensity: 300},
3129-
},
3164+
}
3165+
}
3166+
3167+
AssertEqualWithDiff(t,
3168+
expectedUsages,
31303169
computationGauge.usages,
31313170
)
31323171
})
@@ -3144,8 +3183,7 @@ func TestInterpretComputationMeteringRLP(t *testing.T) {
31443183

31453184
storage := NewUnmeteredInMemoryStorage()
31463185

3147-
// TODO: Also run with compiler
3148-
inter, err := parseCheckAndInterpretWithOptions(t, //nolint:staticcheck
3186+
inter, err := parseCheckAndPrepareWithOptions(t,
31493187
`
31503188
fun test() {
31513189
// [['a']]
@@ -3181,8 +3219,26 @@ func TestInterpretComputationMeteringRLP(t *testing.T) {
31813219
_, err = inter.Invoke("test")
31823220
require.NoError(t, err)
31833221

3184-
AssertEqualWithDiff(t,
3185-
[]common.ComputationUsage{
3222+
var expectedUsages []common.ComputationUsage
3223+
if *compile {
3224+
// The compiler/VM meters the function invocation after the
3225+
// argument array has been constructed and transferred.
3226+
expectedUsages = []common.ComputationUsage{
3227+
{Kind: common.ComputationKindFunctionInvocation, Intensity: 1},
3228+
{Kind: common.ComputationKindStatement, Intensity: 1},
3229+
{Kind: common.ComputationKindCreateArrayValue, Intensity: 1},
3230+
{Kind: common.ComputationKindAtreeArrayBatchConstruction, Intensity: 2},
3231+
{Kind: common.ComputationKindTransferArrayValue, Intensity: 2},
3232+
{Kind: common.ComputationKindAtreeArraySingleSlabConstruction, Intensity: 2},
3233+
{Kind: common.ComputationKindFunctionInvocation, Intensity: 1},
3234+
{Kind: common.ComputationKindSTDLIBRLPDecodeList, Intensity: 2},
3235+
{Kind: common.ComputationKindCreateArrayValue, Intensity: 1},
3236+
{Kind: common.ComputationKindAtreeArrayBatchConstruction, Intensity: 1},
3237+
{Kind: common.ComputationKindCreateArrayValue, Intensity: 1},
3238+
{Kind: common.ComputationKindAtreeArraySingleSlabConstruction, Intensity: 1},
3239+
}
3240+
} else {
3241+
expectedUsages = []common.ComputationUsage{
31863242
{Kind: common.ComputationKindFunctionInvocation, Intensity: 1},
31873243
{Kind: common.ComputationKindStatement, Intensity: 1},
31883244
{Kind: common.ComputationKindFunctionInvocation, Intensity: 1},
@@ -3195,7 +3251,11 @@ func TestInterpretComputationMeteringRLP(t *testing.T) {
31953251
{Kind: common.ComputationKindAtreeArrayBatchConstruction, Intensity: 1},
31963252
{Kind: common.ComputationKindCreateArrayValue, Intensity: 1},
31973253
{Kind: common.ComputationKindAtreeArraySingleSlabConstruction, Intensity: 1},
3198-
},
3254+
}
3255+
}
3256+
3257+
AssertEqualWithDiff(t,
3258+
expectedUsages,
31993259
computationGauge.usages,
32003260
)
32013261
})

test_utils/test_utils.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,26 @@ import (
3939
"github.com/onflow/cadence/test_utils/runtime_utils"
4040
. "github.com/onflow/cadence/test_utils/sema_utils"
4141

42+
"github.com/onflow/cadence/bbq/commons"
4243
"github.com/onflow/cadence/bbq/compiler"
4344
. "github.com/onflow/cadence/bbq/test_utils"
4445
"github.com/onflow/cadence/bbq/vm"
4546
compilerUtils "github.com/onflow/cadence/bbq/vm/test"
4647
)
4748

49+
// builtinContractMemberVMFunctions maps the type-qualifier of a built-in contract
50+
// (e.g. `RLP`) to its member functions (e.g. RLP.decodeString) that tests may use.
51+
// When such a contract value is present in the base activation, its member functions
52+
// are registered as type-qualified globals in both the VM and the compiler,
53+
// mirroring how the runtime environment registers them.
54+
// NOTE: Only contains RLP functions for now. Add as needed.
55+
var builtinContractMemberVMFunctions = map[string][]stdlib.VMFunction{
56+
commons.TypeQualifier(stdlib.RLPType): {
57+
stdlib.VMRLPDecodeStringFunction,
58+
stdlib.VMRLPDecodeListFunction,
59+
},
60+
}
61+
4862
type ParseCheckAndInterpretOptions struct {
4963
ParseAndCheckOptions *ParseAndCheckOptions
5064
InterpreterConfig *interpreter.Config
@@ -328,6 +342,15 @@ func ParseCheckAndPrepareWithOptions(
328342
}
329343
var nestedEntries []nestedVariableEntry
330344

345+
// Collect member functions of built-in contract values that are present
346+
// in the base activation (e.g. `RLP.decodeString`), so they can be
347+
// registered as type-qualified globals in both the VM and the compiler.
348+
type memberFunctionEntry struct {
349+
qualifiedName string
350+
value vm.Value
351+
}
352+
var memberFunctionEntries []memberFunctionEntry
353+
331354
for name, variable := range interpreterBaseActivationVariables { //nolint:maprange
332355
value := variable.GetValue(nil)
333356
if functionValue, ok := value.(*interpreter.HostFunctionValue); ok {
@@ -338,10 +361,24 @@ func ParseCheckAndPrepareWithOptions(
338361
})
339362
}
340363
}
364+
365+
for _, vmFunction := range builtinContractMemberVMFunctions[name] {
366+
functionValue := vmFunction.FunctionValue
367+
memberFunctionEntries = append(memberFunctionEntries, memberFunctionEntry{
368+
qualifiedName: commons.TypeQualifiedName(
369+
vmFunction.BaseType,
370+
functionValue.Name,
371+
),
372+
value: functionValue,
373+
})
374+
}
341375
}
342376
slices.SortFunc(nestedEntries, func(a, b nestedVariableEntry) int {
343377
return strings.Compare(a.qualifiedName, b.qualifiedName)
344378
})
379+
slices.SortFunc(memberFunctionEntries, func(a, b memberFunctionEntry) int {
380+
return strings.Compare(a.qualifiedName, b.qualifiedName)
381+
})
345382

346383
vmConfig.BuiltinGlobalsProvider = func(_ common.Location) *activations.Activation[vm.Variable] {
347384

@@ -420,6 +457,15 @@ func ParseCheckAndPrepareWithOptions(
420457
)
421458
}
422459

460+
// Register member functions of built-in contract values
461+
// as separate type-qualified globals (e.g. `RLP.decodeString`).
462+
for _, entry := range memberFunctionEntries {
463+
activation.Set(
464+
entry.qualifiedName,
465+
interpreter.NewVariableWithValue(nil, entry.value),
466+
)
467+
}
468+
423469
return activation
424470
}
425471

@@ -447,6 +493,15 @@ func ParseCheckAndPrepareWithOptions(
447493
)
448494
}
449495

496+
// Register member functions of built-in contract values
497+
// as separate type-qualified compiler globals (e.g. `RLP.decodeString`).
498+
for _, entry := range memberFunctionEntries {
499+
activation.Set(
500+
entry.qualifiedName,
501+
compiler.NewGlobalImport(entry.qualifiedName),
502+
)
503+
}
504+
450505
return activation
451506
},
452507
}

0 commit comments

Comments
 (0)