Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
q9f authored Jun 23, 2024
2 parents dfc7ac3 + 502aa91 commit f85e47e
Show file tree
Hide file tree
Showing 12 changed files with 157 additions and 21 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
uses: github/codeql-action/analyze@v3
- uses: ruby/setup-ruby@v1
with:
ruby-version: '3.0'
ruby-version: '3.3'
bundler-cache: true
- name: "Run rufo code formatting checks"
run: |
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ jobs:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
ruby-version: '3.0'
ruby-version: '3.3'
bundler-cache: true
- name: Run Yard Doc
run: |
gem install yard
yard doc
- name: Deploy GH Pages
uses: JamesIves/github-pages-deploy-action@v4.5.0
uses: JamesIves/github-pages-deploy-action@v4.6.1
with:
branch: gh-pages
folder: doc/
10 changes: 7 additions & 3 deletions .github/workflows/spec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04, macos-12]
ruby: ['3.0', '3.1', '3.2']
os: [ubuntu-latest, macos-latest]
ruby: ['3.1', '3.2', '3.3']
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
Expand Down Expand Up @@ -49,5 +49,9 @@ jobs:
run: |
bundle exec rspec
env:
COVERAGE: true
INFURA_TOKEN: ${{ secrets.INFURA_TOKEN }}
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
fail_ci_if_error: false
token: ${{ secrets.CODECOV_TOKEN }}
19 changes: 19 additions & 0 deletions lib/eth/abi/decoder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,25 @@ def type(type, arg)
type(Type.parse(type.base_type), arg[pointer + 32, Util.ceil32(data_l) + 32])
end
end
elsif type.base_type == 'tuple'
offset = 0
data = {}
type.components.each do |c|
if c.dynamic?
pointer = Util.deserialize_big_endian_to_int arg[offset, 32] # Pointer to the size of the array's element
data_len = Util.deserialize_big_endian_to_int arg[pointer, 32] # length of the element

data[c.name] = type(c, arg[pointer, Util.ceil32(data_len) + 32])
# puts data
offset += 32
else
size = c.size
data[c.name] = type(c, arg[offset, size])
offset += size
# puts data
end
end
data
elsif type.dynamic?
l = Util.deserialize_big_endian_to_int arg[0, 32]
nested_sub = type.nested_sub
Expand Down
17 changes: 14 additions & 3 deletions lib/eth/abi/event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,20 @@ def decode_logs(interfaces, logs)
def decode_log(inputs, data, topics, anonymous = false)
topic_inputs, data_inputs = inputs.partition { |i| i["indexed"] }

topic_types = topic_inputs.map { |i| i["type"] }
data_types = data_inputs.map { |i| i["type"] }

