glueby 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +35 -0
  3. data/Gemfile +1 -0
  4. data/README.md +111 -6
  5. data/glueby.gemspec +1 -1
  6. data/lib/generators/glueby/contract/reissuable_token_generator.rb +26 -0
  7. data/lib/generators/glueby/contract/templates/key_table.rb.erb +3 -3
  8. data/lib/generators/glueby/contract/templates/reissuable_token_table.rb.erb +10 -0
  9. data/lib/generators/glueby/contract/templates/system_information_table.rb.erb +2 -2
  10. data/lib/generators/glueby/contract/templates/timestamp_table.rb.erb +1 -1
  11. data/lib/generators/glueby/contract/templates/utxo_table.rb.erb +2 -2
  12. data/lib/generators/glueby/contract/templates/wallet_table.rb.erb +2 -2
  13. data/lib/glueby.rb +25 -0
  14. data/lib/glueby/configuration.rb +62 -0
  15. data/lib/glueby/contract.rb +2 -2
  16. data/lib/glueby/contract/active_record.rb +1 -0
  17. data/lib/glueby/contract/active_record/reissuable_token.rb +26 -0
  18. data/lib/glueby/contract/fee_estimator.rb +38 -0
  19. data/lib/glueby/contract/payment.rb +4 -4
  20. data/lib/glueby/contract/timestamp.rb +6 -6
  21. data/lib/glueby/contract/token.rb +69 -22
  22. data/lib/glueby/contract/tx_builder.rb +22 -19
  23. data/lib/glueby/fee_provider.rb +73 -0
  24. data/lib/glueby/fee_provider/tasks.rb +136 -0
  25. data/lib/glueby/generator/migrate_generator.rb +1 -1
  26. data/lib/glueby/internal/wallet.rb +28 -4
  27. data/lib/glueby/internal/wallet/abstract_wallet_adapter.rb +18 -3
  28. data/lib/glueby/internal/wallet/active_record/wallet.rb +15 -5
  29. data/lib/glueby/internal/wallet/active_record_wallet_adapter.rb +15 -5
  30. data/lib/glueby/internal/wallet/errors.rb +3 -0
  31. data/lib/glueby/internal/wallet/tapyrus_core_wallet_adapter.rb +36 -11
  32. data/lib/glueby/version.rb +1 -1
  33. data/lib/glueby/wallet.rb +3 -2
  34. data/lib/tasks/glueby/contract/timestamp.rake +1 -1
  35. data/lib/tasks/glueby/fee_provider.rake +13 -0
  36. metadata +16 -9
  37. data/.travis.yml +0 -7
  38. data/lib/glueby/contract/fee_provider.rb +0 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d0b977d0a922975117e46c6777bf07fb13ad89d03bee8d9785ddec04e311f9c4
4
- data.tar.gz: 5b0472f6ca379fcffd7dac8adcb8fe508237ae8fcf184c1372ba721c4104f13f
3
+ metadata.gz: 572e6f36cf1b1df86b93fcd264ce1a537769588a43cbe8bac5ad3d6d9df21f44
4
+ data.tar.gz: 4516f08781b324f76846057cfe4722552bc413e7f9518d68b038c7bc16f03f79
5
5
  SHA512:
6
- metadata.gz: 1e2e21b82fe9fcb5ac8433d8f5952718624d7900b09f2ecf789163c3037a26a6b1939dbeb03dcccbf0051e890947f1612fc933c75d8093a3e74d26756ea43642
7
- data.tar.gz: 8c6d28c5432a9e8a7d56072bf6398453da18d69ef564225987649ce6bf91e751ff40b42dba9c23d652a3a2b755539b919ad0c98ae83da6607c35b3a78b7f0fd1
6
+ metadata.gz: b04613b40d622b24e14fb45440ea974905daeea6726c4a44c9e458eabe9ea552e1b8a5ad581a7ea19ab8824216f001b95c49101fdefaf2bc424a39c2fdf23d07
7
+ data.tar.gz: 1e6a50bf51dd39249c5b2746e27831ca2b63da7bb02090ba2f04b978bfa172dc0372885774986cbbf94f07ccca11d82194b1d104c467d232e0916adab50c2308
@@ -0,0 +1,35 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: Ruby
9
+
10
+ on:
11
+ push:
12
+ branches: [master]
13
+ pull_request:
14
+ branches: [master]
15
+
16
+ jobs:
17
+ test:
18
+ runs-on: ubuntu-latest
19
+ strategy:
20
+ matrix:
21
+ ruby-version: ["2.6", "2.7", "3.0"]
22
+
23
+ steps:
24
+ - run: docker pull tapyrus/tapyrusd:edge
25
+ - uses: actions/checkout@v2
26
+ - name: Set up Ruby
27
+ # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
28
+ # change this to (see https://github.com/ruby/setup-ruby#versioning):
29
+ # uses: ruby/setup-ruby@v1
30
+ uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
31
+ with:
32
+ ruby-version: ${{ matrix.ruby-version }}
33
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
34
+ - name: Run tests
35
+ run: bundle exec rake
data/Gemfile CHANGED
@@ -5,3 +5,4 @@ gemspec
5
5
 
