Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bignum support for hex and binary formats #198

Merged
merged 15 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions contract/bignum_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,15 @@ const char *lua_set_bignum(lua_State *L, char *s) {
if (x == NULL) {
return mp_num_memory_error;
}
if (vm_is_hardfork(L, 3)) {
if (vm_is_hardfork(L, 4)) {
// remove support for octal format and
// keep support for hex (0x) and binary (0b) formats
if (s && s[0]=='0' && s[1]!=0 && s[1]!='x' && s[1]!='b') {
// convert "0123" -> "123"
while (s && s[0]=='0' && s[1]!=0) s++;
hayarobi marked this conversation as resolved.
Show resolved Hide resolved
}
} else if (vm_is_hardfork(L, 3)) {
// previous code remove support for octal, hex and binary formats
while (s && s[0]=='0' && s[1]!=0) s++;
}
if (mpz_init_set_str(x->mpptr, s, 0) != 0) {
Expand Down Expand Up @@ -119,7 +127,15 @@ static mp_num Bget(lua_State *L, int i) {
if (x == NULL) {
luaL_error(L, mp_num_memory_error);
}
if (vm_is_hardfork(L, 3)) {
if (vm_is_hardfork(L, 4)) {
// remove support for octal format and
// keep support for hex (0x) and binary (0b) formats
if (s && s[0]=='0' && s[1]!=0 && s[1]!='x' && s[1]!='b') {
// convert "0123" -> "123"
while (s && s[0]=='0' && s[1]!=0) s++;
}
} else if (vm_is_hardfork(L, 3)) {
// previous code remove support for octal, hex and binary formats
while (s && s[0]=='0' && s[1]!=0) s++;
}
if (mpz_init_set_str(x->mpptr, s, 0) != 0) {
Expand Down
7 changes: 7 additions & 0 deletions contract/vm_dummy/test_files/bignum_values.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

function parse_bignum(value)
local val = bignum.number(value)
return bignum.tostring(val)
end

abi.register(parse_bignum)
126 changes: 126 additions & 0 deletions contract/vm_dummy/vm_dummy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2389,6 +2389,132 @@ func TestTypeBignum(t *testing.T) {
}
}

func TestBignumValues(t *testing.T) {
code := readLuaCode(t, "bignum_values.lua")

bc, err := LoadDummyChain(SetHardForkVersion(2))
require.NoErrorf(t, err, "failed to create dummy chain")
defer bc.Release()

err = bc.ConnectBlock(
NewLuaTxAccount("user1", 1, types.Aergo),
NewLuaTxDeploy("user1", "contract1", 0, code),
)
require.NoErrorf(t, err, "failed to deploy")

// hardfork 2

// process octal, hex, binary

err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":["0"]}`, "", `"0"`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":["9"]}`, "", `"9"`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":["0055"]}`, "", `"45"`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":["01234567"]}`, "", `"342391"`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":["0x123456789abcdef"]}`, "", `"81985529216486895"`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":["0b1010101010101"]}`, "", `"5461"`)
require.NoErrorf(t, err, "failed to query")

err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":[{"_bignum":"0"}]}`, "", `"0"`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":[{"_bignum":"9"}]}`, "", `"9"`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":[{"_bignum":"01234567"}]}`, "", `"342391"`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":[{"_bignum":"0x123456789abcdef"}]}`, "", `"81985529216486895"`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":[{"_bignum":"0b1010101010101"}]}`, "", `"5461"`)
require.NoErrorf(t, err, "failed to query")


// hardfork 3
bc.HardforkVersion = 3

// block octal, hex and binary

tx := NewLuaTxCall("user1", "contract1", 0, `{"Name":"parse_bignum", "Args":["01234567"]}`)
err = bc.ConnectBlock(tx)
require.NoErrorf(t, err, "failed to call tx")
receipt := bc.GetReceipt(tx.Hash())
assert.Equalf(t, `"1234567"`, receipt.GetRet(), "contract Call ret error")

err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":["0"]}`, "", `"0"`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":["9"]}`, "", `"9"`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":["0055"]}`, "", `"55"`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":["01234567"]}`, "", `"1234567"`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":["0x123456789abcdef"]}`, "bignum invalid number string", `""`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":["0b1010101010101"]}`, "bignum invalid number string", `""`)
require.NoErrorf(t, err, "failed to query")

err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":[{"_bignum":"0"}]}`, "", `"0"`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":[{"_bignum":"9"}]}`, "", `"9"`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":[{"_bignum":"01234567"}]}`, "", `"1234567"`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":[{"_bignum":"0x123456789abcdef"}]}`, "bignum invalid number string", `""`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":[{"_bignum":"0b1010101010101"}]}`, "bignum invalid number string", `""`)
require.NoErrorf(t, err, "failed to query")


// hardfork 4 and after

for version := int32(4); version <= max_version; version++ {
bc, err = LoadDummyChain(SetHardForkVersion(version))
require.NoErrorf(t, err, "failed to create dummy chain")
defer bc.Release()

err = bc.ConnectBlock(
NewLuaTxAccount("user1", 1, types.Aergo),
NewLuaTxDeploy("user1", "contract1", 0, code),
)
require.NoErrorf(t, err, "failed to deploy")

// process hex, binary. block octal

tx = NewLuaTxCall("user1", "contract1", 0, `{"Name":"parse_bignum", "Args":["01234567"]}`)
err = bc.ConnectBlock(tx)
require.NoErrorf(t, err, "failed to call tx")
receipt = bc.GetReceipt(tx.Hash())
assert.Equalf(t, `"1234567"`, receipt.GetRet(), "contract Call ret error")

err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":["0"]}`, "", `"0"`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":["9"]}`, "", `"9"`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":["0055"]}`, "", `"55"`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":["01234567"]}`, "", `"1234567"`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":["0x123456789abcdef"]}`, "", `"81985529216486895"`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":["0b1010101010101"]}`, "", `"5461"`)
require.NoErrorf(t, err, "failed to query")

err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":[{"_bignum":"0"}]}`, "", `"0"`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":[{"_bignum":"9"}]}`, "", `"9"`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":[{"_bignum":"01234567"}]}`, "", `"1234567"`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":[{"_bignum":"0x123456789abcdef"}]}`, "", `"81985529216486895"`)
require.NoErrorf(t, err, "failed to query")
err = bc.Query("contract1", `{"Name":"parse_bignum", "Args":[{"_bignum":"0b1010101010101"}]}`, "", `"5461"`)
require.NoErrorf(t, err, "failed to query")

}
}

func checkRandomIntValue(v string, min, max int) error {
n, _ := strconv.Atoi(v)
if n < min || n > max {
Expand Down
Loading