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