stellar_core_commander 0.0.8 → 0.0.9
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 +4 -4
- data/bin/scc +12 -22
- data/examples/allow_trust.rb +3 -7
- data/examples/non_native_payment.rb +2 -2
- data/examples/pathed_payment.rb +11 -14
- data/examples/simple_payment.rb +2 -2
- data/examples/trade.rb +9 -9
- data/lib/stellar_core_commander.rb +4 -0
- data/lib/stellar_core_commander/commander.rb +27 -12
- data/lib/stellar_core_commander/docker_process.rb +161 -0
- data/lib/stellar_core_commander/local_process.rb +170 -0
- data/lib/stellar_core_commander/operation_builder.rb +26 -17
- data/lib/stellar_core_commander/process.rb +28 -155
- data/lib/stellar_core_commander/transactor.rb +48 -35
- data/lib/stellar_core_commander/version.rb +1 -1
- data/stellar_core_commander.gemspec +2 -2
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ec23f9e827ebf793af1412a68847a9f37ff9278
|
4
|
+
data.tar.gz: 9e2d0a36edb3093e4384067225d95c03341cca8f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2cd2365fb8291e0307c29b5283eb0537950e6bab08ed69999cb4fc9c5f66c14b17d0758aabf37b5467eef99778afb3b8915e0bb6bcef533e6611ca376cdf78ab
|
7
|
+
data.tar.gz: f1c4810b80c622b188c7f936a45dc2db4ecd98e2a1e71103f6cd525293720144481ef49198bda1c0ebe42a3f6f5152d6784960c0a22558d1a5d11b4015ccd0c4
|
data/bin/scc
CHANGED
@@ -6,41 +6,33 @@ require 'slop'
|
|
6
6
|
def run
|
7
7
|
$opts = Slop.parse do
|
8
8
|
banner 'Usage: scc -r RECIPE'
|
9
|
-
|
10
|
-
on 'stellar-core-bin', 'a path to a stellar-core executable (
|
9
|
+
|
10
|
+
on 'stellar-core-bin', 'a path to a stellar-core executable (defaults to `which stellar-core`)', argument: true
|
11
|
+
|
11
12
|
on 'r', 'recipe', 'a recipe file', argument: true #, required: true
|
13
|
+
on 'p', 'process', 'method for running stellar-core', argument: true, default: 'local'
|
12
14
|
end
|
13
15
|
|
14
16
|
recipe = load_recipe
|
15
17
|
commander = make_commander
|
16
|
-
process = commander.make_process
|
17
18
|
|
18
19
|
#run recipe
|
19
|
-
transactor = StellarCoreCommander::Transactor.new(
|
20
|
-
|
21
|
-
|
20
|
+
transactor = StellarCoreCommander::Transactor.new(commander)
|
21
|
+
|
22
|
+
|
22
23
|
transactor.run_recipe recipe
|
23
24
|
transactor.close_ledger
|
24
25
|
|
25
|
-
output_results(process)
|
26
|
+
output_results(transactor.get_process(:process))
|
26
27
|
end
|
27
28
|
|
28
29
|
|
29
30
|
def make_commander
|
30
|
-
|
31
|
+
opts = {
|
32
|
+
stellar_core_bin: $opts[:"stellar-core-bin"],
|
33
|
+
}
|
31
34
|
|
32
|
-
|
33
|
-
search = `which stellar-core`.strip
|
34
|
-
|
35
|
-
if $?.success?
|
36
|
-
stellar_core_bin = search
|
37
|
-
else
|
38
|
-
$stderr.puts "Could not find a `stellar-core` binary, please use --stellar-core-bin to specify"
|
39
|
-
exit 1
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
StellarCoreCommander::Commander.new(stellar_core_bin).tap do |c|
|
35
|
+
StellarCoreCommander::Commander.new($opts[:"process"], opts).tap do |c|
|
44
36
|
c.cleanup_at_exit!
|
45
37
|
end
|
46
38
|
end
|
@@ -66,5 +58,3 @@ def output_results(process)
|
|
66
58
|
end
|
67
59
|
|
68
60
|
run
|
69
|
-
|
70
|
-
|
data/examples/allow_trust.rb
CHANGED
@@ -2,9 +2,9 @@ account :usd_gateway
|
|
2
2
|
account :scott
|
3
3
|
account :andrew
|
4
4
|
|
5
|
-
payment :master, :usd_gateway, [:native,
|
6
|
-
payment :master, :scott, [:native,
|
7
|
-
payment :master, :andrew, [:native,
|
5
|
+
payment :master, :usd_gateway, [:native, 1000 * Stellar::ONE]
|
6
|
+
payment :master, :scott, [:native, 1000 * Stellar::ONE]
|
7
|
+
payment :master, :andrew, [:native, 1000 * Stellar::ONE]
|
8
8
|
|
9
9
|
close_ledger
|
10
10
|
|
@@ -18,7 +18,3 @@ trust :andrew, :usd_gateway, "USD"
|
|
18
18
|
close_ledger
|
19
19
|
|
20
20
|
allow_trust :usd_gateway, :scott, "USD"
|
21
|
-
|
22
|
-
# close_ledger
|
23
|
-
|
24
|
-
# payment :usd_gateway, :scott, ["USD", :usd_gateway, 1000_000000]
|
@@ -13,8 +13,8 @@ trust :andrew, :usd_gateway, "USD"
|
|
13
13
|
|
14
14
|
close_ledger
|
15
15
|
|
16
|
-
payment :usd_gateway, :scott, ["USD", :usd_gateway,
|
16
|
+
payment :usd_gateway, :scott, ["USD", :usd_gateway, 1000 * Stellar::ONE]
|
17
17
|
|
18
18
|
close_ledger
|
19
19
|
|
20
|
-
payment :scott, :andrew, ["USD", :usd_gateway,
|
20
|
+
payment :scott, :andrew, ["USD", :usd_gateway, 500 * Stellar::ONE]
|
data/examples/pathed_payment.rb
CHANGED
@@ -1,17 +1,14 @@
|
|
1
|
-
# DOES NOT YET WORK WITH LATEST TRANSACTION TYPES
|
2
|
-
|
3
1
|
account :usd_gateway
|
4
2
|
account :eur_gateway
|
5
3
|
account :scott
|
6
4
|
account :bartek
|
7
5
|
account :andrew
|
8
6
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
payment :master, :andrew, [:native, 1000_000000]
|
7
|
+
create_account :usd_gateway, :master
|
8
|
+
create_account :eur_gateway, :master
|
9
|
+
create_account :scott, :master
|
10
|
+
create_account :bartek, :master
|
11
|
+
create_account :andrew, :master
|
15
12
|
|
16
13
|
close_ledger
|
17
14
|
|
@@ -22,15 +19,15 @@ trust :andrew, :eur_gateway, "EUR"
|
|
22
19
|
|
23
20
|
close_ledger
|
24
21
|
|
25
|
-
payment :usd_gateway, :scott, ["USD", :usd_gateway,
|
26
|
-
payment :usd_gateway, :andrew, ["USD", :usd_gateway,
|
27
|
-
payment :eur_gateway, :andrew, ["EUR", :eur_gateway,
|
28
|
-
payment :eur_gateway, :bartek, ["EUR", :eur_gateway,
|
22
|
+
payment :usd_gateway, :scott, ["USD", :usd_gateway, 1000 * Stellar::ONE]
|
23
|
+
payment :usd_gateway, :andrew, ["USD", :usd_gateway, 200 * Stellar::ONE]
|
24
|
+
payment :eur_gateway, :andrew, ["EUR", :eur_gateway, 200 * Stellar::ONE]
|
25
|
+
payment :eur_gateway, :bartek, ["EUR", :eur_gateway, 1000 * Stellar::ONE]
|
29
26
|
|
30
27
|
close_ledger
|
31
28
|
|
32
|
-
offer :andrew, {buy:["USD", :usd_gateway], with:["EUR", :eur_gateway]},
|
29
|
+
offer :andrew, {buy:["USD", :usd_gateway], with:["EUR", :eur_gateway]}, 200 * Stellar::ONE, 1.0
|
33
30
|
|
34
31
|
close_ledger
|
35
32
|
|
36
|
-
payment :scott, :bartek, ["EUR", :eur_gateway, 10],
|
33
|
+
payment :scott, :bartek, ["EUR", :eur_gateway, 10], with: ["USD", :usd_gateway, 10], path: []
|
data/examples/simple_payment.rb
CHANGED
data/examples/trade.rb
CHANGED
@@ -3,10 +3,10 @@ account :eur_gateway
|
|
3
3
|
account :scott
|
4
4
|
account :bartek
|
5
5
|
|
6
|
-
create_account :usd_gateway, :master,
|
7
|
-
create_account :eur_gateway, :master,
|
8
|
-
create_account :scott, :master,
|
9
|
-
create_account :bartek, :master,
|
6
|
+
create_account :usd_gateway, :master, 1000 * Stellar::ONE
|
7
|
+
create_account :eur_gateway, :master, 1000 * Stellar::ONE
|
8
|
+
create_account :scott, :master, 1000 * Stellar::ONE
|
9
|
+
create_account :bartek, :master, 1000 * Stellar::ONE
|
10
10
|
|
11
11
|
close_ledger
|
12
12
|
|
@@ -17,15 +17,15 @@ trust :bartek, :eur_gateway, "EUR"
|
|
17
17
|
|
18
18
|
close_ledger
|
19
19
|
|
20
|
-
payment :usd_gateway, :scott, ["USD", :usd_gateway,
|
21
|
-
payment :eur_gateway, :bartek, ["EUR", :eur_gateway,
|
20
|
+
payment :usd_gateway, :scott, ["USD", :usd_gateway, 1000 * Stellar::ONE]
|
21
|
+
payment :eur_gateway, :bartek, ["EUR", :eur_gateway, 1000 * Stellar::ONE]
|
22
22
|
|
23
23
|
close_ledger
|
24
24
|
|
25
|
-
offer :bartek, {buy:["USD", :usd_gateway], with:["EUR", :eur_gateway]},
|
25
|
+
offer :bartek, {buy:["USD", :usd_gateway], with:["EUR", :eur_gateway]}, 1000 * Stellar::ONE, 1.0
|
26
26
|
|
27
27
|
close_ledger
|
28
28
|
|
29
|
-
offer :scott, {sell:["USD", :usd_gateway], for:["EUR", :eur_gateway]},
|
29
|
+
offer :scott, {sell:["USD", :usd_gateway], for:["EUR", :eur_gateway]}, 500 * Stellar::ONE, 1.0
|
30
30
|
|
31
|
-
offer :scott, {sell:["USD", :usd_gateway], for: :native},
|
31
|
+
offer :scott, {sell:["USD", :usd_gateway], for: :native}, 500 * Stellar::ONE, 1.0
|
@@ -1,28 +1,43 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
module StellarCoreCommander
|
3
|
+
|
4
|
+
#
|
5
|
+
# Commander is the object that manages running stellar-core processes. It is
|
6
|
+
# responsible for creating and cleaning Process objects
|
7
|
+
#
|
3
8
|
class Commander
|
4
9
|
include Contracts
|
5
10
|
|
6
|
-
#
|
11
|
+
#
|
7
12
|
# Creates a new core commander
|
8
|
-
#
|
9
|
-
Contract
|
10
|
-
def initialize(
|
11
|
-
@
|
12
|
-
|
13
|
-
|
13
|
+
#
|
14
|
+
Contract Or["local", "docker"], Hash => Any
|
15
|
+
def initialize(process_type, process_options={})
|
16
|
+
@process_type = process_type
|
17
|
+
@process_options = process_options
|
14
18
|
@processes = []
|
15
19
|
end
|
16
20
|
|
17
21
|
Contract None => Process
|
22
|
+
#
|
23
|
+
# make_process returns a new, unlaunched Process object, bound to a new
|
24
|
+
# tmpdir and
|
18
25
|
def make_process
|
19
26
|
tmpdir = Dir.mktmpdir("scc")
|
20
27
|
|
21
28
|
identity = Stellar::KeyPair.random
|
22
|
-
base_port = 39132 +
|
23
|
-
|
24
|
-
|
25
|
-
|
29
|
+
base_port = 39132 + @processes.map(&:required_ports).sum
|
30
|
+
|
31
|
+
process_class = case @process_type
|
32
|
+
when 'local'
|
33
|
+
LocalProcess
|
34
|
+
when 'docker'
|
35
|
+
DockerProcess
|
36
|
+
else
|
37
|
+
raise "Unknown process type: #{@process_type}"
|
38
|
+
end
|
39
|
+
|
40
|
+
process_class.new(tmpdir, base_port, identity, @process_options).tap do |p|
|
26
41
|
p.setup
|
27
42
|
@processes << p
|
28
43
|
end
|
@@ -40,4 +55,4 @@ module StellarCoreCommander
|
|
40
55
|
end
|
41
56
|
|
42
57
|
end
|
43
|
-
end
|
58
|
+
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'securerandom'
|
3
|
+
|
4
|
+
module StellarCoreCommander
|
5
|
+
|
6
|
+
class DockerProcess < Process
|
7
|
+
include Contracts
|
8
|
+
|
9
|
+
Contract None => Num
|
10
|
+
def required_ports
|
11
|
+
3
|
12
|
+
end
|
13
|
+
|
14
|
+
Contract None => Any
|
15
|
+
def launch_state_container
|
16
|
+
run_cmd "docker", %W(run --name #{state_container_name} -p #{postgres_port}:5432 --env-file stellar-core.env -d stellar/stellar-core-state)
|
17
|
+
raise "Could not create state container" unless $?.success?
|
18
|
+
end
|
19
|
+
|
20
|
+
Contract None => Any
|
21
|
+
def shutdown_state_container
|
22
|
+
run_cmd "docker", %W(rm -f -v #{state_container_name})
|
23
|
+
raise "Could not drop db: #{database_name}" unless $?.success?
|
24
|
+
end
|
25
|
+
|
26
|
+
Contract None => Any
|
27
|
+
def write_config
|
28
|
+
IO.write("#{working_dir}/.pgpass", "#{docker_host}:#{postgres_port}:*:#{database_user}:#{database_password}")
|
29
|
+
FileUtils.chmod(0600, "#{working_dir}/.pgpass")
|
30
|
+
IO.write("#{working_dir}/stellar-core.env", config)
|
31
|
+
end
|
32
|
+
|
33
|
+
Contract None => Any
|
34
|
+
def setup
|
35
|
+
write_config
|
36
|
+
launch_state_container
|
37
|
+
end
|
38
|
+
|
39
|
+
Contract None => nil
|
40
|
+
def run
|
41
|
+
raise "already running!" if running?
|
42
|
+
launch_stellar_core
|
43
|
+
end
|
44
|
+
|
45
|
+
Contract None => Bool
|
46
|
+
def running?
|
47
|
+
run_cmd "docker", %W(inspect #{container_name})
|
48
|
+
$?.success?
|
49
|
+
end
|
50
|
+
|
51
|
+
Contract None => Any
|
52
|
+
def shutdown
|
53
|
+
return true unless running?
|
54
|
+
run_cmd "docker", %W(rm -f #{container_name})
|
55
|
+
end
|
56
|
+
|
57
|
+
Contract None => Any
|
58
|
+
def cleanup
|
59
|
+
database.disconnect
|
60
|
+
shutdown
|
61
|
+
shutdown_state_container
|
62
|
+
rm_working_dir
|
63
|
+
end
|
64
|
+
|
65
|
+
Contract None => Any
|
66
|
+
def dump_database
|
67
|
+
Dir.chdir(working_dir) do
|
68
|
+
`docker exec #{state_container_name} pg_dump -U #{database_user} --clean --no-owner #{database_name}`
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
Contract None => Sequel::Database
|
73
|
+
def database
|
74
|
+
@database ||= Sequel.postgres(database_name, host: docker_host, port: postgres_port, user: database_user, password: database_password)
|
75
|
+
end
|
76
|
+
|
77
|
+
Contract None => String
|
78
|
+
def database_name
|
79
|
+
"stellar"
|
80
|
+
end
|
81
|
+
|
82
|
+
Contract None => String
|
83
|
+
def database_user
|
84
|
+
"postgres"
|
85
|
+
end
|
86
|
+
|
87
|
+
Contract None => String
|
88
|
+
def database_password
|
89
|
+
@database_password ||= SecureRandom.hex
|
90
|
+
end
|
91
|
+
|
92
|
+
Contract None => Num
|
93
|
+
def postgres_port
|
94
|
+
base_port + 2
|
95
|
+
end
|
96
|
+
|
97
|
+
Contract None => String
|
98
|
+
def container_name
|
99
|
+
"c#{base_port}"
|
100
|
+
end
|
101
|
+
|
102
|
+
Contract None => String
|
103
|
+
def state_container_name
|
104
|
+
"db#{container_name}"
|
105
|
+
end
|
106
|
+
|
107
|
+
Contract None => String
|
108
|
+
def docker_host
|
109
|
+
docker_uri = URI.parse(ENV['DOCKER_HOST'])
|
110
|
+
if docker_uri.scheme == "tcp"
|
111
|
+
docker_uri.host
|
112
|
+
else
|
113
|
+
"127.0.0.1"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
Contract None => String
|
118
|
+
def http_host
|
119
|
+
docker_host
|
120
|
+
end
|
121
|
+
|
122
|
+
private
|
123
|
+
def launch_stellar_core
|
124
|
+
run_cmd "docker", %W(run
|
125
|
+
--name #{container_name}
|
126
|
+
--net host
|
127
|
+
--volumes-from #{state_container_name}
|
128
|
+
--env-file stellar-core.env
|
129
|
+
-d stellar/stellar-core
|
130
|
+
/run main fresh forcescp
|
131
|
+
)
|
132
|
+
raise "Could not create stellar-core container" unless $?.success?
|
133
|
+
end
|
134
|
+
|
135
|
+
Contract None => String
|
136
|
+
def config
|
137
|
+
<<-EOS.strip_heredoc
|
138
|
+
POSTGRES_PASSWORD=#{database_password}
|
139
|
+
|
140
|
+
main_POSTGRES_PORT=#{postgres_port}
|
141
|
+
main_PEER_PORT=#{peer_port}
|
142
|
+
main_HTTP_PORT=#{http_port}
|
143
|
+
main_PEER_SEED=#{identity.seed}
|
144
|
+
main_VALIDATION_SEED=#{identity.seed}
|
145
|
+
|
146
|
+
MANUAL_CLOSE=true
|
147
|
+
|
148
|
+
QUORUM_THRESHOLD=1
|
149
|
+
|
150
|
+
PREFERRED_PEERS=["127.0.0.1:#{peer_port}"]
|
151
|
+
QUORUM_SET=["#{identity.address}"]
|
152
|
+
|
153
|
+
HISTORY_PEERS=["main"]
|
154
|
+
|
155
|
+
HISTORY_GET=cp history/%s/{0} {1}
|
156
|
+
HISTORY_PUT=cp {0} history/%s/{1}
|
157
|
+
HISTORY_MKDIR=mkdir -p history/%s/{0}
|
158
|
+
EOS
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
module StellarCoreCommander
|
2
|
+
|
3
|
+
class LocalProcess < Process
|
4
|
+
include Contracts
|
5
|
+
|
6
|
+
attr_reader :pid
|
7
|
+
attr_reader :wait
|
8
|
+
|
9
|
+
def initialize(working_dir, base_port, identity, opts)
|
10
|
+
stellar_core_bin = opts[:stellar_core_bin]
|
11
|
+
if stellar_core_bin.blank?
|
12
|
+
search = `which stellar-core`.strip
|
13
|
+
|
14
|
+
if $?.success?
|
15
|
+
stellar_core_bin = search
|
16
|
+
else
|
17
|
+
$stderr.puts "Could not find a `stellar-core` binary, please use --stellar-core-bin to specify"
|
18
|
+
exit 1
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
FileUtils.cp(stellar_core_bin, "#{working_dir}/stellar-core")
|
23
|
+
super
|
24
|
+
end
|
25
|
+
|
26
|
+
Contract None => Any
|
27
|
+
def forcescp
|
28
|
+
run_cmd "./stellar-core", ["--forcescp"]
|
29
|
+
raise "Could not set --forcescp" unless $?.success?
|
30
|
+
end
|
31
|
+
|
32
|
+
Contract None => Any
|
33
|
+
def initialize_history
|
34
|
+
run_cmd "./stellar-core", ["--newhist", "main"]
|
35
|
+
raise "Could not initialize history" unless $?.success?
|
36
|
+
end
|
37
|
+
|
38
|
+
Contract None => Any
|
39
|
+
def initialize_database
|
40
|
+
run_cmd "./stellar-core", ["--newdb"]
|
41
|
+
raise "Could not initialize db" unless $?.success?
|
42
|
+
end
|
43
|
+
|
44
|
+
Contract None => Any
|
45
|
+
def create_database
|
46
|
+
run_cmd "createdb", [database_name]
|
47
|
+
raise "Could not create db: #{database_name}" unless $?.success?
|
48
|
+
end
|
49
|
+
|
50
|
+
Contract None => Any
|
51
|
+
def drop_database
|
52
|
+
run_cmd "dropdb", [database_name]
|
53
|
+
raise "Could not drop db: #{database_name}" unless $?.success?
|
54
|
+
end
|
55
|
+
|
56
|
+
Contract None => Any
|
57
|
+
def write_config
|
58
|
+
IO.write("#{@working_dir}/stellar-core.cfg", config)
|
59
|
+
end
|
60
|
+
|
61
|
+
Contract None => Any
|
62
|
+
def setup
|
63
|
+
write_config
|
64
|
+
create_database
|
65
|
+
initialize_history
|
66
|
+
initialize_database
|
67
|
+
end
|
68
|
+
|
69
|
+
Contract None => Num
|
70
|
+
def run
|
71
|
+
raise "already running!" if running?
|
72
|
+
|
73
|
+
forcescp
|
74
|
+
launch_stellar_core
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
Contract None => Bool
|
79
|
+
def running?
|
80
|
+
return false unless @pid
|
81
|
+
::Process.kill 0, @pid
|
82
|
+
true
|
83
|
+
rescue Errno::ESRCH
|
84
|
+
false
|
85
|
+
end
|
86
|
+
|
87
|
+
Contract Bool => Bool
|
88
|
+
def shutdown(graceful=true)
|
89
|
+
return true if !running?
|
90
|
+
|
91
|
+
if graceful
|
92
|
+
::Process.kill "INT", @pid
|
93
|
+
else
|
94
|
+
::Process.kill "KILL", @pid
|
95
|
+
end
|
96
|
+
|
97
|
+
@wait.value.success?
|
98
|
+
end
|
99
|
+
|
100
|
+
Contract None => Any
|
101
|
+
def cleanup
|
102
|
+
database.disconnect
|
103
|
+
shutdown
|
104
|
+
drop_database
|
105
|
+
rm_working_dir
|
106
|
+
end
|
107
|
+
|
108
|
+
Contract None => Any
|
109
|
+
def dump_database
|
110
|
+
Dir.chdir(@working_dir) do
|
111
|
+
`pg_dump #{database_name} --clean --no-owner`
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
Contract None => Sequel::Database
|
117
|
+
def database
|
118
|
+
@database ||= Sequel.postgres(database_name)
|
119
|
+
end
|
120
|
+
|
121
|
+
Contract None => String
|
122
|
+
def database_name
|
123
|
+
"stellar_core_tmp_#{basename}"
|
124
|
+
end
|
125
|
+
|
126
|
+
Contract None => String
|
127
|
+
def dsn
|
128
|
+
"postgresql://dbname=#{database_name}"
|
129
|
+
end
|
130
|
+
|
131
|
+
private
|
132
|
+
def launch_stellar_core
|
133
|
+
Dir.chdir @working_dir do
|
134
|
+
sin, sout, serr, wait = Open3.popen3("./stellar-core")
|
135
|
+
|
136
|
+
# throwaway stdout, stderr (the logs will record any output)
|
137
|
+
Thread.new{ until (line = sout.gets).nil? ; end }
|
138
|
+
Thread.new{ until (line = serr.gets).nil? ; end }
|
139
|
+
|
140
|
+
@wait = wait
|
141
|
+
@pid = wait.pid
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
Contract None => String
|
146
|
+
def config
|
147
|
+
<<-EOS.strip_heredoc
|
148
|
+
MANUAL_CLOSE=true
|
149
|
+
PEER_PORT=#{peer_port}
|
150
|
+
RUN_STANDALONE=false
|
151
|
+
HTTP_PORT=#{http_port}
|
152
|
+
PUBLIC_HTTP_PORT=false
|
153
|
+
PEER_SEED="#{@identity.seed}"
|
154
|
+
VALIDATION_SEED="#{@identity.seed}"
|
155
|
+
|
156
|
+
DATABASE="#{dsn}"
|
157
|
+
|
158
|
+
[QUORUM_SET]
|
159
|
+
THRESHOLD=1
|
160
|
+
VALIDATORS=["#{@identity.address}"]
|
161
|
+
|
162
|
+
[HISTORY.main]
|
163
|
+
get="cp history/main/{0} {1}"
|
164
|
+
put="cp {0} history/main/{1}"
|
165
|
+
mkdir="mkdir -p history/main/{0}"
|
166
|
+
EOS
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
170
|
+
end
|
@@ -5,9 +5,12 @@ module StellarCoreCommander
|
|
5
5
|
|
6
6
|
Currency = Or[
|
7
7
|
[String, Symbol],
|
8
|
-
:native
|
8
|
+
:native,
|
9
|
+
]
|
10
|
+
Amount = Or[
|
11
|
+
[String, Symbol, Num],
|
12
|
+
[:native, Num],
|
9
13
|
]
|
10
|
-
Amount = Any #TODO
|
11
14
|
|
12
15
|
OfferCurrencies = Or[
|
13
16
|
{sell:Currency, for: Currency},
|
@@ -19,30 +22,27 @@ module StellarCoreCommander
|
|
19
22
|
@transactor = transactor
|
20
23
|
end
|
21
24
|
|
22
|
-
Contract Symbol, Symbol, Amount, Or[{}, {path:
|
25
|
+
Contract Symbol, Symbol, Amount, Or[{}, {path: ArrayOf[Currency], with:Amount}] => Any
|
23
26
|
def payment(from, to, amount, options={})
|
24
27
|
from = get_account from
|
25
28
|
to = get_account to
|
26
29
|
|
27
|
-
if amount.first != :native
|
28
|
-
amount = [:iso4217] + amount
|
29
|
-
amount[2] = get_account(amount[2])
|
30
|
-
amount[1] = amount[1].ljust(4, "\x00")
|
31
|
-
end
|
32
|
-
|
33
30
|
attrs = {
|
34
31
|
account: from,
|
35
32
|
destination: to,
|
36
33
|
sequence: next_sequence(from),
|
37
|
-
amount: amount,
|
34
|
+
amount: normalize_amount(amount),
|
38
35
|
}
|
39
36
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
37
|
+
tx = if options[:with]
|
38
|
+
attrs[:with] = normalize_amount(options[:with])
|
39
|
+
attrs[:path] = options[:path].map{|p| make_currency p}
|
40
|
+
Stellar::Transaction.path_payment(attrs)
|
41
|
+
else
|
42
|
+
Stellar::Transaction.payment(attrs)
|
43
|
+
end
|
44
44
|
|
45
|
-
|
45
|
+
tx.to_envelope(from)
|
46
46
|
end
|
47
47
|
|
48
48
|
Contract Symbol, Symbol, Num => Any
|
@@ -146,10 +146,9 @@ module StellarCoreCommander
|
|
146
146
|
end
|
147
147
|
|
148
148
|
code, issuer = *input
|
149
|
-
code = code.ljust(4, "\x00")
|
150
149
|
issuer = get_account issuer
|
151
150
|
|
152
|
-
[:
|
151
|
+
[:alphanum, code, issuer]
|
153
152
|
end
|
154
153
|
|
155
154
|
def make_account_flags(flags=nil)
|
@@ -157,5 +156,15 @@ module StellarCoreCommander
|
|
157
156
|
flags.map{|f| Stellar::AccountFlags.send(f)}
|
158
157
|
end
|
159
158
|
|
159
|
+
Contract Amount => Any
|
160
|
+
def normalize_amount(amount)
|
161
|
+
return amount if amount.first == :native
|
162
|
+
|
163
|
+
amount = [:alphanum] + amount
|
164
|
+
amount[2] = get_account(amount[2]) # translate issuer to account
|
165
|
+
|
166
|
+
amount
|
167
|
+
end
|
168
|
+
|
160
169
|
end
|
161
170
|
end
|
@@ -6,82 +6,34 @@ module StellarCoreCommander
|
|
6
6
|
attr_reader :working_dir
|
7
7
|
attr_reader :base_port
|
8
8
|
attr_reader :identity
|
9
|
-
attr_reader :
|
10
|
-
attr_reader :wait
|
9
|
+
attr_reader :server
|
11
10
|
|
12
|
-
def initialize(working_dir, base_port, identity)
|
11
|
+
def initialize(working_dir, base_port, identity, opts)
|
13
12
|
@working_dir = working_dir
|
14
13
|
@base_port = base_port
|
15
14
|
@identity = identity
|
16
15
|
|
17
|
-
@server = Faraday.new(url: "http
|
16
|
+
@server = Faraday.new(url: "http://#{http_host}:#{http_port}") do |conn|
|
18
17
|
conn.request :url_encoded
|
19
18
|
conn.adapter Faraday.default_adapter
|
20
19
|
end
|
21
20
|
end
|
22
21
|
|
23
|
-
Contract None =>
|
24
|
-
def
|
25
|
-
|
26
|
-
raise "Could not set --forcescp" unless $?.success?
|
27
|
-
end
|
28
|
-
|
29
|
-
Contract None => Any
|
30
|
-
def initialize_history
|
31
|
-
run_cmd "./stellar-core", ["--newhist", "main"]
|
32
|
-
raise "Could not initialize history" unless $?.success?
|
33
|
-
end
|
34
|
-
|
35
|
-
Contract None => Any
|
36
|
-
def initialize_database
|
37
|
-
run_cmd "./stellar-core", ["--newdb"]
|
38
|
-
raise "Could not initialize db" unless $?.success?
|
39
|
-
end
|
40
|
-
|
41
|
-
Contract None => Any
|
42
|
-
def create_database
|
43
|
-
run_cmd "createdb", [database_name]
|
44
|
-
raise "Could not create db: #{database_name}" unless $?.success?
|
45
|
-
end
|
46
|
-
|
47
|
-
Contract None => Any
|
48
|
-
def drop_database
|
49
|
-
run_cmd "dropdb", [database_name]
|
50
|
-
raise "Could not drop db: #{database_name}" unless $?.success?
|
51
|
-
end
|
52
|
-
|
53
|
-
Contract None => Any
|
54
|
-
def write_config
|
55
|
-
IO.write("#{@working_dir}/stellar-core.cfg", config)
|
22
|
+
Contract None => Num
|
23
|
+
def required_ports
|
24
|
+
2
|
56
25
|
end
|
57
26
|
|
58
27
|
Contract None => Any
|
59
28
|
def rm_working_dir
|
60
|
-
FileUtils.rm_rf
|
61
|
-
end
|
62
|
-
|
63
|
-
Contract None => Any
|
64
|
-
def setup
|
65
|
-
write_config
|
66
|
-
create_database
|
67
|
-
initialize_history
|
68
|
-
initialize_database
|
29
|
+
FileUtils.rm_rf working_dir
|
69
30
|
end
|
70
31
|
|
71
|
-
Contract None => Num
|
72
|
-
def run
|
73
|
-
raise "already running!" if running?
|
74
|
-
|
75
|
-
forcescp
|
76
|
-
launch_stellar_core
|
77
|
-
end
|
78
|
-
|
79
|
-
|
80
32
|
Contract None => Any
|
81
33
|
def wait_for_ready
|
82
34
|
loop do
|
83
35
|
|
84
|
-
response =
|
36
|
+
response = server.get("/info") rescue false
|
85
37
|
|
86
38
|
if response
|
87
39
|
body = ActiveSupport::JSON.decode(response.body)
|
@@ -94,36 +46,14 @@ module StellarCoreCommander
|
|
94
46
|
end
|
95
47
|
end
|
96
48
|
|
97
|
-
Contract None => Bool
|
98
|
-
def running?
|
99
|
-
return false unless @pid
|
100
|
-
::Process.kill 0, @pid
|
101
|
-
true
|
102
|
-
rescue Errno::ESRCH
|
103
|
-
false
|
104
|
-
end
|
105
|
-
|
106
|
-
Contract Bool => Bool
|
107
|
-
def shutdown(graceful=true)
|
108
|
-
return true if !running?
|
109
|
-
|
110
|
-
if graceful
|
111
|
-
::Process.kill "INT", @pid
|
112
|
-
else
|
113
|
-
::Process.kill "KILL", @pid
|
114
|
-
end
|
115
|
-
|
116
|
-
@wait.value.success?
|
117
|
-
end
|
118
|
-
|
119
49
|
Contract None => Bool
|
120
50
|
def close_ledger
|
121
51
|
prev_ledger = latest_ledger
|
122
52
|
next_ledger = prev_ledger + 1
|
123
53
|
|
124
|
-
|
54
|
+
server.get("manualclose")
|
125
55
|
|
126
|
-
Timeout.timeout(
|
56
|
+
Timeout.timeout(close_timeout) do
|
127
57
|
loop do
|
128
58
|
current_ledger = latest_ledger
|
129
59
|
|
@@ -142,9 +72,19 @@ module StellarCoreCommander
|
|
142
72
|
true
|
143
73
|
end
|
144
74
|
|
75
|
+
Contract None => Num
|
76
|
+
def http_port
|
77
|
+
base_port
|
78
|
+
end
|
79
|
+
|
80
|
+
Contract None => Num
|
81
|
+
def peer_port
|
82
|
+
base_port + 1
|
83
|
+
end
|
84
|
+
|
145
85
|
Contract String => Any
|
146
86
|
def submit_transaction(envelope_hex)
|
147
|
-
response =
|
87
|
+
response = server.get("tx", blob: envelope_hex)
|
148
88
|
body = ActiveSupport::JSON.decode(response.body)
|
149
89
|
|
150
90
|
if body["status"] == "ERROR"
|
@@ -153,14 +93,12 @@ module StellarCoreCommander
|
|
153
93
|
|
154
94
|
end
|
155
95
|
|
156
|
-
|
157
96
|
Contract Stellar::KeyPair => Num
|
158
97
|
def sequence_for(account)
|
159
98
|
row = database[:accounts].where(:accountid => account.address).first
|
160
99
|
row[:seqnum]
|
161
100
|
end
|
162
101
|
|
163
|
-
|
164
102
|
Contract None => Num
|
165
103
|
def latest_ledger
|
166
104
|
database[:ledgerheaders].max(:ledgerseq)
|
@@ -172,98 +110,33 @@ module StellarCoreCommander
|
|
172
110
|
row[:txresult]
|
173
111
|
end
|
174
112
|
|
175
|
-
Contract None => Any
|
176
|
-
def cleanup
|
177
|
-
database.disconnect
|
178
|
-
shutdown
|
179
|
-
drop_database
|
180
|
-
rm_working_dir
|
181
|
-
end
|
182
|
-
|
183
|
-
Contract None => Any
|
184
|
-
def dump_database
|
185
|
-
Dir.chdir(@working_dir) do
|
186
|
-
`pg_dump #{database_name} --clean --no-owner`
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
|
191
|
-
Contract None => Sequel::Database
|
192
|
-
def database
|
193
|
-
@database ||= Sequel.postgres(database_name)
|
194
|
-
end
|
195
|
-
|
196
113
|
Contract None => String
|
197
|
-
def
|
198
|
-
"
|
199
|
-
end
|
200
|
-
|
201
|
-
Contract None => String
|
202
|
-
def dsn
|
203
|
-
"postgresql://dbname=#{database_name}"
|
114
|
+
def http_host
|
115
|
+
"127.0.0.1"
|
204
116
|
end
|
205
117
|
|
206
118
|
Contract None => Num
|
207
|
-
def
|
208
|
-
|
209
|
-
end
|
210
|
-
|
211
|
-
Contract None => Num
|
212
|
-
def peer_port
|
213
|
-
@base_port + 1
|
119
|
+
def close_timeout
|
120
|
+
5.0
|
214
121
|
end
|
215
122
|
|
216
123
|
private
|
217
124
|
Contract None => String
|
218
125
|
def basename
|
219
|
-
File.basename(
|
126
|
+
File.basename(working_dir)
|
220
127
|
end
|
221
128
|
|
222
129
|
Contract String, ArrayOf[String] => Maybe[Bool]
|
223
130
|
def run_cmd(cmd, args)
|
224
131
|
args += [{
|
225
|
-
out: "stellar-core.log",
|
132
|
+
out: "stellar-core.log",
|
226
133
|
err: "stellar-core.log",
|
227
134
|
}]
|
228
135
|
|
229
|
-
Dir.chdir
|
136
|
+
Dir.chdir working_dir do
|
230
137
|
system(cmd, *args)
|
231
138
|
end
|
232
139
|
end
|
233
140
|
|
234
|
-
def launch_stellar_core
|
235
|
-
Dir.chdir @working_dir do
|
236
|
-
sin, sout, serr, wait = Open3.popen3("./stellar-core")
|
237
|
-
|
238
|
-
# throwaway stdout, stderr (the logs will record any output)
|
239
|
-
Thread.new{ until (line = sout.gets).nil? ; end }
|
240
|
-
Thread.new{ until (line = serr.gets).nil? ; end }
|
241
|
-
|
242
|
-
@wait = wait
|
243
|
-
@pid = wait.pid
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
|
-
Contract None => String
|
248
|
-
def config
|
249
|
-
<<-EOS.strip_heredoc
|
250
|
-
MANUAL_CLOSE=true
|
251
|
-
PEER_PORT=#{peer_port}
|
252
|
-
RUN_STANDALONE=false
|
253
|
-
HTTP_PORT=#{http_port}
|
254
|
-
PUBLIC_HTTP_PORT=false
|
255
|
-
PEER_SEED="#{@identity.seed}"
|
256
|
-
VALIDATION_SEED="#{@identity.seed}"
|
257
|
-
QUORUM_THRESHOLD=1
|
258
|
-
QUORUM_SET=["#{@identity.address}"]
|
259
|
-
DATABASE="#{dsn}"
|
260
|
-
|
261
|
-
[HISTORY.main]
|
262
|
-
get="cp history/main/{0} {1}"
|
263
|
-
put="cp {0} history/main/{1}"
|
264
|
-
mkdir="mkdir -p history/main/{0}"
|
265
|
-
EOS
|
266
|
-
end
|
267
|
-
|
268
141
|
end
|
269
142
|
end
|
@@ -2,32 +2,37 @@ require 'fileutils'
|
|
2
2
|
module StellarCoreCommander
|
3
3
|
|
4
4
|
|
5
|
-
#
|
5
|
+
#
|
6
6
|
# A transactor plays transactions against a stellar-core test node.
|
7
|
-
#
|
8
|
-
#
|
7
|
+
#
|
8
|
+
#
|
9
9
|
class Transactor
|
10
10
|
include Contracts
|
11
11
|
|
12
12
|
class FailedTransaction < StandardError ; end
|
13
13
|
|
14
|
-
Contract
|
15
|
-
def initialize(
|
16
|
-
@
|
17
|
-
@named
|
18
|
-
@unverified
|
14
|
+
Contract Commander => Any
|
15
|
+
def initialize(commander)
|
16
|
+
@commander = commander
|
17
|
+
@named = {}.with_indifferent_access
|
18
|
+
@unverified = []
|
19
19
|
@operation_builder = OperationBuilder.new(self)
|
20
|
+
|
20
21
|
account :master, Stellar::KeyPair.from_raw_seed("allmylifemyhearthasbeensearching")
|
21
22
|
end
|
22
23
|
|
23
24
|
Contract String => Any
|
24
|
-
#
|
25
|
+
#
|
25
26
|
# Runs the provided recipe against the process identified by @process
|
26
|
-
#
|
27
|
+
#
|
27
28
|
# @param recipe_path [String] path to the recipe file
|
28
|
-
#
|
29
|
+
#
|
29
30
|
def run_recipe(recipe_path)
|
30
|
-
|
31
|
+
@process = @commander.make_process
|
32
|
+
@process.run
|
33
|
+
@process.wait_for_ready
|
34
|
+
|
35
|
+
add_named :process, @process
|
31
36
|
|
32
37
|
recipe_content = IO.read(recipe_path)
|
33
38
|
instance_eval recipe_content
|
@@ -35,13 +40,13 @@ module StellarCoreCommander
|
|
35
40
|
|
36
41
|
|
37
42
|
Contract Symbol, Stellar::KeyPair => Any
|
38
|
-
#
|
43
|
+
#
|
39
44
|
# Registered an account for this scenario. Future calls may refer to
|
40
45
|
# the name provided.
|
41
|
-
#
|
46
|
+
#
|
42
47
|
# @param name [Symbol] the name to register the keypair at
|
43
48
|
# @param keypair=Stellar::KeyPair.random [Stellar::KeyPair] the keypair to use for this account
|
44
|
-
#
|
49
|
+
#
|
45
50
|
def account(name, keypair=Stellar::KeyPair.random)
|
46
51
|
unless keypair.is_a?(Stellar::KeyPair)
|
47
52
|
raise ArgumentError, "`#{keypair.class.name}` is not `Stellar::KeyPair`"
|
@@ -51,71 +56,71 @@ module StellarCoreCommander
|
|
51
56
|
end
|
52
57
|
|
53
58
|
|
54
|
-
#
|
59
|
+
#
|
55
60
|
# @see StellarCoreCommander::OperationBuilder#payment
|
56
61
|
def payment(*args)
|
57
62
|
envelope = @operation_builder.payment(*args)
|
58
63
|
|
59
64
|
submit_transaction envelope do |result|
|
60
|
-
payment_result = result.result.results!.first.tr!.
|
65
|
+
payment_result = result.result.results!.first.tr!.value
|
61
66
|
raise FailedTransaction unless payment_result.code.value >= 0
|
62
67
|
end
|
63
68
|
end
|
64
69
|
|
65
|
-
#
|
70
|
+
#
|
66
71
|
# @see StellarCoreCommander::OperationBuilder#create_account
|
67
72
|
def create_account(*args)
|
68
73
|
envelope = @operation_builder.create_account(*args)
|
69
74
|
submit_transaction envelope
|
70
|
-
end
|
75
|
+
end
|
71
76
|
|
72
|
-
#
|
77
|
+
#
|
73
78
|
# @see StellarCoreCommander::OperationBuilder#trust
|
74
79
|
def trust(*args)
|
75
80
|
envelope = @operation_builder.trust(*args)
|
76
81
|
submit_transaction envelope
|
77
|
-
end
|
82
|
+
end
|
78
83
|
|
79
|
-
#
|
84
|
+
#
|
80
85
|
# @see StellarCoreCommander::OperationBuilder#change_trust
|
81
86
|
def change_trust(*args)
|
82
87
|
envelope = @operation_builder.change_trust(*args)
|
83
88
|
submit_transaction envelope
|
84
89
|
end
|
85
90
|
|
86
|
-
#
|
91
|
+
#
|
87
92
|
# @see StellarCoreCommander::OperationBuilder#offer
|
88
93
|
def offer(*args)
|
89
94
|
envelope = @operation_builder.offer(*args)
|
90
95
|
submit_transaction envelope
|
91
96
|
end
|
92
97
|
|
93
|
-
#
|
98
|
+
#
|
94
99
|
# @see StellarCoreCommander::OperationBuilder#require_trust_auth
|
95
100
|
def require_trust_auth(*args)
|
96
101
|
envelope = @operation_builder.require_trust_auth(*args)
|
97
102
|
submit_transaction envelope
|
98
|
-
end
|
103
|
+
end
|
99
104
|
|
100
|
-
#
|
105
|
+
#
|
101
106
|
# @see StellarCoreCommander::OperationBuilder#set_flags
|
102
107
|
def set_flags(*args)
|
103
108
|
envelope = @operation_builder.set_flags(*args)
|
104
109
|
submit_transaction envelope
|
105
110
|
end
|
106
|
-
|
107
|
-
#
|
111
|
+
|
112
|
+
#
|
108
113
|
# @see StellarCoreCommander::OperationBuilder#allow_trust
|
109
114
|
def allow_trust(*args)
|
110
115
|
envelope = @operation_builder.allow_trust(*args)
|
111
116
|
submit_transaction envelope
|
112
|
-
end
|
117
|
+
end
|
113
118
|
|
114
119
|
Contract None => Any
|
115
|
-
#
|
120
|
+
#
|
116
121
|
# Triggers a ledger close. Any unvalidated transaction will
|
117
122
|
# be validated, which will trigger an error if any fail to be validated
|
118
|
-
#
|
123
|
+
#
|
119
124
|
def close_ledger
|
120
125
|
@process.close_ledger
|
121
126
|
|
@@ -131,7 +136,6 @@ module StellarCoreCommander
|
|
131
136
|
end
|
132
137
|
end
|
133
138
|
|
134
|
-
# TODO: validate in-flight transactions
|
135
139
|
@unverified.clear
|
136
140
|
end
|
137
141
|
|
@@ -144,6 +148,15 @@ module StellarCoreCommander
|
|
144
148
|
end
|
145
149
|
end
|
146
150
|
|
151
|
+
Contract Symbol => Process
|
152
|
+
def get_process(name)
|
153
|
+
@named[name].tap do |found|
|
154
|
+
unless found.is_a?(Process)
|
155
|
+
raise ArgumentError, "#{name.inspect} is not process"
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
147
160
|
Contract Stellar::KeyPair => Num
|
148
161
|
def next_sequence(account)
|
149
162
|
base_sequence = @process.sequence_for(account)
|
@@ -177,9 +190,9 @@ module StellarCoreCommander
|
|
177
190
|
hex_hash = Convert.to_hex(raw_hash)
|
178
191
|
|
179
192
|
base64_result = @process.transaction_result(hex_hash)
|
180
|
-
|
193
|
+
|
181
194
|
raise "couldn't find result for #{hex_hash}" if base64_result.blank?
|
182
|
-
|
195
|
+
|
183
196
|
raw_result = Convert.from_base64(base64_result)
|
184
197
|
|
185
198
|
pair = Stellar::TransactionResultPair.from_xdr(raw_result)
|
@@ -194,4 +207,4 @@ module StellarCoreCommander
|
|
194
207
|
end
|
195
208
|
|
196
209
|
end
|
197
|
-
end
|
210
|
+
end
|
@@ -17,11 +17,11 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
|
-
spec.add_dependency "stellar-base", "= 0.0.
|
20
|
+
spec.add_dependency "stellar-base", "= 0.0.10"
|
21
21
|
spec.add_dependency "slop", "~> 3.6.0"
|
22
22
|
spec.add_dependency "faraday", "~> 0.9.1"
|
23
23
|
spec.add_dependency "faraday_middleware", "~> 0.9.1"
|
24
|
-
spec.add_dependency "pg", "~> 0.18.1"
|
24
|
+
spec.add_dependency "pg", "~> 0.18.1"
|
25
25
|
spec.add_dependency "sequel", "~> 4.21.0"
|
26
26
|
spec.add_dependency "activesupport", ">= 4.0.0"
|
27
27
|
spec.add_dependency "contracts", "~> 0.9"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stellar_core_commander
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scott Fleckenstein
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-06-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: stellar-base
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.0.
|
19
|
+
version: 0.0.10
|
20
20
|
type: :runtime
|
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: 0.0.
|
26
|
+
version: 0.0.10
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: slop
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -186,6 +186,8 @@ files:
|
|
186
186
|
- lib/stellar_core_commander.rb
|
187
187
|
- lib/stellar_core_commander/commander.rb
|
188
188
|
- lib/stellar_core_commander/convert.rb
|
189
|
+
- lib/stellar_core_commander/docker_process.rb
|
190
|
+
- lib/stellar_core_commander/local_process.rb
|
189
191
|
- lib/stellar_core_commander/operation_builder.rb
|
190
192
|
- lib/stellar_core_commander/process.rb
|
191
193
|
- lib/stellar_core_commander/transactor.rb
|