diff options
author | Meng-Ying Yang <garfield@dexon.org> | 2019-04-15 12:16:19 +0800 |
---|---|---|
committer | Jhih-Ming Huang <jm.huang@cobinhood.com> | 2019-05-06 10:44:05 +0800 |
commit | 439168f1a1e3a05c489cdf97d91684c6f498abb4 (patch) | |
tree | a0767f2f9dbf21d806f11a6d66af9b779f182001 | |
parent | ad3ceebebe61718e4eb88ee77eef86d9844fc241 (diff) | |
download | dexon-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.go | 11 | ||||
-rw-r--r-- | core/vm/sqlvm/runtime/functions_test.go | 50 |
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) + } + } +} |