Skip to content
This repository has been archived by the owner on Mar 12, 2024. It is now read-only.

Commit

Permalink
feat(arbitration): resolve PR comments
Browse files Browse the repository at this point in the history
* Split `Client` into `Reader` and `Sender`
* Add variables to control behaviors in entrypoint
* Add `HonestStrategy` concrete type
* Move `pcall` into `Sender:_send_tx`
* `State` tracks all tournaments/commitments/matches
* Optimize `tournament` and `match` structure
* Optimize `player.idle` logic
* Add `commitmentJoined` event
  • Loading branch information
stephenctw committed Sep 13, 2023
1 parent 72fdb2a commit 3b84f8c
Show file tree
Hide file tree
Showing 10 changed files with 423 additions and 316 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
local Hash = require "cryptography.hash"
local MerkleTree = require "cryptography.merkle_tree"
local eth_ebi = require "utils.eth_ebi"

local function parse_topics(json)
Expand Down Expand Up @@ -107,59 +106,26 @@ local function sort_and_dedup(t)
return ret
end

local function quote_args(args, not_quote)
local quoted_args = {}
for _, v in ipairs(args) do
if type(v) == "table" and (getmetatable(v) == Hash or getmetatable(v) == MerkleTree) then
if not_quote then
table.insert(quoted_args, v:hex_string())
else
table.insert(quoted_args, '"' .. v:hex_string() .. '"')
end
elseif type(v) == "table" then
if v._tag == "tuple" then
local qa = quote_args(v, true)
local ca = table.concat(qa, ",")
local sb = "'(" .. ca .. ")'"
table.insert(quoted_args, sb)
else
local qa = quote_args(v, true)
local ca = table.concat(qa, ",")
local sb = "'[" .. ca .. "]'"
table.insert(quoted_args, sb)
end
elseif not_quote then
table.insert(quoted_args, tostring(v))
else
table.insert(quoted_args, '"' .. v .. '"')
end
end
local Reader = {}
Reader.__index = Reader

return quoted_args
end


local Client = {}
Client.__index = Client

function Client:new(account_index)
function Reader:new()
local blockchain_data = require "blockchain.constants"

