Skip to content

Commit

Permalink
Merge pull request #12 from spacemeshos/call-integration
Browse files Browse the repository at this point in the history
  • Loading branch information
YaronWittenstein authored Oct 13, 2021
2 parents cb95652 + 44b9b91 commit 710604c
Showing 13 changed files with 190 additions and 78 deletions.
7 changes: 6 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -23,13 +23,18 @@ jobs:
uses: actions/setup-go@v2
with:
stable: true
go-version: '1.15'
go-version: "1.15"
- name: Checkout sources
uses: actions/checkout@v2
- name: Download SVM artifacts
run: |
set -e
echo '${{ secrets.GITHUB_TOKEN }}' | gh auth login --with-token
./download_artifacts.sh
- name: Generate Binary Transactions
run: |
set -e
cd svm/inputs
./generate_txs.sh
- working-directory: svm
run: go test .
1 change: 1 addition & 0 deletions svm/api.go
Original file line number Diff line number Diff line change
@@ -86,6 +86,7 @@ func RuntimesCount() int {
}

func ReceiptsCount() int {
// TODO
return 0
// count := C.uint32(0)
// result := C.svm_receipts_count(&count)
195 changes: 144 additions & 51 deletions svm/api_test.go
Original file line number Diff line number Diff line change
@@ -13,31 +13,76 @@ func readFile(t *testing.T, path string) []byte {
return bytes
}

func deploy(t *testing.T, path string) (*Runtime, *DeployReceipt, error) {
func runtimeSetup(t *testing.T) *Runtime {
Init(true, "")

rt, err := NewRuntime()
assert.Nil(t, err);
assert.NotNil(t, rt)
assert.Nil(t, err)

msg := readFile(t, path)
gas := 1000000000
env := NewEnvelope(Address{}, Amount(10), TxNonce{Upper: 0, Lower: 0}, Gas(gas), GasFee(0))
ctx := NewContext(Layer(0), TxId{})
return rt
}

receipt, err := rt.Deploy(env, msg, ctx)
return rt, receipt, err
type TestParams struct {
Amount Amount
Principal Address
Nonce TxNonce
TxId TxId
Gas Gas
GasFee GasFee
Layer Layer
}

func NewTestParams() *TestParams {
// # Note
// We inject by default a super high Gas to avoid running Out-of-Gas
return &TestParams{
Amount: Amount(0),
Principal: Address{},
Nonce: TxNonce{Upper: 0, Lower: 0},
TxId: TxId{},
Gas: Gas(1000000000),
GasFee: GasFee(0),
Layer: Layer(0),
}
}

func spawn(t *testing.T, rt *Runtime, path string) (*SpawnReceipt, error) {
func executeTx(t *testing.T, rt *Runtime, path string, params *TestParams, f func(*Runtime, *Envelope, []byte, *Context) (interface{}, error)) (interface{}, error) {
msg := readFile(t, path)
gas := 1000000000
env := NewEnvelope(Address{}, Amount(10), TxNonce{Upper: 0, Lower: 0}, Gas(gas), GasFee(0))
ctx := NewContext(Layer(0), TxId{})
env := NewEnvelope(params.Principal, params.Amount, params.Nonce, params.Gas, params.GasFee)
ctx := NewContext(params.Layer, params.TxId)

receipt, err := rt.Spawn(env, msg, ctx)
receipt, err := f(rt, env, msg, ctx)
return receipt, err
}

func deploy(t *testing.T, rt *Runtime, path string, params *TestParams) (*DeployReceipt, error) {
receipt, err :=
executeTx(t, rt, path, params, func(rt *Runtime, env *Envelope, msg []byte, ctx *Context) (interface{}, error) {
return rt.Deploy(env, msg, ctx)
})

return receipt.(*DeployReceipt), err
}

func spawn(t *testing.T, rt *Runtime, path string, params *TestParams) (*SpawnReceipt, error) {
receipt, err :=
executeTx(t, rt, path, params, func(rt *Runtime, env *Envelope, msg []byte, ctx *Context) (interface{}, error) {
return rt.Spawn(env, msg, ctx)
})

return receipt.(*SpawnReceipt), err
}

func call(t *testing.T, rt *Runtime, path string, params *TestParams) (*CallReceipt, error) {
receipt, err :=
executeTx(t, rt, path, params, func(rt *Runtime, env *Envelope, msg []byte, ctx *Context) (interface{}, error) {
return rt.Call(env, msg, ctx)
})

return receipt.(*CallReceipt), err
}

func TestInitMemoryNilErr(t *testing.T) {
assert.Equal(t, 0, RuntimesCount())
err := Init(true, "")
@@ -47,21 +92,15 @@ func TestInitMemoryNilErr(t *testing.T) {

func TestNewRuntime(t *testing.T) {
assert.Equal(t, 0, RuntimesCount())
Init(true, "")

rt, err := NewRuntime()
assert.NotNil(t, rt)
assert.Nil(t, err)
rt := runtimeSetup(t)

assert.Equal(t, 1, RuntimesCount())
rt.Destroy()
assert.Equal(t, 0, RuntimesCount())
}

func TestValidateEmptyDeploy(t *testing.T) {
Init(true, "")

rt, _ := NewRuntime()
rt := runtimeSetup(t)
defer rt.Destroy()

ok, err := rt.ValidateDeploy([]byte{})
@@ -70,9 +109,7 @@ func TestValidateEmptyDeploy(t *testing.T) {
}

func TestValidateDeployInvalid(t *testing.T) {
Init(true, "")

rt, _ := NewRuntime()
rt := runtimeSetup(t)
defer rt.Destroy()

msg := []byte{0, 0, 0, 0}
@@ -82,21 +119,17 @@ func TestValidateDeployInvalid(t *testing.T) {
}

func TestValidateDeployValid(t *testing.T) {
Init(true, "")

rt, _ := NewRuntime()
rt := runtimeSetup(t)
defer rt.Destroy()

msg := readFile(t, "inputs/deploy.svm")
msg := readFile(t, "inputs/template_example.svm")
valid, err := rt.ValidateDeploy(msg)
assert.True(t, valid)
assert.Nil(t, err)
}

func TestValidateEmptySpawn(t *testing.T) {
Init(true, "")

rt, _ := NewRuntime()
rt := runtimeSetup(t)
defer rt.Destroy()

ok, err := rt.ValidateSpawn([]byte{})
@@ -105,9 +138,7 @@ func TestValidateEmptySpawn(t *testing.T) {
}

func TestValidateEmptyCall(t *testing.T) {
Init(true, "")

rt, _ := NewRuntime()
rt := runtimeSetup(t)
defer rt.Destroy()

ok, err := rt.ValidateCall([]byte{})
@@ -116,12 +147,10 @@ func TestValidateEmptyCall(t *testing.T) {
}

func TestDeployOutOfGas(t *testing.T) {
Init(true, "")

rt, _ := NewRuntime()
rt := runtimeSetup(t)
defer rt.Destroy()

msg := readFile(t, "inputs/deploy.svm")
msg := readFile(t, "inputs/template_example.svm")
env := NewEnvelope(Address{}, Amount(10), TxNonce{Upper: 0, Lower: 0}, Gas(10), GasFee(0))
ctx := NewContext(Layer(0), TxId{})

@@ -133,15 +162,16 @@ func TestDeployOutOfGas(t *testing.T) {
}

func TestDeploySuccess(t *testing.T) {
rt, receipt, err := deploy(t, "inputs/deploy.svm")
rt := runtimeSetup(t)
receipt, err := deploy(t, rt, "inputs/template_example.svm", NewTestParams())
defer rt.Destroy()

assert.Nil(t, err)
assert.Equal(t, true, receipt.Success)
}

func TestSpawnValidateInvalid(t *testing.T) {
rt, _, _ := deploy(t, "inputs/deploy.svm")
rt := runtimeSetup(t)
defer rt.Destroy()

msg := []byte{0, 0, 0, 0}
@@ -150,36 +180,99 @@ func TestSpawnValidateInvalid(t *testing.T) {
}

func TestSpawnValidateValid(t *testing.T) {
rt, _, _ := deploy(t, "inputs/deploy.svm")
rt := runtimeSetup(t)
defer rt.Destroy()

msg := readFile(t, "inputs/spawn/spawn-1.json.bin")
msg := readFile(t, "inputs/spawn/initialize.json.bin")
isValid, _ := rt.ValidateSpawn(msg)
assert.True(t, isValid)
}

func TestSpawnOutOfGas(t *testing.T) {
rt, _, _ := deploy(t, "inputs/deploy.svm")
rt := runtimeSetup(t)
defer rt.Destroy()

msg := readFile(t, "inputs/spawn/spawn-1.json.bin")
env := NewEnvelope(Address{}, Amount(10), TxNonce{Upper: 0, Lower: 0}, Gas(10), GasFee(0))
ctx := NewContext(Layer(0), TxId{})
deploy(t, rt, "inputs/template_example.svm", NewTestParams())

receipt, err := rt.Spawn(env, msg, ctx)
assert.Nil(t, err)
params := NewTestParams()
params.Gas = Gas(10)
receipt, err := spawn(t, rt, "inputs/spawn/initialize.json.bin", params)

assert.Nil(t, err)
assert.Equal(t, false, receipt.Success)
assert.Equal(t, receipt.Error.Kind, RuntimeErrorKind(OOG))
}

func TestSpawnSuccess(t *testing.T) {
rt, _, _ := deploy(t, "inputs/deploy.svm")
rt := runtimeSetup(t)
defer rt.Destroy()

receipt, err := spawn(t, rt, "inputs/spawn/spawn-1.json.bin")
deploy(t, rt, "inputs/template_example.svm", NewTestParams())
receipt, err := spawn(t, rt, "inputs/spawn/initialize.json.bin", NewTestParams())

assert.Nil(t, err)
assert.Equal(t, true, receipt.Success)
assert.NotNil(t, receipt.InitState)
assert.NotNil(t, receipt.AccountAddr)
}
}

func TestCallValidateInvalid(t *testing.T) {
rt := runtimeSetup(t)
defer rt.Destroy()

msg := []byte{0, 0, 0, 0}
isValid, _ := rt.ValidateCall(msg)
assert.False(t, isValid)
}

func TestCallValidateValid(t *testing.T) {
rt := runtimeSetup(t)
defer rt.Destroy()

msg := readFile(t, "inputs/call/load_addr.json.bin")
isValid, _ := rt.ValidateCall(msg)
assert.True(t, isValid)
}

// TODO: fix the gas pricing first under SVM
// func TestCallOutOfGas(t *testing.T) {
// rt := runtimeSetup(t)
// defer rt.Destroy()

// deploy(t, rt, "inputs/template_example.svm")
// spawn(t, rt, "inputs/spawn/initialize.json.bin")

// msg := readFile(t, "inputs/call/store_addr.json.bin")
// env := NewEnvelope(Address{}, Amount(10), TxNonce{Upper: 0, Lower: 0}, Gas(10), GasFee(0))
// ctx := NewContext(Layer(0), TxId{})

// receipt, err := rt.Call(env, msg, ctx)
// assert.Nil(t, err)

// assert.Equal(t, false, receipt.Success)
// assert.Equal(t, receipt.Error.Kind, RuntimeErrorKind(OOG))
// }

func TestCallSuccess(t *testing.T) {
rt := runtimeSetup(t)
defer rt.Destroy()

deploy(t, rt, "inputs/template_example.svm", NewTestParams())
spawn(t, rt, "inputs/spawn/initialize.json.bin", NewTestParams())
receipt, err := call(t, rt, "inputs/call/store_addr.json.bin", NewTestParams())
assert.Nil(t, err)
assert.Equal(t, true, receipt.Success)

receipt, err = call(t, rt, "inputs/call/load_addr.json.bin", NewTestParams())
assert.Nil(t, err)
assert.Equal(t, true, receipt.Success)

returns := receipt.ReturnData
assert.Equal(t, len(returns), 1+AddressLength)

// type is `Address`
assert.Equal(t, returns[0], byte(0x40))

// expected loaded Address to be `102030405060708090102030405060708090AABB`
assert.Equal(t, returns[1:], []byte{16, 32, 48, 64, 80, 96, 112, 128, 144, 16, 32, 48, 64, 80, 96, 112, 128, 144, 170, 187})
}
2 changes: 1 addition & 1 deletion svm/codec.go
Original file line number Diff line number Diff line change
@@ -75,7 +75,7 @@ func decodeAddress(bytes []byte) ([AddressLength]byte, []byte) {
return addr, bytes[AddressLength:]
}

func decodeState(bytes []byte) ([StateLength]byte, []byte) {
func decodeState(bytes []byte) (State, []byte) {
var state [StateLength]byte
copy(state[:], bytes[:StateLength])

13 changes: 0 additions & 13 deletions svm/inputs/call/call-1.json

This file was deleted.

13 changes: 13 additions & 0 deletions svm/inputs/call/load_addr.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"version": 0,
"target": "066818abe361dd44f425da19e17c45babc40e232",
"func_name": "load_addr",
"verifydata": {
"abi": [],
"data": []
},
"calldata": {
"abi": [],
"data": []
}
}
13 changes: 13 additions & 0 deletions svm/inputs/call/store_addr.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"version": 0,
"target": "066818abe361dd44f425da19e17c45babc40e232",
"func_name": "store_addr",
"verifydata": {
"abi": [],
"data": []
},
"calldata": {
"abi": ["address"],
"data": ["102030405060708090102030405060708090AABB"]
}
}
Binary file removed svm/inputs/deploy.svm
Binary file not shown.
10 changes: 10 additions & 0 deletions svm/inputs/spawn/initialize.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"version": 0,
"template": "b5eba98957e6a93173ffb50207cceeedfddb1a72",
"name": "My Account",
"ctor_name": "initialize",
"calldata": {
"abi": ["address", "bool"],
"data": ["8f20ed1a0e342c2a75b1b3f8014545dd3d886078", true]
}
}
Loading

0 comments on commit 710604c

Please sign in to comment.