6
6
  gem "rake", "~> 12.0"
7
7
  gem "rspec", "~> 3.0"
8
+ gem "docker-api", "~> 2.1.0"
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
- # Glueby [![Build Status](https://travis-ci.org/chaintope/glueby.svg?branch=master)](https://travis-ci.org/chaintope/glueby) [![Gem Version](https://badge.fury.io/rb/glueby.svg)](https://badge.fury.io/rb/glueby) [![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE)
1
+ # Glueby [![Ruby](https://github.com/chaintope/glueby/actions/workflows/ruby.yml/badge.svg)](https://github.com/chaintope/glueby/actions/workflows/ruby.yml) [![Gem Version](https://badge.fury.io/rb/glueby.svg)](https://badge.fury.io/rb/glueby) [![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE)
2
+
2
3
 
3
4
  Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/glueby`. To experiment with that code, run `bin/console` for an interactive prompt.
4
5
 
@@ -30,8 +31,10 @@ Glueby has below features.
30
31
 
31
32
  ```ruby
32
33
 
33
- config = {adapter: 'core', schema: 'http', host: '127.0.0.1', port: 12381, user: 'user', password: 'pass'}
34
- Glueby::Wallet.configure(config)
34
+ Glurby.configure do |config|
35
+ config.wallet_adapter = :activerecord
36
+ config.rpc_config = { schema: 'http', host: '127.0.0.1', port: 12381, user: 'user', password: 'pass' }
37
+ end
35
38
 
36
39
  wallet = Glueby::Wallet.create
37
40
  timestamp = Glueby::Contract::Timestamp.new(wallet: wallet, content: "\x01\x02\x03")
@@ -110,10 +113,12 @@ bin/rails glueby:contract:install
110
113
 
111
114
  Install task creates a file `glueby.rb` in `config/initializers` directory like this.
112
115
 
113
- ```
116
+ ```ruby
114
117
  # Edit configuration for connection to tapyrus core
115
- config = {adapter: 'core', schema: 'http', host: '127.0.0.1', port: 12381, user: 'user', password: 'pass'}
116
- Glueby::Wallet.configure(config)
118
+ Glueby.configure do |config|
119
+ config.wallet_adapter = :activerecord
120
+ config.rpc_config = { schema: 'http', host: '127.0.0.1', port: 12381, user: 'user', password: 'pass' }
121
+ end
117
122
  ```
118
123
 
119
124
  If you use timestamp feature, use `glueby:contract:timestamp` generator.
@@ -157,6 +162,106 @@ bin/rails glueby:contract:timestamp:confirm
157
162
  confirmed (id=1, txid=8d602ca8ebdd50fa70b5ee6bc6351965b614d0a4843adacf9f43fedd7112fbf4)
158
163
  ```
159
164
 
