bitcoin 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. metadata +17 -288
  2. data/.rspec +0 -1
  3. data/.rvmrc +0 -1
  4. data/Gemfile +0 -4
  5. data/Gemfile.lock +0 -98
  6. data/Guardfile +0 -38
  7. data/README.markdown +0 -24
  8. data/Rakefile +0 -1
  9. data/bin/rbcoin +0 -8
  10. data/bitcoin.gemspec +0 -40
  11. data/config/cucumber.yml +0 -5
  12. data/config/darcs.boring +0 -121
  13. data/doc/DEFINITION_OF_DONE.markdown +0 -12
  14. data/doc/HISTORY.markdown +0 -19
  15. data/doc/LICENCE.markdown +0 -25
  16. data/doc/TODO.markdown +0 -31
  17. data/doc/UBIQUITOUS_LANGUAGE.markdown +0 -15
  18. data/features/descriptions/command_help.feature +0 -31
  19. data/features/descriptions/satoshi_wallet/add_address.feature +0 -49
  20. data/features/descriptions/satoshi_wallet/show_addresses.feature +0 -18
  21. data/features/descriptions/satoshi_wallet/show_version.feature +0 -17
  22. data/features/descriptions/satoshi_wallet/subcommand_help.feature +0 -20
  23. data/features/fixtures/ABOUT_FIXTURES.markdown +0 -6
  24. data/features/fixtures/addressbook_wallet.dat +0 -0
  25. data/features/fixtures/new_wallet.dat +0 -0
  26. data/features/step_definitions/command_steps.rb +0 -3
  27. data/features/step_definitions/wallet_steps.rb +0 -11
  28. data/features/support/env.rb +0 -9
  29. data/lib/bitcoin.rb +0 -5
  30. data/lib/bitcoin/cli.rb +0 -35
  31. data/lib/bitcoin/commands.rb +0 -3
  32. data/lib/bitcoin/commands/help_command.rb +0 -32
  33. data/lib/bitcoin/commands/satoshi_wallet.rb +0 -11
  34. data/lib/bitcoin/commands/satoshi_wallet/add_address_command.rb +0 -61
  35. data/lib/bitcoin/commands/satoshi_wallet/show_addresses_command.rb +0 -16
  36. data/lib/bitcoin/commands/satoshi_wallet/show_version_command.rb +0 -15
  37. data/lib/bitcoin/commands/satoshi_wallet_command.rb +0 -37
  38. data/lib/bitcoin/commands/satoshi_wallet_command_environment.rb +0 -28
  39. data/lib/bitcoin/console/capturing_stream_bundle.rb +0 -42
  40. data/lib/bitcoin/console/stream_bundle.rb +0 -21
  41. data/lib/bitcoin/data_access/satoshi/bdb_satoshi_wallet_repository.rb +0 -155
  42. data/lib/bitcoin/data_access/satoshi/satoshi_version.rb +0 -58
  43. data/lib/bitcoin/data_access/satoshi/satoshi_wallet.rb +0 -39
  44. data/lib/bitcoin/domain/address_book.rb +0 -19
  45. data/lib/bitcoin/domain/bitcoin_address.rb +0 -33
  46. data/lib/bitcoin/filesystem/empty_temp_dir.rb +0 -74
  47. data/lib/bitcoin/rspec/argument_matchers.rb +0 -1
  48. data/lib/bitcoin/rspec/argument_matchers/block_evaluating_to_matcher.rb +0 -23
  49. data/lib/bitcoin/rspec/directory_helpers.rb +0 -22
  50. data/lib/bitcoin/version.rb +0 -3
  51. data/spec/bitcoin/cli_spec.rb +0 -128
  52. data/spec/bitcoin/commands/help_command_spec.rb +0 -53
  53. data/spec/bitcoin/commands/satoshi_wallet/add_address_command_spec.rb +0 -149
  54. data/spec/bitcoin/commands/satoshi_wallet/show_addresses_command_spec.rb +0 -26
  55. data/spec/bitcoin/commands/satoshi_wallet/show_version_command_spec.rb +0 -26
  56. data/spec/bitcoin/commands/satoshi_wallet_command_environment_spec.rb +0 -76
  57. data/spec/bitcoin/commands/satoshi_wallet_command_spec.rb +0 -73
  58. data/spec/bitcoin/console/_contracts/stream_bundle_contract.rb +0 -29
  59. data/spec/bitcoin/console/capturing_stream_bundle_spec.rb +0 -74
  60. data/spec/bitcoin/console/stream_bundle_spec.rb +0 -13
  61. data/spec/bitcoin/data_access/satoshi/bdb_satoshi_wallet_repository_spec.rb +0 -78
  62. data/spec/bitcoin/data_access/satoshi/satoshi_version_spec.rb +0 -112
  63. data/spec/bitcoin/data_access/satoshi/satoshi_wallet_spec.rb +0 -102
  64. data/spec/bitcoin/domain/address_book_spec.rb +0 -63
  65. data/spec/bitcoin/domain/bitcoin_address_spec.rb +0 -52
  66. data/spec/bitcoin/filesystem/empty_temp_dir_spec.rb +0 -170
  67. data/spec/bitcoin/rspec/argument_matchers/block_evaluating_to_matcher_spec.rb +0 -36
  68. data/spec/spec_helper.rb +0 -29
