glueby 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8d128fa095b1dacb936a8a9ff3306b750d3cf258133f6fa469ccaf9d4d830c08
4
- data.tar.gz: 0a0496a04b1a6b86d3f2790555ac832094cb2a809ea10262f0641520dc7cb96b
3
+ metadata.gz: fbaba6627d1c34e6a2de2a3861016995481ad53163764a057c25fca123a8750b
4
+ data.tar.gz: 209020a3b503ac44cc9d4ef51e95d7ce71f17af59b92ffe3bb4863b4ae750604
5
5
  SHA512:
6
- metadata.gz: '07178bc49443f227073442e2d5e767e2350a1b363f72b1041b6f2feb2a6a7a413399617c97017acf73537d49e57f10d0aecb7439a8524a7c80691ccaf0620ce6'
7
- data.tar.gz: 86d4f463995f258d3ab3496206eabc97af77f16554705f61db69c339efc146d876375cda34bf8a17425954bf51ad6c1699eb19f37676e54401c57e5026bec597
6
+ metadata.gz: 559e4f224359df179cafc4f20c19f3f7c9723f6411103532ad6fd7d9727b5063c369b44e4e6c7872bc49d9355ec0cedd4f720c195302546cab7a5e5b429f6676
7
+ data.tar.gz: b4a4a1641820f23513ea56e1c240db966bcb9b0d62fd463d54f08e09f454125cdca4a087bc8db8c9b0181cd867ee667ec1b2bf5fbe1b95329541b3dd5fe2538b
data/README.md CHANGED
@@ -1,9 +1,31 @@
1
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
+ Glueby is a smart contract library on the [Tapyrus blockchain](https://github.com/chaintope/tapyrus-core). This is
4
+ designed as you can use without any deep blockchain understanding.
3
5
 
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.
6
+ ## Features
5
7
 
6
- TODO: Delete this and the text above, and describe your gem
8
+ Glueby has below features.
9
+
10
+ 1. Wallet
11
+ You can manage wallets for application users. This wallet feature is a foundation of Contracts below to specify tx
12
+ sender and so on.
13
+ You can choose two sorts of wallet implementation :activerecord and :core. :activerecord is implemented using
14
+ ActiveRecord on RDB. :core uses the wallet that bundled with Tapyrus Core.
15
+
16
+ 2. Contracts
17
+ You can use some smart contracts easily
18
+ - [Timestamp](#Timestamp): Record any data as a timestamp to a tapyrus blockchain.
19
+ - [Payment](./lib/glueby/contract/payment.rb): Transfer TPC.
20
+ - [Token](./lib/glueby/contract/token.rb): Issue, transfer and burn colored coin.
21
+
22
+ 3. Sync blocks with your application
23
+ You can use BlockSyncer when you need to synchronize the state of an application with the state of a blockchain.
24
+ See more details at [BlockSyncer](./lib/glueby/block_syncer.rb).
25
+
26
+ 4. Take over tx sender's fees
27
+ FeeProvider module can bear payments of sender's fees. You should provide funds for fees to FeeProvider before use.
28
+ See how to set up at [Use fee provider mode](#use-fee-provider-mode)
7
29
 
8
30
  ## Installation
9
31
 
@@ -21,13 +43,95 @@ Or install it yourself as:
21
43
 
22
44
  $ gem install glueby
23
45
 
24
- ## Usage
46
+ ### Setup for Ruby on Rails application development
25
47
 
26
- Glueby has below features.
48
+ 1. Add this line to your application's Gemfile
49
+
50
+ ```ruby
51
+ gem 'glueby'
52
+ ```
53
+
54
+ and then execute
55
+
56
+ $ bundle install
57
+
58
+ 2. Run installation rake task
59
+
60
+ $ rails glueby:contract:install
61
+
62
+ 3. Run Tapyrus Core as dev mode
63
+
64
+ We recommend to run as a Docker container.
65
+ Docker image is here.
66
+
67
+ * [tapyus/tapyrusd](https://hub.docker.com/repository/docker/tapyrus/tapyrusd)
68
+
69
+ Starts tapryusd container
70
+
71
+ $ docker run -d --name 'tapyrus_node_dev' -p 12381:12381 -e GENESIS_BLOCK_WITH_SIG='0100000000000000000000000000000000000000000000000000000000000000000000002b5331139c6bc8646bb4e5737c51378133f70b9712b75548cb3c05f9188670e7440d295e7300c5640730c4634402a3e66fb5d921f76b48d8972a484cc0361e66ef74f45e012103af80b90d25145da28c583359beb47b21796b2fe1a23c1511e443e7a64dfdb27d40e05f064662d6b9acf65ae416379d82e11a9b78cdeb3a316d1057cd2780e3727f70a61f901d10acbe349cd11e04aa6b4351e782c44670aefbe138e99a5ce75ace01010000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100f2052a010000001976a91445d405b9ed450fec89044f9b7a99a4ef6fe2cd3f88ac00000000' tapyrus/tapyrusd:edge
72
+
73
+ 4. Modify the glueby configuration
74
+
75
+ ```ruby
76
+ # Use tapyrus dev network
77
+ Tapyrus.chain_params = :dev
78
+ Glueby.configure do |config|
79
+ config.wallet_adapter = :activerecord
80
+ # Modify rpc connection info in config/initializers/glueby.rb that is created in step 3.
81
+ config.rpc_config = { schema: 'http', host: '127.0.0.1', port: 12381, user: 'rpcuser', password: 'rpcpassword' }
82
+ end
83
+ ```
84
+
85
+ 5. Generate db migration files for wallet feature
86
+
87
+ These are essential if you use `config.wallet_adapter = :activerecord` configuration.
88
+
89
+ $ rails g glueby:contract:block_syncer
90
+ $ rails g glueby:contract:wallet_adapter
91
+
92
+ If you want to use reissuable token or timestamp, you need to do below generators.
93
+
94
+ $ rails g glueby:contract:reissuable_token
95
+ $ rails g glueby:contract:timestamp
96
+
97
+ Then, run the migrations.
98
+
99
+ $ rails db:migrate
100
+
101
+ ### Provide initial TPC (Tapyrus Coin) to wallets
102
+
103
+ To use contracts, wallets need to have TPC and it can be provided from coinbase tx.
104
+
105
+ 1. Create a wallet and get receive address
106
+
107
+ ```ruby
108
+ wallet = Glueby::Wallet.create
109
+ wallet.balances # => {}
110
+ address = wallet.internal_wallet.receive_address
111
+ puts address
112
+ ```
113
+
114
+ 2. Generate a block
115
+
116
+ Set an address you got in previous step to `[Your address]`
117
+
118
+ $ docker exec tapyrus_node_dev tapyrus-cli -conf=/etc/tapyrus/tapyrus.conf generatetoaddress 1 "[Your address]" "cUJN5RVzYWFoeY8rUztd47jzXCu1p57Ay8V7pqCzsBD3PEXN7Dd4"
119
+
120
+ 3. Sync blocks if you use `:activerecord` wallet adapter
121
+
122
+ You don't need to do this if you are using `:core` wallet_adapter.
123
+
124
+ $ rails glueby:contract:block_syncer:start
125
+
126
+ Here the wallet created in step 1 have 50 TPC and you can see like this:
127
+
128
+ ```ruby
129
+ wallet.balances # => {""=>5000000000}
130
+ ```
27
131
 
28
- - [Timestamp](#Timestamp)
132
+ TPC amount is shown as tapyrus unit. 1 TPC = 100000000 tapyrus.
29
133
 
30
- ### Timestamp
134
+ ## Timestamp
31
135
 
32
136
  ```ruby
33
137
 
@@ -99,7 +203,7 @@ We can see the timestamp transaction using getrawblockchain command
99
203
  }
100
204
  ```
101
205
 
102
- #### Rails support
206
+ ### Rails support
103
207
 
104
208
  Glueby supports ruby on rails integration.
105
209
 
@@ -155,11 +259,10 @@ bin/rails glueby:contract:timestamp:create
155
259
  broadcasted (id=1, txid=8d602ca8ebdd50fa70b5ee6bc6351965b614d0a4843adacf9f43fedd7112fbf4)
156
260
  ```
157
261
 
158
- Run `glueby:contract:timestamp:confirm` task to confirm the transaction and update status(unconfirmed -> confirmded).
262
+ Run `glueby:block_syncer:start` task to confirm the transaction and update status(unconfirmed -> confirmded).
159
263
 
160
264
  ```
161
- bin/rails glueby:contract:timestamp:confirm
162
- confirmed (id=1, txid=8d602ca8ebdd50fa70b5ee6bc6351965b614d0a4843adacf9f43fedd7112fbf4)
265
+ bin/rails glueby:block_syncer:start
163
266
  ```
164
267
 
165
268
  ## Use fee provider mode
@@ -1,3 +1,5 @@
1
1
  # Edit configuration for connection to tapyrus core
2
- config = {adapter: 'core', schema: 'http', host: '127.0.0.1', port: 12381, user: 'user', password: 'pass'}
3
- Glueby::Wallet.configure(config)
2
+ Glueby.configure do |config|
3
+ config.wallet_adapter = :activerecord
4
+ config.rpc_config = { schema: 'http', host: '127.0.0.1', port: 12381, user: 'user', password: 'pass' }
5
+ end
data/lib/glueby.rb CHANGED
@@ -9,27 +9,17 @@ module Glueby
9
9
  autoload :AR, 'glueby/active_record'
10
10
  autoload :FeeProvider, 'glueby/fee_provider'
11
11
  autoload :Configuration, 'glueby/configuration'
12
+ autoload :BlockSyncer, 'glueby/block_syncer'
13
+
14
+ if defined? ::Rails::Railtie
15
+ require 'glueby/railtie'
16
+ end
12
17
 
13
18
  # Add prefix to activerecord table names
14
19
  def self.table_name_prefix
15
20
  'glueby_'
16
21
  end
17
22
 
18
- begin
19
- class Railtie < ::Rails::Railtie
20
- rake_tasks do
21
- load "tasks/glueby/contract.rake"
22
- load "tasks/glueby/contract/timestamp.rake"
23
- load "tasks/glueby/contract/wallet_adapter.rake"
24
- load "tasks/glueby/contract/block_syncer.rake"
25
- load "tasks/glueby/fee_provider.rake"
26
- end
27
- end
28
- rescue
29
- # Rake task is unavailable
30
- puts "Rake task is unavailable"
31
- end
32
-
33
23
  # Returns the global [Configuration](RSpec/Core/Configuration) object.
34
24
  def self.configuration
35
25
  @configuration ||= Glueby::Configuration.new
@@ -0,0 +1,98 @@
1
+ module Glueby
2
+ # You can use BlockSyncer when you need to synchronize the state of
3
+ # an application with the state of a blockchain. When BlockSyncer
4
+ # detects the generation of a new block, it executes the registered
5
+ # syncer code on a block-by-block or transaction-by-transaction basis.
6
+ # By using this, an application can detect that the issued transaction
7
+ # has been captured in blocks, receive a new remittance, and so on.
8
+ #
9
+ # # Syncer logic registration
10
+ #
11
+ # For registration, create a class that implements the method that performs
12
+ # synchronization processing and registers it in BlockSyncer. Implement
13
+ # methods with the following name in that class.
14
+ #
15
+ # Method name | Arguments | Call conditions
16
+ # ------------------ | --------------------- | ------------------------------
17
+ # block_sync (block) | block: Tapyrus::Block | When a new block is created
18
+ # block_tx (tx) | tx: Tapyrus::Tx | When a new block is created, it is executed for each tx contained in that block.
19
+ #
20
+ # @example Register a synchronous logic
21
+ # class Syncer
22
+ # def block_sync (block)
23
+ # # sync a block
24
+ # end
25
+ #
26
+ # def tx_sync (tx)
27
+ # # sync a tx
28
+ # end
29
+ # end
30
+ # BlockSyncer.register_syncer(Syncer)
31
+ #
32
+ # @example Unregister the synchronous logic
33
+ # BlockSyncer.unregister_syncer(Syncer)
34
+ #
35
+ # # Run BlockSyncer
36
+ #
37
+ # Run the `glueby: block_syncer: start` rake task periodically with a program
38
+ # for periodic execution such as cron. If it detects the generation of a new
39
+ # block when it is executed, the synchronization process will be executed.
40
+ # Determine the execution interval according to the requirements of the application.
41
+ class BlockSyncer
42
+ # @!attribute [r] height
43
+ # @return [Integer] The block height to be synced
44
+ attr_reader :height
45
+
46
+ class << self
47
+ # @!attribute r syncers
48
+ # @return [Array<Class>] The syncer classes that is registered
49
+ attr_reader :syncers
50
+
51
+ # Register syncer class
52
+ # @param [Class] syncer The syncer to be registered.
53
+ def register_syncer(syncer)
54
+ @syncers ||= []
55
+ @syncers << syncer
56
+ end
57
+
58
+ # Unregister syncer class
59
+ # @param [Class] syncer The syncer to be unregistered.
60
+ def unregister_syncer(syncer)
61
+ @syncers ||= []
62
+ @syncers.delete(syncer)
63
+ end
64
+ end
65
+
66
+ # @param [Integer] height The block height to be synced in the instance
67
+ def initialize(height)
68
+ @height = height
69
+ end
70
+
71
+ # Run a block synchronization
72
+ def run
73
+ return if self.class.syncers.nil?
74
+
75
+ self.class.syncers.each do |syncer|
76
+ instance = syncer.new
77
+ instance.block_sync(block) if instance.respond_to?(:block_sync)
78
+
79
+ if instance.respond_to?(:tx_sync)
80
+ block.transactions.each { |tx| instance.tx_sync(tx) }
81
+ end
82
+ end
83
+ end
84
+
85
+ private
86
+
87
+ def block
88
+ @block ||= begin
89
+ block = Glueby::Internal::RPC.client.getblock(block_hash, 0)
90
+ Tapyrus::Block.parse_from_payload(block.htb)
91
+ end
92
+ end
93
+
94
+ def block_hash
95
+ @block_hash ||= Glueby::Internal::RPC.client.getblockhash(height)
96
+ end
97
+ end
98
+ end
@@ -10,6 +10,8 @@ module Glueby
10
10
  class Timestamp
11
11
  include Glueby::Contract::TxBuilder
12
12
 
13
+ autoload :Syncer, 'glueby/contract/timestamp/syncer'
14
+
13
15
  module Util
14
16
  include Glueby::Internal::Wallet::TapyrusCoreWalletAdapter::Util
15
17
  module_function
@@ -0,0 +1,13 @@
1
+ module Glueby
2
+ module Contract
3
+ class Timestamp
4
+ class Syncer
5
+ def block_sync(block)
6
+ Glueby::Contract::AR::Timestamp
7
+ .where(txid: block.transactions.map(&:txid), status: :unconfirmed)
8
+ .update_all(status: :confirmed)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -44,7 +44,7 @@ module Glueby
44
44
  .fee(fee_provider.fixed_fee)
45
45
  .build
46
46
  tx = wallet.sign_tx(tx)
47
- wallet.broadcast(tx)
47
+ wallet.broadcast(tx, without_fee_provider: true)
48
48
  ensure
49
49
  status
50
50
  end
@@ -80,6 +80,11 @@ module Glueby
80
80
  EOS
81
81
  end
82
82
 
83
+ # Show the address of Fee Provider
84
+ def address
85
+ puts wallet.receive_address
86
+ end
87
+
83
88
  private
84
89
 
85
90
  def check_wallet_amount!
@@ -34,8 +34,6 @@ module Glueby
34
34
  autoload :Errors, 'glueby/internal/wallet/errors'
35
35
 
36
36
  class << self
37
- attr_writer :wallet_adapter
38
-
39
37
  def create(wallet_id = nil)
40
38
  begin
41
39
  wallet_id = wallet_adapter.create_wallet(wallet_id)
@@ -58,6 +56,16 @@ module Glueby
58
56
  wallet_adapter.wallets.map { |id| new(id) }
59
57
  end
60
58
 
59
+ def wallet_adapter=(adapter)
60
+ if adapter.is_a?(ActiveRecordWalletAdapter)
61
+ BlockSyncer.register_syncer(ActiveRecordWalletAdapter::Syncer)
62
+ else
63
+ BlockSyncer.unregister_syncer(ActiveRecordWalletAdapter::Syncer)
64
+ end
65
+
66
+ @wallet_adapter = adapter
67
+ end
68
+
61
69
  def wallet_adapter
62
70
  @wallet_adapter or
63
71
  raise Errors::ShouldInitializeWalletAdapter, 'You should initialize wallet adapter using `Glueby::Internal::Wallet.wallet_adapter = some wallet adapter instance`.'
@@ -74,6 +82,10 @@ module Glueby
74
82
  wallet_adapter.balance(id, only_finalized)
75
83
  end
76
84
 
85
+ # @param only_finalized [Boolean] The flag to get a UTXO with status only finalized
86
+ # @param label [String] This label is used to filtered the UTXOs with labeled if a key or Utxo is labeled.
87
+ # - If label is not specified (label=nil), all UTXOs will be returned.
88
+ # - If label=:unlabeled, only unlabeled UTXOs will be returned.
77
89
  def list_unspent(only_finalized = true, label = nil)
78
90
  wallet_adapter.list_unspent(id, only_finalized, label)
79
91
  end
@@ -99,8 +111,15 @@ module Glueby
99
111
  wallet_adapter.sign_tx(id, tx, prev_txs, sighashtype: sighashtype)
100
112
  end
101
113
 
102
- def broadcast(tx)
103
- tx = FeeProvider.provide(tx) if Glueby.configuration.fee_provider_bears?
114
+ # Broadcast a transaction via Tapyrus Core RPC
115
+ # @param [Tapyrus::Tx] tx The tx that would be broadcasted
116
+ # @option [Boolean] without_fee_provider The flag to avoid to use FeeProvider temporary.
117
+ # @param [Proc] block The block that is called before broadcasting. It can be used to handle tx that is modified by FeeProvider.
118
+ def broadcast(tx, without_fee_provider: false, &block)
119
+ tx = FeeProvider.provide(tx) if !without_fee_provider && Glueby.configuration.fee_provider_bears?
120
+
121
+ block.call(tx) if block
122
+
104
123
  wallet_adapter.broadcast(id, tx)
105
124
  tx
106
125
  end
@@ -54,6 +54,9 @@ module Glueby
54
54
  # alice_wallet.balances
55
55
  # ```
56
56
  class ActiveRecordWalletAdapter < AbstractWalletAdapter
57
+
58
+ autoload :Syncer, 'glueby/internal/wallet/active_record_wallet_adapter/syncer'
59
+
57
60
  def create_wallet(wallet_id = nil)
58
61
  wallet_id = SecureRandom.hex(16) unless wallet_id
59
62
  begin
@@ -90,7 +93,8 @@ module Glueby
90
93
  wallet = AR::Wallet.find_by(wallet_id: wallet_id)
91
94
  utxos = wallet.utxos
92
95
  utxos = utxos.where(status: :finalized) if only_finalized
93
- utxos = utxos.where(label: label) if label
96
+ utxos = utxos.where(label: label) if label && (label != :unlabeled)
97
+ utxos = utxos.where(label: nil) if label == :unlabeled
94
98
  utxos.map do |utxo|
95
99
  {
96
100
  txid: utxo.txid,
@@ -118,7 +122,7 @@ module Glueby
118
122
 
119
123
  def receive_address(wallet_id, label = nil)
120
124
  wallet = AR::Wallet.find_by(wallet_id: wallet_id)
121
- key = wallet.keys.create(purpose: :receive, label: label || '')
125
+ key = wallet.keys.create(purpose: :receive, label: label)
122
126
  key.address
123
127
  end
124
128
 
@@ -0,0 +1,14 @@
1
+ module Glueby
2
+ module Internal
3
+ class Wallet
4
+ class ActiveRecordWalletAdapter
5
+ class Syncer
6
+ def tx_sync(tx)
7
+ Glueby::Internal::Wallet::AR::Utxo.destroy_for_inputs(tx)
8
+ Glueby::Internal::Wallet::AR::Utxo.create_or_update_for_outputs(tx)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -33,7 +33,7 @@ module Glueby
33
33
  begin
34
34
  RPC.client.createwallet(wallet_name(wallet_id))
35
35
  rescue Tapyrus::RPC::Error => ex
36
- if ex.rpc_error['code'] == RPC_WALLET_ERROR_ERROR_CODE && /Wallet wallet-wallet already exists\./ =~ ex.rpc_error['message']
36
+ if ex.rpc_error && ex.rpc_error['code'] == RPC_WALLET_ERROR_ERROR_CODE && /Wallet wallet-#{wallet_id} already exists\./ =~ ex.rpc_error['message']
37
37
  raise Errors::WalletAlreadyCreated, "Wallet #{wallet_id} has been already created."
38
38
  else
39
39
  raise ex
@@ -52,9 +52,9 @@ module Glueby
52
52
  def load_wallet(wallet_id)
53
53
  RPC.client.loadwallet(wallet_name(wallet_id))
54
54
  rescue Tapyrus::RPC::Error => ex
55
- if ex.rpc_error['code'] == RPC_WALLET_ERROR_ERROR_CODE && /Duplicate -wallet filename specified/ =~ ex.rpc_error['message']
55
+ if ex.rpc_error && ex.rpc_error['code'] == RPC_WALLET_ERROR_ERROR_CODE && /Duplicate -wallet filename specified/ =~ ex.rpc_error['message']
56
56
  raise Errors::WalletAlreadyLoaded, "Wallet #{wallet_id} has been already loaded."
57
- elsif ex.rpc_error['code'] == RPC_WALLET_NOT_FOUND_ERROR_CODE
57
+ elsif ex.rpc_error && ex.rpc_error['code'] == RPC_WALLET_NOT_FOUND_ERROR_CODE
58
58
  raise Errors::WalletNotFound, "Wallet #{wallet_id} does not found"
59
59
  else
60
60
  raise ex
@@ -88,7 +88,8 @@ module Glueby
88
88
  min_conf = only_finalized ? 1 : 0
89
89
  res = client.listunspent(min_conf)
90
90
 
91
- res = res.filter { |i| i['label'] == label } if label
91
+ res = res.filter { |i| i['label'] == label } if label && (label != :unlabeled)
92
+ res = res.filter { |i| i['label'] == "" } if label == :unlabeled
92
93
 
93
94
  res.map do |i|
94
95
  script = Tapyrus::Script.parse_from_payload(i['scriptPubKey'].htb)
@@ -151,7 +152,7 @@ module Glueby
151
152
  begin
152
153
  yield(client)
153
154
  rescue Tapyrus::RPC::Error => ex
154
- if ex.rpc_error['code'] == RPC_WALLET_NOT_FOUND_ERROR_CODE
155
+ if ex.rpc_error && ex.rpc_error['code'] == RPC_WALLET_NOT_FOUND_ERROR_CODE
155
156
  raise Errors::WalletUnloaded, "The wallet #{wallet_id} is unloaded. You should load before use it."
156
157
  else
157
158
  raise ex
@@ -0,0 +1,14 @@
1
+ module Glueby
2
+ class Railtie < ::Rails::Railtie
3
+ initializer "glueby.register_syncers" do
4
+ BlockSyncer.register_syncer(Contract::Timestamp::Syncer)
5
+ end
6
+
7
+ rake_tasks do
8
+ load "tasks/glueby/contract.rake"
9
+ load "tasks/glueby/contract/timestamp.rake"
10
+ load "tasks/glueby/block_syncer.rake"
11
+ load "tasks/glueby/fee_provider.rake"
12
+ end
13
+ end
14
+ end
@@ -1,3 +1,3 @@
1
1
  module Glueby
2
- VERSION = "0.4.1"
2
+ VERSION = "0.4.2"
3
3
  end
@@ -0,0 +1,29 @@
1
+ namespace :glueby do
2
+ namespace :contract do
3
+ namespace :block_syncer do
4
+ desc '[Deprecated use glueby:block_syncer:start instead] sync block into database'
5
+ task :start, [] => [:environment] do |_, _|
6
+ puts '[Deprecated] glueby:contract:block_syncer:start is deprecated. Use \'glueby:block_syncer:start\''
7
+ Rake::Task['glueby:block_syncer:start'].execute
8
+ end
9
+ end
10
+ end
11
+ end
12
+
13
+
14
+ namespace :glueby do
15
+ namespace :block_syncer do
16
+ desc 'sync block into database'
17
+ task :start, [] => [:environment] do |_, _|
18
+ latest_block_num = Glueby::Internal::RPC.client.getblockcount
19
+ synced_block = Glueby::AR::SystemInformation.synced_block_height
20
+ (synced_block.int_value + 1..latest_block_num).each do |height|
21
+ ::ActiveRecord::Base.transaction do
22
+ Glueby::BlockSyncer.new(height).run
23
+ synced_block.update(info_value: height.to_s)
24
+ end
25
+ puts "success in synchronization (block height=#{height})"
26
+ end
27
+ end
28
+ end
29
+ end
@@ -13,9 +13,9 @@ module Glueby
13
13
  ::ActiveRecord::Base.transaction do
14
14
  wallet = Glueby::Wallet.load(t.wallet_id)
15
15
  tx = create_tx(wallet, t.prefix, t.content_hash, Glueby::Contract::FixedFeeEstimator.new)
16
- t.update(txid: tx.txid, status: :unconfirmed)
17
-
18
- wallet.internal_wallet.broadcast(tx)
16
+ wallet.internal_wallet.broadcast(tx) do |tx|
17
+ t.update(txid: tx.txid, status: :unconfirmed)
18
+ end
19
19
  puts "broadcasted (id=#{t.id}, txid=#{tx.txid})"
20
20
  end
21
21
  rescue => e
@@ -23,23 +23,6 @@ module Glueby
23
23
  end
24
24
  end
25
25
  end
26
-
27
- def confirm
28
- timestamps = Glueby::Contract::AR::Timestamp.where(status: :unconfirmed)
29
- timestamps.each do |t|
30
- begin
31
- ::ActiveRecord::Base.transaction do
32
- tx = get_transaction(t)
33
- if tx['confirmations'] && tx['confirmations'] > 0
34
- t.update(status: :confirmed)
35
- puts "confirmed (id=#{t.id}, txid=#{tx['txid']})"
36
- end
37
- end
38
- rescue => e
39
- puts "failed to confirm (id=#{t.id}, reason=#{e.message})"
40
- end
41
- end
42
- end
43
26
  end
44
27
  end
45
28
  end
@@ -52,11 +35,6 @@ namespace :glueby do
52
35
  task :create, [] => [:environment] do |_, _|
53
36
  Glueby::Contract::Task::Timestamp.create
54
37
  end
55
-
56
- desc 'confirm glueby timestamp tx'
57
- task :confirm, [] => [:environment] do |_, _|
58
- Glueby::Contract::Task::Timestamp.confirm
59
- end
60
38
  end
61
39
  end
62
40
  end
@@ -9,5 +9,10 @@ namespace :glueby do
9
9
  task :status, [] => [:environment] do |_, _|
10
10
  Glueby::FeeProvider::Tasks.new.status
11
11
  end
12
+
13
+ desc 'Show the address of the Glueby::FeeProvider'
14
+ task :address, [] => [:environment] do |_, _|
15
+ Glueby::FeeProvider::Tasks.new.address
16
+ end
12
17
  end
13
18
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glueby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - azuchi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-06-30 00:00:00.000000000 Z
11
+ date: 2021-08-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tapyrus
@@ -87,6 +87,7 @@ files:
87
87
  - lib/glueby.rb
88
88
  - lib/glueby/active_record.rb
89
89
  - lib/glueby/active_record/system_information.rb
90
+ - lib/glueby/block_syncer.rb
90
91
  - lib/glueby/configuration.rb
91
92
  - lib/glueby/contract.rb
92
93
  - lib/glueby/contract/active_record.rb
@@ -96,6 +97,7 @@ files:
96
97
  - lib/glueby/contract/fee_estimator.rb
97
98
  - lib/glueby/contract/payment.rb
98
99
  - lib/glueby/contract/timestamp.rb
100
+ - lib/glueby/contract/timestamp/syncer.rb
99
101
  - lib/glueby/contract/token.rb
100
102
  - lib/glueby/contract/tx_builder.rb
101
103
  - lib/glueby/fee_provider.rb
@@ -111,14 +113,15 @@ files:
111
113
  - lib/glueby/internal/wallet/active_record/utxo.rb
112
114
  - lib/glueby/internal/wallet/active_record/wallet.rb
113
115
  - lib/glueby/internal/wallet/active_record_wallet_adapter.rb
116
+ - lib/glueby/internal/wallet/active_record_wallet_adapter/syncer.rb
114
117
  - lib/glueby/internal/wallet/errors.rb
115
118
  - lib/glueby/internal/wallet/tapyrus_core_wallet_adapter.rb
119
+ - lib/glueby/railtie.rb
116
120
  - lib/glueby/version.rb
117
121
  - lib/glueby/wallet.rb
122
+ - lib/tasks/glueby/block_syncer.rake
118
123
  - lib/tasks/glueby/contract.rake
119
- - lib/tasks/glueby/contract/block_syncer.rake
120
124
  - lib/tasks/glueby/contract/timestamp.rake
121
- - lib/tasks/glueby/contract/wallet_adapter.rake
122
125
  - lib/tasks/glueby/fee_provider.rake
123
126
  homepage: https://github.com/chaintope/glueby
124
127
  licenses:
@@ -1,36 +0,0 @@
1
- module Glueby
2
- module Contract
3
- module Task
4
- module BlockSyncer
5
-
6
- def sync_block
7
- latest_block_num = Glueby::Internal::RPC.client.getblockcount
8
- synced_block = Glueby::AR::SystemInformation.synced_block_height
9
- (synced_block.int_value + 1..latest_block_num).each do |i|
10
- ::ActiveRecord::Base.transaction do
11
- block_hash = Glueby::Internal::RPC.client.getblockhash(i)
12
- import_block(block_hash)
13
- synced_block.update(info_value: i.to_s)
14
- puts "success in synchronization (block height=#{i.to_s})"
15
- end
16
- end
17
- end
18
-
19
- end
20
- end
21
- end
22
- end
23
-
24
- namespace :glueby do
25
- namespace :contract do
26
- namespace :block_syncer do
27
- include Glueby::Contract::Task::BlockSyncer
28
-
29
- desc 'sync block into database'
30
- task :start, [] => [:environment] do |_, _|
31
- Glueby::Contract::Task::BlockSyncer.sync_block
32
- end
33
-
34
- end
35
- end
36
- end
@@ -1,42 +0,0 @@
1
- module Glueby
2
- module Contract
3
- module Task
4
- module WalletAdapter
5
- def import_block(block_hash)
6
- block = Glueby::Internal::RPC.client.getblock(block_hash, 0)
7
- block = Tapyrus::Block.parse_from_payload(block.htb)
8
- block.transactions.each { |tx| import_tx(tx.txid) }
9
- end
10
-
11
- def import_tx(txid)
12
- tx = Glueby::Internal::RPC.client.getrawtransaction(txid)
13
- tx = Tapyrus::Tx.parse_from_payload(tx.htb)
14
- Glueby::Internal::Wallet::AR::Utxo.destroy_for_inputs(tx)
15
- Glueby::Internal::Wallet::AR::Utxo.create_or_update_for_outputs(tx)
16
- end
17
- end
18
- end
19
- end
20
- end
21
-
22
- namespace :glueby do
23
- namespace :contract do
24
- namespace :wallet_adapter do
25
- include Glueby::Contract::Task::WalletAdapter
26
-
27
- desc 'import block into database'
28
- task :import_block, [:block_hash] => [:environment] do |_, args|
29
- block_hash = args[:block_hash]
30
-
31
- ::ActiveRecord::Base.transaction { import_block(block_hash) }
32
- end
33
-
34
- desc 'import transaction into database'
35
- task :import_tx, [:txid] => [:environment] do |_, args|
36
- txid = args[:txid]
37
-
38
- ::ActiveRecord::Base.transaction { import_tx(txid) }
39
- end
40
- end
41
- end
42
- end