165
+ ## Use fee provider mode
166
+
167
+ Glueby contracts have two different way of fee provisions.
168
+
169
+ 1. `:sender_pays_itself`
170
+ 2. `:fee_provider_bears`
171
+
172
+ The first one: `:sender_pays_itself`, is the default behavior.
173
+ In the second Fee Provider mode, the Fee Provider module pays a fee instead of the transaction's sender.
174
+
175
+ ### Fee Provider Specification
176
+
177
+ * Fee Provider pays fixed amount fee, and it is configurable.
178
+ * Fee Provider needs to have enough funds into their wallet.
179
+ * Fee Provider is managed to keep some number of UTXOs that have fixed fee value by rake tasks.
180
+
181
+ ### Setting up Fee Provider
182
+
183
+ 1. Set like below
184
+
185
+ ```ruby
186
+ Glurby.configure do |config|
187
+ # Use FeeProvider to supply inputs for fees on each transaction that is created on Glueby.
188
+ config.fee_provider_bears!
189
+ config.fee_provider_config = {
190
+ # The fee that Fee Provider pays on each transaction.
191
+ fixed_fee: 1000,
192
+ # Fee Provider tries to keep the number of utxo in utxo pool as this size using `glueby:fee_provider:manage_utxo_pool` rake task
193
+ utxo_pool_size: 20
194
+ }
195
+ end
196
+ ```
197
+
198
+ 2. Deposit TPC into Fee Provider's wallet
199
+
200
+ Get an address from the wallet.
201
+
202
+ ```
203
+ $ bundle exec rake glueby:fee_provider:address
204
+ mqYTLdLCUCCZkTkcpbVx1GqpvV1gK4euRD
205
+ ```
206
+
207
+ Send TPC to the address.
208
+
209
+ If you use `Glueby::Contract::Payment` to the sending, you can do like this:
210
+
211
+ ```ruby
212
+ Glueby::Contract::Payment.transfer(sender: sender, receiver_address: 'mqYTLdLCUCCZkTkcpbVx1GqpvV1gK4euRD', amount: 1_000_000)
213
+ ```
214
+
215
+ 3. Manage UTXO pool
216
+
217
+ The Fee Provider's wallet has to keep some UTXOs with `fixed_fee` amount for paying fees using `manage_utxo_pool` rake task below.
218
+ This rake task tries to split UTOXs up to `utxo_pool_size`. If the pool has more than `utxo_pool_size` UTXOs, it does nothing.
219
+
220
+ ```
221
+ $ bundle exec rake glueby:fee_provider:manage_utxo_pool
222
+ Status: Ready
223
+ TPC amount: 999_000
224
+ UTXO pool size: 20
225
+
226
+ Configuration:
227
+ fixed_fee = 1_000
228
+ utxo_pool_size = 20
229
+ ```
230
+
231
+ This shows that the UTXO pool has 20 UTXOs with `fixed_fee` amount for paying fees and has other UTXOs that never use for paying fees.
232
+ The sum of all the UTXOs that includes both kinds of UTXO is 999_000 tapyrus.
233
+
234
+ If the wallet doesn't have enough amount, the rake task shows an error like:
235
+
236
+ ```
237
+ $ bundle exec rake glueby:fee_provider:manage_utxo_pool
238
+ Status: Insufficient Amount
239
+ TPC amount: 15_000
240
+ UTXO pool size: 15
241
+
242
+ 1. Please replenishment TPC which is for paying fee to FeeProvider.
243
+ FeeProvider needs 21000 tapyrus at least for paying 20 transaction fees.
244
+ FeeProvider wallet's address is '1DBgMCNBdjQ1Ntz1vpwx2HMYJmc9kw88iT'
245
+ 2. Then create UTXOs for paying in UTXO pool with 'rake glueby:fee_provider:manage_utxo_pool'
246
+
247
+ Configuration:
248
+ fixed_fee = 1_000
249
+ utxo_pool_size = 20
250
+ ```
251
+
252
+ If you want to get the status information, you can use the `status` task.
253
+
254
+ ```
255
+ $ bundle exec rake glueby:fee_provider:status
256
+ Status: Ready
257
+ TPC amount: 999_000
258
+ UTXO pool size: 20
259
+
260
+ Configuration:
261
+ fixed_fee = 1_000
262
+ utxo_pool_size = 20
263
+ ```
264
+
160
265
  ## Development
161
266
 
162
267
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/glueby.gemspec CHANGED
@@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
27
  spec.require_paths = ["lib"]
28
28
 
29
- spec.add_runtime_dependency 'tapyrus', '>= 0.2.6'
29
+ spec.add_runtime_dependency 'tapyrus', '>= 0.2.9'
30
30
  spec.add_development_dependency 'activerecord'
31
31
  spec.add_development_dependency 'sqlite3'
32
32
  end
@@ -0,0 +1,26 @@
1
+ module Glueby
2
+ module Contract
3
+ class ReissuableTokenGenerator < Rails::Generators::Base
4
+ include ::Rails::Generators::Migration
5
+ include Glueby::Generator::MigrateGenerator
6
+ extend Glueby::Generator::MigrateGenerator::ClassMethod
7
+
8
+ source_root File.expand_path('templates', __dir__)
9
+
10
+ def create_migration_file
11
+ migration_dir = File.expand_path("db/migrate")
12
+
13
+ if self.class.migration_exists?(migration_dir, "create_reissuable_token")
14
+ ::Kernel.warn "Migration already exists: create_reissuable_token"
15
+ else
16
+ migration_template(
17
+ "reissuable_token_table.rb.erb",
18
+ "db/migrate/create_reissuable_token.rb",
19
+ migration_version: migration_version,
20
+ table_options: table_options,
21
+ )
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,6 +1,6 @@
1
1
  class CreateKey < ActiveRecord::Migration<%= migration_version %>
