merkle_tree 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c4803a642169c873dcc0ece2b6a63c6322db9ebf9794c36ddaec8dd6d8bfbb5a
4
- data.tar.gz: '008ea58e5d83dbef7c888e5d06507d001ed0cf1c8cc020a9242f37c0a5f56bc4'
3
+ metadata.gz: ec49337a87e559e775e365bdbb2ebb20233846e2ee6d35c11350a83c7c7c70c0
4
+ data.tar.gz: 66540e38039f3ad8351c2b6565431fa173c6a1dc157033e1efa1e8fdf060fbe7
5
5
  SHA512:
6
- metadata.gz: 8c962e9d69320a7822a2f4a52e0836f5b7f813b31174e2719d8a3f8391f44fb3ddfb0a4f0fea81c323c1183740ff8924380ba794156afcb562c38c07c14c8552
7
- data.tar.gz: 3ff25ab4867c9bc5179e485243489f0ac4feff35b61e8416944d330d9d8520bb9151f05dc09fdc1d24b0a20a2e7b2cd4215417a10fb544744fb9d14476be0e8d
6
+ metadata.gz: a8f0ad9244ccb004d87f33c366be56866fba373b827fbeeb1edd3f6ecccfbbac6788157ed537bdd475279912e898aa5c372781d666196781a13abef2216b4811
7
+ data.tar.gz: d1fd3c6f36b173efa437ccdb525ee76357335eb751d2dbbb31012904d6bce4cce71901431d2e450aad54067ce236cb0621837b5e063262a227ce2a0dd117f8e2
data/CHANGELOG.md CHANGED
@@ -1,7 +1,14 @@
1
1
  # Change log
2
2
 
3
+ ## [v0.2.0] - 2021-03-20
4
+
5
+ ### Changed
6
+ * Change gemspec to remove test and rake task files to reduce gem size
7
+ * Change to require Ruby 2.0 or higher
8
+
3
9
  ## [v0.1.0] - 2019-03-16
4
10
 
5
11
  * Initial implementation and release
6
12
 