topic_types = topic_inputs.map do |i|
if i['type'] == 'tuple'
Type.parse(i['type'], i['components'], i['name'])
else
i['type']
end
end
data_types = data_inputs.map do |i|
if i['type'] == 'tuple'
Type.parse(i['type'], i['components'], i['name'])
else
i['type']
end
end
# If event is anonymous, all topics are arguments. Otherwise, the first
# topic will be the event signature.
if anonymous == false
Expand Down
10 changes: 9 additions & 1 deletion lib/eth/abi/type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,15 @@ def initialize(base_type, sub_type, dimensions, components = nil, component_name
# @return [Eth::Abi::Type] a parsed Type object.
# @raise [ParseError] if it fails to parse the type.
def parse(type, components = nil, component_name = nil)
return type if type.is_a?(Type)
if type.is_a?(Type)
@base_type = type.base_type
@sub_type = type.sub_type
@dimensions = type.dimensions
@components = type.components
@name = type.name
return
end

_, base_type, sub_type, dimension = /([a-z]*)([0-9]*x?[0-9]*)((\[[0-9]*\])*)/.match(type).to_a

# type dimension can only be numeric
Expand Down
1 change: 0 additions & 1 deletion lib/eth/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ module Api
"eth_blockNumber",
"eth_call",
"eth_chainId",
"eth_coinbase",
"eth_compileLLL",
"eth_compileSerpent",
"eth_compileSolidity",
Expand Down
16 changes: 8 additions & 8 deletions lib/eth/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class Client
# The connected network's chain ID.
attr_reader :chain_id

# The connected network's client coinbase.
# The connected network's client default account.
attr_accessor :default_account

# The default transaction max priority fee per gas in Wei, defaults to {Tx::DEFAULT_PRIORITY_FEE}.
Expand Down Expand Up @@ -62,15 +62,15 @@ def initialize(_)
@max_fee_per_gas = Tx::DEFAULT_GAS_PRICE
end

# Gets the default account (coinbase) of the connected client.
# Gets the default account (first account) of the connected client.
#
# **Note**, that many remote providers (e.g., Infura) do not provide
# any accounts.
#
# @return [Eth::Address] the coinbase account address.
# @return [Eth::Address] the default account address.
def default_account
raise ArgumentError, "The default account is not available on remote connections!" unless local? || @default_account
@default_account ||= Address.new eth_coinbase["result"]
@default_account ||= Address.new eth_accounts["result"].first
end

# Gets the chain ID of the connected network.
Expand Down Expand Up @@ -108,7 +108,7 @@ def resolve_ens(ens_name, registry = Ens::DEFAULT_ADDRESS, coin_type = Ens::Coin
end

# Simply transfer Ether to an account and waits for it to be mined.
# Uses `eth_coinbase` and external signer if no sender key is
# Uses `eth_accounts` and external signer if no sender key is
# provided.
#
# See {#transfer} for params and overloads.
Expand All @@ -119,7 +119,7 @@ def transfer_and_wait(destination, amount, **kwargs)
end

# Simply transfer Ether to an account without any call data or
# access lists attached. Uses `eth_coinbase` and external signer
# access lists attached. Uses `eth_accounts` and external signer
# if no sender key is provided.
#
# **Note**, that many remote providers (e.g., Infura) do not provide
Expand Down Expand Up @@ -179,7 +179,7 @@ def transfer_erc20(erc20_contract, destination, amount, **kwargs)
end

# Deploys a contract and waits for it to be mined. Uses
# `eth_coinbase` or external signer if no sender key is provided.
# `eth_accounts` or external signer if no sender key is provided.
#
# See {#deploy} for params and overloads.
#
Expand All @@ -190,7 +190,7 @@ def deploy_and_wait(contract, *args, **kwargs)
contract.address = Address.new(addr).to_s
end

# Deploys a contract. Uses `eth_coinbase` or external signer
# Deploys a contract. Uses `eth_accounts` or external signer
# if no sender key is provided.
#
# **Note**, that many remote providers (e.g., Infura) do not provide
Expand Down
15 changes: 14 additions & 1 deletion lib/eth/contract/event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ class Contract::Event
# @param data [Hash] contract event data.
def initialize(data)
@name = data["name"]
@input_types = data["inputs"].collect { |x| x["type"] }
@input_types = data["inputs"].collect do |x|
type_name x
end
@inputs = data["inputs"].collect { |x| x["name"] }
@event_string = Abi::Event.signature(data)
@signature = Digest::Keccak.hexdigest(@event_string, 256)
Expand All @@ -38,5 +40,16 @@ def initialize(data)
def set_address(address)
@address = address.nil? ? nil : Eth::Address.new(address).address
end

private
def type_name(x)
type = x["type"]
case type
when "tuple"
"(#{x['components'].collect { |c| type_name(c) }.join(',')})"
else
type
end
end
end
end
1 change: 1 addition & 0 deletions spec/eth/abi/event_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@
expect(signature).to eq "Transfer(address,address,uint256)"
end


it "generates transfer function signature" do
abi = erc20_abi.find { |i| i["type"] == "function" && i["name"] == "transfer" }
signature = Abi::Event.signature(abi)
Expand Down
80 changes: 80 additions & 0 deletions spec/eth/contract/event_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,85 @@
expect(contract.events[1].signature).to eq("1f3a0e41bf4d8306f04763663bf025d1824a391571ce3a07186a195f8c4cfd3c")
expect(contract.events[1].event_string).to eq("killed()")
end

it "generates signature for event with tuple params" do
event = Eth::Contract::Event.new({
"anonymous" => false,
"inputs" => [
{
"components" => [
{
"internalType" => "uint256",
"name" => "topicId",
"type" => "uint256"
},
{
"internalType" => "uint256",
"name" => "proposalId",
"type" => "uint256"
},
{
"internalType" => "string",
"name" => "name",
"type" => "string"
},
{
"internalType" => "string",
"name" => "symbol",
"type" => "string"
},
{
"internalType" => "uint256",
"name" => "duration",
"type" => "uint256"
},
{
"internalType" => "uint256",
"name" => "totalSupply",
"type" => "uint256"
},
{
"internalType" => "uint256",
"name" => "miniStakeValue",
"type" => "uint256"
},
{
"internalType" => "uint256",
"name" => "maxStakeValue",
"type" => "uint256"
},
{
"internalType" => "uint256",
"name" => "maxParticipants",
"type" => "uint256"
},
{
"internalType" => "uint256",
"name" => "whitelistIndex",
"type" => "uint256"
},
{
"internalType" => "address",
"name" => "proposer",
"type" => "address"
},
{
"internalType" => "bool",
"name" => "useWhitelist",
"type" => "bool"
}
],
"indexed" => false,
"internalType" => "struct VoteContract.ProposalCreatedParams",
"name" => "params",
"type" => "tuple"
}
],
"name" => "ProposalCreated",
"type" => "event"
})
expect(event.event_string).to eq('ProposalCreated((uint256,uint256,string,string,uint256,uint256,uint256,uint256,uint256,uint256,address,bool))')
expect(event.signature).to eq('4449031b77cbe261580701c097fb63211e768f685581e616330dfff20493536c')
end
end
end
3 changes: 2 additions & 1 deletion spec/eth/solidity_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
result = solc.compile contract
expect(result["DepositContract"]).to be
payload = result["DepositContract"]["bin"]
expect(payload).to start_with "604060808152"
expect(payload).to start_with "60"
expect(payload).to end_with "33"
params = {
from: geth.default_account,
priority_fee: 0,
Expand Down

0 comments on commit f85e47e

Please sign in to comment.