2
2
  def change
3
- create_table :keys<%= table_options %> do |t|
3
+ create_table :glueby_keys<%= table_options %> do |t|
4
4
  t.string :private_key
5
5
  t.string :public_key
6
6
  t.string :script_pubkey
@@ -9,7 +9,7 @@ class CreateKey < ActiveRecord::Migration<%= migration_version %>
9
9
  t.timestamps
10
10
  end
11
11
 
12
- add_index :keys, [:script_pubkey], unique: true
13
- add_index :keys, [:private_key], unique: true
12
+ add_index :glueby_keys, [:script_pubkey], unique: true
13
+ add_index :glueby_keys, [:private_key], unique: true
14
14
  end
15
15
  end
@@ -0,0 +1,10 @@
1
+ class CreateReissuableToken < ActiveRecord::Migration<%= migration_version %>
2
+ def change
3
+ create_table :glueby_reissuable_tokens<%= table_options %> do |t|
4
+ t.string :color_id, null: false
5
+ t.string :script_pubkey, null: false
6
+ t.timestamps
7
+ end
8
+ add_index :glueby_reissuable_tokens, [:color_id], unique: true
9
+ end
10
+ end
@@ -1,11 +1,11 @@
1
1
  class CreateSystemInformation < ActiveRecord::Migration<%= migration_version %>
2
2
  def change
3
- create_table :system_informations<%= table_options %> do |t|
3
+ create_table :glueby_system_informations<%= table_options %> do |t|
4
4
  t.string :info_key
5
5
  t.string :info_value
6
6
  t.timestamps
7
7
  end
8
- add_index :system_informations, [:info_key], unique: true
8
+ add_index :glueby_system_informations, [:info_key], unique: true
9
9
 
10
10
  Glueby::AR::SystemInformation.create(info_key: "synced_block_number", info_value: "0")
11
11
  end
@@ -1,6 +1,6 @@
1
1
  class CreateTimestamp < ActiveRecord::Migration<%= migration_version %>
2
2
  def change
3
- create_table :timestamps<%= table_options %> do |t|
3
+ create_table :glueby_timestamps<%= table_options %> do |t|
4
4
  t.string :txid
5
5
  t.integer :status
6
6
  t.string :content_hash
@@ -1,6 +1,6 @@
1
1
  class CreateUtxo < ActiveRecord::Migration<%= migration_version %>
2
2
  def change
3
- create_table :utxos<%= table_options %> do |t|
3
+ create_table :glueby_utxos<%= table_options %> do |t|
4
4
  t.string :txid
5
5
  t.integer :index
6
6
  t.bigint :value
@@ -10,6 +10,6 @@ class CreateUtxo < ActiveRecord::Migration<%= migration_version %>
10
10
  t.timestamps
11
11
  end
12
12
 
13
- add_index :utxos, [:txid, :index], unique: true
13
+ add_index :glueby_utxos, [:txid, :index], unique: true
14
14
  end
15
15
  end
@@ -1,10 +1,10 @@
1
1
  class CreateWallet < ActiveRecord::Migration<%= migration_version %>
2
2
  def change
3
- create_table :wallets<%= table_options %> do |t|
3
+ create_table :glueby_wallets<%= table_options %> do |t|
4
4
  t.string :wallet_id
5
5
  t.timestamps
6
6
  end
7
7
 
8
- add_index :wallets, [:wallet_id], unique: true
8
+ add_index :glueby_wallets, [:wallet_id], unique: true
9
9
  end
10
10
  end
data/lib/glueby.rb CHANGED
@@ -7,6 +7,13 @@ module Glueby
7
7
  autoload :Wallet, 'glueby/wallet'
8
8
  autoload :Internal, 'glueby/internal'
9
9
  autoload :AR, 'glueby/active_record'
10
+ autoload :FeeProvider, 'glueby/fee_provider'
11
+ autoload :Configuration, 'glueby/configuration'
12
+
13
+ # Add prefix to activerecord table names
14
+ def self.table_name_prefix
15
+ 'glueby_'
16
+ end
10
17
 
11
18
  begin
12
19
  class Railtie < ::Rails::Railtie
@@ -15,10 +22,28 @@ module Glueby
15
22
  load "tasks/glueby/contract/timestamp.rake"
16
23
  load "tasks/glueby/contract/wallet_adapter.rake"
17
24
  load "tasks/glueby/contract/block_syncer.rake"
25
+ load "tasks/glueby/fee_provider.rake"
18
26
  end
19
27
  end
20
28
  rescue
21
29
  # Rake task is unavailable
