From d8178ab199ce325dbf0405480b0630f4e0cdf5f0 Mon Sep 17 00:00:00 2001 From: Omar Date: Mon, 15 Nov 2021 13:21:07 +0600 Subject: [PATCH] feature(lib/runtime): implement `ext_offchain_timestamp` and `ext_offchain_sleep_until` (#1806) * Issue#1508 First commit * Changed interface name + Added testcase * Removed leftover comments * Updated host api runtime + Added testcase * add support for polkadot runtime v0.9.10 * cleanup * Removed testcases temporarily * Updated base Go version to 1.17 to resolve time.UnixMilli issues * Updated go.mod * Removed unused context * Updated go-version to 1.17.x in github workflows * Updated go version in the Dockerfile * added .devcontainer in the gitignore * Linked related issue for the unimplemented unit test * Fixed CGO issues * Fixed lint issues * Fixed unit tests Co-authored-by: noot Co-authored-by: noot <36753753+noot@users.noreply.github.com> --- lib/runtime/constants.go | 7 ++++--- lib/runtime/wasmer/imports.go | 16 ++++++++++----- lib/runtime/wasmer/imports_test.go | 33 ++++++++++++++++++++++++++++-- 3 files changed, 46 insertions(+), 10 deletions(-) diff --git a/lib/runtime/constants.go b/lib/runtime/constants.go index 2a49c5b734..e1298a5ffc 100644 --- a/lib/runtime/constants.go +++ b/lib/runtime/constants.go @@ -32,9 +32,10 @@ const ( POLKADOT_RUNTIME_URL = "https://github.com/noot/polkadot/blob/noot/v0.8.25/polkadot_runtime.wasm?raw=true" // v0.9 test API wasm - HOST_API_TEST_RUNTIME = "hostapi_runtime" - HOST_API_TEST_RUNTIME_FP = "hostapi_runtime.compact.wasm" - HOST_API_TEST_RUNTIME_URL = "https://github.com/ChainSafe/polkadot-spec/blob/b94d8c58ad6ea8bf827b0cae1645a999719c2bc7/test/runtimes/hostapi/hostapi_runtime.compact.wasm?raw=true" + HOST_API_TEST_RUNTIME = "hostapi_runtime" + HOST_API_TEST_RUNTIME_FP = "hostapi_runtime.compact.wasm" + // HOST_API_TEST_RUNTIME_URL = "https://github.com/ChainSafe/polkadot-spec/blob/b94d8c58ad6ea8bf827b0cae1645a999719c2bc7/test/runtimes/hostapi/hostapi_runtime.compact.wasm?raw=true" + HOST_API_TEST_RUNTIME_URL = "https://github.com/ChainSafe/polkadot-spec/blob/omar/offchain/test/runtimes/hostapi/hostapi_runtime.compact.wasm?raw=true" // v0.8 substrate runtime with modified name and babe C=(1, 1) DEV_RUNTIME = "dev_runtime" diff --git a/lib/runtime/wasmer/imports.go b/lib/runtime/wasmer/imports.go index fb13cc9e66..b3f292d652 100644 --- a/lib/runtime/wasmer/imports.go +++ b/lib/runtime/wasmer/imports.go @@ -104,6 +104,7 @@ import ( "math/big" "math/rand" "reflect" + "time" "unsafe" "github.com/ChainSafe/gossamer/internal/log" @@ -1699,16 +1700,21 @@ func ext_offchain_submit_transaction_version_1(context unsafe.Pointer, data C.in } //export ext_offchain_timestamp_version_1 -func ext_offchain_timestamp_version_1(context unsafe.Pointer) C.int64_t { +func ext_offchain_timestamp_version_1(_ unsafe.Pointer) C.int64_t { logger.Trace("[ext_offchain_timestamp_version_1] executing...") - logger.Warn("[ext_offchain_timestamp_version_1] unimplemented") - return 0 + + now := time.Now().Unix() + return C.int64_t(now) } //export ext_offchain_sleep_until_version_1 func ext_offchain_sleep_until_version_1(_ unsafe.Pointer, deadline C.int64_t) { - logger.Trace("executing...") - logger.Warn("unimplemented") + logger.Trace("[ext_offchain_sleep_until_version_1] executing...") + + dur := time.Until(time.UnixMilli(int64(deadline))) + if dur > 0 { + time.Sleep(dur) + } } //export ext_offchain_http_request_start_version_1 diff --git a/lib/runtime/wasmer/imports_test.go b/lib/runtime/wasmer/imports_test.go index 7058f11dc3..6bb8fa89fe 100644 --- a/lib/runtime/wasmer/imports_test.go +++ b/lib/runtime/wasmer/imports_test.go @@ -10,6 +10,7 @@ import ( "os" "sort" "testing" + "time" "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/internal/log" @@ -47,6 +48,35 @@ func TestMain(m *testing.M) { os.Exit(code) } +func Test_ext_offchain_timestamp_version_1(t *testing.T) { + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + runtimeFunc, ok := inst.vm.Exports["rtm_ext_offchain_timestamp_version_1"] + require.True(t, ok) + + res, err := runtimeFunc(0, 0) + require.NoError(t, err) + + offset, length := runtime.Int64ToPointerAndSize(res.ToI64()) + data := inst.load(offset, length) + var timestamp int64 + err = scale.Unmarshal(data, ×tamp) + require.NoError(t, err) + + expected := time.Now().Unix() + require.GreaterOrEqual(t, expected, timestamp) +} + +func Test_ext_offchain_sleep_until_version_1(t *testing.T) { + inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) + + input := time.Now().UnixMilli() + enc, err := scale.Marshal(input) + require.NoError(t, err) + + _, err = inst.Exec("rtm_ext_offchain_sleep_until_version_1", enc) //auto conversion to i64 + require.NoError(t, err) +} + func Test_ext_hashing_blake2_128_version_1(t *testing.T) { t.Parallel() inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME) @@ -1454,8 +1484,7 @@ func Test_ext_default_child_storage_storage_kill_version_2_limit_none(t *testing encChildKey, err := scale.Marshal(testChildKey) require.NoError(t, err) - var val *[]byte // nolint - val = nil + var val *[]byte optLimit, err := scale.Marshal(val) require.NoError(t, err)