glueby 0.3.0 → 0.4.0

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.
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