22
30
  puts "Rake task is unavailable"
23
31
  end
32
+
33
+ # Returns the global [Configuration](RSpec/Core/Configuration) object.
34
+ def self.configuration
35
+ @configuration ||= Glueby::Configuration.new
36
+ end
37
+
38
+ # Yields the global configuration to a block.
39
+ # @yield [Configuration] global configuration
40
+ #
41
+ # @example
42
+ # Glueby.configure do |config|
43
+ # config.wallet_adapter = :activerecord
44
+ # config.rpc_config = { schema: 'http', host: '127.0.0.1', port: 12381, user: 'user', password: 'pass' }
45
+ # end
46
+ def self.configure
47
+ yield configuration if block_given?
48
+ end
24
49
  end
@@ -0,0 +1,62 @@
1
+ module Glueby
2
+ # Global configuration on runtime
3
+ #
4
+ # The global configuration treats configurations for all modules in Glueby.
5
+ #
6
+ # @example
7
+ # Glueby.configure do |config|
8
+ # config.wallet_adapter = :activerecord
9
+ # config.rpc_config = { schema: 'http', host: '127.0.0.1', port: 12381, user: 'user', password: 'pass' }
10
+ # end
11
+ class Configuration
12
+
13
+ attr_reader :fee_provider_bears
14
+ alias_method :fee_provider_bears?, :fee_provider_bears
15
+
16
+ def initialize
17
+ @fee_provider_bears = false
18
+ end
19
+
20
+ # Specify wallet adapter.
21
+ # @param [Symbol] adapter - The adapter type :activerecord or :core is currently supported.
22
+ def wallet_adapter=(adapter)
23
+ case adapter
24
+ when :core
25
+ Glueby::Internal::Wallet.wallet_adapter = Glueby::Internal::Wallet::TapyrusCoreWalletAdapter.new
26
+ when :activerecord
27
+ Glueby::Internal::Wallet.wallet_adapter = Glueby::Internal::Wallet::ActiveRecordWalletAdapter.new
28
+ else
29
+ raise 'Not implemented'
30
+ end
31
+ end
32
+
33
+ # Specify connection information to Tapyrus Core RPC.
34
+ # @param [Hash] config
35
+ # @option config [String] :schema - http or https
36
+ # @option config [String] :host - The host of the RPC endpoint
37
+ # @option config [Integer] :port - The port of the RPC endpoint
38
+ # @Option config [String] :user - The user for Basic Authorization of the RPC endpoint
39
+ # @Option config [String] :password - The password for Basic Authorization of the RPC endpoint
40
+ def rpc_config=(config)
41
+ Glueby::Internal::RPC.configure(config)
42
+ end
43
+
44
+ # Use This to enable to use FeeProvider to supply inputs for fees on each transaction that is created on Glueby.
45
+ def fee_provider_bears!
46
+ @fee_provider_bears = true
47
+ end
48
+
49
+ # Use This to disable to use FeeProvider
50
+ def disable_fee_provider_bears!
51
+ @fee_provider_bears = false
52
+ end
53
+
54
+ # Specify FeeProvider configuration.
55
+ # @param [Hash] config
56
+ # @option config [Integer] :fixed_fee - The fee that Fee Provider pays on each transaction.
57
+ # @option config [Integer] :utxo_pool_size - Fee Provider tries to keep the number of utxo in utxo pool as this size using `glueby:fee_provider:manage_utxo_pool` rake task
58
+ def fee_provider_config=(config)
59
+ FeeProvider.configure(config)
60
+ end
61
+ end
62
+ end
@@ -1,8 +1,8 @@
1
1
  module Glueby
2
2
  module Contract
3
3
  autoload :Errors, 'glueby/contract/errors'
4
- autoload :FeeProvider, 'glueby/contract/fee_provider'
5
- autoload :FixedFeeProvider, 'glueby/contract/fee_provider'
4
+ autoload :FeeEstimator, 'glueby/contract/fee_estimator'
5
+ autoload :FixedFeeEstimator, 'glueby/contract/fee_estimator'
6
6
  autoload :Payment, 'glueby/contract/payment'
7
7
  autoload :Timestamp, 'glueby/contract/timestamp'
8
8
  autoload :Token, 'glueby/contract/token'
@@ -3,6 +3,7 @@ require 'active_record'
3
3
  module Glueby
4
4
  module Contract
5
5
  module AR
6
+ autoload :ReissuableToken, 'glueby/contract/active_record/reissuable_token'
6
7
  autoload :Timestamp, 'glueby/contract/active_record/timestamp'
7
8
  end
8
9
  end