Skip to content

Commit

Permalink
feat: add batch rpc requests
Browse files Browse the repository at this point in the history
  • Loading branch information
shaojunda committed Jun 28, 2020
1 parent 664a183 commit 04963df
Showing 1 changed file with 32 additions and 163 deletions.
195 changes: 32 additions & 163 deletions lib/ckb/rpc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ def initialize(host: DEFAULT_URL)
@http = Net::HTTP::Persistent.new
end

def method_missing(method, *params)
single_request(method, params)
end

def genesis_block
@genesis_block ||= get_block_by_number(0)
end
Expand All @@ -41,188 +45,53 @@ def genesis_block_hash
@genesis_block_hash ||= get_block_hash(0)
end

def get_block_hash(block_number)
rpc_request("get_block_hash", params: [Utils.to_hex(block_number)])
end

def get_block(block_hash)
rpc_request("get_block", params: [block_hash])
end

def get_block_by_number(block_number)
rpc_request("get_block_by_number", params: [Utils.to_hex(block_number)])
end

def get_tip_header
rpc_request("get_tip_header")
end

def get_tip_block_number
rpc_request("get_tip_block_number")
end

def get_cells_by_lock_hash(hash, from, to)
rpc_request("get_cells_by_lock_hash", params: [hash, Utils.to_hex(from), Utils.to_hex(to)])
end

def get_transaction(tx_hash)
rpc_request("get_transaction", params: [tx_hash])
end

def get_live_cell(out_point, with_data = false)
rpc_request("get_live_cell", params: [out_point, with_data])
end

def send_transaction(transaction, outputs_validator = nil)
unless outputs_validator.nil?
raise ArgumentError, "Invalid outputs_validator, outputs_validator should be `default` or `passthrough`" unless %w(default passthrough).include?(outputs_validator)
end

rpc_request("send_transaction", params: [transaction, outputs_validator])
end

def local_node_info
rpc_request("local_node_info")
end

def get_current_epoch
rpc_request("get_current_epoch")
end

def get_epoch_by_number(number)
rpc_request("get_epoch_by_number", params: [Utils.to_hex(number)])
end

# @return [Hash[]]
def get_peers
rpc_request("get_peers")
end

# @return [Hash]
def tx_pool_info
rpc_request("tx_pool_info")
end

def get_block_economic_state(block_hash)
rpc_request("get_block_economic_state", params: [block_hash])
end

def get_blockchain_info
rpc_request("get_blockchain_info")
end

def get_peers_state
rpc_request("get_peers_state")
end

def compute_transaction_hash(transaction)
rpc_request("_compute_transaction_hash", params: [transaction])
end

def compute_script_hash(script_h)
rpc_request("_compute_script_hash", params: [script_h])
single_request("send_transaction", params: [transaction, outputs_validator])
end

# @param transaction [Hash]
def dry_run_transaction(transaction)
rpc_request("dry_run_transaction", params: [transaction])
end

def calculate_dao_maximum_withdraw(out_point, hash)
rpc_request("calculate_dao_maximum_withdraw", params: [out_point, hash])
end

# Indexer

# @param lock_hash [String]
def deindex_lock_hash(lock_hash)
rpc_request("deindex_lock_hash", params: [lock_hash])
end

def get_live_cells_by_lock_hash(lock_hash, page, per, reverse_order: false)
rpc_request("get_live_cells_by_lock_hash", params: [lock_hash, Utils.to_hex(page), Utils.to_hex(per), reverse_order])
end

def get_lock_hash_index_states
rpc_request("get_lock_hash_index_states")
end

def get_transactions_by_lock_hash(lock_hash, page, per, reverse_order: false)
rpc_request("get_transactions_by_lock_hash", params: [lock_hash, Utils.to_hex(page), Utils.to_hex(per), reverse_order])
end

def index_lock_hash(lock_hash, index_from: 0)
rpc_request("index_lock_hash", params: [lock_hash, Utils.to_hex(index_from)])
end

# @param lock_hash [String]
def get_capacity_by_lock_hash(lock_hash)
rpc_request('get_capacity_by_lock_hash', params: [lock_hash])
end

def get_header(block_hash)
rpc_request("get_header", params: [block_hash])
end

def get_header_by_number(block_number)
rpc_request("get_header_by_number", params: [Utils.to_hex(block_number)])
end

def get_cellbase_output_capacity_details(block_hash)
rpc_request("get_cellbase_output_capacity_details", params: [block_hash])
end

# @param address [String]
# @param command [String]
# @param ban_time [String | nil] timestamp
# @param absolute [Boolean | nil]
# @param reason [String | nil]
def set_ban(address, command, ban_time = nil, absolute = nil, reason = nil)
rpc_request("set_ban", params: [address, command, Utils.to_hex(ban_time), absolute, reason])
def inspect
"\#<RPC@#{uri}>"
end

def get_banned_addresses
rpc_request("get_banned_addresses")
end
def batch_request(*requests)
body = requests.map do |request|
{ id: SecureRandom.uuid, jsonrpc: "2.0", method: request[0], params: request[1..-1].map { |param| param.is_a?(Integer) ? Utils.to_hex(param) : param } }
end
parsed_response = parse_response(post(body))
errors = parsed_response.select { |response| response[:error] }
raise RPCError, errors unless errors.empty?

# @param expect_confirm_blocks [Integer]
def estimate_fee_rate(expect_confirm_blocks)
rpc_request("estimate_fee_rate", params: [Utils.to_hex(expect_confirm_blocks)])
parsed_response.map { |response| response[:result] }
end

# @param bytes_limit [String | Integer] integer or hex number
# @param proposals_limit [String | Integer] integer or hex number
# @param max_version [String | Integer] integer or hex number
# @return block_template [Hash]
def get_block_template(bytes_limit = nil, proposals_limit = nil, max_version = nil)
rpc_request("get_block_template", params: [Utils.to_hex(bytes_limit), Utils.to_hex(proposals_limit), Utils.to_hex(max_version)])
end
private

def submit_block(work_id = nil, block_h = nil)
rpc_request("submit_block", params: [work_id, block_h])
end
def single_request(method, params)
response = post(id: SecureRandom.uuid, jsonrpc: "2.0", method: method, params: params.map { |param| param.is_a?(Integer) ? Utils.to_hex(param) : param })
parsed_response = parse_response(response)
raise RPCError, "jsonrpc error: #{parsed_response[:error]}" if parsed_response[:error]

def inspect
"\#<RPC@#{uri}>"
parsed_response[:result]
end

private

def rpc_request(method, params: nil)
def post(body)
request = Net::HTTP::Post.new("/")
request.body = {
id: 1,
jsonrpc: "2.0",
method: method.to_s,
params: params
}.to_json
request.body = body.to_json
request["Content-Type"] = "application/json"
response = http.request(uri, request)
result = JSON.parse(response.body, symbolize_names: true)

raise RPCError, "jsonrpc error: #{result[:error]}" if result[:error]
http.request(uri, request)
end

result[:result]
def parse_response(response)
if response.code == "200"
JSON.parse(response.body, symbolize_names: true)
else
error_messages = { body: response.body, code: response.code }
raise RuntimeError, error_messages
end
end
end
end
Expand Down

0 comments on commit 04963df

Please sign in to comment.