From 2ab7217d66c860ba171047d304c2ccea12942bf7 Mon Sep 17 00:00:00 2001 From: classicalliu Date: Mon, 23 Sep 2019 10:59:33 +0800 Subject: [PATCH 01/37] feat: add CellOutputWithOutPoint type and add block_hash --- lib/ckb/api.rb | 4 +- lib/ckb/types/cell_output_with_out_point.rb | 45 +++++++++++++++++++ lib/ckb/types/output.rb | 14 ++---- lib/ckb/types/types.rb | 1 + .../types/cell_output_with_out_point_spec.rb | 33 ++++++++++++++ 5 files changed, 85 insertions(+), 12 deletions(-) create mode 100644 lib/ckb/types/cell_output_with_out_point.rb create mode 100644 spec/ckb/types/cell_output_with_out_point_spec.rb diff --git a/lib/ckb/api.rb b/lib/ckb/api.rb index 84e19853..f2b0b2e2 100644 --- a/lib/ckb/api.rb +++ b/lib/ckb/api.rb @@ -108,10 +108,10 @@ def get_tip_block_number # @param from [String | Integer] # @param to [String | Integer] # - # @return [CKB::Types::Output[]] + # @return [CKB::Types::CellOutputWithOutPoint[]] def get_cells_by_lock_hash(hash, from, to) outputs = rpc.get_cells_by_lock_hash(hash, from, to) - outputs.map { |output| Types::Output.from_h(output) } + outputs.map { |output| Types::CellOutputWithOutPoint.from_h(output) } end # @param tx_hash [String] diff --git a/lib/ckb/types/cell_output_with_out_point.rb b/lib/ckb/types/cell_output_with_out_point.rb new file mode 100644 index 00000000..ee5d0608 --- /dev/null +++ b/lib/ckb/types/cell_output_with_out_point.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +module CKB + module Types + class CellOutputWithOutPoint + attr_accessor :lock, :out_point, :block_hash + attr_reader :capacity + + # @param capacity [String | Integer] integer or hex number + # @param lock [CKB::Types::Script] + # @param out_point [CKB::Types::OutPoint] + # @param block_hash [String] + def initialize(capacity:, lock:, out_point:, block_hash:) + @capacity = Utils.to_int(capacity) + @lock = lock + @out_point = out_point + @block_hash = block_hash + end + + def capacity=(value) + @capacity = Utils.to_int(value) + end + + def to_h + { + capacity: Utils.to_hex(@capacity), + lock: @lock.to_h, + block_hash: @block_hash, + out_point: @out_point.to_h + } + end + + def self.from_h(hash) + return if hash.nil? + + new( + capacity: hash[:capacity], + lock: Script.from_h(hash[:lock]), + out_point: OutPoint.from_h(hash[:out_point]), + block_hash: hash[:block_hash] + ) + end + end + end +end diff --git a/lib/ckb/types/output.rb b/lib/ckb/types/output.rb index 6fa1ed2e..82083bd4 100644 --- a/lib/ckb/types/output.rb +++ b/lib/ckb/types/output.rb @@ -3,18 +3,16 @@ module CKB module Types class Output - attr_accessor :lock, :type, :out_point + attr_accessor :lock, :type attr_reader :capacity # @param capacity [String | Integer] integer or hex number # @param lock [CKB::Types::Script] # @param type [CKB::Types::Script | nil] - # @param out_point [CKB::Types::OutPoint | nil] - def initialize(capacity:, lock:, type: nil, out_point: nil) + def initialize(capacity:, lock:, type: nil) @capacity = Utils.to_int(capacity) @lock = lock @type = type - @out_point = out_point end def capacity=(value) @@ -34,25 +32,21 @@ def calculate_min_capacity(data) end def to_h - hash = { + { capacity: Utils.to_hex(@capacity), lock: @lock.to_h, type: @type&.to_h } - hash[:out_point] = @out_point if @out_point - hash end def self.from_h(hash) return if hash.nil? type = Script.from_h(hash[:type]) if hash[:type] - out_point = OutPoint.from_h(hash[:out_point]) if hash[:out_point] new( capacity: hash[:capacity], lock: Script.from_h(hash[:lock]), - type: type, - out_point: out_point + type: type ) end end diff --git a/lib/ckb/types/types.rb b/lib/ckb/types/types.rb index ffad4a65..89595537 100644 --- a/lib/ckb/types/types.rb +++ b/lib/ckb/types/types.rb @@ -6,6 +6,7 @@ require_relative "input" require_relative "out_point" require_relative "output" +require_relative "cell_output_with_out_point" require_relative "cell_with_status" require_relative "script" require_relative "transaction_with_status" diff --git a/spec/ckb/types/cell_output_with_out_point_spec.rb b/spec/ckb/types/cell_output_with_out_point_spec.rb new file mode 100644 index 00000000..1ab6806d --- /dev/null +++ b/spec/ckb/types/cell_output_with_out_point_spec.rb @@ -0,0 +1,33 @@ +RSpec.describe CKB::Types::CellOutputWithOutPoint do + let(:cell_output_with_out_point_h) do + { + "block_hash": "0x03935a4b5e3c03a9c1deb93a39183a9a116c16cff3dc9ab129e847487da0e2b8", + "capacity": "0x1d1a94a200", + "lock": { + "args": [], + "code_hash": "0x28e83a1277d48add8e72fadaa9248559e1b632bab2bd60b27955ebc4c03800a5", + "hash_type": "data" + }, + "out_point": { + "index": "0x0", + "tx_hash": "0x5ba156200c6310bf140fbbd3bfe7e8f03d4d5f82b612c1a8ec2501826eaabc17" + } + } + end + + let(:cell_output_with_out_point) { CKB::Types::CellOutputWithOutPoint.from_h(cell_output_with_out_point_h) } + + it "from_h" do + expect(cell_output_with_out_point).to be_a(CKB::Types::CellOutputWithOutPoint) + expect(cell_output_with_out_point.lock).to be_a(CKB::Types::Script) + expect(cell_output_with_out_point.out_point).to be_a(CKB::Types::OutPoint) + expect(cell_output_with_out_point.capacity).to eq cell_output_with_out_point_h[:capacity].hex + expect(cell_output_with_out_point.block_hash).to eq cell_output_with_out_point_h[:block_hash] + end + + it "to_h" do + expect( + cell_output_with_out_point.to_h + ).to eq cell_output_with_out_point_h + end +end From f86ba79a137603c0f498b052e78b0570671e6d59 Mon Sep 17 00:00:00 2001 From: shaojunda Date: Wed, 25 Sep 2019 17:45:50 +0800 Subject: [PATCH 02/37] test: get_block_template rpc --- spec/ckb/rpc_spec.rb | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/spec/ckb/rpc_spec.rb b/spec/ckb/rpc_spec.rb index e4597e69..f60e2358 100644 --- a/spec/ckb/rpc_spec.rb +++ b/spec/ckb/rpc_spec.rb @@ -153,4 +153,31 @@ result = rpc.get_banned_addresses expect(result).not_to be nil end + + context "miner RPCs" do + it "get_block_template" do + result = rpc.get_block_template + expect(result).not_to be nil + end + + it "get_block_template with bytes_limit" do + result = rpc.get_block_template(bytes_limit: 1000) + expect(result).not_to be nil + end + + it "get_block_template with proposals_limit" do + result = rpc.get_block_template(proposals_limit: 1000) + expect(result).not_to be nil + end + + it "get_block_template with max_version" do + result = rpc.get_block_template(max_version: 1000) + expect(result).not_to be nil + end + + it "get_block_template with bytes_limit, proposals_limit and max_version" do + result = rpc.get_block_template(max_version: 1000) + expect(result).not_to be nil + end + end end From ecfe65ebd16c0751d557a3395642b5031e61f736 Mon Sep 17 00:00:00 2001 From: shaojunda Date: Wed, 25 Sep 2019 19:21:48 +0800 Subject: [PATCH 03/37] feat: get_block_template rpc --- lib/ckb/rpc.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/ckb/rpc.rb b/lib/ckb/rpc.rb index 8c1581a8..f8217dcb 100644 --- a/lib/ckb/rpc.rb +++ b/lib/ckb/rpc.rb @@ -172,6 +172,14 @@ def get_banned_addresses rpc_request("get_banned_addresses") 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 + def inspect "\#" end From 97a826c2e4937201a58270711e06f3c60956b79f Mon Sep 17 00:00:00 2001 From: shaojunda Date: Wed, 25 Sep 2019 19:24:09 +0800 Subject: [PATCH 04/37] test: get_block_template api --- spec/ckb/api_spec.rb | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/spec/ckb/api_spec.rb b/spec/ckb/api_spec.rb index a54aa875..4428803f 100644 --- a/spec/ckb/api_spec.rb +++ b/spec/ckb/api_spec.rb @@ -188,4 +188,31 @@ expect(result).not_to be nil expect(result).to all(be_a(Types::BannedAddress)) end + + context "miner APIs" do + it "get_block_template" do + result = api.get_block_template + expect(result).not_to be nil + end + + it "get_block_template with bytes_limit" do + result = api.get_block_template(bytes_limit: 1000) + expect(result).to be_a(Types::BlockTemplate) + end + + it "get_block_template with proposals_limit" do + result = api.get_block_template(proposals_limit: 1000) + expect(result).to be_a(Types::BlockTemplate) + end + + it "get_block_template with max_version" do + result = api.get_block_template(max_version: 1000) + expect(result).to be_a(Types::BlockTemplate) + end + + it "get_block_template with bytes_limit, proposals_limit and max_version" do + result = api.get_block_template(max_version: 1000) + expect(result).to be_a(Types::BlockTemplate) + end + end end From 46bec6236b9f22560a7fe8872370456395e6eded Mon Sep 17 00:00:00 2001 From: shaojunda Date: Thu, 26 Sep 2019 10:42:45 +0800 Subject: [PATCH 05/37] feat: add template related types block_template, cellbase_template, transaction_template and uncle_template --- lib/ckb/types/block_template.rb | 101 ++++++++++++++++++++++++++ lib/ckb/types/cellbase_template.rb | 37 ++++++++++ lib/ckb/types/transaction_template.rb | 45 ++++++++++++ lib/ckb/types/types.rb | 4 + lib/ckb/types/uncle_template.rb | 41 +++++++++++ 5 files changed, 228 insertions(+) create mode 100644 lib/ckb/types/block_template.rb create mode 100644 lib/ckb/types/cellbase_template.rb create mode 100644 lib/ckb/types/transaction_template.rb create mode 100644 lib/ckb/types/uncle_template.rb diff --git a/lib/ckb/types/block_template.rb b/lib/ckb/types/block_template.rb new file mode 100644 index 00000000..996d1eb9 --- /dev/null +++ b/lib/ckb/types/block_template.rb @@ -0,0 +1,101 @@ +# frozen_string_literal: true + +module CKB + module Types + class BlockTemplate + attr_accessor :version, :difficulty, :current_time, :number, :epoch, :parent_hash, :cycles_limit, + :bytes_limit, :uncles_count_limit, :uncles, :transactions, :proposals, :cellbase, :work_id, :dao + + # @param version [String | Integer] integer or hex number + # @param difficulty [String | Integer] integer or hex number + # @param current_time [String | Integer] integer or hex number + # @param number [String | Integer] integer or hex number + # @param epoch [String | Integer] integer or hex number + # @param parent_hash [String] 0x... + # @param cycles_limit [String | Integer] integer or hex number + # @param bytes_limit [String | Integer] integer or hex number + # @param uncles_count_limit [String | Integer] integer or hex number + # @param uncles [CKB::Types::UncleTemplate[]] + # @param transactions [CKB::Types::TransactionTemplate[]] + # @param proposals [String[]] 0x... + # @param cellbase [CellbaseTemplate] + # @param work_id [String | Integer] integer or hex number + # @param dao [String] 0x... + def initialize( + version:, + difficulty:, + current_time:, + number:, + epoch:, + parent_hash:, + cycles_limit:, + bytes_limit:, + uncles_count_limit:, + uncles:, + transactions:, + proposals:, + cellbase:, + work_id:, + dao: + ) + @version = Utils.to_int(version) + @difficulty = Utils.to_int(difficulty) + @current_time = Utils.to_int(current_time) + @number = Utils.to_int(number) + @epoch = Utils.to_int(epoch) + @parent_hash = parent_hash + @cycles_limit = Utils.to_int(cycles_limit) + @bytes_limit = Utils.to_int(bytes_limit) + @uncles_count_limit = Utils.to_int(uncles_count_limit) + @uncles = uncles + @transactions = transactions + @proposals = proposals + @cellbase = cellbase + @work_id = Utils.to_int(work_id) + @dao = dao + end + + def to_h + { + version: Utils.to_hex(version), + difficulty: Utils.to_hex(difficulty), + current_time: Utils.to_hex(current_time), + number: Utils.to_hex(number), + epoch: Utils.to_hex(epoch), + parent_hash: parent_hash, + cycles_limit: Utils.to_hex(cycles_limit), + bytes_limit: Utils.to_hex(bytes_limit), + uncles_count_limit: Utils.to_hex(uncles_count_limit), + uncles: uncles.map(&:to_h), + transactions: transactions.map(&:to_h), + proposals: proposals, + cellbase: cellbase.to_h, + work_id: work_id, + dao: dao + } + end + + def self.from_h(hash) + return if hash.nil? + + new( + version: hash[:version], + difficulty: hash[:difficulty], + current_time: hash[:current_time], + number: hash[:number], + epoch: hash[:epoch], + parent_hash: hash[:parent_hash], + cycles_limit: hash[:cycles_limit], + bytes_limit: hash[:bytes_limit], + uncles_count_limit: hash[:uncles_count_limit], + uncles: hash[:uncles], + transactions: hash[:transactions], + proposals: hash[:proposals], + cellbase: hash[:cellbase], + work_id: hash[:work_id], + dao: hash[:dao] + ) + end + end + end +end diff --git a/lib/ckb/types/cellbase_template.rb b/lib/ckb/types/cellbase_template.rb new file mode 100644 index 00000000..3a8e4766 --- /dev/null +++ b/lib/ckb/types/cellbase_template.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module CKB + module Types + class CellbaseTemplate + attr_accessor :hash, :cycles, :data + + # @param hash [String] 0x.. + # @param cycles [String | Integer] integer or hex number + # @param data [CKB::Type::Transaction] + def initialize(hash:, cycles:, data:) + @hash = hash + @cycles = Utils.to_int(cycles) + @data = data + end + + def to_h + { + hash: hash, + cycles: Utils.to_hex(cycles), + data: data.to_h + } + end + + def self.from_h(hash) + return if hash.nil? + + new( + hash: hash[:hash], + cycles: hash[:cycles], + data: Transaction.from_h(hash[:data]), + ) + end + end + end +end + diff --git a/lib/ckb/types/transaction_template.rb b/lib/ckb/types/transaction_template.rb new file mode 100644 index 00000000..eafcb0ce --- /dev/null +++ b/lib/ckb/types/transaction_template.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +module CKB + module Types + class TransactionTemplate + attr_accessor :hash, :required, :cycles, :depends, :data + + # @param hash [String] 0x.. + # @param required [Boolean] + # @param cycles [String | Integer] integer or hex number + # @param depends [String[] | Integer[]] integer[] or hex number[] + # @param data [CKB::Type::Transaction] + def initialize(hash:, required:, cycles:, depends:, data:) + @hash = hash + @required = required + @cycles = Utils.to_int(cycles) + @depends = depends.map { |depend| Utils.to_int(depend) } + @data = data + end + + def to_h + { + hash: hash, + required: required, + cycles: Utils.to_hex(cycles), + depends: depends.map { |depend| Utils.to_hex(depend) }, + data: data.to_h + } + end + + def self.from_h(hash) + return if hash.nil? + + new( + hash: hash[:hash], + required: hash[:required], + cycles: hash[:cycles], + depends: hash[:depends], + data: Transaction.from_h(hash[:data]), + ) + end + end + end +end + diff --git a/lib/ckb/types/types.rb b/lib/ckb/types/types.rb index 89595537..2e02fb8e 100644 --- a/lib/ckb/types/types.rb +++ b/lib/ckb/types/types.rb @@ -30,6 +30,10 @@ require_relative "cell_dep" require_relative "cell_data" require_relative "cell_info" +require_relative "uncle_template" +require_relative "transaction_template" +require_relative "cellbase_template" +require_relative "block_template" module CKB module Types diff --git a/lib/ckb/types/uncle_template.rb b/lib/ckb/types/uncle_template.rb new file mode 100644 index 00000000..fc9f792e --- /dev/null +++ b/lib/ckb/types/uncle_template.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +module CKB + module Types + class UncleTemplate + attr_accessor :hash, :required, :proposals, :header + + # @param hash [String] 0x.. + # @param required [Boolean] + # @param proposals [String[]] 0x.. + # @param header [CKB::Type::BlockHeader] + def initialize(hash:, required:, proposals:, header:) + @hash = hash + @required = required + @proposals = proposals + @header = header + end + + def to_h + { + hash: hash, + required: required, + proposals: proposals, + header: header.to_h + } + end + + def self.from_h(hash) + return if hash.nil? + + new( + hash: hash[:hash], + required: hash[:required], + proposals: hash[:proposals], + header: BlockHeader.from_h(hash[:header]) + ) + end + end + end +end + From 942d52516c023448e051be05ae6fbdadbdad9820 Mon Sep 17 00:00:00 2001 From: shaojunda Date: Thu, 26 Sep 2019 10:43:05 +0800 Subject: [PATCH 06/37] feat: get_block_template api --- lib/ckb/api.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/ckb/api.rb b/lib/ckb/api.rb index f2b0b2e2..c925ef2b 100644 --- a/lib/ckb/api.rb +++ b/lib/ckb/api.rb @@ -290,6 +290,15 @@ def get_banned_addresses result.map { |addr| Types::BannedAddress.from_h(addr) } 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 [BlockTemplate] + def get_block_template(bytes_limit: nil, proposals_limit: nil, max_version: nil) + block_template_h = rpc.get_block_template(bytes_limit, proposals_limit, max_version) + Types::BlockTemplate.from_h(block_template_h) + end + def inspect "\#" end From 8a621613fc52f69de4d9aa60486e414a12d2e4ff Mon Sep 17 00:00:00 2001 From: shaojunda Date: Thu, 26 Sep 2019 10:43:26 +0800 Subject: [PATCH 07/37] test: block_template --- spec/ckb/types/block_template_spec.rb | 70 +++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 spec/ckb/types/block_template_spec.rb diff --git a/spec/ckb/types/block_template_spec.rb b/spec/ckb/types/block_template_spec.rb new file mode 100644 index 00000000..dca0092a --- /dev/null +++ b/spec/ckb/types/block_template_spec.rb @@ -0,0 +1,70 @@ +RSpec.describe CKB::Types::BlockTemplate do + let(:block_template_h) do + {:version=>"0x0", + :difficulty=>"0x48", + :current_time=>"0x16d6b6111b3", + :number=>"0xab3", + :epoch=>"0x70806cb000001", + :parent_hash=>"0x17784aea72da790a1a058221869c7948c7ed46f6dc2e514febcd9241baf8daa9", + :cycles_limit=>"0x2540be400", + :bytes_limit=>"0x25e", + :uncles_count_limit=>"0x2", + :uncles=>[], + :transactions=>[], + :proposals=>[], + :cellbase=> + {:cycles=>nil, + :data=> + {:cell_deps=>[], + :header_deps=>[], + :inputs=> + [{:previous_output=> + {:index=>"0xffffffff", :tx_hash=>"0x0000000000000000000000000000000000000000000000000000000000000000"}, + :since=>"0xab3"}], + :outputs=> + [{:capacity=>"0x1a1eef7320", + :lock=> + {:args=>["0x3954acece65096bfa81258983ddb83915fc56bd8"], + :code_hash=>"0x1892ea40d82b53c678ff88312450bbb17e164d7a3e0a90941aa58839f56f8df2", + :hash_type=>"type"}, + :type=>nil}], + :outputs_data=>["0x"], + :version=>"0x0", + :witnesses=> + [{:data=> + ["0x1892ea40d82b53c678ff88312450bbb17e164d7a3e0a90941aa58839f56f8df201", + "0x3954acece65096bfa81258983ddb83915fc56bd8"]}]}, + :hash=>"0x6d6e478ae632208f4cc4120078bba78852e88ef136e8c5cc8c102b1e21c62dad"}, + :work_id=>4, + :dao=>"0xbcbcf54f7e4b090038b2d9a13464250018f37dd3985a000000f678cfa9890100"} + end + + let(:block_template) { CKB::Types::BlockTemplate.from_h(block_template_h) } + + it "from_h" do + expect(CKB::Types::BlockTemplate.from_h(block_template_h)).to be_a(CKB::Types::BlockTemplate) + end + + it "block_template's attributes value should equal with block_template_h" do + number_keys = %i(version difficulty current_time number epoch parent_hash cycles_limit bytes_limit uncles_count_limit uncles transactions proposals cellbase work_id dao) + number_keys.each do |key| + expect(block_template.to_h[key]).to eq block_template_h[key] + end + end + + it "to_h" do + expect( + block_template.to_h + ).to eq block_template_h + end + + it "block header should contains correct attributes" do + skip "not test api" if ENV["SKIP_RPC_TESTS"] + + api = CKB::API.new + block_template = api.get_block_template + expected_attributes = %w(version difficulty current_time number epoch parent_hash cycles_limit bytes_limit uncles_count_limit uncles transactions proposals cellbase work_id dao).sort + + expect(expected_attributes).to eq(block_template.instance_variables.map { |attribute| attribute.to_s.gsub("@", "") }.sort) + end +end From ae55017cb49aced471c3e8c757e56834204ea4a4 Mon Sep 17 00:00:00 2001 From: shaojunda Date: Thu, 26 Sep 2019 15:39:07 +0800 Subject: [PATCH 08/37] test: uncle_template --- spec/ckb/types/uncle_template_spec.rb | 44 +++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 spec/ckb/types/uncle_template_spec.rb diff --git a/spec/ckb/types/uncle_template_spec.rb b/spec/ckb/types/uncle_template_spec.rb new file mode 100644 index 00000000..1e93447f --- /dev/null +++ b/spec/ckb/types/uncle_template_spec.rb @@ -0,0 +1,44 @@ +RSpec.describe CKB::Types::UncleTemplate do + let(:uncle_template_h) do + { + :hash=>"0x6d6e478ae632208f4cc4120078bba78852e88ef136e8c5cc8c102b1e21c62dad", + :required=>false, + :proposals=>[], + :header => { + :dao=>"0x0100000000000000005827f2ba13b000d77fa3d595aa00000061eb7ada030000", + :difficulty=>"0x7a1200", + :epoch=>"0x1", + :hash=>"0xd629a10a08fb0f43fcb97e948fc2b6eb70ebd28536490fe3864b0e40d08397d1", + :nonce=>"0x0", + :number=>"0x400", + :parent_hash=>"0x30a78d902d7c89ae41feaeb4652c79439e2224a3a32bc0f12059f71d86239d03", + :proposals_hash=>"0x0000000000000000000000000000000000000000000000000000000000000000", + :timestamp=>"0x5cd2b117", + :transactions_root=>"0x8ad0468383d0085e26d9c3b9b648623e4194efc53a03b7cd1a79e92700687f1e", + :uncles_count=>"0x0", + :uncles_hash=>"0x0000000000000000000000000000000000000000000000000000000000000000", + :version=>"0x0", + :witnesses_root=>"0x90445a0795a2d7d4af033ec0282a8a1f68f11ffb1cd091b95c2c5515a8336e9c" + } + } + end + + let(:uncle_template) { CKB::Types::UncleTemplate.from_h(uncle_template_h) } + + it "from_h" do + expect(CKB::Types::UncleTemplate.from_h(uncle_template_h)).to be_a(CKB::Types::UncleTemplate) + end + + it "block_template's attributes value should equal with block_template_h" do + number_keys = %i(hash required proposals header) + number_keys.each do |key| + expect(uncle_template.to_h[key]).to eq uncle_template_h[key] + end + end + + it "to_h" do + expect( + uncle_template.to_h + ).to eq uncle_template_h + end +end From fee11400a66e7aa490af5f95c4fe5682ac324d38 Mon Sep 17 00:00:00 2001 From: shaojunda Date: Thu, 26 Sep 2019 16:08:43 +0800 Subject: [PATCH 09/37] test: transaction_template --- spec/ckb/types/transaction_template_spec.rb | 59 +++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 spec/ckb/types/transaction_template_spec.rb diff --git a/spec/ckb/types/transaction_template_spec.rb b/spec/ckb/types/transaction_template_spec.rb new file mode 100644 index 00000000..c2f6487a --- /dev/null +++ b/spec/ckb/types/transaction_template_spec.rb @@ -0,0 +1,59 @@ +RSpec.describe CKB::Types::TransactionTemplate do + let(:transaction_template_h) do + { + :hash=>"0x6d6e478ae632208f4cc4120078bba78852e88ef136e8c5cc8c102b1e21c62dad", + :required=>false, + :cycles=>"0x7a1200", + :depends=> %w(0x3a1200 0x2a1200), + :data=> { + :version=>"0x0", + :cell_deps=>[], + :header_deps=>[], + :inputs=>[ + { + :args=>[], + :previous_output=>{ + :tx_hash=>"0xa80a8e01d45b10e1cbc8a2557c62ba40edbdc36cd63a31fc717006ca7b157b50", + :index=>"0x0" + }, + :since=>"0x0" + } + ], + :outputs=>[ + { + :capacity=>"0x174876e800", + :lock=>{ + :code_hash=>"0x9e3b3557f11b2b3532ce352bfe8017e9fd11d154c4c7f9b7aaaa1e621b539a08", + :args=>[ + "0xe2193df51d78411601796b35b17b4f8f2cd85bd0" + ], + :hash_type=>"type" + }, + :type=>nil + } + ], + :outputs_data=>["0x"], + :witnesses=>[ + { + :data=> %w(0x1892ea40d82b53c678ff88312450bbb17e164d7a3e0a90941aa58839f56f8df201 0x3954acece65096bfa81258983ddb83915fc56bd8) + } + ] + } + } + end + + let(:transaction_template) { CKB::Types::TransactionTemplate.from_h(transaction_template_h) } + + it "from_h" do + expect(CKB::Types::TransactionTemplate.from_h(transaction_template_h)).to be_a(CKB::Types::TransactionTemplate) + end + + it "to_h" do + data = transaction_template.to_h[:data] + expect( + transaction_template.to_h.reject { |key| key == :data } + ).to eq transaction_template_h.reject { |key| key == :data } + + expect(CKB::Types::Transaction.from_h(data)).to be_a(CKB::Types::Transaction) + end +end From 3c57e4098d322d3572a4a6401f52a0926ce7559d Mon Sep 17 00:00:00 2001 From: shaojunda Date: Wed, 25 Sep 2019 17:45:50 +0800 Subject: [PATCH 10/37] test: get_block_template rpc --- spec/ckb/rpc_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/ckb/rpc_spec.rb b/spec/ckb/rpc_spec.rb index f60e2358..8529d193 100644 --- a/spec/ckb/rpc_spec.rb +++ b/spec/ckb/rpc_spec.rb @@ -161,22 +161,22 @@ end it "get_block_template with bytes_limit" do - result = rpc.get_block_template(bytes_limit: 1000) + result = rpc.get_block_template(1000) expect(result).not_to be nil end it "get_block_template with proposals_limit" do - result = rpc.get_block_template(proposals_limit: 1000) + result = rpc.get_block_template(1000) expect(result).not_to be nil end it "get_block_template with max_version" do - result = rpc.get_block_template(max_version: 1000) + result = rpc.get_block_template(1000) expect(result).not_to be nil end it "get_block_template with bytes_limit, proposals_limit and max_version" do - result = rpc.get_block_template(max_version: 1000) + result = rpc.get_block_template(1000) expect(result).not_to be nil end end From 9a83c5101fb10b96ee5489972f0d8b7b2561bbab Mon Sep 17 00:00:00 2001 From: shaojunda Date: Thu, 26 Sep 2019 16:15:43 +0800 Subject: [PATCH 11/37] test: cellbase_template --- spec/ckb/types/cellbase_template_spec.rb | 57 ++++++++++++++++++++++++ spec/ckb/types/uncle_template_spec.rb | 2 +- 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 spec/ckb/types/cellbase_template_spec.rb diff --git a/spec/ckb/types/cellbase_template_spec.rb b/spec/ckb/types/cellbase_template_spec.rb new file mode 100644 index 00000000..d0577410 --- /dev/null +++ b/spec/ckb/types/cellbase_template_spec.rb @@ -0,0 +1,57 @@ +RSpec.describe CKB::Types::CellbaseTemplate do + let(:cellbase_template_h) do + { + :hash=>"0x6d6e478ae632208f4cc4120078bba78852e88ef136e8c5cc8c102b1e21c62dad", + :cycles=>"0x7a1200", + :data=> { + :version=>"0x0", + :cell_deps=>[], + :header_deps=>[], + :inputs=>[ + { + :args=>[], + :previous_output=>{ + :tx_hash=>"0xa80a8e01d45b10e1cbc8a2557c62ba40edbdc36cd63a31fc717006ca7b157b50", + :index=>"0x0" + }, + :since=>"0x0" + } + ], + :outputs=>[ + { + :capacity=>"0x174876e800", + :lock=>{ + :code_hash=>"0x9e3b3557f11b2b3532ce352bfe8017e9fd11d154c4c7f9b7aaaa1e621b539a08", + :args=>[ + "0xe2193df51d78411601796b35b17b4f8f2cd85bd0" + ], + :hash_type=>"type" + }, + :type=>nil + } + ], + :outputs_data=>["0x"], + :witnesses=>[ + { + :data=> %w(0x1892ea40d82b53c678ff88312450bbb17e164d7a3e0a90941aa58839f56f8df201 0x3954acece65096bfa81258983ddb83915fc56bd8) + } + ] + } + } + end + + let(:cellbase_template) { CKB::Types::CellbaseTemplate.from_h(cellbase_template_h) } + + it "from_h" do + expect(CKB::Types::CellbaseTemplate.from_h(cellbase_template_h)).to be_a(CKB::Types::CellbaseTemplate) + end + + it "to_h" do + data = cellbase_template.to_h[:data] + expect( + cellbase_template.to_h.reject { |key| key == :data } + ).to eq cellbase_template_h.reject { |key| key == :data } + + expect(CKB::Types::Transaction.from_h(data)).to be_a(CKB::Types::Transaction) + end +end diff --git a/spec/ckb/types/uncle_template_spec.rb b/spec/ckb/types/uncle_template_spec.rb index 1e93447f..269e0aff 100644 --- a/spec/ckb/types/uncle_template_spec.rb +++ b/spec/ckb/types/uncle_template_spec.rb @@ -29,7 +29,7 @@ expect(CKB::Types::UncleTemplate.from_h(uncle_template_h)).to be_a(CKB::Types::UncleTemplate) end - it "block_template's attributes value should equal with block_template_h" do + it "uncle_template's attributes value should equal with block_template_h" do number_keys = %i(hash required proposals header) number_keys.each do |key| expect(uncle_template.to_h[key]).to eq uncle_template_h[key] From baa886aac4dd41c36a6ba52373546d0f018e6a11 Mon Sep 17 00:00:00 2001 From: shaojunda Date: Thu, 26 Sep 2019 16:46:31 +0800 Subject: [PATCH 12/37] test: submit_block rpc --- spec/ckb/rpc_spec.rb | 45 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/spec/ckb/rpc_spec.rb b/spec/ckb/rpc_spec.rb index 8529d193..d3623ca7 100644 --- a/spec/ckb/rpc_spec.rb +++ b/spec/ckb/rpc_spec.rb @@ -1,8 +1,39 @@ +# frozen_string_literal: true + RSpec.describe CKB::RPC do before do skip "not test rpc" if ENV["SKIP_RPC_TESTS"] end - + let(:raw_block_h) do + { uncles: [], + proposals: [], + transactions: [{ version: "0x0", + cell_deps: [], + header_deps: [], + inputs: [{ previous_output: { tx_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", index: "0xffffffff" }, + since: "0x1" }], + outputs: [{ capacity: "0x2ca7071b9e", + lock: { code_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", + args: [], + hash_type: "type" }, + type: nil }], + outputs_data: ["0x"], + witnesses: [{ data: %w[0x1892ea40d82b53c678ff88312450bbb17e164d7a3e0a90941aa58839f56f8df201 + 0x3954acece65096bfa81258983ddb83915fc56bd8] }]}], + header: { difficulty: "0x100", + number: "0x1", + parent_hash: "0x6944997e76680c03a7b30fa8b1d30da9e77685de5b28796898b05c6e6e3f9ace", + nonce: "0xd20cf913474dbf0e", + timestamp: "0x16d6731e6e1", + transactions_root: "0x761909b19c96df2b38283bcd6ddf7162a1947e3fad2be70c32f3c7596ddcfad3", + proposals_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", + uncles_count: "0x0", + uncles_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", + version: "0x0", + witnesses_root: "0x4c1f2995e6507bd45f0295dd775b9d6c9cd21fc775f95582fe2a6ce0ed8ee00a", + epoch: "0x3e80001000000", + dao: "0x2c7ecb6d26870700f1d8f5e035872300683cb95e9a0000000094b5c67d7a0100" } } + end let(:rpc) { CKB::RPC.new } let(:lock_hash) { "0xd0e22f863da970a3ff51a937ae78ba490bbdcede7272d658a053b9f80e30305d" } @@ -79,9 +110,9 @@ outputs: [] } - expect { + expect do rpc.send_transaction(tx) - }.to raise_error(CKB::RPCError, /:code=>-3/) + end.to raise_error(CKB::RPCError, /:code=>-3/) end it "local node info" do @@ -144,7 +175,7 @@ end it "set ban" do - params = ["192.168.0.2", "insert", 1840546800000, true, "test set_ban rpc"] + params = ["192.168.0.2", "insert", 1_840_546_800_000, true, "test set_ban rpc"] result = rpc.set_ban(*params) expect(result).to be nil end @@ -179,5 +210,11 @@ result = rpc.get_block_template(1000) expect(result).not_to be nil end + + # must use real data + it "submit_block" do + result = rpc.submit_block("test", raw_block_h) + expect(result).not_to be nil + end end end From 2a10a7a882c90a4d65a0af4b7667232fce72ab2f Mon Sep 17 00:00:00 2001 From: shaojunda Date: Thu, 26 Sep 2019 16:46:46 +0800 Subject: [PATCH 13/37] feat: submit_block rpc --- lib/ckb/rpc.rb | 4 ++++ spec/ckb/rpc_spec.rb | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/ckb/rpc.rb b/lib/ckb/rpc.rb index f8217dcb..2e097862 100644 --- a/lib/ckb/rpc.rb +++ b/lib/ckb/rpc.rb @@ -180,6 +180,10 @@ def get_block_template(bytes_limit = nil, proposals_limit = nil, max_version = n rpc_request("get_block_template", params: [Utils.to_hex(bytes_limit), Utils.to_hex(proposals_limit), Utils.to_hex(max_version)]) end + def submit_block(work_id = nil, block_h = nil) + rpc_request("submit_block", params: [work_id, block_h]) + end + def inspect "\#" end diff --git a/spec/ckb/rpc_spec.rb b/spec/ckb/rpc_spec.rb index d3623ca7..8e385189 100644 --- a/spec/ckb/rpc_spec.rb +++ b/spec/ckb/rpc_spec.rb @@ -1,5 +1,4 @@ # frozen_string_literal: true - RSpec.describe CKB::RPC do before do skip "not test rpc" if ENV["SKIP_RPC_TESTS"] From deb12279bc28f7859af11d3a3c87b8823873ec5f Mon Sep 17 00:00:00 2001 From: shaojunda Date: Thu, 26 Sep 2019 17:10:11 +0800 Subject: [PATCH 14/37] chore: add idea to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 628d1c9b..13a8ba14 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ /spec/reports/ /tmp/ /.ruby-version +.idea/ # rspec failure tracking .rspec_status From 862aa0a0787db71c5a0991d4540cdbcfecda0bab Mon Sep 17 00:00:00 2001 From: shaojunda Date: Thu, 26 Sep 2019 17:32:18 +0800 Subject: [PATCH 15/37] test: submit_block api --- spec/ckb/api_spec.rb | 46 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/spec/ckb/api_spec.rb b/spec/ckb/api_spec.rb index 4428803f..37d1db5b 100644 --- a/spec/ckb/api_spec.rb +++ b/spec/ckb/api_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + RSpec.describe CKB::API do Types = CKB::Types @@ -7,6 +9,38 @@ let(:api) { CKB::API.new } let(:lock_hash) { "0xe94e4b509d5946c54ea9bc7500af12fd35eebe0d47a6b3e502127f94d34997ac" } + let(:block_h) do + { uncles: [], + proposals: [], + transactions: [{ hash: "0x8ad0468383d0085e26d9c3b9b648623e4194efc53a03b7cd1a79e92700687f1e", + version: "0x0", + cell_deps: [], + header_deps: [], + inputs: [{ previous_output: { tx_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", index: "0xffffffff" }, + since: "0x1" }], + outputs: [{ capacity: "0x2ca7071b9e", + lock: { code_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", + args: [], + hash_type: "type" }, + type: nil }], + outputs_data: ["0x"], + witnesses: [{ data: %w[0x1892ea40d82b53c678ff88312450bbb17e164d7a3e0a90941aa58839f56f8df201 + 0x3954acece65096bfa81258983ddb83915fc56bd8] }] }], + header: { difficulty: "0x100", + hash: "0xd629a10a08fb0f43fcb97e948fc2b6eb70ebd28536490fe3864b0e40d08397d1", + number: "0x1", + parent_hash: "0x6944997e76680c03a7b30fa8b1d30da9e77685de5b28796898b05c6e6e3f9ace", + nonce: "0xd20cf913474dbf0e", + timestamp: "0x16d6731e6e1", + transactions_root: "0x761909b19c96df2b38283bcd6ddf7162a1947e3fad2be70c32f3c7596ddcfad3", + proposals_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", + uncles_count: "0x0", + uncles_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", + version: "0x0", + witnesses_root: "0x4c1f2995e6507bd45f0295dd775b9d6c9cd21fc775f95582fe2a6ce0ed8ee00a", + epoch: "0x3e80001000000", + dao: "0x2c7ecb6d26870700f1d8f5e035872300683cb95e9a0000000094b5c67d7a0100" } } + end it "genesis block" do expect(api.genesis_block).to be_a(Types::Block) @@ -72,9 +106,9 @@ outputs: [] ) - expect { + expect do api.send_transaction(tx) - }.to raise_error(CKB::RPCError, /:code=>-3/) + end.to raise_error(CKB::RPCError, /:code=>-3/) end it "get current epoch" do @@ -178,7 +212,7 @@ end it "set ban" do - params = ["192.168.0.2", "insert", 1840546800000, true, "test set_ban rpc"] + params = ["192.168.0.2", "insert", 1_840_546_800_000, true, "test set_ban rpc"] result = api.set_ban(*params) expect(result).to be nil end @@ -214,5 +248,11 @@ result = api.get_block_template(max_version: 1000) expect(result).to be_a(Types::BlockTemplate) end + + it "submit_block should return block hash" do + block = Types::Block.from_h(block_h) + result = api.submit_block(work_id: "test", raw_block_h: block.to_raw_block_h) + expect(result).to be_a(String) + end end end From 60443f756203016e98719e913388f6a190f9eb62 Mon Sep 17 00:00:00 2001 From: shaojunda Date: Thu, 26 Sep 2019 17:32:30 +0800 Subject: [PATCH 16/37] feat: add submit_block api --- lib/ckb/api.rb | 8 ++++++++ lib/ckb/types/block.rb | 9 +++++++++ 2 files changed, 17 insertions(+) diff --git a/lib/ckb/api.rb b/lib/ckb/api.rb index c925ef2b..17183c1d 100644 --- a/lib/ckb/api.rb +++ b/lib/ckb/api.rb @@ -299,6 +299,14 @@ def get_block_template(bytes_limit: nil, proposals_limit: nil, max_version: nil) Types::BlockTemplate.from_h(block_template_h) end + + # @param work_id [String | Integer] integer or hex number + # @param raw_block_h [hash] + # @return block_hash [String] + def submit_block(work_id: nil, raw_block_h: nil) + rpc.submit_block(work_id, raw_block_h) + end + def inspect "\#" end diff --git a/lib/ckb/types/block.rb b/lib/ckb/types/block.rb index 86d42423..1d46bac2 100644 --- a/lib/ckb/types/block.rb +++ b/lib/ckb/types/block.rb @@ -25,6 +25,15 @@ def to_h } end + def to_raw_block_h + { + uncles: uncles.map(&:to_h), + proposals: proposals, + transactions: transactions.map(&:to_raw_transaction_h), + header: header.to_h.reject { |key| key == :hash } + } + end + def self.from_h(hash) return if hash.nil? From 78f3f596081f5aa9f50a2c334b4f45bd19574038 Mon Sep 17 00:00:00 2001 From: shaojunda Date: Fri, 27 Sep 2019 12:26:50 +0800 Subject: [PATCH 17/37] feat: update expected code_hash and type_hash --- lib/ckb/api.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ckb/api.rb b/lib/ckb/api.rb index 17183c1d..6ebbdd45 100644 --- a/lib/ckb/api.rb +++ b/lib/ckb/api.rb @@ -19,8 +19,8 @@ def initialize(host: CKB::RPC::DEFAULT_URL, mode: MODE::TESTNET) @rpc = CKB::RPC.new(host: host) if mode == MODE::TESTNET # Testnet system script code_hash - expected_code_hash = "0xa656f172b6b45c245307aeb5a7a37a176f002f6f22e92582c58bf7ba362e4176" - expected_type_hash = "0x1892ea40d82b53c678ff88312450bbb17e164d7a3e0a90941aa58839f56f8df2" + expected_code_hash = "0xc8b0772347016713ee8039d6b1d2f4b02803abdc4ea4e95677b0c5e8ff52ea3b" + expected_type_hash = "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8" # For testnet chain, we can assume the second cell of the first transaction # in the genesis block contains default lock script we can use here. system_cell_transaction = genesis_block.transactions.first From ff9314941cab5374ad172c1d5288c0423e92cb74 Mon Sep 17 00:00:00 2001 From: shaojunda Date: Fri, 27 Sep 2019 12:27:15 +0800 Subject: [PATCH 18/37] refactor: remove witness type --- lib/ckb/types/types.rb | 1 - lib/ckb/types/witness.rb | 28 ---------------------------- 2 files changed, 29 deletions(-) delete mode 100644 lib/ckb/types/witness.rb diff --git a/lib/ckb/types/types.rb b/lib/ckb/types/types.rb index 2e02fb8e..d9aa211f 100644 --- a/lib/ckb/types/types.rb +++ b/lib/ckb/types/types.rb @@ -12,7 +12,6 @@ require_relative "transaction_with_status" require_relative "transaction" require_relative "tx_status" -require_relative "witness" require_relative "epoch" require_relative "alert_message" require_relative "chain_info" diff --git a/lib/ckb/types/witness.rb b/lib/ckb/types/witness.rb deleted file mode 100644 index 8b06e752..00000000 --- a/lib/ckb/types/witness.rb +++ /dev/null @@ -1,28 +0,0 @@ -# frozen_string_literal: true - -module CKB - module Types - class Witness - attr_accessor :data - - # @param data [String[]] 0x... - def initialize(data:) - @data = data - end - - def to_h - { - data: @data - } - end - - def self.from_h(hash) - return if hash.nil? - - new( - data: hash[:data] - ) - end - end - end -end From f946c9dfa30b620a6552d5ede3bcb0c27901d072 Mon Sep 17 00:00:00 2001 From: shaojunda Date: Fri, 27 Sep 2019 12:29:25 +0800 Subject: [PATCH 19/37] feat: change witnesses to String[] --- lib/ckb/types/transaction.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/ckb/types/transaction.rb b/lib/ckb/types/transaction.rb index 6401c987..bc9b5300 100644 --- a/lib/ckb/types/transaction.rb +++ b/lib/ckb/types/transaction.rb @@ -12,7 +12,7 @@ class Transaction # @param inputs [CKB::Types::Input[]] # @param outputs [CKB::Types::Output[]] # @param outputs_data [String[]] - # @param witnesses [CKB::Types::Witness[]] + # @param witnesses [String[]] def initialize( hash: nil, version: 0, @@ -70,7 +70,7 @@ def to_h inputs: @inputs.map(&:to_h), outputs: @outputs.map(&:to_h), outputs_data: @outputs_data, - witnesses: @witnesses.map(&:to_h) + witnesses: @witnesses } hash[:hash] = @hash if @hash hash @@ -84,7 +84,7 @@ def to_raw_transaction_h inputs: @inputs.map(&:to_h), outputs: @outputs.map(&:to_h), outputs_data: @outputs_data, - witnesses: @witnesses.map(&:to_h) + witnesses: @witnesses } end @@ -106,7 +106,7 @@ def self.from_h(hash) inputs: hash[:inputs].map { |input| Input.from_h(input) }, outputs: hash[:outputs].map { |output| Output.from_h(output) }, outputs_data: hash[:outputs_data], - witnesses: hash[:witnesses].map { |witness| Witness.from_h(witness) } + witnesses: hash[:witnesses] ) end end From c59691a8c14aa504e6061f521f3307f9b988e7a3 Mon Sep 17 00:00:00 2001 From: shaojunda Date: Fri, 27 Sep 2019 12:29:48 +0800 Subject: [PATCH 20/37] feat: update args serializer --- lib/ckb/serializers/script_serializer.rb | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/ckb/serializers/script_serializer.rb b/lib/ckb/serializers/script_serializer.rb index 92ea545c..45e21f20 100644 --- a/lib/ckb/serializers/script_serializer.rb +++ b/lib/ckb/serializers/script_serializer.rb @@ -9,12 +9,24 @@ class ScriptSerializer def initialize(script) @code_hash_serializer = CodeHashSerializer.new(script.code_hash) @hash_type_serializer = HashTypeSerializer.new(script.hash_type) - @args_serializer = DynVecSerializer.new(script.args, ArgSerializer) + args = init_args(script) + @args_serializer = FixVecSerializer.new(args.scan(/../), ByteSerializer) @items_count = 3 end private + def init_args(script) + args = script.args + if args + args = args.start_with?("0x") ? args[2..-1] : args + else + args = "" + end + + args + end + attr_reader :code_hash_serializer, :hash_type_serializer, :args_serializer, :items_count def body From ca1a6b83136c57c3d29855cd2edfca2142c0f5a5 Mon Sep 17 00:00:00 2001 From: shaojunda Date: Fri, 27 Sep 2019 13:19:11 +0800 Subject: [PATCH 21/37] feat: change args type to string --- lib/ckb/types/script.rb | 10 +++++----- spec/ckb/types/script_spec.rb | 13 ++++++------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/lib/ckb/types/script.rb b/lib/ckb/types/script.rb index 242de549..9d229834 100644 --- a/lib/ckb/types/script.rb +++ b/lib/ckb/types/script.rb @@ -6,7 +6,7 @@ class Script attr_accessor :code_hash, :args, :hash_type # @param code_hash [String] - # @param args [String[]] + # @param args [String] # @param hash_type [String] data/type def initialize(code_hash:, args:, hash_type: "data") @code_hash = code_hash @@ -18,7 +18,9 @@ def initialize(code_hash:, args:, hash_type: "data") def calculate_bytesize bytesize = 1 bytesize += Utils.hex_to_bin(@code_hash).bytesize if @code_hash - (@args || []).map { |arg| Utils.hex_to_bin(arg).bytesize }.reduce(bytesize, &:+) + bytesize += Utils.hex_to_bin(args).bytesize if args + + bytesize end def to_h @@ -50,9 +52,7 @@ def compute_hash def self.generate_lock(target_pubkey_blake160, secp_cell_type_hash, hash_type = "type") new( code_hash: secp_cell_type_hash, - args: [ - target_pubkey_blake160 - ], + args: target_pubkey_blake160, hash_type: hash_type ) end diff --git a/spec/ckb/types/script_spec.rb b/spec/ckb/types/script_spec.rb index ea7f91fa..be247a0c 100644 --- a/spec/ckb/types/script_spec.rb +++ b/spec/ckb/types/script_spec.rb @@ -7,7 +7,7 @@ ) CKB::Types::Script.new( code_hash: code_hash, - args: [] + args: "0x" ) end @@ -27,9 +27,9 @@ end it "should build correct hash when there is only one arg" do - CKB::Types::Script.new( + script = CKB::Types::Script.new( code_hash: code_hash, - args: ["0x3954acece65096bfa81258983ddb83915fc56bd8"] + args: "0x3954acece65096bfa81258983ddb83915fc56bd8" ) expect( @@ -38,11 +38,10 @@ end it "should build correct hash when args more than one" do - CKB::Types::Script.new( + script = CKB::Types::Script.new( code_hash: code_hash, - args: ["0x3954acece65096bfa81258983ddb83915fc56bd8", "0x3954acece65096bfa81258983ddb83915fc56bd83232323"] + args: "0x3954acece65096bfa81258983ddb83915fc56bd83954acece65096bfa81258983ddb83915fc56bd8" ) - expect( script.compute_hash ).to eq api.compute_script_hash(script) @@ -51,7 +50,7 @@ context "calculate bytesize" do let(:code_hash) { "0x9e3b3557f11b2b3532ce352bfe8017e9fd11d154c4c7f9b7aaaa1e621b539a08" } - let(:args) { ["0x36c329ed630d6ce750712a477543672adab57f4c"] } + let(:args) { "0x36c329ed630d6ce750712a477543672adab57f4c" } let(:lock_script) do CKB::Types::Script.new( From 52eca197bbe667787dbffd17659531fb2612c61e Mon Sep 17 00:00:00 2001 From: shaojunda Date: Fri, 27 Sep 2019 14:18:45 +0800 Subject: [PATCH 22/37] chore: adjust tests --- spec/ckb/api_spec.rb | 23 +++++++++++------------ spec/ckb/rpc_spec.rb | 17 ++++++++--------- spec/ckb/types/output_spec.rb | 4 ++-- 3 files changed, 21 insertions(+), 23 deletions(-) diff --git a/spec/ckb/api_spec.rb b/spec/ckb/api_spec.rb index 37d1db5b..6df08c64 100644 --- a/spec/ckb/api_spec.rb +++ b/spec/ckb/api_spec.rb @@ -12,34 +12,33 @@ let(:block_h) do { uncles: [], proposals: [], - transactions: [{ hash: "0x8ad0468383d0085e26d9c3b9b648623e4194efc53a03b7cd1a79e92700687f1e", - version: "0x0", + transactions: [{ version: "0x0", cell_deps: [], header_deps: [], inputs: [{ previous_output: { tx_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", index: "0xffffffff" }, since: "0x1" }], outputs: [{ capacity: "0x2ca7071b9e", lock: { code_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", - args: [], + args: "0x", hash_type: "type" }, type: nil }], outputs_data: ["0x"], - witnesses: [{ data: %w[0x1892ea40d82b53c678ff88312450bbb17e164d7a3e0a90941aa58839f56f8df201 - 0x3954acece65096bfa81258983ddb83915fc56bd8] }] }], + witnesses: ["0x490000001000000030000000310000009bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce801140000003954acece65096bfa81258983ddb83915fc56bd8"], + hash: "0x249ba6cc038ccb16a18b1da03b994f87a6e32bf128b553a66a5805e9d6f36c50" }], header: { difficulty: "0x100", - hash: "0xd629a10a08fb0f43fcb97e948fc2b6eb70ebd28536490fe3864b0e40d08397d1", + hash: "0x358df0eb01609fe8631a8d666ab4fd3ffac4025b46f2fbafeb92783181e6ea80", number: "0x1", - parent_hash: "0x6944997e76680c03a7b30fa8b1d30da9e77685de5b28796898b05c6e6e3f9ace", - nonce: "0xd20cf913474dbf0e", - timestamp: "0x16d6731e6e1", - transactions_root: "0x761909b19c96df2b38283bcd6ddf7162a1947e3fad2be70c32f3c7596ddcfad3", + parent_hash: "0xe10b8035540bf0976aa991dbcc1dfb2237a81706e6848596aca8773a69efb85c", + nonce: "0x58df949326a72a42", + timestamp: "0x16d70d9f580", + transactions_root: "0x249ba6cc038ccb16a18b1da03b994f87a6e32bf128b553a66a5805e9d6f36c50", proposals_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", uncles_count: "0x0", uncles_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", version: "0x0", - witnesses_root: "0x4c1f2995e6507bd45f0295dd775b9d6c9cd21fc775f95582fe2a6ce0ed8ee00a", + witnesses_root: "0xbfdb7bd77c9be65784a070aef4b21628d930db5bcd6054d8856fd4c28c8aaa2a", epoch: "0x3e80001000000", - dao: "0x2c7ecb6d26870700f1d8f5e035872300683cb95e9a0000000094b5c67d7a0100" } } + dao: "0x2cd631702e870700a715aee035872300a804ad5e9a00000000ec1bc9857a0100" } } end it "genesis block" do diff --git a/spec/ckb/rpc_spec.rb b/spec/ckb/rpc_spec.rb index 8e385189..193e9e82 100644 --- a/spec/ckb/rpc_spec.rb +++ b/spec/ckb/rpc_spec.rb @@ -13,25 +13,24 @@ since: "0x1" }], outputs: [{ capacity: "0x2ca7071b9e", lock: { code_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", - args: [], + args: "0x", hash_type: "type" }, type: nil }], outputs_data: ["0x"], - witnesses: [{ data: %w[0x1892ea40d82b53c678ff88312450bbb17e164d7a3e0a90941aa58839f56f8df201 - 0x3954acece65096bfa81258983ddb83915fc56bd8] }]}], + witnesses: ["0x490000001000000030000000310000009bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce801140000003954acece65096bfa81258983ddb83915fc56bd8"]}], header: { difficulty: "0x100", number: "0x1", - parent_hash: "0x6944997e76680c03a7b30fa8b1d30da9e77685de5b28796898b05c6e6e3f9ace", - nonce: "0xd20cf913474dbf0e", - timestamp: "0x16d6731e6e1", - transactions_root: "0x761909b19c96df2b38283bcd6ddf7162a1947e3fad2be70c32f3c7596ddcfad3", + parent_hash: "0xe10b8035540bf0976aa991dbcc1dfb2237a81706e6848596aca8773a69efb85c", + nonce: "0x58df949326a72a42", + timestamp: "0x16d70d9f580", + transactions_root: "0x249ba6cc038ccb16a18b1da03b994f87a6e32bf128b553a66a5805e9d6f36c50", proposals_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", uncles_count: "0x0", uncles_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", version: "0x0", - witnesses_root: "0x4c1f2995e6507bd45f0295dd775b9d6c9cd21fc775f95582fe2a6ce0ed8ee00a", + witnesses_root: "0xbfdb7bd77c9be65784a070aef4b21628d930db5bcd6054d8856fd4c28c8aaa2a", epoch: "0x3e80001000000", - dao: "0x2c7ecb6d26870700f1d8f5e035872300683cb95e9a0000000094b5c67d7a0100" } } + dao: "0x2cd631702e870700a715aee035872300a804ad5e9a00000000ec1bc9857a0100" } } end let(:rpc) { CKB::RPC.new } let(:lock_hash) { "0xd0e22f863da970a3ff51a937ae78ba490bbdcede7272d658a053b9f80e30305d" } diff --git a/spec/ckb/types/output_spec.rb b/spec/ckb/types/output_spec.rb index 4f9e4cbd..14241085 100644 --- a/spec/ckb/types/output_spec.rb +++ b/spec/ckb/types/output_spec.rb @@ -3,7 +3,7 @@ { "capacity": "0x174876e800", "lock": { - "args": ["0x36c329ed630d6ce750712a477543672adab57f4c"], + "args": "0x36c329ed630d6ce750712a477543672adab57f4c", "code_hash": "0x28e83a1277d48add8e72fadaa9248559e1b632bab2bd60b27955ebc4c03800a5", "hash_type": "data" }, @@ -40,7 +40,7 @@ it "with type script" do type_script = CKB::Types::Script.new( - args: [], + args: "0x", code_hash: "0x9e3b3557f11b2b3532ce352bfe8017e9fd11d154c4c7f9b7aaaa1e621b539a08", ) output.instance_variable_set(:@type, type_script) From 3838fd8d709fae3e9d27b2ca0bebea0fc3a66dda Mon Sep 17 00:00:00 2001 From: shaojunda Date: Fri, 27 Sep 2019 15:43:14 +0800 Subject: [PATCH 23/37] feat: update witnesses type --- lib/ckb/types/transaction.rb | 11 +- lib/ckb/wallet.rb | 6 +- spec/ckb/types/transaction_spec.rb | 415 ++++++++++------------------- 3 files changed, 151 insertions(+), 281 deletions(-) diff --git a/lib/ckb/types/transaction.rb b/lib/ckb/types/transaction.rb index bc9b5300..f708ff45 100644 --- a/lib/ckb/types/transaction.rb +++ b/lib/ckb/types/transaction.rb @@ -39,15 +39,14 @@ def sign(key, tx_hash) raise "Invalid number of witnesses!" if witnesses.length < inputs.length signed_witnesses = witnesses.map do |witness| - old_data = witness.data || [] + old_datum = witness blake2b = CKB::Blake2b.new blake2b.update(Utils.hex_to_bin(tx_hash)) - old_data.each do |datum| - blake2b.update(Utils.hex_to_bin(datum)) - end + blake2b.update(Utils.hex_to_bin(old_datum)) message = blake2b.hexdigest - data = [key.sign_recoverable(message)] + old_data - Types::Witness.from_h(data: data) + data = key.sign_recoverable(message) + old_datum[2..-1] + + data end self.class.new( diff --git a/lib/ckb/wallet.rb b/lib/ckb/wallet.rb index 98149ca4..f30e845d 100644 --- a/lib/ckb/wallet.rb +++ b/lib/ckb/wallet.rb @@ -145,7 +145,7 @@ def deposit_to_dao(capacity, key: nil) lock: Types::Script.generate_lock(addr.blake160, code_hash, hash_type), type: Types::Script.new( code_hash: api.dao_code_hash, - args: [] + args: "0x" ) ) output_data = "0x" @@ -247,7 +247,7 @@ def generate_withdraw_from_dao_transaction(out_point, key: nil) outputs: outputs, outputs_data: outputs_data, witnesses: [ - Types::Witness.new(data: ["0x0000000000000000"]) + "0x0000000000000000" ] ) tx.sign(key, tx.compute_hash) @@ -305,7 +305,7 @@ def gather_inputs(capacity, min_capacity, min_change_capacity, fee) since: 0 ) inputs << input - witnesses << Types::Witness.new(data: []) + witnesses << "0x" input_capacities += cell.capacity.to_i diff = input_capacities - total_capacities diff --git a/spec/ckb/types/transaction_spec.rb b/spec/ckb/types/transaction_spec.rb index 682949d2..8940be65 100644 --- a/spec/ckb/types/transaction_spec.rb +++ b/spec/ckb/types/transaction_spec.rb @@ -1,118 +1,70 @@ +# frozen_string_literal: true + RSpec.describe CKB::Types::Transaction do let(:tx_to_sign_hash) do - { - "version": "0x0", - "cell_deps":[], - "header_deps":[], - "inputs": [ - { - "args": [], - "previous_output": { - "tx_hash": "0xa80a8e01d45b10e1cbc8a2557c62ba40edbdc36cd63a31fc717006ca7b157b50", - "index": "0x0" - }, - "since": "0x0" - } - ], - "outputs": [ - { - "capacity": "0x174876e800", - "lock": { - "code_hash": "0x9e3b3557f11b2b3532ce352bfe8017e9fd11d154c4c7f9b7aaaa1e621b539a08", - "args": [ - "0xe2193df51d78411601796b35b17b4f8f2cd85bd0" - ] - }, - "type": nil, - "data": "0x" - }, - { - "capacity": "0x474dec26800", - "lock": { - "code_hash": "0x9e3b3557f11b2b3532ce352bfe8017e9fd11d154c4c7f9b7aaaa1e621b539a08", - "args": [ - "0x36c329ed630d6ce750712a477543672adab57f4c" - ] - }, - "type": nil, - "data": "0x" - } - ], - "witnesses": [ - { - data: [] - } - ] - } + { version: "0x0", + cell_deps: [{ out_point: { tx_hash: "0xe7d5ddd093bcc5909a6f441882e58906062eaf66a6ac1bcf7d7411931bc9ab72", index: "0x0" }, + dep_type: "dep_group" }], + header_deps: [], + inputs: [{ previous_output: { tx_hash: "0x650b8f3fcb2627b5500c308a9b0485b806e256886c36d641517eec53707bbcf9", index: "0x0" }, + since: "0x0" }], + outputs: [{ capacity: "0x174876e800", + lock: { code_hash: "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + args: "0x59a27ef3ba84f061517d13f42cf44ed020610061", + hash_type: "type" }, + type: nil }, + { capacity: "0x182ca202c9", + lock: { code_hash: "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + args: "0x3954acece65096bfa81258983ddb83915fc56bd8", + hash_type: "type" }, + type: nil }], + outputs_data: %w[0x 0x], + witnesses: ["0x"] } end it "sign" do tx_to_sign = CKB::Types::Transaction.from_h(tx_to_sign_hash) - key = CKB::Key.new("0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3") - tx_hash = "0xac1bb95455cdfb89b6e977568744e09b6b80e08cab9477936a09c4ca07f5b8ab" + key = CKB::Key.new("0x845b781a1a094057b972714a2b09b85de4fc2eb205351c3e5179aabd264f3805") + tx_hash = "0x993e6e629be2f016bf72becaa9ad4b39f7fdd72357c9341335783f451010b94e" signed_tx = tx_to_sign.sign(key, tx_hash) expect(signed_tx.to_h[:hash]).to eq(tx_hash) - expect(signed_tx.to_h[:witnesses]).to eq([ - { - data: [ - "0x2c643579e47045be050d3842ed9270151af8885e33954bddad0e53e81d1c2dbe2dc637877a8302110846ebc6a16d9148c106e25f945063ad1c4d4db2b695240800", - ] - } - ]) + expect(signed_tx.to_h[:witnesses]).to eq(["0xf198c795adfc5aead05ad0ac9d979519b0a707e7987c5addb3a6be42669af7f86e3a76a3ce8c770a92915e2d5a0212b3417db1c2152f2107ee7683601a4ecb5001"]) end - context "sign with witness (dao tx)" do + context "multiple inputs sign" do let(:tx_to_sign_hash) do - { - version: "0x0", - cell_deps:[], - header_deps:[], - inputs: [ - { - previous_output: { - tx_hash: "0x91fcfd61f420c1090aeded6b6d91d5920a279fe53ec34353afccc59264eeddd4", - index: "0x0" - }, - since: "0x71" - }, - { - previous_output: { - tx_hash: "0x00000000000000000000000000004e4552564f5344414f494e50555430303031", - index: "0x0" - }, - since: "0x0" - } - ], - outputs: [ - { - capacity: "0x9184efca682", - lock: { - code_hash: "0xf1951123466e4479842387a66fabfd6b65fc87fd84ae8e6cd3053edb27fff2fd", - args: [ - "0x36c329ed630d6ce750712a477543672adab57f4c" - ] - }, - type: nil, - data: "0x" - } - ], - witnesses: [ - { - data: [ - "0x4107bd23eedb9f2a2a749108f6bb9720d745d50f044cc4814bafe189a01fe6fb" - ] - }, - { - data: [] - } - ] - } + { version: "0x0", + cell_deps: [{ out_point: { tx_hash: "0xe7d5ddd093bcc5909a6f441882e58906062eaf66a6ac1bcf7d7411931bc9ab72", index: "0x0" }, + dep_type: "dep_group" }], + header_deps: [], + inputs: [{ previous_output: { tx_hash: "0xa31b9b8d105c62d69b7fbfc09bd700f3a1d6659232ffcfaa12a048ee5d7b7f2d", index: "0x0" }, + since: "0x0" }, + { previous_output: { tx_hash: "0xec5e63e19ec0161092ba78a841e9ead5deb30e56c2d98752ed974f2f2b4aeff2", index: "0x0" }, + since: "0x0" }, + { previous_output: { tx_hash: "0x5ad2600cb884572f9d8f568822c0447f6f49eb63b53257c20d0d8559276bf4e2", index: "0x0" }, + since: "0x0" }, + { previous_output: { tx_hash: "0xf21e34224e90c1ab47f42e2977ea455445d22ba3aaeb4bd2fcb2075704f330ff", index: "0x0" }, + since: "0x0" }, + { previous_output: { tx_hash: "0xc8212696d516c63bced000d3008c4a8c27c72c03f4becb40f0bf24a31063271f", index: "0x0" }, + since: "0x0" }], + outputs: [{ capacity: "0xe8d4a51000", + lock: { code_hash: "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + args: "0x59a27ef3ba84f061517d13f42cf44ed020610061", + hash_type: "type" }, + type: nil }, + { capacity: "0x47345dea3", + lock: { code_hash: "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + args: "0x3954acece65096bfa81258983ddb83915fc56bd8", + hash_type: "type" }, + type: nil }], + outputs_data: %w[0x 0x], + witnesses: %w[0x 0x 0x 0x 0x] } end - let(:tx_hash) { "0x985772e541c23d4e7dbf9844a9b9d93fcdc62273fa1f4ae1ae82703962dc1a4e" } + let(:tx_hash) { "0x03aea57404a99c685b098b7ee96469f0c5db57fa49aaef27cf7c080960da4b19" } - let(:private_key) { "0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3" } + let(:private_key) { "0x845b781a1a094057b972714a2b09b85de4fc2eb205351c3e5179aabd264f3805" } let(:key) { CKB::Key.new(private_key) } it "sign" do @@ -120,176 +72,111 @@ signed_tx = tx_to_sign.sign(key, tx_hash) expect(signed_tx.hash).to eq tx_hash - expect(signed_tx.witnesses.map(&:to_h)).to eq([ - { - data: [ - "0x68a57373f4e98aecfb9501ec1cc4a78c048361332e4b6706bdc1469d30bd52ea42feca657dd1de1eff384e6ed24a6910b011d49d855bd1ed209f5ce77d8116ac01", - "0x4107bd23eedb9f2a2a749108f6bb9720d745d50f044cc4814bafe189a01fe6fb" - ] - }, - { - data: [ - "0x3b13c362f254e7becb0e731e4756e742bfddbf2f5d7c16cd609ba127d2b7e07f1d588c3a7132fc20c478e2de14f6370fbb9e4402d240e4b32c8d671177e1f31101" - ] - } - ]) + expect(signed_tx.witnesses).to eq(%w[0xc5fb0574026cb74a8633bc2c67a32db701025ea5e3f4438c713daaa31539183d719a079a06e426036fc95d5ac97bcde84374a4b7002480d63f1bfc7dc5ee0d4801 0xc5fb0574026cb74a8633bc2c67a32db701025ea5e3f4438c713daaa31539183d719a079a06e426036fc95d5ac97bcde84374a4b7002480d63f1bfc7dc5ee0d4801 0xc5fb0574026cb74a8633bc2c67a32db701025ea5e3f4438c713daaa31539183d719a079a06e426036fc95d5ac97bcde84374a4b7002480d63f1bfc7dc5ee0d4801 0xc5fb0574026cb74a8633bc2c67a32db701025ea5e3f4438c713daaa31539183d719a079a06e426036fc95d5ac97bcde84374a4b7002480d63f1bfc7dc5ee0d4801 0xc5fb0574026cb74a8633bc2c67a32db701025ea5e3f4438c713daaa31539183d719a079a06e426036fc95d5ac97bcde84374a4b7002480d63f1bfc7dc5ee0d4801]) end end context "generate tx_hash" do let(:specific_tx_h) do - { - :version=>"0x0", - :cell_deps=>[], - :header_deps=>[], - :inputs=> - [{:previous_output=> - {:tx_hash=>"0x0000000000000000000000000000000000000000000000000000000000000000", :index=>"0xffffffff"}, - :since=>"0x3e8"}], - :outputs=> - [{:capacity=>"0x1d37af3e8a", - :lock=> - {:code_hash=>"0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88", - :args=>["0x0001acc717d6424ee6efdd84e0c5befb8e44a89c"], - :hash_type=>"type"}, - :type=>nil}], - :outputs_data=>["0x48656c6c6f2c204b652057616e67212120456e6a6f7921"], - :witnesses=> - [{:data=> - ["0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e8801", "0x0001acc717d6424ee6efdd84e0c5befb8e44a89c"]}], - :hash=>"0xc6da9fd9f29b269b302b388f59329c16131c7f4487f5c59d01094bd5db7c9847" - } + { version: "0x0", + cell_deps: [], + header_deps: [], + inputs: [{ previous_output: { tx_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", index: "0xffffffff" }, + since: "0xa" }], + outputs: [{ capacity: "0x2ca7071b9e", + lock: { code_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", + args: "0x", + hash_type: "type" }, + type: nil }], + outputs_data: ["0x"], + witnesses: ["0x490000001000000030000000310000009bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce801140000003954acece65096bfa81258983ddb83915fc56bd8"], + hash: "0x1c9e75323c160a52e18b8e7deaa09b31af600e4e942c7fa4934059a8f4a64d61" } end let(:one_cell_dep_tx_h) do - { - :version=>"0x0", - :cell_deps=> - [{:out_point=>{:tx_hash=>"0xc12386705b5cbb312b693874f3edf45c43a274482e27b8df0fd80c8d3f5feb8b", :index=>"0x0"}, - :dep_type=>"dep_group"}], - :header_deps=>[], - :inputs=> - [{:previous_output=> - {:tx_hash=>"0x1a565d7d24705b65aea74e7c5cdbbdf43f00c1a0b9f7e11e4bde0f54321bb429", :index=>"0x1"}, - :since=>"0x0"}], - :outputs=> - [{:capacity=>"0x174876e800", - :lock=> - {:code_hash=>"0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88", - :args=>["0xf485c551e77fc77750115a36b7d2033fbab00951"], - :hash_type=>"type"}, - :type=>nil}, - {:capacity=>"0x59b2b07c8000", - :lock=> - {:code_hash=>"0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88", - :args=>["0x59a27ef3ba84f061517d13f42cf44ed020610061"], - :hash_type=>"type"}, - :type=>nil}], - :outputs_data=>["0x", "0x"], - :witnesses=> - [{:data=> - ["0x7d31e525720fd16d5500aad97f92ee87a97e9510259621c77776f75f8703b90618bd07ff2d5a447553df272d1203ce090dd11f236fbd60f992a49445ff09d8fd01"]}], - :hash=>"0x5cf2f68d5d22a0f58465564490a4fe4e88af2d1d3592c4033cb27a2450c6c27e" - } + { version: "0x0", + cell_deps: [{ out_point: { tx_hash: "0xe7d5ddd093bcc5909a6f441882e58906062eaf66a6ac1bcf7d7411931bc9ab72", index: "0x0" }, + dep_type: "dep_group" }], + header_deps: [], + inputs: [{ previous_output: { tx_hash: "0xa31b9b8d105c62d69b7fbfc09bd700f3a1d6659232ffcfaa12a048ee5d7b7f2d", index: "0x0" }, + since: "0x0" }, + { previous_output: { tx_hash: "0xec5e63e19ec0161092ba78a841e9ead5deb30e56c2d98752ed974f2f2b4aeff2", index: "0x0" }, + since: "0x0" }, + { previous_output: { tx_hash: "0x5ad2600cb884572f9d8f568822c0447f6f49eb63b53257c20d0d8559276bf4e2", index: "0x0" }, + since: "0x0" }, + { previous_output: { tx_hash: "0xf21e34224e90c1ab47f42e2977ea455445d22ba3aaeb4bd2fcb2075704f330ff", index: "0x0" }, + since: "0x0" }, + { previous_output: { tx_hash: "0xc8212696d516c63bced000d3008c4a8c27c72c03f4becb40f0bf24a31063271f", index: "0x0" }, + since: "0x0" }], + outputs: [{ capacity: "0xe8d4a51000", + lock: { code_hash: "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + args: "0x59a27ef3ba84f061517d13f42cf44ed020610061", + hash_type: "type" }, + type: nil }, + { capacity: "0x47345dea3", + lock: { code_hash: "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + args: "0x3954acece65096bfa81258983ddb83915fc56bd8", + hash_type: "type" }, + type: nil }], + outputs_data: %w[0x 0x], + witnesses: %w[0xc5fb0574026cb74a8633bc2c67a32db701025ea5e3f4438c713daaa31539183d719a079a06e426036fc95d5ac97bcde84374a4b7002480d63f1bfc7dc5ee0d4801 + 0xc5fb0574026cb74a8633bc2c67a32db701025ea5e3f4438c713daaa31539183d719a079a06e426036fc95d5ac97bcde84374a4b7002480d63f1bfc7dc5ee0d4801 + 0xc5fb0574026cb74a8633bc2c67a32db701025ea5e3f4438c713daaa31539183d719a079a06e426036fc95d5ac97bcde84374a4b7002480d63f1bfc7dc5ee0d4801 + 0xc5fb0574026cb74a8633bc2c67a32db701025ea5e3f4438c713daaa31539183d719a079a06e426036fc95d5ac97bcde84374a4b7002480d63f1bfc7dc5ee0d4801 + 0xc5fb0574026cb74a8633bc2c67a32db701025ea5e3f4438c713daaa31539183d719a079a06e426036fc95d5ac97bcde84374a4b7002480d63f1bfc7dc5ee0d4801], + hash: "0x03aea57404a99c685b098b7ee96469f0c5db57fa49aaef27cf7c080960da4b19" } end let(:multiple_cell_dep_tx_h) do - { - :version=>"0x0", - :cell_deps=> - [{:out_point=>{:tx_hash=>"0xc12386705b5cbb312b693874f3edf45c43a274482e27b8df0fd80c8d3f5feb8b", :index=>"0x0"}, - :dep_type=>"dep_group"}], - :header_deps=>[], - :inputs=> - [{:previous_output=> - {:tx_hash=>"0x1a565d7d24705b65aea74e7c5cdbbdf43f00c1a0b9f7e11e4bde0f54321bb429", :index=>"0x1"}, - :since=>"0x0"}], - :outputs=> - [{:capacity=>"0x174876e800", - :lock=> - {:code_hash=>"0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88", - :args=>["0xf485c551e77fc77750115a36b7d2033fbab00951"], - :hash_type=>"type"}, - :type=>nil}, - {:capacity=>"0x59b2b07c8000", - :lock=> - {:code_hash=>"0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88", - :args=>["0x59a27ef3ba84f061517d13f42cf44ed020610061"], - :hash_type=>"type"}, - :type=>nil}], - :outputs_data=>["0x", "0x"], - :witnesses=> - [{:data=> - ["0x7d31e525720fd16d5500aad97f92ee87a97e9510259621c77776f75f8703b90618bd07ff2d5a447553df272d1203ce090dd11f236fbd60f992a49445ff09d8fd01"]}], - :hash=>"0x5cf2f68d5d22a0f58465564490a4fe4e88af2d1d3592c4033cb27a2450c6c27e" - } - end - - let(:code_dep_type_tx_h) do - { - :version=>"0x0", - :cell_deps=> - [{:out_point=>{:tx_hash=>"0x0fb4945d52baf91e0dee2a686cdd9d84cad95b566a1d7409b970ee0a0f364f60", :index=>"0x2"}, - :dep_type=>"code"}, - {:out_point=>{:tx_hash=>"0xc12386705b5cbb312b693874f3edf45c43a274482e27b8df0fd80c8d3f5feb8b", :index=>"0x0"}, - :dep_type=>"dep_group"}], - :header_deps=> - ["0x28a548494dfc02a952f5ae25bf2886abb7ba5a8092bd139700641b4979a57217", "0x3bff5d655b9e309f0d0bfea2b792e720a88df702a5724dbb9beef92516827b3f"], - :inputs=> - [{:previous_output=> - {:tx_hash=>"0x9d1bf801b235ce62812844f01381a070c0cc72876364861e00492eac1d8b54e7", :index=>"0x0"}, - :since=>"0x108a0"}], - :outputs=> - [{:capacity=>"0x1768454ed7", - :lock=> - {:code_hash=>"0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88", - :args=>["0x59a27ef3ba84f061517d13f42cf44ed020610061"], - :hash_type=>"type"}, - :type=>nil}], - :outputs_data=>["0x"], - :witnesses=> - [{:data=> - ["0x25d094fdab0bfbb0261f4d665a340bfcfca1cc33be317b654dd1ea2a9c42b05847cfe13ce5eae67335858295e456ebc3d40bf44f98e862974799890d6401215300", - "0x0000000000000000"]}], - :hash=>"0x3d1624dada9eafe506f8d0a44531993a41a91b496e5ce3ea18e16322ec997944" - } + { version: "0x0", + cell_deps: [{ out_point: { tx_hash: "0xe7d5ddd093bcc5909a6f441882e58906062eaf66a6ac1bcf7d7411931bc9ab72", index: "0x0" }, + dep_type: "dep_group" }, + { out_point: { tx_hash: "0x50b9240d466800a6d0b2d07e10151b3a48f44c801a0f7f22e4e033419bd69b8e", index: "0x2" }, + dep_type: "code" }], + header_deps: [], + inputs: [{ previous_output: { tx_hash: "0x3c515d38292bff5068eeddc94fa4aaea0f60f78a9c565ea3fb5835c8c395febf", index: "0x0" }, + since: "0x0" }], + outputs: [{ capacity: "0x9502f9000", + lock: { code_hash: "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + args: "0x59a27ef3ba84f061517d13f42cf44ed020610061", + hash_type: "type" }, + type: { code_hash: "0x88af2314293c7799a11a8ce3b551fb632d5ffa21b42d04326b051f580ca55f6a", + args: "0x", + hash_type: "data" } }, + { capacity: "0xdf8475800", + lock: { code_hash: "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + args: "0x59a27ef3ba84f061517d13f42cf44ed020610061", + hash_type: "type" }, + type: nil }], + outputs_data: %w[0x 0x], + witnesses: ["0x7da70e8d0d529afb5f9193a5063463a757c305a4af0e882f6dbacc7cbe74096f1b14aabac84990e7902f28f40e2c8dd70f8dd06a600185c4e89090c25a7bf61700"], + hash: "0xb4d2204035bf8df2ecec1ef9b632b5fc91a245555a96eb0812ed0b29b3f4039a" } end let(:has_type_script_tx_h) do - { - :version=>"0x0", - :cell_deps=> - [{:out_point=>{:tx_hash=>"0xc12386705b5cbb312b693874f3edf45c43a274482e27b8df0fd80c8d3f5feb8b", :index=>"0x0"}, - :dep_type=>"dep_group"}, - {:out_point=>{:tx_hash=>"0x0fb4945d52baf91e0dee2a686cdd9d84cad95b566a1d7409b970ee0a0f364f60", :index=>"0x2"}, - :dep_type=>"code"}], - :header_deps=>[], - :inputs=> - [{:previous_output=> - {:tx_hash=>"0x31f695263423a4b05045dd25ce6692bb55d7bba2965d8be16b036e138e72cc65", :index=>"0x1"}, - :since=>"0x0"}], - :outputs=> - [{:capacity=>"0x174876e800", - :lock=> - {:code_hash=>"0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88", - :args=>["0x59a27ef3ba84f061517d13f42cf44ed020610061"], - :hash_type=>"type"}, - :type=> - {:code_hash=>"0xece45e0979030e2f8909f76258631c42333b1e906fd9701ec3600a464a90b8f6", - :args=>[], - :hash_type=>"data"}}, - {:capacity=>"0x59e1416a5000", - :lock=> - {:code_hash=>"0x68d5438ac952d2f584abf879527946a537e82c7f3c1cbf6d8ebf9767437d8e88", - :args=>["0x59a27ef3ba84f061517d13f42cf44ed020610061"], - :hash_type=>"type"}, - :type=>nil}], - :outputs_data=>["0x", "0x"], - :witnesses=> - [{:data=> - ["0x82df73581bcd08cb9aa270128d15e79996229ce8ea9e4f985b49fbf36762c5c37936caf3ea3784ee326f60b8992924fcf496f9503c907982525a3436f01ab32900"]}], - :hash=>"0x09ce2223304a5f48d5ce2b6ee2777d96503591279671460fa39ae894ea9e2b87" - } + { version: "0x0", + cell_deps: [{ out_point: { tx_hash: "0xe7d5ddd093bcc5909a6f441882e58906062eaf66a6ac1bcf7d7411931bc9ab72", index: "0x0" }, + dep_type: "dep_group" }, + { out_point: { tx_hash: "0x50b9240d466800a6d0b2d07e10151b3a48f44c801a0f7f22e4e033419bd69b8e", index: "0x2" }, + dep_type: "code" }], + header_deps: [], + inputs: [{ previous_output: { tx_hash: "0x3c515d38292bff5068eeddc94fa4aaea0f60f78a9c565ea3fb5835c8c395febf", index: "0x0" }, + since: "0x0" }], + outputs: [{ capacity: "0x9502f9000", + lock: { code_hash: "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + args: "0x59a27ef3ba84f061517d13f42cf44ed020610061", + hash_type: "type" }, + type: { code_hash: "0x88af2314293c7799a11a8ce3b551fb632d5ffa21b42d04326b051f580ca55f6a", + args: "0x", + hash_type: "data" } }, + { capacity: "0xdf8475800", + lock: { code_hash: "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + args: "0x59a27ef3ba84f061517d13f42cf44ed020610061", + hash_type: "type" }, + type: nil }], + outputs_data: %w[0x 0x], + witnesses: ["0x7da70e8d0d529afb5f9193a5063463a757c305a4af0e882f6dbacc7cbe74096f1b14aabac84990e7902f28f40e2c8dd70f8dd06a600185c4e89090c25a7bf61700"], + hash: "0xb4d2204035bf8df2ecec1ef9b632b5fc91a245555a96eb0812ed0b29b3f4039a" } end it "should build correct hash for specific transaction" do @@ -316,14 +203,6 @@ ).to eq tx.hash end - it "should build correct hash when has dep_type is code cell_dep" do - tx = CKB::Types::Transaction.from_h(code_dep_type_tx_h) - - expect( - tx.compute_hash - ).to eq tx.hash - end - it "should build correct hash when has type script" do tx = CKB::Types::Transaction.from_h(has_type_script_tx_h) @@ -363,14 +242,6 @@ ).to eq api.compute_transaction_hash(tx) end - it "should build correct hash when has dep_type is code cell_dep" do - tx = CKB::Types::Transaction.from_h(code_dep_type_tx_h) - - expect( - tx.compute_hash - ).to eq api.compute_transaction_hash(tx) - end - it "should build correct hash when has type script" do tx = CKB::Types::Transaction.from_h(has_type_script_tx_h) From be07b5bc85b89a450252b95eb8c72f35e4aa0d7c Mon Sep 17 00:00:00 2001 From: shaojunda Date: Fri, 27 Sep 2019 17:14:40 +0800 Subject: [PATCH 24/37] chore: add more test --- spec/ckb/types/transaction_spec.rb | 60 ++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/spec/ckb/types/transaction_spec.rb b/spec/ckb/types/transaction_spec.rb index 8940be65..3cb40b37 100644 --- a/spec/ckb/types/transaction_spec.rb +++ b/spec/ckb/types/transaction_spec.rb @@ -22,6 +22,27 @@ witnesses: ["0x"] } end + let(:tx_to_sign_hash_use_data_hash) do + { version: "0x0", + cell_deps: [{ out_point: { tx_hash: "0xa76801d09a0eabbfa545f1577084b6f3bafb0b6250e7f5c89efcfd4e3499fb55", index: "0x1" }, + dep_type: "code" }], + header_deps: [], + inputs: [{ previous_output: { tx_hash: "0xa80a8e01d45b10e1cbc8a2557c62ba40edbdc36cd63a31fc717006ca7b157b50", index: "0x0" }, + since: "0x0" }], + outputs: [{ capacity: "0x174876e800", + lock: { code_hash: "0x9e3b3557f11b2b3532ce352bfe8017e9fd11d154c4c7f9b7aaaa1e621b539a08", + args: "0xe2193df51d78411601796b35b17b4f8f2cd85bd0", + hash_type: "data" }, + type: nil }, + { capacity: "0x474dec26800", + lock: { code_hash: "0x9e3b3557f11b2b3532ce352bfe8017e9fd11d154c4c7f9b7aaaa1e621b539a08", + args: "0x36c329ed630d6ce750712a477543672adab57f4c", + hash_type: "data" }, + type: nil }], + outputs_data: %w[0x 0x], + witnesses: ["0x"] } + end + it "sign" do tx_to_sign = CKB::Types::Transaction.from_h(tx_to_sign_hash) key = CKB::Key.new("0x845b781a1a094057b972714a2b09b85de4fc2eb205351c3e5179aabd264f3805") @@ -32,6 +53,16 @@ expect(signed_tx.to_h[:witnesses]).to eq(["0xf198c795adfc5aead05ad0ac9d979519b0a707e7987c5addb3a6be42669af7f86e3a76a3ce8c770a92915e2d5a0212b3417db1c2152f2107ee7683601a4ecb5001"]) end + it "sign with data hash" do + tx_to_sign = CKB::Types::Transaction.from_h(tx_to_sign_hash_use_data_hash) + key = CKB::Key.new("0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3") + tx_hash = tx_to_sign.compute_hash + signed_tx = tx_to_sign.sign(key, tx_hash) + + expect(signed_tx.to_h[:hash]).to eq(tx_hash) + expect(signed_tx.to_h[:witnesses]).to eq(["0x15edb4da91bd5beebf0aee82a9daa4d590ecdfc0895c6b010638573b2d1d502c50373e7d540e74eb8e3a3bd1dbd20c372c492fc7242592c8a04763be029325a900"]) + end + context "multiple inputs sign" do let(:tx_to_sign_hash) do { version: "0x0", @@ -74,6 +105,35 @@ expect(signed_tx.hash).to eq tx_hash expect(signed_tx.witnesses).to eq(%w[0xc5fb0574026cb74a8633bc2c67a32db701025ea5e3f4438c713daaa31539183d719a079a06e426036fc95d5ac97bcde84374a4b7002480d63f1bfc7dc5ee0d4801 0xc5fb0574026cb74a8633bc2c67a32db701025ea5e3f4438c713daaa31539183d719a079a06e426036fc95d5ac97bcde84374a4b7002480d63f1bfc7dc5ee0d4801 0xc5fb0574026cb74a8633bc2c67a32db701025ea5e3f4438c713daaa31539183d719a079a06e426036fc95d5ac97bcde84374a4b7002480d63f1bfc7dc5ee0d4801 0xc5fb0574026cb74a8633bc2c67a32db701025ea5e3f4438c713daaa31539183d719a079a06e426036fc95d5ac97bcde84374a4b7002480d63f1bfc7dc5ee0d4801 0xc5fb0574026cb74a8633bc2c67a32db701025ea5e3f4438c713daaa31539183d719a079a06e426036fc95d5ac97bcde84374a4b7002480d63f1bfc7dc5ee0d4801]) end + + let(:tx_to_sign_hash_use_data_hash) do + { version: "0x0", + cell_deps: [{ out_point: { tx_hash: "0xa76801d09a0eabbfa545f1577084b6f3bafb0b6250e7f5c89efcfd4e3499fb55", index: "0x1" }, + dep_type: "code" }], + header_deps: [], + inputs: [{ previous_output: { tx_hash: "0x91fcfd61f420c1090aeded6b6d91d5920a279fe53ec34353afccc59264eeddd4", index: "0x0" }, + since: "0x71" }, + { previous_output: { tx_hash: "0x00000000000000000000000000004e4552564f5344414f494e50555430303031", index: "0x0" }, + since: "0x0" } + ], + outputs: [{ capacity: "0x9184efca682", + lock: { code_hash: "0xf1951123466e4479842387a66fabfd6b65fc87fd84ae8e6cd3053edb27fff2fd", + args: "0x36c329ed630d6ce750712a477543672adab57f4c", + hash_type: "data" }, + type: nil }], + outputs_data: %w[0x], + witnesses: %w(0x4107bd23eedb9f2a2a749108f6bb9720d745d50f044cc4814bafe189a01fe6fb 0x)} + end + + it "sign2" do + tx_to_sign = CKB::Types::Transaction.from_h(tx_to_sign_hash_use_data_hash) + key = CKB::Key.new("0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3") + tx_hash = tx_to_sign.compute_hash + signed_tx = tx_to_sign.sign(key, tx_hash) + + expect(signed_tx.to_h[:hash]).to eq(tx_hash) + expect(signed_tx.to_h[:witnesses]).to eq(["0x2db8278bf806fb7eac778e56eb0b34deccb16bae68c2a088d277bded265d90da37fb995a1f629a9de7c9722640f2f9c67c5572e6b5fca1e831649484ba9a0b81004107bd23eedb9f2a2a749108f6bb9720d745d50f044cc4814bafe189a01fe6fb", "0x014de9c721a5a33435a02d44580978ecdb794d2a7f3fe7d875e7f058ef8c961f2e983079400cfd8a2bbe34f2d1fd3f0a6e2c390bf7e45006c06c7831e4a67e8101"]) + end end context "generate tx_hash" do From 5508b9e41514b4d0183da3a37a9999a77a7fb99e Mon Sep 17 00:00:00 2001 From: shaojunda Date: Sun, 29 Sep 2019 10:10:27 +0800 Subject: [PATCH 25/37] feat: remove uncles_count from block header --- lib/ckb/types/block_header.rb | 7 +------ spec/ckb/api_spec.rb | 1 - spec/ckb/rpc_spec.rb | 1 - spec/ckb/types/block_header_spec.rb | 5 ++--- spec/ckb/types/block_spec.rb | 1 - spec/ckb/types/uncle_template_spec.rb | 1 - 6 files changed, 3 insertions(+), 13 deletions(-) diff --git a/lib/ckb/types/block_header.rb b/lib/ckb/types/block_header.rb index ce818544..1c425cac 100644 --- a/lib/ckb/types/block_header.rb +++ b/lib/ckb/types/block_header.rb @@ -4,7 +4,7 @@ module CKB module Types class BlockHeader attr_accessor :difficulty, :hash, :number, :parent_hash, :nonce, :timestamp, :transactions_root, :proposals_hash, \ - :uncles_count, :uncles_hash, :version, :witnesses_root, :epoch, :dao + :uncles_hash, :version, :witnesses_root, :epoch, :dao # @param difficulty [String | Integer] integer or hex number # @param hash [String] 0x... @@ -14,7 +14,6 @@ class BlockHeader # @param timestamp [String | Integer] integer or hex number # @param transactions_root [String] 0x... # @param proposals_hash [String] 0x... - # @param uncles_count [String | Integer] integer or hex number # @param uncles_hash [String] 0x... # @param version [String | Integer] integer or hex number # @param witnesses_root [String] 0x... @@ -29,7 +28,6 @@ def initialize( timestamp:, transactions_root:, proposals_hash:, - uncles_count:, uncles_hash:, version:, witnesses_root:, @@ -44,7 +42,6 @@ def initialize( @timestamp = Utils.to_int(timestamp) @transactions_root = transactions_root @proposals_hash = proposals_hash - @uncles_count = Utils.to_int(uncles_count) @uncles_hash = uncles_hash @version = Utils.to_int(version) @witnesses_root = witnesses_root @@ -62,7 +59,6 @@ def to_h timestamp: Utils.to_hex(@timestamp), transactions_root: @transactions_root, proposals_hash: @proposals_hash, - uncles_count: Utils.to_hex(@uncles_count), uncles_hash: @uncles_hash, version: Utils.to_hex(@version), witnesses_root: @witnesses_root, @@ -83,7 +79,6 @@ def self.from_h(hash) timestamp: hash[:timestamp], transactions_root: hash[:transactions_root], proposals_hash: hash[:proposals_hash], - uncles_count: hash[:uncles_count], uncles_hash: hash[:uncles_hash], version: hash[:version], witnesses_root: hash[:witnesses_root], diff --git a/spec/ckb/api_spec.rb b/spec/ckb/api_spec.rb index 6df08c64..580c0fa0 100644 --- a/spec/ckb/api_spec.rb +++ b/spec/ckb/api_spec.rb @@ -33,7 +33,6 @@ timestamp: "0x16d70d9f580", transactions_root: "0x249ba6cc038ccb16a18b1da03b994f87a6e32bf128b553a66a5805e9d6f36c50", proposals_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", - uncles_count: "0x0", uncles_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", version: "0x0", witnesses_root: "0xbfdb7bd77c9be65784a070aef4b21628d930db5bcd6054d8856fd4c28c8aaa2a", diff --git a/spec/ckb/rpc_spec.rb b/spec/ckb/rpc_spec.rb index 193e9e82..dd12af27 100644 --- a/spec/ckb/rpc_spec.rb +++ b/spec/ckb/rpc_spec.rb @@ -25,7 +25,6 @@ timestamp: "0x16d70d9f580", transactions_root: "0x249ba6cc038ccb16a18b1da03b994f87a6e32bf128b553a66a5805e9d6f36c50", proposals_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", - uncles_count: "0x0", uncles_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", version: "0x0", witnesses_root: "0xbfdb7bd77c9be65784a070aef4b21628d930db5bcd6054d8856fd4c28c8aaa2a", diff --git a/spec/ckb/types/block_header_spec.rb b/spec/ckb/types/block_header_spec.rb index d516c4f0..51d937ba 100644 --- a/spec/ckb/types/block_header_spec.rb +++ b/spec/ckb/types/block_header_spec.rb @@ -11,7 +11,6 @@ "proposals_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "timestamp": "0x5cd2b117", "transactions_root": "0x8ad0468383d0085e26d9c3b9b648623e4194efc53a03b7cd1a79e92700687f1e", - "uncles_count": "0x0", "uncles_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "version": "0x0", "witnesses_root": "0x90445a0795a2d7d4af033ec0282a8a1f68f11ffb1cd091b95c2c5515a8336e9c" @@ -22,7 +21,7 @@ it "from_h" do expect(block_header).to be_a(CKB::Types::BlockHeader) - number_keys = %i(difficulty epoch nonce number timestamp uncles_count version) + number_keys = %i(difficulty epoch nonce number timestamp version) number_keys.each do |key| expect(block_header.public_send(key)).to eq block_header_h[key].hex end @@ -42,7 +41,7 @@ api = CKB::API.new tip_header = api.get_tip_header - expected_attributes = %w(dao difficulty epoch hash nonce number parent_hash proposals_hash timestamp transactions_root uncles_count uncles_hash version witnesses_root) + expected_attributes = %w(dao difficulty epoch hash nonce number parent_hash proposals_hash timestamp transactions_root uncles_hash version witnesses_root) expect(expected_attributes).to eq(tip_header.instance_variables.map { |attribute| attribute.to_s.gsub("@", "") }.sort) end diff --git a/spec/ckb/types/block_spec.rb b/spec/ckb/types/block_spec.rb index 086b2ecd..50a32eee 100644 --- a/spec/ckb/types/block_spec.rb +++ b/spec/ckb/types/block_spec.rb @@ -12,7 +12,6 @@ "proposals_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "timestamp": "0x5cd2b117", "transactions_root": "0x8ad0468383d0085e26d9c3b9b648623e4194efc53a03b7cd1a79e92700687f1e", - "uncles_count": "0x0", "uncles_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "version": "0x0", "witnesses_root": "0x90445a0795a2d7d4af033ec0282a8a1f68f11ffb1cd091b95c2c5515a8336e9c" diff --git a/spec/ckb/types/uncle_template_spec.rb b/spec/ckb/types/uncle_template_spec.rb index 269e0aff..72704e28 100644 --- a/spec/ckb/types/uncle_template_spec.rb +++ b/spec/ckb/types/uncle_template_spec.rb @@ -15,7 +15,6 @@ :proposals_hash=>"0x0000000000000000000000000000000000000000000000000000000000000000", :timestamp=>"0x5cd2b117", :transactions_root=>"0x8ad0468383d0085e26d9c3b9b648623e4194efc53a03b7cd1a79e92700687f1e", - :uncles_count=>"0x0", :uncles_hash=>"0x0000000000000000000000000000000000000000000000000000000000000000", :version=>"0x0", :witnesses_root=>"0x90445a0795a2d7d4af033ec0282a8a1f68f11ffb1cd091b95c2c5515a8336e9c" From ca6417f34737bd9fb2d3c00c1f5b018b4c862dd0 Mon Sep 17 00:00:00 2001 From: shaojunda Date: Sun, 29 Sep 2019 10:31:50 +0800 Subject: [PATCH 26/37] feat: remove witnesses_root from block header --- lib/ckb/types/block_header.rb | 7 +------ spec/ckb/api_spec.rb | 1 - spec/ckb/rpc_spec.rb | 1 - spec/ckb/types/block_header_spec.rb | 3 +-- spec/ckb/types/block_spec.rb | 1 - spec/ckb/types/uncle_template_spec.rb | 1 - 6 files changed, 2 insertions(+), 12 deletions(-) diff --git a/lib/ckb/types/block_header.rb b/lib/ckb/types/block_header.rb index 1c425cac..ef67429b 100644 --- a/lib/ckb/types/block_header.rb +++ b/lib/ckb/types/block_header.rb @@ -4,7 +4,7 @@ module CKB module Types class BlockHeader attr_accessor :difficulty, :hash, :number, :parent_hash, :nonce, :timestamp, :transactions_root, :proposals_hash, \ - :uncles_hash, :version, :witnesses_root, :epoch, :dao + :uncles_hash, :version, :epoch, :dao # @param difficulty [String | Integer] integer or hex number # @param hash [String] 0x... @@ -16,7 +16,6 @@ class BlockHeader # @param proposals_hash [String] 0x... # @param uncles_hash [String] 0x... # @param version [String | Integer] integer or hex number - # @param witnesses_root [String] 0x... # @param epoch [String | Integer] integer or hex number # @param dao [String] 0x... def initialize( @@ -30,7 +29,6 @@ def initialize( proposals_hash:, uncles_hash:, version:, - witnesses_root:, epoch:, dao: ) @@ -44,7 +42,6 @@ def initialize( @proposals_hash = proposals_hash @uncles_hash = uncles_hash @version = Utils.to_int(version) - @witnesses_root = witnesses_root @epoch = Utils.to_int(epoch) @dao = dao end @@ -61,7 +58,6 @@ def to_h proposals_hash: @proposals_hash, uncles_hash: @uncles_hash, version: Utils.to_hex(@version), - witnesses_root: @witnesses_root, epoch: Utils.to_hex(@epoch), dao: @dao, } @@ -81,7 +77,6 @@ def self.from_h(hash) proposals_hash: hash[:proposals_hash], uncles_hash: hash[:uncles_hash], version: hash[:version], - witnesses_root: hash[:witnesses_root], epoch: hash[:epoch], dao: hash[:dao], ) diff --git a/spec/ckb/api_spec.rb b/spec/ckb/api_spec.rb index 580c0fa0..97f425da 100644 --- a/spec/ckb/api_spec.rb +++ b/spec/ckb/api_spec.rb @@ -35,7 +35,6 @@ proposals_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", uncles_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", version: "0x0", - witnesses_root: "0xbfdb7bd77c9be65784a070aef4b21628d930db5bcd6054d8856fd4c28c8aaa2a", epoch: "0x3e80001000000", dao: "0x2cd631702e870700a715aee035872300a804ad5e9a00000000ec1bc9857a0100" } } end diff --git a/spec/ckb/rpc_spec.rb b/spec/ckb/rpc_spec.rb index dd12af27..72263d40 100644 --- a/spec/ckb/rpc_spec.rb +++ b/spec/ckb/rpc_spec.rb @@ -27,7 +27,6 @@ proposals_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", uncles_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", version: "0x0", - witnesses_root: "0xbfdb7bd77c9be65784a070aef4b21628d930db5bcd6054d8856fd4c28c8aaa2a", epoch: "0x3e80001000000", dao: "0x2cd631702e870700a715aee035872300a804ad5e9a00000000ec1bc9857a0100" } } end diff --git a/spec/ckb/types/block_header_spec.rb b/spec/ckb/types/block_header_spec.rb index 51d937ba..d8f3711d 100644 --- a/spec/ckb/types/block_header_spec.rb +++ b/spec/ckb/types/block_header_spec.rb @@ -13,7 +13,6 @@ "transactions_root": "0x8ad0468383d0085e26d9c3b9b648623e4194efc53a03b7cd1a79e92700687f1e", "uncles_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "version": "0x0", - "witnesses_root": "0x90445a0795a2d7d4af033ec0282a8a1f68f11ffb1cd091b95c2c5515a8336e9c" } end @@ -41,7 +40,7 @@ api = CKB::API.new tip_header = api.get_tip_header - expected_attributes = %w(dao difficulty epoch hash nonce number parent_hash proposals_hash timestamp transactions_root uncles_hash version witnesses_root) + expected_attributes = %w(dao difficulty epoch hash nonce number parent_hash proposals_hash timestamp transactions_root uncles_hash version) expect(expected_attributes).to eq(tip_header.instance_variables.map { |attribute| attribute.to_s.gsub("@", "") }.sort) end diff --git a/spec/ckb/types/block_spec.rb b/spec/ckb/types/block_spec.rb index 50a32eee..402651bf 100644 --- a/spec/ckb/types/block_spec.rb +++ b/spec/ckb/types/block_spec.rb @@ -14,7 +14,6 @@ "transactions_root": "0x8ad0468383d0085e26d9c3b9b648623e4194efc53a03b7cd1a79e92700687f1e", "uncles_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "version": "0x0", - "witnesses_root": "0x90445a0795a2d7d4af033ec0282a8a1f68f11ffb1cd091b95c2c5515a8336e9c" }, "proposals": [], "transactions": [ diff --git a/spec/ckb/types/uncle_template_spec.rb b/spec/ckb/types/uncle_template_spec.rb index 72704e28..5cc3200e 100644 --- a/spec/ckb/types/uncle_template_spec.rb +++ b/spec/ckb/types/uncle_template_spec.rb @@ -17,7 +17,6 @@ :transactions_root=>"0x8ad0468383d0085e26d9c3b9b648623e4194efc53a03b7cd1a79e92700687f1e", :uncles_hash=>"0x0000000000000000000000000000000000000000000000000000000000000000", :version=>"0x0", - :witnesses_root=>"0x90445a0795a2d7d4af033ec0282a8a1f68f11ffb1cd091b95c2c5515a8336e9c" } } end From a88ef6ba9be7b4b70dc187ef6ca93bd975609b83 Mon Sep 17 00:00:00 2001 From: shaojunda Date: Sun, 29 Sep 2019 11:01:45 +0800 Subject: [PATCH 27/37] feat: replace difficulty with compact_target --- lib/ckb/types/block_header.rb | 12 ++++++------ lib/ckb/types/block_template.rb | 12 ++++++------ lib/ckb/types/epoch.rb | 12 ++++++------ spec/ckb/api_spec.rb | 12 ++++++------ spec/ckb/rpc_spec.rb | 13 +++++++------ spec/ckb/types/block_header_spec.rb | 6 +++--- spec/ckb/types/block_spec.rb | 2 +- spec/ckb/types/block_template_spec.rb | 6 +++--- spec/ckb/types/epoch_spec.rb | 2 +- spec/ckb/types/uncle_template_spec.rb | 2 +- 10 files changed, 40 insertions(+), 39 deletions(-) diff --git a/lib/ckb/types/block_header.rb b/lib/ckb/types/block_header.rb index ef67429b..00dba56d 100644 --- a/lib/ckb/types/block_header.rb +++ b/lib/ckb/types/block_header.rb @@ -3,10 +3,10 @@ module CKB module Types class BlockHeader - attr_accessor :difficulty, :hash, :number, :parent_hash, :nonce, :timestamp, :transactions_root, :proposals_hash, \ + attr_accessor :compact_target, :hash, :number, :parent_hash, :nonce, :timestamp, :transactions_root, :proposals_hash, \ :uncles_hash, :version, :epoch, :dao - # @param difficulty [String | Integer] integer or hex number + # @param compact_target [String | Integer] integer or hex number # @param hash [String] 0x... # @param number [String | Integer] integer or hex number # @param parent_hash [String] 0x... @@ -19,7 +19,7 @@ class BlockHeader # @param epoch [String | Integer] integer or hex number # @param dao [String] 0x... def initialize( - difficulty:, + compact_target:, hash:, number:, parent_hash:, @@ -32,7 +32,7 @@ def initialize( epoch:, dao: ) - @difficulty = Utils.to_int(difficulty) + @compact_target = Utils.to_int(compact_target) @hash = hash @number = Utils.to_int(number) @parent_hash = parent_hash @@ -48,7 +48,7 @@ def initialize( def to_h { - difficulty: Utils.to_hex(@difficulty), + compact_target: Utils.to_hex(@compact_target), hash: @hash, number: Utils.to_hex(@number), parent_hash: parent_hash, @@ -67,7 +67,7 @@ def self.from_h(hash) return if hash.nil? new( - difficulty: hash[:difficulty], + compact_target: hash[:compact_target], hash: hash[:hash], number: hash[:number], parent_hash: hash[:parent_hash], diff --git a/lib/ckb/types/block_template.rb b/lib/ckb/types/block_template.rb index 996d1eb9..deb0f130 100644 --- a/lib/ckb/types/block_template.rb +++ b/lib/ckb/types/block_template.rb @@ -3,11 +3,11 @@ module CKB module Types class BlockTemplate - attr_accessor :version, :difficulty, :current_time, :number, :epoch, :parent_hash, :cycles_limit, + attr_accessor :version, :compact_target, :current_time, :number, :epoch, :parent_hash, :cycles_limit, :bytes_limit, :uncles_count_limit, :uncles, :transactions, :proposals, :cellbase, :work_id, :dao # @param version [String | Integer] integer or hex number - # @param difficulty [String | Integer] integer or hex number + # @param compact_target [String | Integer] integer or hex number # @param current_time [String | Integer] integer or hex number # @param number [String | Integer] integer or hex number # @param epoch [String | Integer] integer or hex number @@ -23,7 +23,7 @@ class BlockTemplate # @param dao [String] 0x... def initialize( version:, - difficulty:, + compact_target:, current_time:, number:, epoch:, @@ -39,7 +39,7 @@ def initialize( dao: ) @version = Utils.to_int(version) - @difficulty = Utils.to_int(difficulty) + @compact_target = Utils.to_int(compact_target) @current_time = Utils.to_int(current_time) @number = Utils.to_int(number) @epoch = Utils.to_int(epoch) @@ -58,7 +58,7 @@ def initialize( def to_h { version: Utils.to_hex(version), - difficulty: Utils.to_hex(difficulty), + compact_target: Utils.to_hex(compact_target), current_time: Utils.to_hex(current_time), number: Utils.to_hex(number), epoch: Utils.to_hex(epoch), @@ -80,7 +80,7 @@ def self.from_h(hash) new( version: hash[:version], - difficulty: hash[:difficulty], + compact_target: hash[:compact_target], current_time: hash[:current_time], number: hash[:number], epoch: hash[:epoch], diff --git a/lib/ckb/types/epoch.rb b/lib/ckb/types/epoch.rb index 62ecee75..99656b3e 100644 --- a/lib/ckb/types/epoch.rb +++ b/lib/ckb/types/epoch.rb @@ -3,19 +3,19 @@ module CKB module Types class Epoch - attr_accessor :difficulty, :length, :number, :start_number + attr_accessor :compact_target, :length, :number, :start_number - # @param difficulty [String | Integer] integer or hex number + # @param compact_target [String | Integer] integer or hex number # @param length [String | Integer] integer or hex number # @param number [String | Integer] integer or hex number # @param start_number [String | Integer] integer or hex number def initialize( - difficulty:, + compact_target:, length:, number:, start_number: ) - @difficulty = Utils.to_int(difficulty) + @compact_target = Utils.to_int(compact_target) @length = Utils.to_int(length) @number = Utils.to_int(number) @start_number = Utils.to_int(start_number) @@ -23,7 +23,7 @@ def initialize( def to_h { - difficulty: Utils.to_hex(@difficulty), + compact_target: Utils.to_hex(@compact_target), length: Utils.to_hex(@length), number: Utils.to_hex(@number), start_number: Utils.to_hex(@start_number) @@ -34,7 +34,7 @@ def self.from_h(hash) return if hash.nil? new( - difficulty: hash[:difficulty], + compact_target: hash[:compact_target], length: hash[:length], number: hash[:number], start_number: hash[:start_number] diff --git a/spec/ckb/api_spec.rb b/spec/ckb/api_spec.rb index 97f425da..1d3107ef 100644 --- a/spec/ckb/api_spec.rb +++ b/spec/ckb/api_spec.rb @@ -25,13 +25,13 @@ outputs_data: ["0x"], witnesses: ["0x490000001000000030000000310000009bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce801140000003954acece65096bfa81258983ddb83915fc56bd8"], hash: "0x249ba6cc038ccb16a18b1da03b994f87a6e32bf128b553a66a5805e9d6f36c50" }], - header: { difficulty: "0x100", - hash: "0x358df0eb01609fe8631a8d666ab4fd3ffac4025b46f2fbafeb92783181e6ea80", + header: { compact_target: "0x20010000", + hash: "0x22946a72d17b745d950ae1b67326d77f708ba5c0411cbf424c7f4df04c1ac317", number: "0x1", - parent_hash: "0xe10b8035540bf0976aa991dbcc1dfb2237a81706e6848596aca8773a69efb85c", - nonce: "0x58df949326a72a42", - timestamp: "0x16d70d9f580", - transactions_root: "0x249ba6cc038ccb16a18b1da03b994f87a6e32bf128b553a66a5805e9d6f36c50", + parent_hash: "0x70396940ae2e81bd2627a8e0e75f3d277585bb1afd78839cfd8f2c54e8697bbc", + nonce: "0x3a7937c78d7ae069", + timestamp: "0x16d7ad5d9de", + transactions_root: "0xfcf1ec1c5da7f80b23ad81e72885d381ee04ad58c79003100d38ad285ae44959", proposals_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", uncles_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", version: "0x0", diff --git a/spec/ckb/rpc_spec.rb b/spec/ckb/rpc_spec.rb index 72263d40..0f866015 100644 --- a/spec/ckb/rpc_spec.rb +++ b/spec/ckb/rpc_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + RSpec.describe CKB::RPC do before do skip "not test rpc" if ENV["SKIP_RPC_TESTS"] @@ -17,13 +18,13 @@ hash_type: "type" }, type: nil }], outputs_data: ["0x"], - witnesses: ["0x490000001000000030000000310000009bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce801140000003954acece65096bfa81258983ddb83915fc56bd8"]}], - header: { difficulty: "0x100", + witnesses: ["0x490000001000000030000000310000009bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce801140000003954acece65096bfa81258983ddb83915fc56bd8"] }], + header: { compact_target: "0x20010000", number: "0x1", - parent_hash: "0xe10b8035540bf0976aa991dbcc1dfb2237a81706e6848596aca8773a69efb85c", - nonce: "0x58df949326a72a42", - timestamp: "0x16d70d9f580", - transactions_root: "0x249ba6cc038ccb16a18b1da03b994f87a6e32bf128b553a66a5805e9d6f36c50", + parent_hash: "0x70396940ae2e81bd2627a8e0e75f3d277585bb1afd78839cfd8f2c54e8697bbc", + nonce: "0x3a7937c78d7ae069", + timestamp: "0x16d7ad5d9de", + transactions_root: "0xfcf1ec1c5da7f80b23ad81e72885d381ee04ad58c79003100d38ad285ae44959", proposals_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", uncles_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", version: "0x0", diff --git a/spec/ckb/types/block_header_spec.rb b/spec/ckb/types/block_header_spec.rb index d8f3711d..38f14e45 100644 --- a/spec/ckb/types/block_header_spec.rb +++ b/spec/ckb/types/block_header_spec.rb @@ -2,7 +2,7 @@ let(:block_header_h) do { "dao": "0x0100000000000000005827f2ba13b000d77fa3d595aa00000061eb7ada030000", - "difficulty": "0x7a1200", + "compact_target": "0x7a1200", "epoch": "0x1", "hash": "0xd629a10a08fb0f43fcb97e948fc2b6eb70ebd28536490fe3864b0e40d08397d1", "nonce": "0x0", @@ -20,7 +20,7 @@ it "from_h" do expect(block_header).to be_a(CKB::Types::BlockHeader) - number_keys = %i(difficulty epoch nonce number timestamp version) + number_keys = %i(compact_target epoch nonce number timestamp version) number_keys.each do |key| expect(block_header.public_send(key)).to eq block_header_h[key].hex end @@ -40,7 +40,7 @@ api = CKB::API.new tip_header = api.get_tip_header - expected_attributes = %w(dao difficulty epoch hash nonce number parent_hash proposals_hash timestamp transactions_root uncles_hash version) + expected_attributes = %w(dao compact_target epoch hash nonce number parent_hash proposals_hash timestamp transactions_root uncles_hash version).sort expect(expected_attributes).to eq(tip_header.instance_variables.map { |attribute| attribute.to_s.gsub("@", "") }.sort) end diff --git a/spec/ckb/types/block_spec.rb b/spec/ckb/types/block_spec.rb index 402651bf..c9a25c0f 100644 --- a/spec/ckb/types/block_spec.rb +++ b/spec/ckb/types/block_spec.rb @@ -3,7 +3,7 @@ { "header": { "dao": "0x0100000000000000005827f2ba13b000d77fa3d595aa00000061eb7ada030000", - "difficulty": "0x7a1200", + "compact_target": "0x7a1200", "epoch": "0x1", "hash": "0xd629a10a08fb0f43fcb97e948fc2b6eb70ebd28536490fe3864b0e40d08397d1", "nonce": "0x0", diff --git a/spec/ckb/types/block_template_spec.rb b/spec/ckb/types/block_template_spec.rb index dca0092a..983832a7 100644 --- a/spec/ckb/types/block_template_spec.rb +++ b/spec/ckb/types/block_template_spec.rb @@ -1,7 +1,7 @@ RSpec.describe CKB::Types::BlockTemplate do let(:block_template_h) do {:version=>"0x0", - :difficulty=>"0x48", + :compact_target=>"0x48", :current_time=>"0x16d6b6111b3", :number=>"0xab3", :epoch=>"0x70806cb000001", @@ -46,7 +46,7 @@ end it "block_template's attributes value should equal with block_template_h" do - number_keys = %i(version difficulty current_time number epoch parent_hash cycles_limit bytes_limit uncles_count_limit uncles transactions proposals cellbase work_id dao) + number_keys = %i(version compact_target current_time number epoch parent_hash cycles_limit bytes_limit uncles_count_limit uncles transactions proposals cellbase work_id dao) number_keys.each do |key| expect(block_template.to_h[key]).to eq block_template_h[key] end @@ -63,7 +63,7 @@ api = CKB::API.new block_template = api.get_block_template - expected_attributes = %w(version difficulty current_time number epoch parent_hash cycles_limit bytes_limit uncles_count_limit uncles transactions proposals cellbase work_id dao).sort + expected_attributes = %w(version compact_target current_time number epoch parent_hash cycles_limit bytes_limit uncles_count_limit uncles transactions proposals cellbase work_id dao).sort expect(expected_attributes).to eq(block_template.instance_variables.map { |attribute| attribute.to_s.gsub("@", "") }.sort) end diff --git a/spec/ckb/types/epoch_spec.rb b/spec/ckb/types/epoch_spec.rb index cb9364a5..c7e2e58c 100644 --- a/spec/ckb/types/epoch_spec.rb +++ b/spec/ckb/types/epoch_spec.rb @@ -1,7 +1,7 @@ RSpec.describe CKB::Types::Epoch do let(:epoch_h) do { - "difficulty": "0x7a1200", + "compact_target": "0x7a1200", "length": "0x708", "number": "0x1", "start_number": "0x3e8" diff --git a/spec/ckb/types/uncle_template_spec.rb b/spec/ckb/types/uncle_template_spec.rb index 5cc3200e..406fb26e 100644 --- a/spec/ckb/types/uncle_template_spec.rb +++ b/spec/ckb/types/uncle_template_spec.rb @@ -6,7 +6,7 @@ :proposals=>[], :header => { :dao=>"0x0100000000000000005827f2ba13b000d77fa3d595aa00000061eb7ada030000", - :difficulty=>"0x7a1200", + :compact_target=>"0x7a1200", :epoch=>"0x1", :hash=>"0xd629a10a08fb0f43fcb97e948fc2b6eb70ebd28536490fe3864b0e40d08397d1", :nonce=>"0x0", From 27498fad06eec7f7045b0aeeeab39fb6f4a5ce25 Mon Sep 17 00:00:00 2001 From: classicalliu Date: Sun, 29 Sep 2019 11:07:10 +0800 Subject: [PATCH 28/37] feat: add sign_input for transaction --- lib/ckb/types/transaction.rb | 20 ++++++++++++++++++++ spec/ckb/types/transaction_spec.rb | 10 ++++++++++ 2 files changed, 30 insertions(+) diff --git a/lib/ckb/types/transaction.rb b/lib/ckb/types/transaction.rb index f708ff45..0cfe22f2 100644 --- a/lib/ckb/types/transaction.rb +++ b/lib/ckb/types/transaction.rb @@ -61,6 +61,26 @@ def sign(key, tx_hash) ) end + # @param index [Integer] + # @param key [CKB::Key] + # + # @return [CKBP::Types::Transaction] + def sign_input(index, key) + @hash = @hash || compute_hash + + witness = witnesses[index] || "" + + blake2b = CKB::Blake2b.new + blake2b.update(Utils.hex_to_bin(@hash)) + blake2b.update(Utils.hex_to_bin(witness)) + message = blake2b.hexdigest + signed_witness = key.sign_recoverable(message) + witness[2..-1] + + witnesses[index] = signed_witness + + self + end + def to_h hash = { version: Utils.to_hex(@version), diff --git a/spec/ckb/types/transaction_spec.rb b/spec/ckb/types/transaction_spec.rb index 3cb40b37..f5e2b1e7 100644 --- a/spec/ckb/types/transaction_spec.rb +++ b/spec/ckb/types/transaction_spec.rb @@ -63,6 +63,16 @@ expect(signed_tx.to_h[:witnesses]).to eq(["0x15edb4da91bd5beebf0aee82a9daa4d590ecdfc0895c6b010638573b2d1d502c50373e7d540e74eb8e3a3bd1dbd20c372c492fc7242592c8a04763be029325a900"]) end + it "sign input" do + tx_to_sign = CKB::Types::Transaction.from_h(tx_to_sign_hash) + key = CKB::Key.new("0x845b781a1a094057b972714a2b09b85de4fc2eb205351c3e5179aabd264f3805") + tx_hash = "0x993e6e629be2f016bf72becaa9ad4b39f7fdd72357c9341335783f451010b94e" + signed_tx = tx_to_sign.sign_input(0, key) + + expect(signed_tx.to_h[:hash]).to eq(tx_hash) + expect(signed_tx.to_h[:witnesses]).to eq(["0xf198c795adfc5aead05ad0ac9d979519b0a707e7987c5addb3a6be42669af7f86e3a76a3ce8c770a92915e2d5a0212b3417db1c2152f2107ee7683601a4ecb5001"]) + end + context "multiple inputs sign" do let(:tx_to_sign_hash) do { version: "0x0", From c5fd7f886f32e391ace03f1bd925a4ceef554ea6 Mon Sep 17 00:00:00 2001 From: classicalliu Date: Sun, 29 Sep 2019 12:10:38 +0800 Subject: [PATCH 29/37] feat: add `CellCollector` --- lib/ckb.rb | 1 + lib/ckb/cell_collector.rb | 108 ++++++++++++++++++++++++++++++++++++++ lib/ckb/wallet.rb | 71 ++++++++++--------------- 3 files changed, 137 insertions(+), 43 deletions(-) create mode 100644 lib/ckb/cell_collector.rb diff --git a/lib/ckb.rb b/lib/ckb.rb index a6504d70..27a13279 100644 --- a/lib/ckb.rb +++ b/lib/ckb.rb @@ -9,6 +9,7 @@ require "ckb/blake2b" require "ckb/convert_address" require "ckb/utils" +require "ckb/cell_collector" require "ckb/wallet" require "ckb/address" require "ckb/key" diff --git a/lib/ckb/cell_collector.rb b/lib/ckb/cell_collector.rb new file mode 100644 index 00000000..dbe1613a --- /dev/null +++ b/lib/ckb/cell_collector.rb @@ -0,0 +1,108 @@ +# frozen_string_literal: true + +module CKB + class CellCollector + attr_reader :api, :skip_data_and_type, :hash_type + + # @param api [CKB::API] + def initialize(api, skip_data_and_type: true, hash_type: "type") + @api = api + @skip_data_and_type = skip_data_and_type + @hash_type = hash_type + end + + # @param lock_hash [String] + # @param need_capacities [Integer | nil] capacity in shannon, nil means collect all + # + # @return [Hash] + def get_unspent_cells(lock_hash, need_capacities: nil) + to = api.get_tip_block_number.to_i + results = [] + total_capacities = 0 + current_from = 0 + while current_from <= to + current_to = [current_from + 100, to].min + cells = api.get_cells_by_lock_hash(lock_hash, current_from, current_to) + if skip_data_and_type + cells.each do |cell| + live_cell = api.get_live_cell(cell.out_point, true) + output = live_cell.cell.output + output_data = live_cell.cell.data.content + if (output_data.nil? || output_data == "0x") && output.type.nil? + results << cell + total_capacities += cell.capacity + break if need_capacities && total_capacities >= need_capacities + end + end + break if need_capacities && total_capacities >= need_capacities + else + results.concat(cells) + total_capacities += cells.map(&:capacity).reduce(:+) + break if need_capacities && total_capacities >= need_capacities + end + current_from = current_to + 1 + end + { + outputs: results, + total_capacities: total_capacities + } + end + + # @param lock_hashes [String[]] + # @param need_capacities [Integer | nil] capacity in shannon, nil means collect all + # + # @return [Hash] + def get_unspent_cells_by_lock_hashes(lock_hashes, need_capacities: nil) + total_capacities = 0 + outputs = [] + lock_hashes.map do |lock_hash| + result = get_unspent_cells( + lock_hash, + need_capacities: need_capacities && need_capacities - total_capacities + ) + outputs += result[:outputs] + total_capacities += result[:total_capacities] + break if need_capacities && total_capacities >= need_capacities + end + + { + outputs: outputs, + total_capacities: total_capacities + } + end + + # @param lock_hashes [String[]] + # @param capacity [Integer] + # @param min_capacity [Integer] + # @param min_change_capacity [Integer] + # @param fee [Integer] + def gather_inputs(lock_hashes, capacity, min_capacity, min_change_capacity, fee) + raise "capacity cannot be less than #{min_capacity}" if capacity < min_capacity + + total_capacities = capacity + fee + input_capacities = 0 + inputs = [] + witnesses = [] + get_unspent_cells_by_lock_hashes(lock_hashes, need_capacities: total_capacities)[:outputs].each do |cell| + input = Types::Input.new( + previous_output: cell.out_point, + since: 0 + ) + inputs << input + witnesses << "0x" + input_capacities += cell.capacity.to_i + + diff = input_capacities - total_capacities + break if diff >= min_change_capacity || diff.zero? + end + + raise "Capacity not enough!" if input_capacities < total_capacities + + OpenStruct.new( + inputs: inputs, + capacities: input_capacities, + witnesses: witnesses + ) + end + end +end \ No newline at end of file diff --git a/lib/ckb/wallet.rb b/lib/ckb/wallet.rb index f30e845d..5b1f9bc2 100644 --- a/lib/ckb/wallet.rb +++ b/lib/ckb/wallet.rb @@ -42,31 +42,27 @@ def hash_type=(hash_type) @hash_type = hash_type end + # @param need_capacities [Integer | nil] capacity in shannon, nil means collect all # @return [CKB::Types::Output[]] - def get_unspent_cells - to = api.get_tip_block_number.to_i - results = [] - current_from = 0 - while current_from <= to - current_to = [current_from + 100, to].min - cells = api.get_cells_by_lock_hash(lock_hash, current_from, current_to) - if skip_data_and_type - cells.each do |cell| - live_cell = api.get_live_cell(cell.out_point, true) - output = live_cell.cell.output - output_data = live_cell.cell.data.content - results << cell if (output_data.nil? || output_data == "0x") && output.type.nil? - end - else - results.concat(cells) - end - current_from = current_to + 1 - end - results + def get_unspent_cells(need_capacities: nil) + CellCollector.new( + @api, + skip_data_and_type: @skip_data_and_type, + hash_type: @hash_type + ).get_unspent_cells( + lock_hash, + need_capacities: need_capacities + )[:outputs] end def get_balance - get_unspent_cells.map { |cell| cell.capacity.to_i }.reduce(0, &:+) + CellCollector.new( + @api, + skip_data_and_type: @skip_data_and_type, + hash_type: @hash_type + ).get_unspent_cells( + lock_hash + )[:total_capacities] end # @param target_address [String] @@ -293,28 +289,17 @@ def send_transaction(transaction) # @param min_change_capacity [Integer] # @param fee [Integer] def gather_inputs(capacity, min_capacity, min_change_capacity, fee) - raise "capacity cannot be less than #{min_capacity}" if capacity < min_capacity - - total_capacities = capacity + fee - input_capacities = 0 - inputs = [] - witnesses = [] - get_unspent_cells.each do |cell| - input = Types::Input.new( - previous_output: cell.out_point, - since: 0 - ) - inputs << input - witnesses << "0x" - input_capacities += cell.capacity.to_i - - diff = input_capacities - total_capacities - break if diff >= min_change_capacity || diff.zero? - end - - raise "Capacity not enough!" if input_capacities < total_capacities - - OpenStruct.new(inputs: inputs, capacities: input_capacities, witnesses: witnesses) + CellCollector.new( + @api, + skip_data_and_type: @skip_data_and_type, + hash_type: @hash_type + ).gather_inputs( + [lock_hash], + capacity, + min_capacity, + min_change_capacity, + fee + ) end def code_hash From 58d034afab86f5b19faf909370c34f909ee8911b Mon Sep 17 00:00:00 2001 From: classicalliu Date: Mon, 30 Sep 2019 11:35:32 +0800 Subject: [PATCH 30/37] chore: bump version to 0.22.0 --- Gemfile.lock | 2 +- lib/ckb/version.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 18309fef..835e4b20 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - ckb-sdk-ruby (0.21.0) + ckb-sdk-ruby (0.22.0) bitcoin-secp256k1 (~> 0.5.2) net-http-persistent (~> 3.0.0) rbnacl (~> 6.0, >= 6.0.1) diff --git a/lib/ckb/version.rb b/lib/ckb/version.rb index 69ac5706..71b1967a 100644 --- a/lib/ckb/version.rb +++ b/lib/ckb/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module CKB - VERSION = "0.21.0" + VERSION = "0.22.0" end From 962e3505d1c901a9fa2dbca002cae88324237aa6 Mon Sep 17 00:00:00 2001 From: classicalliu Date: Mon, 30 Sep 2019 11:37:37 +0800 Subject: [PATCH 31/37] docs: update CHANGELOG for v0.22.0 --- CHANGELOG.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 520b9f0e..1c5d6f8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,29 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [v0.22.0](https://github.com/nervosnetwork/ckb-sdk-ruby/compare/v0.21.0...v0.22.0) (2019-10-05) + + +### Features + +* add `CellCollector` ([c5fd7f8](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/c5fd7f8)) +* add CellOutputWithOutPoint type and add block_hash ([2ab7217](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/2ab7217)) +* add sign_input for transaction ([27498fa](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/27498fa)) +* add submit_block api ([60443f7](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/60443f7)) +* add template related types ([46bec62](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/46bec62)) +* change args type to string ([ca1a6b8](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/ca1a6b8)) +* change witnesses to String[] ([f946c9d](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/f946c9d)) +* get_block_template api ([942d525](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/942d525)) +* get_block_template rpc ([ecfe65e](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/ecfe65e)) +* remove uncles_count from block header ([5508b9e](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/5508b9e)) +* remove witnesses_root from block header ([ca6417f](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/ca6417f)) +* replace difficulty with compact_target ([a88ef6b](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/a88ef6b)) +* submit_block rpc ([2a10a7a](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/2a10a7a)) +* update args serializer ([c59691a](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/c59691a)) +* update expected code_hash and type_hash ([78f3f59](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/78f3f59)) +* update witnesses type ([3838fd8](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/3838fd8)) + + # [v0.21.0](https://github.com/nervosnetwork/ckb-sdk-ruby/compare/v0.20.0...v0.21.0) (2019-09-21) From c9856674c5900af16455d7f0482263a78906cc00 Mon Sep 17 00:00:00 2001 From: shaojunda Date: Mon, 30 Sep 2019 14:37:07 +0800 Subject: [PATCH 32/37] feat: update full payload address generator --- lib/ckb/address.rb | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/lib/ckb/address.rb b/lib/ckb/address.rb index 7d6b40f0..e1646935 100644 --- a/lib/ckb/address.rb +++ b/lib/ckb/address.rb @@ -45,7 +45,7 @@ def self.generate_short_payload_hash160_address(hash160, mode: DEFAULT_MODE) end # Generates full payload format address - # payload = 0x02/0x04 | code_hash | len(arg[0]) | arg[0] | ... + # payload = 0x02/0x04 | code_hash | args # see https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0021-ckb-address-format/0021-ckb-address-format.md for more info. # @param [String | Integer] format_type # @param [String] code_hash @@ -55,18 +55,9 @@ def self.generate_full_payload_address(format_type, code_hash, args, mode: DEFAU prefix = prefix(mode: mode) format_type = Utils.to_hex(format_type)[2..-1].rjust(2, '0') raise InvalidFormatTypeError.new("Invalid format type") unless TYPES[1..-1].include?(format_type) - raise InvalidArgsTypeError.new("Args should be an array") unless args.is_a?(Array) - - payload = [format_type].pack("H*") + CKB::Utils.hex_to_bin(code_hash) - args.each do |arg| - arg_bytes = CKB::Utils.hex_to_bin(arg) - arg_len = arg_bytes.bytesize - if arg_len > 256 - raise InvalidArgSizeError.new("The maximum size of arg is 256") - else - payload += [arg_len].pack("C") + arg_bytes - end - end + raise InvalidArgsTypeError.new("Args should be an hex string") unless CKB::Utils.valid_hex_string?(args) + + payload = [format_type].pack("H*") + CKB::Utils.hex_to_bin(code_hash) + CKB::Utils.hex_to_bin(args) CKB::ConvertAddress.encode(prefix, payload) end @@ -99,19 +90,11 @@ def self.parse_full_payload_address(address, mode: DEFAULT_MODE) offset = 1 code_hash_size = 32 - code_hash = "0x#{data.slice(offset..code_hash_size).unpack("H*").first}" - offset += 32 - data_size = data.bytesize - args = [] - while offset < data_size - arg_len = data[offset].unpack("C").first.to_i - offset += 1 - arg = data[offset...offset + arg_len] - args << arg - offset += arg_len - end + code_hash = "0x#{data.slice(1..code_hash_size).unpack("H*").first}" + offset += code_hash_size + args = data[offset..-1] - ["0x#{format_type}", code_hash, args.map { |item| CKB::Utils.bin_to_hex(item) }] + ["0x#{format_type}", code_hash, CKB::Utils.bin_to_hex(args)] end def self.parse(address, mode: DEFAULT_MODE) From d84a00570ad5dbea511319172dbdfc3a4bbcf0b9 Mon Sep 17 00:00:00 2001 From: shaojunda Date: Mon, 30 Sep 2019 14:50:32 +0800 Subject: [PATCH 33/37] chore: adjust tests --- lib/ckb/address.rb | 2 +- spec/ckb/address_spec.rb | 40 +++++++++++++++++----------------------- 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/lib/ckb/address.rb b/lib/ckb/address.rb index e1646935..f031b523 100644 --- a/lib/ckb/address.rb +++ b/lib/ckb/address.rb @@ -55,7 +55,7 @@ def self.generate_full_payload_address(format_type, code_hash, args, mode: DEFAU prefix = prefix(mode: mode) format_type = Utils.to_hex(format_type)[2..-1].rjust(2, '0') raise InvalidFormatTypeError.new("Invalid format type") unless TYPES[1..-1].include?(format_type) - raise InvalidArgsTypeError.new("Args should be an hex string") unless CKB::Utils.valid_hex_string?(args) + raise InvalidArgsTypeError.new("Args should be a hex string") unless CKB::Utils.valid_hex_string?(args) payload = [format_type].pack("H*") + CKB::Utils.hex_to_bin(code_hash) + CKB::Utils.hex_to_bin(args) diff --git a/spec/ckb/address_spec.rb b/spec/ckb/address_spec.rb index 8f9ce0f9..e93ac571 100644 --- a/spec/ckb/address_spec.rb +++ b/spec/ckb/address_spec.rb @@ -1,3 +1,4 @@ +require 'pry' RSpec.describe CKB::Address do let(:privkey) { "0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3" } let(:pubkey) { "0x024a501efd328e062c8675f2365970728c859c592beeefd6be8ead3d901330bc01" } @@ -13,11 +14,11 @@ let(:short_payload_blake160_address_with_invalid_format_type) { "ckt1qvqrdsefa43s6m882pcj53m4gdnj4k440axqdxkp8n" } let(:short_payload_blake160_address_with_invalid_code_hash_index) { "ckt1qypndsefa43s6m882pcj53m4gdnj4k440axq2jsln8" } let(:short_payload_hash160_address) { "ckt1qyquspzltz8xy75rsxqsjg7xr5rst5gtsmfsjh777d" } - let(:full_payload_data_address) { "ckt1q2n9dutjk669cfznq7httfar0gtk7qp0du3wjfvzck9l0w3k9eqhv9pkcv576ccddnn4quf2ga65xee2m26h7nq2rtnac" } - let(:full_payload_type_address) { "ckt1qsvf96jqmq4483ncl7yrzfzshwchu9jd0glq4yy5r2jcsw04d7xly9pkcv576ccddnn4quf2ga65xee2m26h7nqp5mnpu" } - let(:full_payload_data_address_with_multiple_args) { "ckt1q2n9dutjk669cfznq7httfar0gtk7qp0du3wjfvzck9l0w3k9eqhv9xau7qpcpealv6xf3a37pdcq6ajhwuyaxg5q8qam7wpx5rpka34efg7wd0u9vpuaceescp87n" } - let(:full_payload_type_address_with_multiple_args) { "ckt1qsvf96jqmq4483ncl7yrzfzshwchu9jd0glq4yy5r2jcsw04d7xly9xau7qpcpealv6xf3a37pdcq6ajhwuyaxg5q8qam7wpx5rpka34efg7wd0u9vpuaceexvj7zq" } - let(:multiple_args) { %w(0xdde7801c073dfb3464c7b1f05b806bb2bbb84e99 0x01c1ddf9c135061b7635ca51e735fc2b03cee339) } + let(:full_payload_data_address) { "ckt1q2n9dutjk669cfznq7httfar0gtk7qp0du3wjfvzck9l0w3k9eqhvdkr98kkxrtvuag8z2j8w4pkw2k6k4l5czshhac" } + let(:full_payload_type_address) { "ckt1qsvf96jqmq4483ncl7yrzfzshwchu9jd0glq4yy5r2jcsw04d7xlydkr98kkxrtvuag8z2j8w4pkw2k6k4l5c02auef" } + let(:full_payload_data_address_with_multiple_args) { "ckt1q2n9dutjk669cfznq7httfar0gtk7qp0du3wjfvzck9l0w3k9eqhdh08sqwqw00mx3jv0v0stwqxhv4mhp8fjqwpmhuuzdgxrdmrtjj3uu6lc2crem3nj204af0" } + let(:full_payload_type_address_with_multiple_args) { "ckt1qsvf96jqmq4483ncl7yrzfzshwchu9jd0glq4yy5r2jcsw04d7xl9h08sqwqw00mx3jv0v0stwqxhv4mhp8fjqwpmhuuzdgxrdmrtjj3uu6lc2crem3njluztad" } + let(:multiple_args) { "0xdde7801c073dfb3464c7b1f05b806bb2bbb84e9901c1ddf9c135061b7635ca51e735fc2b03cee339" } context "from pubkey" do let(:addr) { CKB::Address.from_pubkey(pubkey) } @@ -44,7 +45,7 @@ it "generate full payload data address" do expect( - CKB::Address.generate_full_payload_address(2, data_hash, [pubkey_blake160]) + CKB::Address.generate_full_payload_address(2, data_hash, pubkey_blake160) ).to eq full_payload_data_address end @@ -54,28 +55,21 @@ }.to raise_error(CKB::Address::InvalidFormatTypeError) end - it "generate full payload data address should raise error when args is not an array" do + it "generate full payload data address should raise error when args is not an hex string" do expect { - CKB::Address.generate_full_payload_address(2, data_hash, pubkey_blake160) + CKB::Address.generate_full_payload_address(2, data_hash, pubkey_blake160[2..-1]) }.to raise_error(CKB::Address::InvalidArgsTypeError) end - it "generate full payload data address should raise error when args size is too large" do - args = ["0x#{SecureRandom.hex(300)}"] - expect { - CKB::Address.generate_full_payload_address(2, data_hash, args) - }.to raise_error(CKB::Address::InvalidArgSizeError) - end - it "generate full payload data address can accept empty arg" do expect { - CKB::Address.generate_full_payload_address(2, data_hash, ["0x"]) + CKB::Address.generate_full_payload_address(2, data_hash, "0x") }.not_to raise_error end it "generate full payload type address" do expect( - CKB::Address.generate_full_payload_address(4, type_hash, [pubkey_blake160]) + CKB::Address.generate_full_payload_address(4, type_hash, pubkey_blake160) ).to eq full_payload_type_address end @@ -106,13 +100,13 @@ it "parse full payload data address" do expect( addr.parse(full_payload_data_address) - ).to eq ["0x02", data_hash, [pubkey_blake160]] + ).to eq ["0x02", data_hash, pubkey_blake160] end it "parse full payload type address" do expect( addr.parse(full_payload_type_address) - ).to eq ["0x04", type_hash, [pubkey_blake160]] + ).to eq ["0x04", type_hash, pubkey_blake160] end it "parse full payload data address with multiple args" do @@ -145,13 +139,13 @@ it "generate full payload data address" do expect( - CKB::Address.generate_full_payload_address("0x02", data_hash, [pubkey_blake160]) + CKB::Address.generate_full_payload_address("0x02", data_hash, pubkey_blake160) ).to eq full_payload_data_address end it "generate full payload type address" do expect( - CKB::Address.generate_full_payload_address("0x04", type_hash, [pubkey_blake160]) + CKB::Address.generate_full_payload_address("0x04", type_hash, pubkey_blake160) ).to eq full_payload_type_address end @@ -182,13 +176,13 @@ it "parse full payload data address" do expect( addr.parse(full_payload_data_address) - ).to eq ["0x02", data_hash, [pubkey_blake160]] + ).to eq ["0x02", data_hash, pubkey_blake160] end it "parse full payload type address" do expect( addr.parse(full_payload_type_address) - ).to eq ["0x04", type_hash, [pubkey_blake160]] + ).to eq ["0x04", type_hash, pubkey_blake160] end it "parse full payload data address with multiple args" do From 880622a24e52597efd34b901fc37f6cbb2f2130c Mon Sep 17 00:00:00 2001 From: shaojunda Date: Mon, 30 Sep 2019 16:28:56 +0800 Subject: [PATCH 34/37] chore: remove require pry --- spec/ckb/address_spec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/ckb/address_spec.rb b/spec/ckb/address_spec.rb index e93ac571..94335ebe 100644 --- a/spec/ckb/address_spec.rb +++ b/spec/ckb/address_spec.rb @@ -1,4 +1,3 @@ -require 'pry' RSpec.describe CKB::Address do let(:privkey) { "0xe79f3207ea4980b7fed79956d5934249ceac4751a4fae01a0f7c4a96884bc4e3" } let(:pubkey) { "0x024a501efd328e062c8675f2365970728c859c592beeefd6be8ead3d901330bc01" } From 8ecb8f21eb844079cb64077092195d8591385516 Mon Sep 17 00:00:00 2001 From: classicalliu Date: Mon, 30 Sep 2019 17:21:13 +0800 Subject: [PATCH 35/37] feat: update NervosDAO lock period to 180 epochs --- lib/ckb/api.rb | 7 +++++-- lib/ckb/wallet.rb | 37 ++++++++++++++++++++++++++++++------- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/lib/ckb/api.rb b/lib/ckb/api.rb index 6ebbdd45..a93ab626 100644 --- a/lib/ckb/api.rb +++ b/lib/ckb/api.rb @@ -14,6 +14,7 @@ class API attr_reader :secp_cell_code_hash attr_reader :dao_out_point attr_reader :dao_code_hash + attr_reader :dao_type_hash def initialize(host: CKB::RPC::DEFAULT_URL, mode: MODE::TESTNET) @rpc = CKB::RPC.new(host: host) @@ -47,8 +48,9 @@ def initialize(host: CKB::RPC::DEFAULT_URL, mode: MODE::TESTNET) ) dao_cell_data = CKB::Utils.hex_to_bin(system_cell_transaction.outputs_data[2]) dao_code_hash = CKB::Blake2b.hexdigest(dao_cell_data) + dao_type_hash = system_cell_transaction.outputs[2].type.compute_hash - set_dao_dep(dao_out_point, dao_code_hash) + set_dao_dep(dao_out_point, dao_code_hash, dao_type_hash) end end @@ -59,9 +61,10 @@ def set_secp_group_dep(out_point, secp_cell_type_hash) @secp_cell_type_hash = secp_cell_type_hash end - def set_dao_dep(out_point, code_hash) + def set_dao_dep(out_point, code_hash, type_hash) @dao_out_point = out_point @dao_code_hash = code_hash + @dao_type_hash = type_hash end def genesis_block diff --git a/lib/ckb/wallet.rb b/lib/ckb/wallet.rb index 5b1f9bc2..e99eae5b 100644 --- a/lib/ckb/wallet.rb +++ b/lib/ckb/wallet.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module CKB - DAO_LOCK_PERIOD_BLOCKS = 10 + DAO_LOCK_PERIOD_EPOCHS = 180 DAO_MATURITY_BLOCKS = 5 class Wallet @@ -140,8 +140,9 @@ def deposit_to_dao(capacity, key: nil) capacity: capacity, lock: Types::Script.generate_lock(addr.blake160, code_hash, hash_type), type: Types::Script.new( - code_hash: api.dao_code_hash, - args: "0x" + code_hash: api.dao_type_hash, + args: "0x", + hash_type: "type" ) ) output_data = "0x" @@ -202,17 +203,26 @@ def generate_withdraw_from_dao_transaction(out_point, key: nil) raise "Transaction is not commtted yet!" end deposit_block = api.get_block(tx.tx_status.block_hash).header + deposit_epoch = self.class.parse_epoch(deposit_block.epoch) deposit_block_number = deposit_block.number current_block = api.get_tip_header + current_epoch = self.class.parse_epoch(current_block.epoch) current_block_number = current_block.number if deposit_block_number == current_block_number raise "You need to at least wait for 1 block before generating DAO withdraw transaction!" end - windowleft = DAO_LOCK_PERIOD_BLOCKS - (current_block_number - deposit_block_number) % DAO_LOCK_PERIOD_BLOCKS - windowleft = DAO_MATURITY_BLOCKS if windowleft < DAO_MATURITY_BLOCKS - since = current_block_number + windowleft + 1 + withdraw_fraction = current_epoch.index * deposit_epoch.length + deposit_fraction = deposit_epoch.index * current_epoch.length + deposited_epoches = current_epoch.number - deposit_epoch.number + deposited_epoches +=1 if withdraw_fraction > deposit_fraction + lock_epochs = (deposited_epoches + (DAO_LOCK_PERIOD_EPOCHS - 1)) / DAO_LOCK_PERIOD_EPOCHS * DAO_LOCK_PERIOD_EPOCHS + minimal_since_epoch_number = deposit_epoch.number + lock_epochs + minimal_since_epoch_index = deposit_epoch.index + minimal_since_epoch_length = deposit_epoch.length + + minimal_since = self.class.epoch_since(minimal_since_epoch_length, minimal_since_epoch_index, minimal_since_epoch_number) # a hex string output_capacity = api.calculate_dao_maximum_withdraw(out_point, current_block.hash) @@ -238,7 +248,7 @@ def generate_withdraw_from_dao_transaction(out_point, key: nil) deposit_block.hash ], inputs: [ - Types::Input.new(previous_output: new_out_point, since: since) + Types::Input.new(previous_output: new_out_point, since: minimal_since) ], outputs: outputs, outputs_data: outputs_data, @@ -249,6 +259,19 @@ def generate_withdraw_from_dao_transaction(out_point, key: nil) tx.sign(key, tx.compute_hash) end + # @param epoch [Integer] + def self.parse_epoch(epoch) + OpenStruct.new( + length: (epoch >> 40) & 0xFFFF, + index: (epoch >> 24) & 0xFFFF, + number: (epoch) & 0xFFFFFF + ) + end + + def self.epoch_since(length, index, number) + (0x20 << 56) + (length << 40) + (index << 24) + number + end + # @param hash_hex [String] "0x..." # # @return [CKB::Types::Transaction] From 4b291ad75fc340c2ed7b3aae74e1bd88c70d636d Mon Sep 17 00:00:00 2001 From: classicalliu Date: Sat, 5 Oct 2019 13:27:52 +0800 Subject: [PATCH 36/37] docs: update CHANGELOG v0.22.0 --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c5d6f8e..6a13d8c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline * submit_block rpc ([2a10a7a](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/2a10a7a)) * update args serializer ([c59691a](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/c59691a)) * update expected code_hash and type_hash ([78f3f59](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/78f3f59)) +* update full payload address generator ([c985667](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/c985667)) +* update NervosDAO lock period to 180 epochs ([8ecb8f2](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/8ecb8f2)) * update witnesses type ([3838fd8](https://github.com/nervosnetwork/ckb-sdk-ruby/commit/3838fd8)) From dd1f8b681d690fde5c6ffb939d1185993536dcd2 Mon Sep 17 00:00:00 2001 From: classicalliu Date: Sat, 5 Oct 2019 15:16:29 +0800 Subject: [PATCH 37/37] fix: submit block tests --- spec/ckb/api_spec.rb | 21 ++++++++------------- spec/ckb/rpc_spec.rb | 19 ++++++++----------- 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/spec/ckb/api_spec.rb b/spec/ckb/api_spec.rb index 1d3107ef..3ef8d148 100644 --- a/spec/ckb/api_spec.rb +++ b/spec/ckb/api_spec.rb @@ -17,26 +17,20 @@ header_deps: [], inputs: [{ previous_output: { tx_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", index: "0xffffffff" }, since: "0x1" }], - outputs: [{ capacity: "0x2ca7071b9e", - lock: { code_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", - args: "0x", - hash_type: "type" }, - type: nil }], - outputs_data: ["0x"], - witnesses: ["0x490000001000000030000000310000009bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce801140000003954acece65096bfa81258983ddb83915fc56bd8"], - hash: "0x249ba6cc038ccb16a18b1da03b994f87a6e32bf128b553a66a5805e9d6f36c50" }], + outputs: [], + outputs_data: [], + witnesses: ["0x590000000c00000055000000490000001000000030000000310000009bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8011400000036c329ed630d6ce750712a477543672adab57f4c00000000"] }], header: { compact_target: "0x20010000", - hash: "0x22946a72d17b745d950ae1b67326d77f708ba5c0411cbf424c7f4df04c1ac317", number: "0x1", - parent_hash: "0x70396940ae2e81bd2627a8e0e75f3d277585bb1afd78839cfd8f2c54e8697bbc", - nonce: "0x3a7937c78d7ae069", + parent_hash: "0xe49352ee4984694d88eb3c1493a33d69d61c786dc5b0a32c4b3978d4fad64379", + nonce: "0x7622c91cd47ca43fa63f7db0ee0fd3ef", timestamp: "0x16d7ad5d9de", - transactions_root: "0xfcf1ec1c5da7f80b23ad81e72885d381ee04ad58c79003100d38ad285ae44959", + transactions_root: "0x29c04a85c4b686ec8a78615d193d64d4416dbc428f9e4631f27c62419926110f", proposals_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", uncles_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", version: "0x0", epoch: "0x3e80001000000", - dao: "0x2cd631702e870700a715aee035872300a804ad5e9a00000000ec1bc9857a0100" } } + dao: "0x04d0a006e1840700df5d55f5358723001206877a0b00000000e3bad4847a0100" } } end it "genesis block" do @@ -247,6 +241,7 @@ end it "submit_block should return block hash" do + block_h[:header][:parent_hash] = api.genesis_block_hash block = Types::Block.from_h(block_h) result = api.submit_block(work_id: "test", raw_block_h: block.to_raw_block_h) expect(result).to be_a(String) diff --git a/spec/ckb/rpc_spec.rb b/spec/ckb/rpc_spec.rb index 0f866015..fcd5290d 100644 --- a/spec/ckb/rpc_spec.rb +++ b/spec/ckb/rpc_spec.rb @@ -12,24 +12,20 @@ header_deps: [], inputs: [{ previous_output: { tx_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", index: "0xffffffff" }, since: "0x1" }], - outputs: [{ capacity: "0x2ca7071b9e", - lock: { code_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", - args: "0x", - hash_type: "type" }, - type: nil }], - outputs_data: ["0x"], - witnesses: ["0x490000001000000030000000310000009bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce801140000003954acece65096bfa81258983ddb83915fc56bd8"] }], + outputs: [], + outputs_data: [], + witnesses: ["0x590000000c00000055000000490000001000000030000000310000009bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8011400000036c329ed630d6ce750712a477543672adab57f4c00000000"] }], header: { compact_target: "0x20010000", number: "0x1", - parent_hash: "0x70396940ae2e81bd2627a8e0e75f3d277585bb1afd78839cfd8f2c54e8697bbc", - nonce: "0x3a7937c78d7ae069", + parent_hash: "0xe49352ee4984694d88eb3c1493a33d69d61c786dc5b0a32c4b3978d4fad64379", + nonce: "0x7622c91cd47ca43fa63f7db0ee0fd3ef", timestamp: "0x16d7ad5d9de", - transactions_root: "0xfcf1ec1c5da7f80b23ad81e72885d381ee04ad58c79003100d38ad285ae44959", + transactions_root: "0x29c04a85c4b686ec8a78615d193d64d4416dbc428f9e4631f27c62419926110f", proposals_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", uncles_hash: "0x0000000000000000000000000000000000000000000000000000000000000000", version: "0x0", epoch: "0x3e80001000000", - dao: "0x2cd631702e870700a715aee035872300a804ad5e9a00000000ec1bc9857a0100" } } + dao: "0x04d0a006e1840700df5d55f5358723001206877a0b00000000e3bad4847a0100" } } end let(:rpc) { CKB::RPC.new } let(:lock_hash) { "0xd0e22f863da970a3ff51a937ae78ba490bbdcede7272d658a053b9f80e30305d" } @@ -210,6 +206,7 @@ # must use real data it "submit_block" do + raw_block_h[:header][:parent_hash] = rpc.genesis_block_hash result = rpc.submit_block("test", raw_block_h) expect(result).not_to be nil end