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

fix: 🐛 improve chain id import in ethereum transaction #625

Merged
merged 3 commits into from
Mar 31, 2023
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
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ indent_size = 4
indent_style = space
indent_size = 4

[test/**.bats]
indent_style = space
indent_size = 4

[src/lua/crypto_ethereum.lua]
indent_style = space
indent_size = 3
Expand Down
46 changes: 24 additions & 22 deletions src/lua/crypto_ethereum.lua
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,30 @@ function ETH.address_from_public_key(pk)
return H:process(pk:sub(2, #pk)):sub(13, 32)
end

function encode(t, arg)
local function encode_uint(val)
return BIG.new(val):fixed(32)
end

-- The following types are called “dynamic”:
-- bytes
-- string
-- T[] for any T
-- T[k] for any dynamic T and any k >= 0
-- (T1,...,Tk) if Ti is dynamic for some 1 <= i <= k
local function is_dynamic(t)
local dyn = t == 'string' or t == 'bytes' or string.match(t, '[a-zA-Z0-9]+%[%]')
if not dyn then
t = string.match(t, '([a-zA-Z]+)%[%d+%]')
if t then
dyn = is_dynamic(t)
end
end
return dyn
end

local encode_tuple

local function encode(t, arg)
local res
if type(t) == "string" then
if string.match(t, 'uint%d+$') or t == 'address' then
Expand Down Expand Up @@ -391,27 +414,6 @@ function encode(t, arg)
return res
end

function encode_uint(val)
return BIG.new(val):fixed(32)
end

-- The following types are called “dynamic”:
-- bytes
-- string
-- T[] for any T
-- T[k] for any dynamic T and any k >= 0
-- (T1,...,Tk) if Ti is dynamic for some 1 <= i <= k
function is_dynamic(t)
local dyn = t == 'string' or t == 'bytes' or string.match(t, '[a-zA-Z0-9]+%[%]')
if not dyn then
t = string.match(t, '([a-zA-Z]+)%[%d+%]')
if t then
dyn = is_dynamic(t)
end
end
return dyn
end

function encode_tuple(params, args)
local res = O.empty()

Expand Down
1 change: 1 addition & 0 deletions src/lua/zencode.lua
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ function mayhave(obj)
local name = uscore(trim(obj))
res = ACK[name]
if not res then
I.warn(name .. " not found in DATA or KEYS")
return nil
end
local codec = ZEN.CODEC[name]
Expand Down
13 changes: 9 additions & 4 deletions src/lua/zencode_ethereum.lua
Original file line number Diff line number Diff line change
Expand Up @@ -209,14 +209,19 @@ When("create the signed ethereum transaction for chain ''",
function(chainid)
local sk = havekey'ethereum'
local tx = have'ethereum transaction'
local cid = mayhave(chainid)
local cid, cid_codec = mayhave(chainid)
if cid then
cid = tonumber(cid) or cid:octet()
local enc = cid_codec.encoding
if enc == "string" then
cid = tonumber(cid:str()) or cid:octet()
elseif enc ~= "integer" then
error("Invalid chain id encoding: "..cid_codec.encoding)
end
else
cid = tonumber(chainid) or O.from_string(chainid)
cid = tonumber(chainid) or O.from_string(chainid)
end
cid = INT.new(cid)
ZEN.assert(cid, "Invalid chain id: "..chainid)
ZEN.assert(cid, "Invalid chain id")
if not tx.data then tx.data = O.new() end
if not tx.value then tx.value = O.new() end
tx.v = cid
Expand Down
60 changes: 60 additions & 0 deletions test/zencode/ethereum.bats
Original file line number Diff line number Diff line change
Expand Up @@ -474,3 +474,63 @@ Then print the 'data retrieved' as 'string'
EOF
save_output 'doc_retrieved_data.json'
}

@test "Import transaction" {
cat <<EOF | save_asset 'import_tx.data'
{
"keyring": {
"bitcoin": "L44aGie6PCJY6drzVFszi9HPc7g98LQmcsJwDEGumBnMReX45xGK",
"ecdh": "0L/FuN1ZaIG/imjoDBGgAvCpHMLL/WB2lX+DEQOSC4o=",
"eddsa": "Cwj9CcqHNoBnXBo8iDfnhFkQeDun4Y4LStd2m3TEAYAg",
"ethereum": "9ab36c2688502bd219eeea9e6021a056fb7f734f86ea727feec8ed96431bf6ad",
"reflow": "OUaM/6vq37bVO8xRU7a/yh7mZZygU8aD+zWo5gRE6DA=",
"schnorr": "ZQR+vMkjuRpcoqQ9bAcDowI3noEcjFVUmLLxyP1gPDg="
},
"ethereum_transaction": {
"gas_limit": "50000",
"gas_price": "2000000000",
"nonce": "241",
"to": "4806db98240cd10f9575737f6d0fc17afb50e936",
"value": "500000"
},
"bigcid": "80",
"strcid": "fabt",
"numcid": "80"
}
EOF

cat <<EOF | zexe import_tx.zen import_tx.data
scenario ethereum

given I have the 'keyring'
and I have a 'ethereum transaction'

given I have a 'string' named 'strcid'
given I have a 'string' named 'numcid'
given I have a 'integer' named 'bigcid'

When I create the signed ethereum transaction for chain 'fabt'
When I copy the 'v' in 'ethereum_transaction' to 'v0'
When I remove 'signed ethereum transaction'
When I create the signed ethereum transaction for chain 'strcid'
When I copy the 'v' in 'ethereum_transaction' to 'v1'
When I remove 'signed ethereum transaction'
When I create the signed ethereum transaction for chain '80'
When I copy the 'v' in 'ethereum_transaction' to 'v2'
When I remove 'signed ethereum transaction'
When I create the signed ethereum transaction for chain 'numcid'
When I copy the 'v' in 'ethereum_transaction' to 'v3'
When I remove 'signed ethereum transaction'
When I create the signed ethereum transaction for chain 'bigcid'
When I copy the 'v' in 'ethereum_transaction' to 'v4'
When I remove 'signed ethereum transaction'

then print the 'v0' as 'hex'
then print the 'v1' as 'hex'
then print the 'v2' as 'hex'
then print the 'v3' as 'hex'
then print the 'v4' as 'hex'
EOF
save_output 'import_tx.json'
assert_output '{"v0":"3435316491","v1":"3435316492","v2":"195","v3":"196","v4":"196"}'
}