@@ -1,58 +0,0 @@
1
- module Bitcoin
2
- module DataAccess
3
- module Satoshi
4
- class SatoshiVersion
5
- include Comparable
6
-
7
- class << self
8
- # Takes an array of unsigned bytes as extracted from a BDB wallet
9
- def from_wallet_bytes(bytes)
10
- from_wallet_int(bytes.pack("C*").unpack("V").first)
11
- end
12
-
13
- # Takes an 4-byte unsigned little-endian integer as extracted from a BDB wallet
14
- def from_wallet_int(int_version)
15
- new(*[int_version / 1_000_000, (int_version / 10_000) % 100, (int_version / 100) % 100, int_version % 100])
16
- end
17
- end
18
-
19
- def initialize(*version_components)
20
- @version_components = pad_4(version_components)
21
- end
22
-
23
- def <=>(other)
24
- other.compare_version_components(@version_components)
25
- end
26
-
27
- def to_s
28
- components = @version_components.dup
29
- components.delete_at(3) if components[3] == 0
30
- components.join(".")
31
- end
32
-
33
- alias_method :to_str, :to_s
34
-
35
- def to_wallet_bytes
36
- [
37
- @version_components.zip([1_000_000, 10_000, 100, 1]).map { |component, multiplier|
38
- component * multiplier
39
- }.inject(:+)
40
- ].pack("V").unpack("C*")
41
- end
42
-
43
- protected
44
-
45
- def compare_version_components(other_version_components)
46
- other_version_components <=> @version_components
47
- end
48
-
49
- # Pads 3-digit arrays with a 4th 0 value if necessary
50
- def pad_4(components)
51
- ([0] * 4).tap do |padded|
52
- padded[0...components.length] = components
53
- end
54
- end
55
- end
56
- end
57
- end
58
- end
@@ -1,39 +0,0 @@
1
- require 'bitcoin/data_access/satoshi/bdb_satoshi_wallet_repository'
2
- require 'bitcoin/data_access/satoshi/satoshi_version'
3
- require 'bitcoin/domain/address_book'
4
- require 'bitcoin/domain/bitcoin_address'
5
-
6
- module Bitcoin
7
- module DataAccess
8
- module Satoshi
9
- class SatoshiWallet
10
- class << self
11
- def open(options, &block)
12
- raise ArgumentError.new("You must provide a block to SatoshiWallet.new") unless block_given?
13
- yield(new(BDBSatoshiWalletRepository.new(options[:wallet_filename], db_dirname: options[:db_dirname])))
14
- end
15
- end
16
-
17
- def initialize(wallet_repository)
18
- @wallet_repository = wallet_repository
19
- end
20
-
21
- def version
22
- SatoshiVersion.from_wallet_int(@wallet_repository.get_value_immediate_uint32le("version"))
23
- end
24
-
25
- def addresses
26
- addresses =
27
- @wallet_repository.get_key_and_value_data_string_utf8("name").map { |key_data, value_data|
28
- { address: Domain::BitcoinAddress.new(key_data), name: value_data }
29
- }
30
- Domain::AddressBook.new(addresses)
31
- end
32
-
33
- def add_address(bitcoin_address, options)
34
- @wallet_repository.set_value_with_key_data_string_utf8("name", bitcoin_address.to_s, options[:name])
35
- end
36
- end
37
- end
38
- end
39
- end
@@ -1,19 +0,0 @@
1
- module Bitcoin
2
- module Domain
3
- class AddressBook
4
- def initialize(address_list = [])
5
- @address_list = Marshal.load(Marshal.dump(address_list))
6
- end
7
-
8
- def to_a
9
- @address_list
10
- end
11
-
12
- def to_s
13
- @address_list.map { |address|
14
- "#{address[:address]} #{address[:name]}"
15
- }.join("\n")
16
- end
17
- end
18
- end
19
- end
@@ -1,33 +0,0 @@
1
- module Bitcoin
2
- module Domain
3
- # A Value Object representing a Bitcoin address
4
- class BitcoinAddress
5
- # An error indicating that we tried to create a BitcoinAddress with an invalid string
6
- class InvalidBitcoinAddressError < ArgumentError
7
- def initialize(address)
8
- super(%'The address "#{address}" is not a valid Bitcoin address')
9
- end
10
- end
11
-
12
- def initialize(string_address)
13
- raise InvalidBitcoinAddressError.new(string_address) unless string_address.length == 34
14
- @string_address = string_address
15
- end
16
-
17
- def to_s
18
- @string_address
19
- end
20
-
21
- def ==(other)
22
- other.is_a?(BitcoinAddress) &&
23
- other.has_string_address_representation?(@string_address)
24
- end
25
-
26
- protected
27
-
28
- def has_string_address_representation?(string_representation)
29
- @string_address == string_representation
30
- end
31
- end
32
- end
33
- end
@@ -1,74 +0,0 @@
1
- require 'fileutils'
2
-
3
- module Bitcoin
4
- module FileSystem
5
- # A class for managing temporary directories
6
- #
7
- # Example:
8
- #
9
- # EmptyTempDir.new(with_name: "foo", parallel_to: "/tmp/myfile") do |temp_dir|
10
- # # ...
11
- # end
12
- #
13
- # creates the directory "/tmp/foo". It will be deleted at the end of the block,
14
- # regardless of whether it existed before or not.
15
- #
16
- # If it existed before, it will be emptied before the block starts.
17
- #
18
- # If the requested directory name exists but is a file, the behaviour is undefined
19
- class EmptyTempDir
20
- class << self
21
- def open(options, &block)
22
- raise ArgumentError.new("You must provide a block to EmptyTempDir.open") if block.nil?
23
- BlockRunner.new(dirname(options[:with_name], options[:parallel_to])).run(block)
24
- end
25
-
26
- private
27
-
28
- def dirname(name, parallel_to)
29
- File.expand_path(File.join(File.dirname(parallel_to), name))
30
- end
31
- end
32
-
33
- class BlockRunner
34
- def initialize(path)
35
- @path = path
36
- raise_if_path_is_unsafe
37
- end
38
-
39
- def run(proc)
40
- ensure_empty_directory(absolute_path)
41
- result = proc.(self)
42
- ensure
43
- FileUtils.rm_rf(absolute_path)
44
- result
45
- end
46
-
47
- def absolute_path
48
- @path
49
- end
50
-
51
- private
52
-
53
- def ensure_empty_directory(absolute_path)
54
- if File.directory?(@path)
55
- File.join(@path, "*")
56
- FileUtils.rm_rf(Dir[path_entries_wildcard])
57
- else
58
- FileUtils.mkdir(@path)
59
- end
60
- end
61
-
62
- def raise_if_path_is_unsafe
63
- if path_entries_wildcard =~ %r"^/+\*"
64
- raise ArgumentError.new("Unacceptable directory name for EmptyTempDir")
65
- end
66
- end
67
-
68
- def path_entries_wildcard
69
- File.join(@path, "*")
70
- end
71
- end
72
- end
73
- end
74
- end
@@ -1 +0,0 @@
1
- require_relative 'argument_matchers/block_evaluating_to_matcher'
@@ -1,23 +0,0 @@
1
- module Bitcoin
2
- module RSpec
3
- module ArgumentMatchers
4
- class BlockEvaluatingToMatcher
5
- def initialize(expected_value)
6
- @expected_value = expected_value
7
- end
8
-
9
- def description
10
- "block_evaluating_to(#{@expected_value.inspect})"
11
- end
12
-
13
- def ==(other)
14
- @expected_value == other.()
15
- end
16
- end
17
-
18
- def block_evaluating_to(expected_value)
19
- BlockEvaluatingToMatcher.new(expected_value)
20
- end
21
- end
22
- end
23
- end
@@ -1,22 +0,0 @@
1
- module Bitcoin
2
- module RSpec
3
- module DirectoryHelpers
4
- module ClassMethods
5
- def ensure_empty_test_dir(dirname)
6
- before(:each) do
7
- ensure_empty_directory(dirname)
8
- end
9
- end
10
- end
11
-
12
- def self.included(host)
13
- host.extend(ClassMethods)
14
- end
15
-
16
- def ensure_empty_directory(dirname)
17
- FileUtils.rm_rf(dirname)
18
- FileUtils.mkdir_p(dirname)
19
- end
20
- end
21
- end
22
- end
@@ -1,3 +0,0 @@
1
- module Bitcoin
2
- VERSION = "0.1.2"
3
- end
@@ -1,128 +0,0 @@
1
- require 'spec_helper'
2
-
3
- require 'bitcoin/cli'
4
-
5
- # Dependencies only used in the spec
6
- require 'bitcoin/console/capturing_stream_bundle'
7
-
8
- module Bitcoin
9
- describe CLI do
10
- let(:stream_bundle) { Console::CapturingStreamBundle.test_bundle }
11
- let(:cli) { CLI.new(stream_bundle) }
12
-
13
- describe "help" do
14
- shared_examples_for "inputs that trigger a full help message" do
15
- let(:help_command) { mock(Commands::HelpCommand, show_help: nil) }
16
-
17
- before(:each) do
18
- Commands::HelpCommand.stub(new: help_command)
19
- end
20
-
21
- it "creates a Help Command" do
22
- Commands::HelpCommand.should_receive(:new).with(stream_bundle)
23
- run_command
24
- end
25
-
26
- it "shows the full help" do
27
- help_command.should_receive(:show_help)
28
- run_command
29
- end
30
-
31
- it "returns 0", because: "the CLI wrapper exits with this value" do
32
- run_command.should eq 0
33
- end
34
- end
35
-
36
- describe "<no command>" do
37
- def run_command
38
- cli.run([ ])
39
- end
40
-
41
- it_behaves_like "inputs that trigger a full help message"
42
- end
43
-
44
- describe "help" do
45
- def run_command
46
- cli.run(%w[ help ])
47
- end
48
-
49
- it_behaves_like "inputs that trigger a full help message"
50
- end
51
-
52
- describe "<unknown command>" do
53
- let(:help_command) { mock(Commands::HelpCommand, show_unknown_command_help: nil) }
54
-
55
- before(:each) do
56
- Commands::HelpCommand.stub(new: help_command)
57
- end
58
-
59
- def run_command
60
- cli.run(%w[ thiscommanddoesnotexist ])
61
- end
62
-
63
- it "creates a Help Command" do
64
- Commands::HelpCommand.should_receive(:new).with(stream_bundle)
65
- run_command
66
- end
67
-
68
- it "shows the unknown command help" do
69
- help_command.should_receive(:show_unknown_command_help).with("thiscommanddoesnotexist")
70
- run_command
71
- end
72
-
73
- it "returns 1", because: "the CLI wrapper exits with this value" do
74
- run_command.should eq 1
75
- end
76
- end
77
- end
78
-
79
- describe "satoshi-wallet" do
80
- let(:wallet_command) { mock(Commands::SatoshiWalletCommand, run: nil) }
81
- let(:satoshi_wallet_command_environment) { mock(Commands::SatoshiWalletCommandEnvironment) }
82
-
83
- before(:each) do
84
- Commands::SatoshiWalletCommand.stub(new: wallet_command)
85
- Commands::SatoshiWalletCommandEnvironment.stub(new: satoshi_wallet_command_environment)
86
- end
87
-
88
- def run_command
89
- cli.run(%W[ satoshi-wallet subcommand-name wallet.dat foo bar ])
90
- end
91
-
92
- it "creates an environment" do
93
- Commands::SatoshiWalletCommandEnvironment.should_receive(:new).with(stream_bundle)
94
- run_command
95
- end
96
-
97
- it "creates a command" do
98
- Commands::SatoshiWalletCommand.should_receive(:new).with(stream_bundle, satoshi_wallet_command_environment)
99
- run_command
100
- end
101
-
102
- it "runs the command" do
103
- wallet_command.should_receive(:run).with(%w[ subcommand-name wallet.dat foo bar ])
104
- run_command
105
- end
106
-
107
- context "the command succeeds" do
108
- before(:each) do
109
- wallet_command.stub(run: nil)
110
- end
111
-
112
- it "returns 0", because: "the CLI wrapper exits with this value" do
113
- run_command.should eq 0
114
- end
115
- end
116
-
117
- context "the command fails" do
118
- before(:each) do
119
- wallet_command.stub(:run).and_raise(CLI::CommandError.new)
120
- end
121
-
122
- it "returns 1", because: "the CLI wrapper exits with this value" do
123
- run_command.should eq 1
124
- end
125
- end
126
- end
127
- end
128
- end
@@ -1,53 +0,0 @@
1
- require 'spec_helper'
2
-
3
- require 'bitcoin/commands/help_command'
4
- require 'bitcoin/console/capturing_stream_bundle'
5
-
6
- module Bitcoin
7
- module Commands
8
- describe HelpCommand do
9
- let(:stream_bundle) { Console::CapturingStreamBundle.test_bundle }
10
-
11
- subject { HelpCommand.new(stream_bundle) }
12
-
13
- describe "#show_help" do
14
- it "prints the full help" do
15
- subject.show_help
16
- # Duplicated from the Cucumber feature to get us going
17
- stream_bundle.captured_output.should eq(
18
- -%{
19
- Usage: rbcoin COMMAND ...
20
-
21
- Commands:
22
- help Display help about rbcoin and rbcoin commands
23
- satoshi-wallet Manipulate the wallet.dat file of the original client
24
-
25
- Use "rbcoin COMMAND --help" or "rbcoin help COMMAND" for help on a single command
26
- Use "rbcoin --version" to see the rbcoin version number
27
- Use "rbcoin --exact-version" to see the all version details (with dependencies)
28
- } + "\n"
29
- )
30
- end
31
- end
32
-
33
- describe "#show_unknown_command_help" do
34
- it "prints an error message to the output", because: "it's currently not this object that detected the error" do
35
- subject.show_unknown_command_help("thiscommanddoesnotexist")
36
- # Duplicated from the Cucumber feature
37
- stream_bundle.captured_output.should eq(
38
- -%{
39
- rbcoin failed: No such command "thiscommanddoesnotexist"
40
- Try: `rbcoin help`
41
- } + "\n"
42
- )
43
- end
44
-
45
- it "doesn't raise an error", because: "it's currently not this object that detected the error" do
46
- expect {
47
- subject.show_unknown_command_help("thiscommanddoesnotexist")
48
- }.to_not raise_error
49
- end
50
- end
51
- end
52
- end
53
- end