From a968f040503e86274f7ac9c522110ce66e99b110 Mon Sep 17 00:00:00 2001 From: Philip Stanislaus <6912756+philipstanislaus@users.noreply.github.com> Date: Thu, 28 May 2020 12:25:53 +0200 Subject: [PATCH] Change error handling to not panic when querying block info from runtime --- runtime/interface.go | 4 ++-- runtime/runtime.go | 23 +++++++++++++++++------ runtime/runtime_test.go | 7 ++++--- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/runtime/interface.go b/runtime/interface.go index 1e39f558f1..dc1304afe9 100644 --- a/runtime/interface.go +++ b/runtime/interface.go @@ -65,7 +65,7 @@ type Interface interface { // GetCurrentBlockHeight returns the current block height. GetCurrentBlockHeight() uint64 // GetBlockAtHeight returns the block at the given height. - GetBlockAtHeight(height uint64) (hash BlockHash, timestamp int64, exists bool) + GetBlockAtHeight(height uint64) (hash BlockHash, timestamp int64, exists bool, err error) } type Metrics interface { @@ -142,6 +142,6 @@ func (i *EmptyRuntimeInterface) GetCurrentBlockHeight() uint64 { return 0 } -func (i *EmptyRuntimeInterface) GetBlockAtHeight(_ uint64) (hash BlockHash, timestamp int64, exists bool) { +func (i *EmptyRuntimeInterface) GetBlockAtHeight(_ uint64) (hash BlockHash, timestamp int64, exists bool, err error) { return } diff --git a/runtime/runtime.go b/runtime/runtime.go index b599acbab1..dd1981ce6e 100644 --- a/runtime/runtime.go +++ b/runtime/runtime.go @@ -1206,28 +1206,36 @@ func (r *interpreterRuntime) getCurrentBlockHeight(runtimeInterface Interface) ( return } -func (r *interpreterRuntime) getBlockAtHeight(height uint64, runtimeInterface Interface) *BlockValue { +func (r *interpreterRuntime) getBlockAtHeight(height uint64, runtimeInterface Interface) (*BlockValue, error) { var hash BlockHash var timestamp int64 var exists bool + var err error wrapPanic(func() { - hash, timestamp, exists = runtimeInterface.GetBlockAtHeight(height) + hash, timestamp, exists, err = runtimeInterface.GetBlockAtHeight(height) }) + if err != nil { + return nil, err + } + if !exists { - return nil + return nil, nil } block := NewBlockValue(height, hash, time.Unix(0, timestamp)) - return &block + return &block, nil } func (r *interpreterRuntime) newGetCurrentBlockFunction(runtimeInterface Interface) interpreter.HostFunction { return func(invocation interpreter.Invocation) trampoline.Trampoline { height := r.getCurrentBlockHeight(runtimeInterface) - block := r.getBlockAtHeight(height, runtimeInterface) + block, err := r.getBlockAtHeight(height, runtimeInterface) + if err != nil { + panic(err) + } return trampoline.Done{Result: *block} } } @@ -1235,7 +1243,10 @@ func (r *interpreterRuntime) newGetCurrentBlockFunction(runtimeInterface Interfa func (r *interpreterRuntime) newGetBlockFunction(runtimeInterface Interface) interpreter.HostFunction { return func(invocation interpreter.Invocation) trampoline.Trampoline { height := uint64(invocation.Arguments[0].(interpreter.UInt64Value)) - block := r.getBlockAtHeight(height, runtimeInterface) + block, err := r.getBlockAtHeight(height, runtimeInterface) + if err != nil { + panic(err) + } var result interpreter.Value if block == nil { result = interpreter.NilValue{} diff --git a/runtime/runtime_test.go b/runtime/runtime_test.go index bf49ce2c12..29727111fd 100644 --- a/runtime/runtime_test.go +++ b/runtime/runtime_test.go @@ -222,9 +222,10 @@ func (i *testRuntimeInterface) GetCurrentBlockHeight() uint64 { return 1 } -func (i *testRuntimeInterface) GetBlockAtHeight(height uint64) (hash BlockHash, timestamp int64, exists bool) { +func (i *testRuntimeInterface) GetBlockAtHeight(height uint64) (hash BlockHash, timestamp int64, exists bool, + err error) { buf := new(bytes.Buffer) - err := binary.Write(buf, binary.BigEndian, height) + err = binary.Write(buf, binary.BigEndian, height) if err != nil { panic(err) } @@ -232,7 +233,7 @@ func (i *testRuntimeInterface) GetBlockAtHeight(height uint64) (hash BlockHash, encoded := buf.Bytes() copy(hash[stdlib.BlockIDSize-len(encoded):], encoded) - return hash, time.Unix(int64(height), 0).UnixNano(), true + return hash, time.Unix(int64(height), 0).UnixNano(), true, nil } func TestRuntimeImport(t *testing.T) {