aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMeng-Ying Yang <garfield@dexon.org>2019-04-15 12:09:23 +0800
committerJhih-Ming Huang <jm.huang@cobinhood.com>2019-05-06 10:44:05 +0800
commit1613ba12dd8279511acd1997c2d85f82663ac38b (patch)
treeb31a2a7cdd64f7646f05f9718b3eed7ad8268746
parentba915a703cda5172b37d20d93cc46c8d4c1ddc34 (diff)
downloaddexon-1613ba12dd8279511acd1997c2d85f82663ac38b.tar.gz
dexon-1613ba12dd8279511acd1997c2d85f82663ac38b.tar.zst
dexon-1613ba12dd8279511acd1997c2d85f82663ac38b.zip
core: vm: sqlvm: add built-in function BLOCK_GASLIMIT()
-rw-r--r--core/vm/sqlvm/runtime/functions.go21
-rw-r--r--core/vm/sqlvm/runtime/functions_test.go47
2 files changed, 68 insertions, 0 deletions
diff --git a/core/vm/sqlvm/runtime/functions.go b/core/vm/sqlvm/runtime/functions.go
index c21d1da19..c180f1714 100644
--- a/core/vm/sqlvm/runtime/functions.go
+++ b/core/vm/sqlvm/runtime/functions.go
@@ -1,6 +1,9 @@
package runtime
import (
+ "fmt"
+ "math"
+
"github.com/dexon-foundation/decimal"
"github.com/dexon-foundation/dexon/core/vm/sqlvm/ast"
@@ -15,6 +18,7 @@ const (
BLOCKNUMBER = "BLOCK_NUMBER"
BLOCKTIMESTAMP = "BLOCK_TIMESTAMP"
BLOCKCOINBASE = "BLOCK_COINBASE"
+ BLOCKGASLIMIT = "BLOCK_GAS_LIMIT"
NOW = "NOW"
)
@@ -27,6 +31,7 @@ var (
BLOCKTIMESTAMP: fnBlockTimestamp,
NOW: fnBlockTimestamp,
BLOCKCOINBASE: fnBlockCoinBase,
+ BLOCKGASLIMIT: fnBlockGasLimit,
}
)
@@ -110,3 +115,19 @@ func fnBlockCoinBase(ctx *common.Context, ops []*Operand, length uint64) (result
return
}
+func fnBlockGasLimit(ctx *common.Context, ops []*Operand, length uint64) (result *Operand, err error) {
+ r := &Raw{}
+ if ctx.GasLimit > uint64(math.MaxInt64) {
+ r.Value, err = decimal.NewFromString(fmt.Sprint(ctx.GasLimit))
+ if err != nil {
+ return
+ }
+ } else {
+ r.Value = decimal.New(int64(ctx.GasLimit), 0)
+ }
+ result = assignFuncResult(
+ []ast.DataType{ast.ComposeDataType(ast.DataTypeMajorUint, 7)},
+ r.clone, length,
+ )
+ return
+}
diff --git a/core/vm/sqlvm/runtime/functions_test.go b/core/vm/sqlvm/runtime/functions_test.go
index cda24fcdf..638d8e2ec 100644
--- a/core/vm/sqlvm/runtime/functions_test.go
+++ b/core/vm/sqlvm/runtime/functions_test.go
@@ -1,6 +1,7 @@
package runtime
import (
+ "math"
"math/big"
"testing"
@@ -11,6 +12,7 @@ import (
"github.com/dexon-foundation/dexon/core/vm"
"github.com/dexon-foundation/dexon/core/vm/sqlvm/ast"
"github.com/dexon-foundation/dexon/core/vm/sqlvm/common"
+ dec "github.com/dexon-foundation/dexon/core/vm/sqlvm/common/decimal"
)
func TestFunction(t *testing.T) {
@@ -258,3 +260,48 @@ func (s *FunctionSuite) TestFnCoinBase() {
}
}
+func (s *FunctionSuite) TestFnGasLimit() {
+ type blockGasLimitCase struct {
+ Name string
+ Limit uint64
+ Length uint64
+ Res decimal.Decimal
+ Err error
+ }
+ testcases := []blockGasLimitCase{
+ {"max int64 with length 1", uint64(math.MaxInt64), 1, dec.MaxInt64, nil},
+ {"max uint64 with length 1", math.MaxUint64, 10, dec.MaxUint64, nil},
+ {"address with length 0", math.MaxUint64, 0, decimal.Zero, nil},
+ }
+
+ callFn := func(c blockGasLimitCase) (*Operand, error) {
+ return fnBlockGasLimit(
+ &common.Context{
+ Context: vm.Context{GasLimit: c.Limit},
+ },
+ nil,
+ c.Length)
+ }
+
+ meta := []ast.DataType{ast.ComposeDataType(ast.DataTypeMajorUint, 7)}
+
+ for idx, tCase := range testcases {
+ r, err := callFn(tCase)
+ s.Require().Equal(
+ tCase.Err, err,
+ "Index: %v. Error not expected: %v != %v", idx, tCase.Err, err)
+ s.Require().Equal(
+ meta, r.Meta,
+ "Index: %v. Meta not equal: %v != %v", idx, meta, r.Meta)
+ s.Require().Equal(
+ uint64(len(r.Data)), tCase.Length,
+ "Index: %v. Length not equal: %v != %v", idx, len(r.Data), tCase.Length)
+
+ for i := 0; i < len(r.Data); i++ {
+ s.Require().True(
+ tCase.Res.Equal(r.Data[i][0].Value),
+ "Index: %v. Data Index: %v. Value not equal: %v != %v",
+ idx, i, tCase.Res, r.Data[i][0].Value)
+ }
+ }
+}