7
- [v0.1.0]: https://github.com/piotrmurach/merkle_tree/compare/v0.1.0
13
+ [v0.2.0]: https://github.com/piotrmurach/merkle_tree/compare/v0.1.0...v0.2.0
14
+ [v0.1.0]: https://github.com/piotrmurach/merkle_tree/compare/d18e34c...v0.1.0
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2019 Piotr Murach
3
+ Copyright (c) 2019 Piotr Murach (piotrmurach.com)
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,14 +1,14 @@
1
1
  # MerkleTree
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/merkle_tree.svg)][gem]
4
- [![Build Status](https://secure.travis-ci.org/piotrmurach/merkle_tree.svg?branch=master)][travis]
4
+ [![Actions CI](https://github.com/piotrmurach/merkle_tree/workflows/CI/badge.svg?branch=master)][gh_actions_ci]
5
5
  [![Build status](https://ci.appveyor.com/api/projects/status/kcbi55cyq2wlfuhc?svg=true)][appveyor]
6
6
  [![Maintainability](https://api.codeclimate.com/v1/badges/ce00667c8785a62cd892/maintainability)][codeclimate]
7
7
  [![Coverage Status](https://coveralls.io/repos/piotrmurach/merkle_tree/badge.svg)][coverage]
8
8
  [![Inline docs](http://inch-ci.org/github/piotrmurach/merkle_tree.svg?branch=master)][inchpages]
9
9
 
10
10
  [gem]: http://badge.fury.io/rb/merkle_tree
11
- [travis]: http://travis-ci.org/piotrmurach/merkle_tree
11
+ [gh_actions_ci]: https://github.com/piotrmurach/merkle_tree/actions?query=workflow%3ACI
12
12
  [appveyor]: https://ci.appveyor.com/project/piotrmurach/merkle-tree
13
13
  [codeclimate]: https://codeclimate.com/github/piotrmurach/merkle_tree/maintainability
14
14
  [coverage]: https://coveralls.io/r/piotrmurach/merkle_tree
@@ -16,6 +16,8 @@
16
16
 
17
17
  > A binary tree of one-time signatures known as merkle tree. Often used in distributed systems such as Git, Cassandra or Bitcoin for efficiently summarizing sets of data.
18
18
 
19
+ A binary tree originally developed to authenticate a large number of public keys with a single value, namely the root of the tree. The merkle root is usually available publicly. Each node in the tree contains a cryptographic hash of node values of its children. The N values/messages that need to be authenticated are placed at the N leaves of the tree. A leaf can store an arbitrary value, usually a public authentication key, that is a cryptographic hash of the value that needs to be authenticated. A leaf can be then verified by publicly available merkle tree root value and its authentication path.
20
+
19
21
  ## Installation
20
22
 
21
23
  Add this line to your application's Gemfile:
data/lib/merkle_tree.rb CHANGED
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'openssl'
4
- require 'English'
3
+ require "English"
4
+ require "openssl"
5
5
 
6
- require_relative 'merkle_tree/leaf'
7
- require_relative 'merkle_tree/node'
8
- require_relative 'merkle_tree/version'
6
+ require_relative "merkle_tree/leaf"
7
+ require_relative "merkle_tree/node"
8
+ require_relative "merkle_tree/version"
9
9
 
10
10
  # A binary tree of one-time signatures known as merkle tree.
11
11
  class MerkleTree
@@ -252,7 +252,7 @@ class MerkleTree
252
252
  # String representation of this tree
253
253
  #
254
254
  # @api public
255
- def to_s(indent = '')
255
+ def to_s(indent = "")
256
256
  root.to_s(indent)
257
257
  end
258
258
  end # MerkleTree
@@ -50,7 +50,7 @@ class MerkleTree
50
50
  { value: value }
51
51
  end
52
52
 
53
- def to_s(indent = '')
53
+ def to_s(indent = "")
54
54
  indent + value
55
55
  end
56
56
  end # Leaf
@@ -95,17 +95,17 @@ class MerkleTree
95
95
  { value: value, left: left.to_h, right: right.to_h }
96
96
  end
97
97
 
98
- def to_s(indent = '')
98
+ def to_s(indent = "")
99
99
  indent + value.to_s + $RS +
100
- left.to_s(indent + ' ') + $RS +
101
- right.to_s(indent + ' ')
100
+ left.to_s(indent + " ") + $RS +
101
+ right.to_s(indent + " ")
102
102
  end
103
103
 
104
104
  # An empty node used as placeholder
105
105
  # @api private
106
106
  class EmptyNode < Node
107
107
  def initialize
108
- @value = ''
108
+ @value = ""
109
109
  @height = 0
110
110
  @left = UNDEFINED
111
111
  @right = UNDEFINED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class MerkleTree
4
- VERSION = '0.1.0'
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,119 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: merkle_tree
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Murach
8
8
  autorequire:
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-16 00:00:00.000000000 Z
11
+ date: 2021-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: bundler
14
+ name: rake
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.17'
19
+ version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '1.17'
27
- - !ruby/object:Gem::Dependency
28
- name: rake
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '10.0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '10.0'
26
+ version: '0'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: rspec
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '3.0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '3.0'
55
- - !ruby/object:Gem::Dependency
56
- name: rspec-benchmark
57
29
  requirement: !ruby/object:Gem::Requirement
58
30
  requirements:
59
31
  - - ">="
60
32
  - !ruby/object:Gem::Version
61
- version: '0'
33
+ version: '3.0'
62
34
  type: :development
63
35
  prerelease: false
64
36
  version_requirements: !ruby/object:Gem::Requirement
65
37
  requirements:
66
38
  - - ">="
67
39
  - !ruby/object:Gem::Version
68
- version: '0'
40
+ version: '3.0'
69
41
  description: A binary tree of one-time singatures known as a merkle tree. Often used
70
42
  in distributed systems such as Git, Cassandra or Bitcoin for efficiently summarizing
71
43
  sets of data.
72
44
  email:
73
- - me@piotrmurach.com
45
+ - piotr@piotrmurach.com
74
46
  executables: []
75
47
  extensions: []
76
- extra_rdoc_files: []
48
+ extra_rdoc_files:
49
+ - README.md
50
+ - CHANGELOG.md
51
+ - LICENSE.txt
77
52
  files:
78
53
  - CHANGELOG.md
79
54
  - LICENSE.txt
80
55
  - README.md
81
- - Rakefile
82
- - bin/console
83
- - bin/setup
84
56
  - lib/merkle_tree.rb
85
57
  - lib/merkle_tree/leaf.rb
86
58
  - lib/merkle_tree/node.rb
87
59
  - lib/merkle_tree/version.rb
88
- - merkle_tree.gemspec
89
- - spec/perf/speed_spec.rb
90
- - spec/spec_helper.rb
91
- - spec/unit/add_spec.rb
92
- - spec/unit/auth_path_spec.rb
93
- - spec/unit/empty_spec.rb
94
- - spec/unit/height_spec.rb
95
- - spec/unit/include_spec.rb
96
- - spec/unit/leaf/build_spec.rb
97
- - spec/unit/leaf/eql_spec.rb
98
- - spec/unit/leaves_spec.rb
99
- - spec/unit/new_spec.rb
100
- - spec/unit/node/build_spec.rb
101
- - spec/unit/node/eql_spec.rb
102
- - spec/unit/root_spec.rb
103
- - spec/unit/size_spec.rb
104
- - spec/unit/subtree_spec.rb
105
- - spec/unit/to_s_spec.rb
106
- - spec/unit/update_spec.rb
107
- - tasks/console.rake
108
- - tasks/coverage.rake
109
- - tasks/spec.rake
110
60
  homepage: https://github.com/piotrmurach/merkle_tree
111
61
  licenses:
112
62
  - MIT
113
63
  metadata:
64
+ bug_tracker_uri: https://github.com/piotrmurach/merkle_tree/issues
65
+ changelog_uri: https://github.com/piotrmurach/merkle_tree/blob/master/CHANGELOG.md
66
+ documentation_uri: https://www.rubydoc.info/gems/merkle_tree
114
67
  homepage_uri: https://github.com/piotrmurach/merkle_tree
115
68
  source_code_uri: https://github.com/piotrmurach/merkle_tree
116
- changelog_uri: https://github.com/piotrmurach/merkle_tree/blob/master/CHANGELOG.md
117
69
  post_install_message:
118
70
  rdoc_options: []
119
71
  require_paths:
@@ -122,15 +74,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
122
74
  requirements:
123
75
  - - ">="
124
76
  - !ruby/object:Gem::Version
125
- version: '0'
77
+ version: 2.0.0
126
78
  required_rubygems_version: !ruby/object:Gem::Requirement
127
79
  requirements:
128
80
  - - ">="
129
81
  - !ruby/object:Gem::Version
130
82
  version: '0'
131
83
  requirements: []
132
- rubyforge_project:
133
- rubygems_version: 2.7.3
84
+ rubygems_version: 3.1.2
134
85
  signing_key:
135
86
  specification_version: 4
136
87
  summary: A binary tree of one-time signatures known as a merkle tree.
data/Rakefile DELETED
@@ -1,8 +0,0 @@
1
- require "bundler/gem_tasks"
2
-
3
- FileList['tasks/**/*.rake'].each(&method(:import))
4
-
5
- desc 'Run all specs'
6
- task ci: %w[ spec ]
7
-
8
- task default: %w[ spec ]
data/bin/console DELETED
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "merkle_tree"
5
-
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start(__FILE__)
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
data/merkle_tree.gemspec DELETED
@@ -1,33 +0,0 @@
1
- lib = File.expand_path("../lib", __FILE__)
2
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require "merkle_tree/version"
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = "merkle_tree"
7
- spec.version = MerkleTree::VERSION
8
- spec.authors = ["Piotr Murach"]
9
- spec.email = ["me@piotrmurach.com"]
10
-
11
- spec.summary = %q{A binary tree of one-time signatures known as a merkle tree.}
12
- spec.description = %q{A binary tree of one-time singatures known as a merkle tree. Often used in distributed systems such as Git, Cassandra or Bitcoin for efficiently summarizing sets of data.}
13
- spec.homepage = "https://github.com/piotrmurach/merkle_tree"
14
- spec.license = "MIT"
15
-
16
- if spec.respond_to?(:metadata)
17
- spec.metadata["homepage_uri"] = spec.homepage
18
- spec.metadata["source_code_uri"] = "https://github.com/piotrmurach/merkle_tree"
19
- spec.metadata["changelog_uri"] = "https://github.com/piotrmurach/merkle_tree/blob/master/CHANGELOG.md"
20
- end
21
-
22
- spec.files = Dir['{lib,spec,examples}/**/*.rb']
23
- spec.files += Dir['{bin,tasks}/*', 'merkle_tree.gemspec']
24
- spec.files += Dir['README.md', 'CHANGELOG.md', 'LICENSE.txt', 'Rakefile']
25
- spec.bindir = "exe"
26
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
- spec.require_paths = ["lib"]
28
-
29
- spec.add_development_dependency "bundler", ">= 1.17"
30
- spec.add_development_dependency "rake", "~> 10.0"
31
- spec.add_development_dependency "rspec", "~> 3.0"
32
- spec.add_development_dependency "rspec-benchmark"
33
- end
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe 'speed performance' do
4
- it "creates merkle trees in linear time" do
5
- messages = bench_range(8, 8 << 12).map do |n|
6
- Array.new(n) { "L#{n}" }
7
- end
8
-
9
- expect { |n, i|
10
- MerkleTree.new(*messages[i])
11
- }.to perform_linear.in_range(8, 8 << 12)
12
- end
13
-
14
- it "checks if a message belongs in logarithmic time" do
15
- trees = []
16
- bench_range(8, 8 << 12).each do |n|
17
- messages = []
18
- n.times { |i| messages << "L#{i}" }
19
- trees << MerkleTree.new(*messages)
20
- end
21
-
22
- expect { |n, i|
23
- trees[i].include?("L#{n/2}", n/2)
24
- }.to perform_logarithmic.in_range(8, 8 << 12).sample(100).times
25
- end
26
- end
data/spec/spec_helper.rb DELETED
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- if ENV['COVERAGE'] || ENV['TRAVIS']
4
- require 'simplecov'
5
- require 'coveralls'
6
-
7
- SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
8
- SimpleCov::Formatter::HTMLFormatter,
9
- Coveralls::SimpleCov::Formatter
10
- ]
11
-
12
- SimpleCov.start do
13
- command_name 'spec'
14
- add_filter 'spec'
15
- end
16
- end
17
-
18
- require "bundler/setup"
19
- require "rspec-benchmark"
20
- require "merkle_tree"
21
-
22
- RSpec.configure do |config|
23
- config.include RSpec::Benchmark::Matchers
24
-
25
- # Enable flags like --only-failures and --next-failure
26
- # config.example_status_persistence_file_path = ".rspec_status"
27
-
28
- # Disable RSpec exposing methods globally on `Module` and `main`
29
- config.disable_monkey_patching!
30
-
31
- config.expect_with :rspec do |c|
32
- c.syntax = :expect
33
- end
34
- end
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe MerkleTree, '#add' do
4
- it "adds one message" do
5
- merkle_tree = MerkleTree.new("L1", "L2", "L3", "L4")
6
- expanded_tree = MerkleTree.new("L1", "L2", "L3", "L4", "L5")
7
-
8
- merkle_tree << "L5"
9
-
10
- expect(merkle_tree.leaves.size).to eq(expanded_tree.leaves.size)
11
- expect(merkle_tree.size).to eq(expanded_tree.size)
12
- expect(merkle_tree.root.value).to eq(expanded_tree.root.value)
13
- end
14
-
15
- it "adds even messages" do
16
- merkle_tree = MerkleTree.new("L1", "L2", "L3", "L4")
17
- expanded_tree = MerkleTree.new("L1", "L2", "L3", "L4", "L5", "L6")
18
-
19
- merkle_tree.add("L5", "L6")
20
-
21
- expect(merkle_tree.leaves.size).to eq(expanded_tree.leaves.size)
22
- expect(merkle_tree.size).to eq(expanded_tree.size)
23
- expect(merkle_tree.root.value).to eq(expanded_tree.root.value)
24
- end
25
-
26
- it "adds messages double the size" do
27
- merkle_tree = MerkleTree.new("L1", "L2", "L3", "L4")
28
- expanded_tree = MerkleTree.new("L1", "L2", "L3", "L4", "L5", "L6", "L7", "L8")
29
-
30
- merkle_tree.add("L5", "L6", "L7", "L8")
31
-
32
- expect(merkle_tree.leaves.size).to eq(expanded_tree.leaves.size)
33
- expect(merkle_tree.root.value).to eq(expanded_tree.root.value)
34
- expect(merkle_tree.size).to eq(expanded_tree.size)
35
- end
36
- end
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe MerkleTree, '#auth_path' do
4
- it "fails to find authentication path for an index" do
5
- merkle_tree = MerkleTree.new("L1", "L2", "L3", "L4")
6
-
7
- expect(merkle_tree.auth_path(100)).to eq([MerkleTree::Node::EMPTY])
8
- end
9
-
10
- it "finds authentication path for an index" do
11
- merkle_tree = MerkleTree.new("L1", "L2", "L3", "L4")
12
-
13
- expect(merkle_tree.auth_path(2)).to eq([
14
- [:left,"f2b92f33b56466fce14bc2ccf6a92f6edfcd8111446644c20221d6ae831dd67c"],
15
- [:right,"4a5a97c6433c4c062457e9335709d57493e75527809d8a9586c141e591ac9f2c"]
16
- ])
17
- end
18
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe MerkleTree, '#empty?' do
4
- it "returns true when tree has no messages" do
5
- merkle_tree = MerkleTree.new
6
-
7
- expect(merkle_tree.empty?).to eq(true)
8
- end
9
-
10
- it "returns false when tree has messages" do
11
- merkle_tree = MerkleTree.new("L1", "L2", "L3", "L4", "L5", "L6", "L7", "L8")
12
-
13
- expect(merkle_tree.empty?).to eq(false)
14
- end
15
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe MerkleTree, '#height' do
4
- it "has no messages" do
5
- merkle_tree = MerkleTree.new
6
-
7
- expect(merkle_tree.height).to eq(0)
8
- end
9
-
10
- it "calculates tree height" do
11
- merkle_tree = MerkleTree.new("L1", "L2", "L3", "L4", "L5", "L6")
12
-
13
- expect(merkle_tree.height).to eq(3)
14
- end
15
- end
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe MerkleTree, '#include?' do
4
- it "checks message inclusion in an empty tree" do
5
- merkle_tree = MerkleTree.new
6
-
7
- expect(merkle_tree.include?("L3", 2)).to eq(false)
8
- end
9
-
10
- it "checks valid message inclusion in 4 signatures tree" do
11
- merkle_tree = MerkleTree.new("L1", "L2", "L3", "L4")
12
-
13
- expect(merkle_tree.include?("L3", 2)).to eq(true)
14
- end
15
-
16
- it "checks valid message inclusion in 8 signatures tree" do
17
- merkle_tree = MerkleTree.new("L1", "L2", "L3", "L4", "L5", "L6", "L7", "L8")
18
-
19
- expect(merkle_tree.include?("L5", 4)).to eq(true)
20
- end
21
-
22
- it "checks invalid message inclusion in 8 signatures tree" do
23
- merkle_tree = MerkleTree.new("L1", "L2", "L3", "L4", "L5", "L6", "L7", "L8")
24
-
25
- expect(merkle_tree.include?("invalid", 4)).to eq(false)
26
- end
27
- end
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe MerkleTree::Leaf, '::build' do
4
- it "creates a leaf node" do
5
- leaf_node = MerkleTree::Leaf.build("L1", 0)
6
-
7
- expect(leaf_node.value).to eq("dffe8596427fc50e8f64654a609af134d45552f18bbecef90b31135a9e7acaa0")
8
- end
9
- end
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe MerkleTree::Leaf, '#==' do
4
- it "compares two different leaves with the same message" do
5
- leaf_a = MerkleTree::Leaf.build("L1", 0)
6
- leaf_b = MerkleTree::Leaf.build("L1", 1)
7
-
8
- expect(leaf_a).to_not eq(leaf_b)
9
- end
10
-
11
- it "compares successfully only with the same leaf" do
12
- leaf = MerkleTree::Leaf.build("L1", 0)
13
-
14
- expect(leaf).to eq(leaf)
15
- end
16
- end
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe MerkleTree, '#leaves' do
4
- it "returns empty array when tree has no leaves" do
5
- merkle_tree = MerkleTree.new
6
-
7
- expect(merkle_tree.leaves).to be_empty
8
- end
9
-
10
- it "returns all leaves" do
11
- leaves = ["L1", "L2", "L3", "L4", "L5", "L6", "L7", "L8"]
12
- merkle_tree = MerkleTree.new(*leaves)
13
-
14
- expect(merkle_tree.leaves.size).to eq(leaves.size)
15
- end
16
- end
@@ -1,80 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe MerkleTree, '#new' do
4
- it "creates tree from even number of messages" do
5
- merkle_tree = MerkleTree.new("L1", "L2", "L3", "L4")
6
-
7
- expect(merkle_tree.to_h).to eq({
8
- root: {
9
- value: "63442ffc2d48a92c8ba746659331f273748ccede648b27f4eacf00cb0786c439",
10
- left: {
11
- value: "f2b92f33b56466fce14bc2ccf6a92f6edfcd8111446644c20221d6ae831dd67c",
12
- left: {
13
- value: "dffe8596427fc50e8f64654a609af134d45552f18bbecef90b31135a9e7acaa0"
14
- },
15
- right: {
16
- value: "d76354d8457898445bb69e0dc0dc95fb74cc3cf334f8c1859162a16ad0041f8d"
17
- }
18
- },
19
- right: {
20
- value: "8f75b0c1b3d1c0bb2eda264a43f8fdc5c72c853c95fbf2b01c1d5a3e12c6fe9a",
21
- left: {
22
- value: "842983de8fb1d277a3fad5c8295c7a14317c458718a10c5a35b23e7f992a5c80"
23
- },
24
- right: {
25
- value: "4a5a97c6433c4c062457e9335709d57493e75527809d8a9586c141e591ac9f2c"
26
- }
27
- }
28
- }
29
- })
30
- end
31
-
32
- it "creates tree from odd number of messages by duplicating the last message" do
33
- merkle_tree = MerkleTree.new("L1", "L2", "L3")
34
-
35
- expect(merkle_tree.to_h).to eq({
36
- root: {
37
- value: "bdb1b6778b2923c883a078a6d8dbf40f99bb1a58bf5f650349f965bd8a222f43",
38
- left: {
39
- value: "f2b92f33b56466fce14bc2ccf6a92f6edfcd8111446644c20221d6ae831dd67c",
40
- left: {
41
- value: "dffe8596427fc50e8f64654a609af134d45552f18bbecef90b31135a9e7acaa0"
42
- },
43
- right: {
44
- value: "d76354d8457898445bb69e0dc0dc95fb74cc3cf334f8c1859162a16ad0041f8d"
45
- }
46
- },
47
- right: {
48
- value: "5ca8ce04894dcfaacfe7b77d5f003b355ca0df2e0055d6c9fa3b006a8e56a2ba",
49
- left: {
50
- value: "842983de8fb1d277a3fad5c8295c7a14317c458718a10c5a35b23e7f992a5c80"
51
- },
52
- right: {
53
- value: "842983de8fb1d277a3fad5c8295c7a14317c458718a10c5a35b23e7f992a5c80"
54
- }
55
- }
56
- }
57
- })
58
- end
59
-
60
- it "changes hashing function" do
61
- merkle_tree = MerkleTree.new("L1", "L2", "L3", "L4",
62
- digest: -> (val) { "(#{val}h)"})
63
-
64
- expect(merkle_tree.to_h).to eq({
65
- root: {
66
- value: "(((L1h)(L2h)h)((L3h)(L4h)h)h)",
67
- left: {
68
- value: "((L1h)(L2h)h)",
69
- left: { value: "(L1h)" },
70
- right: { value: "(L2h)" },
71
- },
72
- right: {
73
- value: "((L3h)(L4h)h)",
74
- left: { value: "(L3h)" },
75
- right: { value: "(L4h)" }
76
- }
77
- }
78
- })
79
- end
80
- end
@@ -1,56 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe MerkleTree::Node, '::build' do
4
- it "combines two leaf nodes" do
5
- nodes = [
6
- MerkleTree::Leaf.build("L1", 0),
7
- MerkleTree::Leaf.build("L2", 1)
8
- ]
9
-
10
- node = MerkleTree::Node.build(*nodes)
11
-
12
- expect(node.value).to eq('f2b92f33b56466fce14bc2ccf6a92f6edfcd8111446644c20221d6ae831dd67c')
13
- expect(node.left).to eq(nodes[0])
14
- expect(node.right).to eq(nodes[1])
15
- expect(node.left_index).to eq(0)
16
- expect(node.right_index).to eq(1)
17
- end
18
-
19
- it "combines leaf node with empty node" do
20
- leaf = MerkleTree::Leaf.build("L1", 0)
21
- nodes = [
22
- leaf,
23
- MerkleTree::Node::EMPTY
24
- ]
25
-
26
- node = MerkleTree::Node.build(*nodes)
27
-
28
- expect(node.value).to eq("15253c068a787616f4a6580d34a099f5bde3991f771a5c8a7841638db7e69e24")
29
-
30
- expect(node.left_index).to eq(0)
31
- expect(node.right_index).to eq(MerkleTree::Node::UNDEFINED)
32
- end
33
-
34
- it "combines 2 nodes" do
35
- nodes_left = [
36
- MerkleTree::Leaf.build("L1", 0),
37
- MerkleTree::Leaf.build("L2", 1)
38
- ]
39
-
40
- nodes_right = [
41
- MerkleTree::Leaf.build("L3", 2),
42
- MerkleTree::Leaf.build("L4", 3)
43
- ]
44
-
45
- node_left = MerkleTree::Node.build(*nodes_left)
46
- node_right = MerkleTree::Node.build(*nodes_right)
47
-
48
- node = MerkleTree::Node.build(node_left, node_right)
49
-
50
- expect(node.value).to eq("63442ffc2d48a92c8ba746659331f273748ccede648b27f4eacf00cb0786c439")
51
- expect(node.left).to eq(node_left)
52
- expect(node.right).to eq(node_right)
53
- expect(node.left_index).to eq(0)
54
- expect(node.right_index).to eq(3)
55
- end
56
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe MerkleTree::Node, '#==' do
4
- it "compares two different nodes" do
5
- nodes_left = [
6
- MerkleTree::Leaf.build("L1", 0),
7
- MerkleTree::Leaf.build("L2", 1)
8
- ]
9
-
10
- nodes_right = [
11
- MerkleTree::Leaf.build("L3", 2),
12
- MerkleTree::Leaf.build("L4", 3)
13
- ]
14
-
15
- node_left = MerkleTree::Node.build(*nodes_left)
16
- node_right = MerkleTree::Node.build(*nodes_right)
17
-
18
- expect(node_left).to_not eq(node_right)
19
- end
20
-
21
- it "compares same node" do
22
- nodes = [
23
- MerkleTree::Leaf.build("L1", 0),
24
- MerkleTree::Leaf.build("L2", 1)
25
- ]
26
-
27
- node = MerkleTree::Node.build(*nodes)
28
-
29
- expect(node).to eq(node)
30
- end
31
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe MerkleTree, '#root' do
4
- it "returns empty root when no messages" do
5
- merkle_tree = MerkleTree.new
6
-
7
- expect(merkle_tree.root).to eq(MerkleTree::Node::EMPTY)
8
- end
9
-
10
- it "calculates root signature" do
11
- merkle_tree = MerkleTree.new("L1", "L2", "L3", "L4")
12
-
13
- expect(merkle_tree.root.value).to eq("63442ffc2d48a92c8ba746659331f273748ccede648b27f4eacf00cb0786c439")
14
- end
15
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe MerkleTree, '#size' do
4
- it "returns 0 when tree has no messages" do
5
- merkle_tree = MerkleTree.new
6
-
7
- expect(merkle_tree.size).to eq(0)
8
- end
9
-
10
- it "returns 15 when tree has 8 messages" do
11
- merkle_tree = MerkleTree.new("L1", "L2", "L3", "L4", "L5", "L6", "L7", "L8")
12
-
13
- expect(merkle_tree.size).to eq(15)
14
- end
15
- end
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe MerkleTree, '#subtree' do
4
- it "return empty node for non existent index" do
5
- merkle_tree = MerkleTree.new("L1", "L2", "L3", "L4")
6
-
7
- expect(merkle_tree.subtree(10)).to eq(MerkleTree::Node::EMPTY)
8
- end
9
-
10
- it "extracts subtree for a given index" do
11
- merkle_tree = MerkleTree.new("L1", "L2", "L3", "L4", "L5", "L6", "L7", "L8")
12
-
13
- expect(merkle_tree.subtree(2).to_h).to eq({
14
- value: "63442ffc2d48a92c8ba746659331f273748ccede648b27f4eacf00cb0786c439",
15
- left: {
16
- value: "f2b92f33b56466fce14bc2ccf6a92f6edfcd8111446644c20221d6ae831dd67c",
17
- left: {
18
- value: "dffe8596427fc50e8f64654a609af134d45552f18bbecef90b31135a9e7acaa0",
19
- },
20
- right: {
21
- value: "d76354d8457898445bb69e0dc0dc95fb74cc3cf334f8c1859162a16ad0041f8d",
22
- }
23
- },
24
- right: {
25
- value: "8f75b0c1b3d1c0bb2eda264a43f8fdc5c72c853c95fbf2b01c1d5a3e12c6fe9a",
26
- left: {
27
- value: "842983de8fb1d277a3fad5c8295c7a14317c458718a10c5a35b23e7f992a5c80",
28
- },
29
- right: {
30
- value: "4a5a97c6433c4c062457e9335709d57493e75527809d8a9586c141e591ac9f2c"
31
- }
32
- }
33
- })
34
- end
35
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe MerkleTree, '#to_s' do
4
- it "prints all tree signatures indented by 2 spaces" do
5
- merkle_tree = MerkleTree.new("L1", "L2", "L3", "L4")
6
-
7
- expect(merkle_tree.to_s).to eq([
8
- "63442ffc2d48a92c8ba746659331f273748ccede648b27f4eacf00cb0786c439",
9
- " f2b92f33b56466fce14bc2ccf6a92f6edfcd8111446644c20221d6ae831dd67c",
10
- " dffe8596427fc50e8f64654a609af134d45552f18bbecef90b31135a9e7acaa0",
11
- " d76354d8457898445bb69e0dc0dc95fb74cc3cf334f8c1859162a16ad0041f8d",
12
- " 8f75b0c1b3d1c0bb2eda264a43f8fdc5c72c853c95fbf2b01c1d5a3e12c6fe9a",
13
- " 842983de8fb1d277a3fad5c8295c7a14317c458718a10c5a35b23e7f992a5c80",
14
- " 4a5a97c6433c4c062457e9335709d57493e75527809d8a9586c141e591ac9f2c"
15
- ].join("\n"))
16
- end
17
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe MerkleTree, '#update' do
4
- it "updates a leaf at index position with a new message" do
5
- merkle_tree = MerkleTree.new("L1", "L2", "L3", "L4")
6
- updated_merkle_tree = MerkleTree.new("L1", "L2", "L3*", "L4")
7
- expected_leaf = MerkleTree::Leaf.build("L3*", 2)
8
-
9
- updated_leaf = merkle_tree.update("L3*", 2)
10
-
11
- expect(updated_leaf.value).to eq(expected_leaf.value)
12
- expect(merkle_tree.root.value).to eq(updated_merkle_tree.root.value)
13
- end
14
-
15
- it "updates a leaf in tree with 8 messages with a new message" do
16
- merkle_tree = MerkleTree.new("L1", "L2", "L3", "L4", "L5", "L6", "L7", "L8")
17
- updated_merkle_tree = MerkleTree.new("L1", "L2", "L3*", "L4", "L5", "L6", "L7", "L8")
18
- expected_leaf = MerkleTree::Leaf.build("L3*", 2)
19
-
20
- updated_leaf = merkle_tree.update("L3*", 2)
21
-
22
- expect(updated_leaf.value).to eq(expected_leaf.value)
23
- expect(merkle_tree.root.value).to eq(updated_merkle_tree.root.value)
24
- end
25
- end
data/tasks/console.rake DELETED
@@ -1,9 +0,0 @@
1
- desc 'Load gem inside irb console'
2
- task :console do
3
- require 'irb'
4
- require 'irb/completion'
5
- require File.join(__FILE__, '../../lib/merkle_tree')
6
- ARGV.clear
7
- IRB.start
8
- end
9
- task c: %w[ console ]
data/tasks/coverage.rake DELETED
@@ -1,9 +0,0 @@
1
- desc 'Measure code coverage'
2
- task :coverage do
3
- begin
4
- original, ENV['COVERAGE'] = ENV['COVERAGE'], 'true'
5
- Rake::Task['spec'].invoke
6
- ensure
7
- ENV['COVERAGE'] = original
8
- end
9
- end
data/tasks/spec.rake DELETED
@@ -1,32 +0,0 @@
1
- begin
2
- require 'rspec/core/rake_task'
3
-
4
- desc 'Run all specs'
5
- RSpec::Core::RakeTask.new(:spec) do |task|
6
- task.pattern = 'spec/{unit,integration}{,/*/**}/*_spec.rb'
7
- end
8
-
9
- namespace :spec do
10
- desc 'Run unit specs'
11
- RSpec::Core::RakeTask.new(:unit) do |task|
12
- task.pattern = 'spec/unit{,/*/**}/*_spec.rb'
13
- end
14
-
15
- desc 'Run integration specs'
16
- RSpec::Core::RakeTask.new(:integration) do |task|
17
- task.pattern = 'spec/integration{,/*/**}/*_spec.rb'
18
- end
19
-
20
- desc 'Run integration specs'
21
- RSpec::Core::RakeTask.new(:perf) do |task|
22
- task.pattern = 'spec/perf{,/*/**}/*_spec.rb'
23
- end
24
- end
25
-
26
- rescue LoadError
27
- %w[spec spec:unit spec:integration].each do |name|
28
- task name do
29
- $stderr.puts "In order to run #{name}, do `gem install rspec`"
30
- end
31
- end
32
- end