aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMeng-Ying Yang <garfield@dexon.org>2019-04-15 12:16:19 +0800
committerJhih-Ming Huang <jm.huang@cobinhood.com>2019-05-06 10:44:05 +0800
commit439168f1a1e3a05c489cdf97d91684c6f498abb4 (patch)
treea0767f2f9dbf21d806f11a6d66af9b779f182001
parentad3ceebebe61718e4eb88ee77eef86d9844fc241 (diff)
downloaddexon-439168f1a1e3a05c489cdf97d91684c6f498abb4.tar.gz
dexon-439168f1a1e3a05c489cdf97d91684c6f498abb4.tar.zst
dexon-439168f1a1e3a05c489cdf97d91684c6f498abb4.zip
core: vm: sqlvm: add built-in function MSG_DATA()
-rw-r--r--core/vm/sqlvm/runtime/functions.go11
-rw-r--r--core/vm/sqlvm/runtime/functions_test.go50
2 files changed, 61 insertions, 0 deletions
diff --git a/core/vm/sqlvm/runtime/functions.go b/core/vm/sqlvm/runtime/functions.go
index fad6e475a..6708ad542 100644
--- a/core/vm/sqlvm/runtime/functions.go
+++ b/core/vm/sqlvm/runtime/functions.go
@@ -20,6 +20,7 @@ const (
BLOCKCOINBASE = "BLOCK_COINBASE"
BLOCKGASLIMIT = "BLOCK_GAS_LIMIT"
MSGSENDER = "MSG_SENDER"
+ MSGDATA = "MSG_DATA"
NOW = "NOW"
)
@@ -34,6 +35,7 @@ var (
BLOCKCOINBASE: fnBlockCoinBase,
BLOCKGASLIMIT: fnBlockGasLimit,
MSGSENDER: fnMsgSender,
+ MSGDATA: fnMsgData,
}
)
@@ -143,3 +145,12 @@ func fnMsgSender(ctx *common.Context, ops []*Operand, length uint64) (result *Op
return
}
+func fnMsgData(ctx *common.Context, ops []*Operand, length uint64) (result *Operand, err error) {
+ r := &Raw{Bytes: ctx.Contract.Input}
+ result = assignFuncResult(
+ []ast.DataType{ast.ComposeDataType(ast.DataTypeMajorDynamicBytes, 0)},
+ r.clone, length,
+ )
+ return
+}
+
diff --git a/core/vm/sqlvm/runtime/functions_test.go b/core/vm/sqlvm/runtime/functions_test.go
index cb122e28d..bd9d460b5 100644
--- a/core/vm/sqlvm/runtime/functions_test.go
+++ b/core/vm/sqlvm/runtime/functions_test.go
@@ -359,3 +359,53 @@ func (s *FunctionSuite) TestFnMsgSender() {
}
}
+func (s *FunctionSuite) TestFnMsgData() {
+ type txMsgDataCase struct {
+ Name string
+ Length uint64
+ Res []byte
+ Err error
+ }
+
+ res := []byte{
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}
+
+ testcases := []txMsgDataCase{
+ {"address with length 1", 1, res, nil},
+ {"address with length 10", 10, res, nil},
+ {"address with length 0", 0, res, nil},
+ }
+
+ callFn := func(c txMsgDataCase) (*Operand, error) {
+ return fnMsgData(
+ &common.Context{
+ Contract: &vm.Contract{Input: c.Res},
+ },
+ nil,
+ c.Length)
+ }
+
+ meta := []ast.DataType{ast.ComposeDataType(ast.DataTypeMajorDynamicBytes, 0)}
+
+ 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().Equal(
+ tCase.Res, r.Data[i][0].Bytes,
+ "Index: %v. Data Index: %v. Value not equal: %v != %v",
+ idx, i, tCase.Res, r.Data[i][0].Value)
+ }
+ }
+}