merkle_tree 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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