Skip to content

Commit

Permalink
Merge pull request #2770 from onflow/sainati/merge-master-stable-cadence
Browse files Browse the repository at this point in the history
Merge `master` into Stable Cadence
  • Loading branch information
dsainati1 authored Sep 8, 2023
2 parents 2de499c + 9345cac commit 97ef057
Show file tree
Hide file tree
Showing 11 changed files with 322 additions and 21 deletions.
12 changes: 6 additions & 6 deletions runtime/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,24 @@ type Context struct {
CoverageReport *CoverageReport
}

// codesAndPrograms collects the source code and AST for each location.
// CodesAndPrograms collects the source code and AST for each location.
// It is purely used for debugging: Both the codes and the programs
// are provided in runtime errors.
type codesAndPrograms struct {
type CodesAndPrograms struct {
codes map[Location][]byte
programs map[Location]*ast.Program
}

func (c codesAndPrograms) setCode(location Location, code []byte) {
func (c CodesAndPrograms) setCode(location Location, code []byte) {
c.codes[location] = code
}

func (c codesAndPrograms) setProgram(location Location, program *ast.Program) {
func (c CodesAndPrograms) setProgram(location Location, program *ast.Program) {
c.programs[location] = program
}

func newCodesAndPrograms() codesAndPrograms {
return codesAndPrograms{
func NewCodesAndPrograms() CodesAndPrograms {
return CodesAndPrograms{
codes: map[Location][]byte{},
programs: map[Location]*ast.Program{},
}
Expand Down
4 changes: 2 additions & 2 deletions runtime/contract_function_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ type interpreterContractFunctionExecutor struct {
result cadence.Value
executeErr error
preprocessErr error
codesAndPrograms codesAndPrograms
codesAndPrograms CodesAndPrograms
runtime *interpreterRuntime
storage *Storage
contractLocation common.AddressLocation
Expand Down Expand Up @@ -90,7 +90,7 @@ func (executor *interpreterContractFunctionExecutor) preprocess() (err error) {
context := executor.context
location := context.Location

codesAndPrograms := newCodesAndPrograms()
codesAndPrograms := NewCodesAndPrograms()
executor.codesAndPrograms = codesAndPrograms

interpreterRuntime := executor.runtime
Expand Down
6 changes: 3 additions & 3 deletions runtime/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ type Environment interface {
Declare(valueDeclaration stdlib.StandardLibraryValue)
Configure(
runtimeInterface Interface,
codesAndPrograms codesAndPrograms,
codesAndPrograms CodesAndPrograms,
storage *Storage,
coverageReport *CoverageReport,
)
Expand Down Expand Up @@ -72,7 +72,7 @@ type interpreterEnvironmentReconfigured struct {
runtimeInterface Interface
storage *Storage
coverageReport *CoverageReport
codesAndPrograms codesAndPrograms
codesAndPrograms CodesAndPrograms
}

type interpreterEnvironment struct {
Expand Down Expand Up @@ -180,7 +180,7 @@ func NewScriptInterpreterEnvironment(config Config) Environment {

func (e *interpreterEnvironment) Configure(
runtimeInterface Interface,
codesAndPrograms codesAndPrograms,
codesAndPrograms CodesAndPrograms,
storage *Storage,
coverageReport *CoverageReport,
) {
Expand Down
2 changes: 1 addition & 1 deletion runtime/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type Error struct {
Programs map[Location]*ast.Program
}

func newError(err error, location Location, codesAndPrograms codesAndPrograms) Error {
func newError(err error, location Location, codesAndPrograms CodesAndPrograms) Error {
return Error{
Err: err,
Location: location,
Expand Down
10 changes: 5 additions & 5 deletions runtime/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ func (r *interpreterRuntime) Config() Config {
return r.defaultConfig
}

func (r *interpreterRuntime) Recover(onError func(Error), location Location, codesAndPrograms codesAndPrograms) {
func (r *interpreterRuntime) Recover(onError func(Error), location Location, codesAndPrograms CodesAndPrograms) {
recovered := recover()
if recovered == nil {
return
Expand All @@ -231,7 +231,7 @@ func (r *interpreterRuntime) Recover(onError func(Error), location Location, cod
onError(err)
}

func getWrappedError(recovered any, location Location, codesAndPrograms codesAndPrograms) Error {
func getWrappedError(recovered any, location Location, codesAndPrograms CodesAndPrograms) Error {
switch recovered := recovered.(type) {

// If the error is already a `runtime.Error`, then avoid redundant wrapping.
Expand Down Expand Up @@ -510,7 +510,7 @@ func (r *interpreterRuntime) ParseAndCheckProgram(
) {
location := context.Location

codesAndPrograms := newCodesAndPrograms()
codesAndPrograms := NewCodesAndPrograms()

defer r.Recover(
func(internalErr Error) {
Expand Down Expand Up @@ -549,7 +549,7 @@ func (r *interpreterRuntime) Storage(context Context) (*Storage, *interpreter.In

location := context.Location

codesAndPrograms := newCodesAndPrograms()
codesAndPrograms := NewCodesAndPrograms()

storage := NewStorage(context.Interface, context.Interface)

Expand Down Expand Up @@ -587,7 +587,7 @@ func (r *interpreterRuntime) ReadStored(
) {
location := context.Location

var codesAndPrograms codesAndPrograms
var codesAndPrograms CodesAndPrograms

defer r.Recover(
func(internalErr Error) {
Expand Down
4 changes: 2 additions & 2 deletions runtime/script_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (
type interpreterScriptExecutorPreparation struct {
environment Environment
preprocessErr error
codesAndPrograms codesAndPrograms
codesAndPrograms CodesAndPrograms
functionEntryPointType *sema.FunctionType
program *interpreter.Program
storage *Storage
Expand Down Expand Up @@ -92,7 +92,7 @@ func (executor *interpreterScriptExecutor) preprocess() (err error) {
location := context.Location
script := executor.script

codesAndPrograms := newCodesAndPrograms()
codesAndPrograms := NewCodesAndPrograms()
executor.codesAndPrograms = codesAndPrograms

interpreterRuntime := executor.runtime
Expand Down
36 changes: 36 additions & 0 deletions runtime/stdlib/contracts/test.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,29 @@ contract Test {
fun moveTime(by delta: Fix64) {
self.backend.moveTime(by: delta)
}

/// Creates a snapshot of the blockchain, at the
/// current ledger state, with the given name.
///
access(all)
fun createSnapshot(name: String) {
let err = self.backend.createSnapshot(name: name)
if err != nil {
panic(err!.message)
}
}

/// Loads a snapshot of the blockchain, with the
/// given name, and updates the current ledger
/// state.
///
access(all)
fun loadSnapshot(name: String) {
let err = self.backend.loadSnapshot(name: name)
if err != nil {
panic(err!.message)
}
}
}

access(all)
Expand Down Expand Up @@ -394,6 +417,19 @@ contract Test {
///
access(all)
fun moveTime(by delta: Fix64)

/// Creates a snapshot of the blockchain, at the
/// current ledger state, with the given name.
///
access(all)
fun createSnapshot(name: String): Error?

/// Loads a snapshot of the blockchain, with the
/// given name, and updates the current ledger
/// state.
///
access(all)
fun loadSnapshot(name: String): Error?
}

/// Returns a new matcher that negates the test of the given matcher.
Expand Down
4 changes: 4 additions & 0 deletions runtime/stdlib/test-framework.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ type Blockchain interface {
Reset(uint64)

MoveTime(int64)

CreateSnapshot(string) error

LoadSnapshot(string) error
}

type ScriptResult struct {
Expand Down
86 changes: 86 additions & 0 deletions runtime/stdlib/test_emulatorbackend.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ type testEmulatorBackendType struct {
eventsFunctionType *sema.FunctionType
resetFunctionType *sema.FunctionType
moveTimeFunctionType *sema.FunctionType
createSnapshotFunctionType *sema.FunctionType
loadSnapshotFunctionType *sema.FunctionType
}

func newTestEmulatorBackendType(
Expand Down Expand Up @@ -112,6 +114,16 @@ func newTestEmulatorBackendType(
testEmulatorBackendTypeMoveTimeFunctionName,
)

createSnapshotFunctionType := interfaceFunctionType(
blockchainBackendInterfaceType,
testEmulatorBackendTypeCreateSnapshotFunctionName,
)

loadSnapshotFunctionType := interfaceFunctionType(
blockchainBackendInterfaceType,
testEmulatorBackendTypeLoadSnapshotFunctionName,
)

compositeType := &sema.CompositeType{
Identifier: testEmulatorBackendTypeName,
Kind: common.CompositeKindStructure,
Expand Down Expand Up @@ -194,6 +206,18 @@ func newTestEmulatorBackendType(
moveTimeFunctionType,
testEmulatorBackendTypeMoveTimeFunctionDocString,
),
sema.NewUnmeteredPublicFunctionMember(
compositeType,
testEmulatorBackendTypeCreateSnapshotFunctionName,
createSnapshotFunctionType,
testEmulatorBackendTypeCreateSnapshotFunctionDocString,
),
sema.NewUnmeteredPublicFunctionMember(
compositeType,
testEmulatorBackendTypeLoadSnapshotFunctionName,
loadSnapshotFunctionType,
testEmulatorBackendTypeLoadSnapshotFunctionDocString,
),
}

compositeType.Members = sema.MembersAsMap(members)
Expand All @@ -213,6 +237,8 @@ func newTestEmulatorBackendType(
eventsFunctionType: eventsFunctionType,
resetFunctionType: resetFunctionType,
moveTimeFunctionType: moveTimeFunctionType,
createSnapshotFunctionType: createSnapshotFunctionType,
loadSnapshotFunctionType: loadSnapshotFunctionType,
}
}

Expand Down Expand Up @@ -739,6 +765,58 @@ func (t *testEmulatorBackendType) newMoveTimeFunction(
)
}

// 'Emulator.createSnapshot' function

const testEmulatorBackendTypeCreateSnapshotFunctionName = "createSnapshot"

const testEmulatorBackendTypeCreateSnapshotFunctionDocString = `
Creates a snapshot of the blockchain, at the
current ledger state, with the given name.
`

func (t *testEmulatorBackendType) newCreateSnapshotFunction(
blockchain Blockchain,
) *interpreter.HostFunctionValue {
return interpreter.NewUnmeteredHostFunctionValue(
t.createSnapshotFunctionType,
func(invocation interpreter.Invocation) interpreter.Value {
name, ok := invocation.Arguments[0].(*interpreter.StringValue)
if !ok {
panic(errors.NewUnreachableError())
}

err := blockchain.CreateSnapshot(name.Str)
return newErrorValue(invocation.Interpreter, err)
},
)
}

// 'Emulator.loadSnapshot' function

const testEmulatorBackendTypeLoadSnapshotFunctionName = "loadSnapshot"

const testEmulatorBackendTypeLoadSnapshotFunctionDocString = `
Loads a snapshot of the blockchain, with the given name, and
updates the current ledger state.
`

func (t *testEmulatorBackendType) newLoadSnapshotFunction(
blockchain Blockchain,
) *interpreter.HostFunctionValue {
return interpreter.NewUnmeteredHostFunctionValue(
t.loadSnapshotFunctionType,
func(invocation interpreter.Invocation) interpreter.Value {
name, ok := invocation.Arguments[0].(*interpreter.StringValue)
if !ok {
panic(errors.NewUnreachableError())
}

err := blockchain.LoadSnapshot(name.Str)
return newErrorValue(invocation.Interpreter, err)
},
)
}

func (t *testEmulatorBackendType) newEmulatorBackend(
inter *interpreter.Interpreter,
blockchain Blockchain,
Expand Down Expand Up @@ -792,6 +870,14 @@ func (t *testEmulatorBackendType) newEmulatorBackend(
Name: testEmulatorBackendTypeMoveTimeFunctionName,
Value: t.newMoveTimeFunction(blockchain),
},
{
Name: testEmulatorBackendTypeCreateSnapshotFunctionName,
Value: t.newCreateSnapshotFunction(blockchain),
},
{
Name: testEmulatorBackendTypeLoadSnapshotFunctionName,
Value: t.newLoadSnapshotFunction(blockchain),
},
}

// TODO: Use SimpleCompositeValue
Expand Down
Loading

0 comments on commit 97ef057

Please sign in to comment.