local client = {
endpoint = blockchain_data.endpoint,
pk = blockchain_data.pks[account_index],
local reader = {
endpoint = blockchain_data.endpoint
}

setmetatable(client, self)
return client
setmetatable(reader, self)
return reader
end

local cast_logs_template = [==[
cast rpc -r "%s" eth_getLogs \
'[{"fromBlock": "earliest", "toBlock": "latest", "address": "%s", "topics": [%s]}]' -w 2>&1
]==]

function Client:_read_logs(tournament_address, sig, topics, data_sig)
function Reader:_read_logs(tournament_address, sig, topics, data_sig)
topics = topics or { false, false, false }
local encoded_sig = eth_ebi.encode_sig(sig)
table.insert(topics, 1, encoded_sig)
Expand Down Expand Up @@ -201,7 +167,7 @@ local cast_call_template = [==[
cast call --rpc-url "%s" "%s" "%s" %s 2>&1
]==]

function Client:_call(address, sig, args)
function Reader:_call(address, sig, args)
local quoted_args = {}
for _, v in ipairs(args) do
table.insert(quoted_args, '"' .. v .. '"')
Expand Down Expand Up @@ -236,14 +202,11 @@ function Client:_call(address, sig, args)
return ret
end

function Client:read_match_created(tournament_address, commitment_hash)
function Reader:read_match_created(tournament_address, commitment_hash)
local sig = "matchCreated(bytes32,bytes32,bytes32)"
local data_sig = "(bytes32)"

local logs1 = self:_read_logs(tournament_address, sig, { commitment_hash:hex_string(), false, false }, data_sig)
local logs2 = self:_read_logs(tournament_address, sig, { false, commitment_hash:hex_string(), false }, data_sig)

local logs = sort_and_dedup(join_tables(logs1, logs2))
local logs = self:_read_logs(tournament_address, sig, { false, false, false }, data_sig)

local ret = {}
for k, v in ipairs(logs) do
Expand All @@ -262,7 +225,26 @@ function Client:read_match_created(tournament_address, commitment_hash)
return ret
end

function Client:read_commitment(tournament_address, commitment_hash)
function Reader:read_commitment_joined(tournament_address)
local sig = "commitmentJoined(bytes32)"
local data_sig = "(bytes32)"

local logs = self:_read_logs(tournament_address, sig, { false, false, false }, data_sig)

local ret = {}
for k, v in ipairs(logs) do
local log = {}
log.tournament_address = tournament_address
log.meta = v.meta
log.root = Hash:from_digest_hex(v.decoded_data[1])

ret[k] = log
end

return ret
end

function Reader:read_commitment(tournament_address, commitment_hash)
local sig = "getCommitment(bytes32)((uint64,uint64),bytes32)"

local call_ret = self:_call(tournament_address, sig, { commitment_hash:hex_string() })
Expand All @@ -284,7 +266,7 @@ function Client:read_commitment(tournament_address, commitment_hash)
return ret
end

function Client:read_tournament_created(tournament_address, match_id_hash)
function Reader:read_tournament_created(tournament_address, match_id_hash)
local sig = "newInnerTournament(bytes32,address)"
local data_sig = "(address)"

Expand All @@ -302,7 +284,7 @@ function Client:read_tournament_created(tournament_address, match_id_hash)
return ret
end

function Client:match(address, match_id_hash)
function Reader:match(address, match_id_hash)
local sig = "getMatch(bytes32)(bytes32,bytes32,bytes32,uint256,uint64,uint64)"
local ret = self:_call(address, sig, { match_id_hash:hex_string() })
ret[1] = Hash:from_digest_hex(ret[1])
Expand All @@ -312,15 +294,15 @@ function Client:match(address, match_id_hash)
return ret
end

function Client:inner_tournament_winner(address)
function Reader:inner_tournament_winner(address)
local sig = "innerTournamentWinner()(bool,bytes32)"
local ret = self:_call(address, sig, {})
ret[2] = Hash:from_digest_hex(ret[2])

return ret
end

function Client:root_tournament_winner(address)
function Reader:root_tournament_winner(address)
local sig = "arbitrationResult()(bool,bytes32,bytes32)"
local ret = self:_call(address, sig, {})
ret[2] = Hash:from_digest_hex(ret[2])
Expand All @@ -329,108 +311,18 @@ function Client:root_tournament_winner(address)
return ret
end

function Client:maximum_delay(address)
function Reader:maximum_delay(address)
local sig = "maximumEnforceableDelay()(uint64)"
local ret = self:_call(address, sig, {})

return ret
end

local cast_send_template = [[
cast send --private-key "%s" --rpc-url "%s" "%s" "%s" %s 2>&1
]]

function Client:_send_tx(tournament_address, sig, args)
local quoted_args = quote_args(args)
local args_str = table.concat(quoted_args, " ")

local cmd = string.format(
cast_send_template,
self.pk,
self.endpoint,
tournament_address,
sig,
args_str
)

local handle = io.popen(cmd)
assert(handle)

local ret = handle:read "*a"
if ret:find "Error" then
handle:close()
error(string.format("Send transaction `%s` reverted:\n%s", sig, ret))
end
handle:close()
end

function Client:tx_join_tournament(tournament_address, final_state, proof, left_child, right_child)
local sig = [[joinTournament(bytes32,bytes32[],bytes32,bytes32)]]
self:_send_tx(tournament_address, sig, { final_state, proof, left_child, right_child })
end

function Client:tx_advance_match(
tournament_address, commitment_one, commitment_two, left, right, new_left, new_right
)
local sig = [[advanceMatch((bytes32,bytes32),bytes32,bytes32,bytes32,bytes32)]]
self:_send_tx(
tournament_address,
sig,
{ { commitment_one, commitment_two, _tag = "tuple" }, left, right, new_left, new_right }
)
end

function Client:tx_seal_inner_match(
tournament_address, commitment_one, commitment_two, left, right, initial_hash, proof
)
local sig =
[[sealInnerMatchAndCreateInnerTournament((bytes32,bytes32),bytes32,bytes32,bytes32,bytes32[])]]
self:_send_tx(
tournament_address,
sig,
{ { commitment_one, commitment_two, _tag = "tuple" }, left, right, initial_hash:hex_string(), proof }
)
end

function Client:tx_win_inner_match(tournament_address, child_tournament_address, left, right)
local sig =
[[winInnerMatch(address,bytes32,bytes32)]]
self:_send_tx(
tournament_address,
sig,
{ child_tournament_address, left, right }
)
end

function Client:tx_seal_leaf_match(
tournament_address, commitment_one, commitment_two, left, right, initial_hash, proof
)
local sig =
[[sealLeafMatch((bytes32,bytes32),bytes32,bytes32,bytes32,bytes32[])]]
self:_send_tx(
tournament_address,
sig,
{ { commitment_one, commitment_two, _tag = "tuple" }, left, right, initial_hash, proof }
)
end

function Client:tx_win_leaf_match(
tournament_address, commitment_one, commitment_two, left, right, proof
)
local sig =
[[winLeafMatch((bytes32,bytes32),bytes32,bytes32,bytes)]]
self:_send_tx(
tournament_address,
sig,
{ { commitment_one, commitment_two, _tag = "tuple" }, left, right, proof }
)
end

local cast_advance_template = [[
cast rpc -r "%s" evm_increaseTime %d
]]

function Client:advance_time(seconds)
function Reader:advance_time(seconds)
local cmd = string.format(
cast_advance_template,
self.endpoint,
Expand All @@ -447,4 +339,4 @@ function Client:advance_time(seconds)
end
end

return Client
return Reader

0 comments on commit 3b84f8c

Please sign in to comment.