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 +4 -4
- data/README.md +113 -10
- data/lib/generators/glueby/contract/templates/initializer.rb.erb +4 -2
- data/lib/glueby.rb +5 -15
- data/lib/glueby/block_syncer.rb +98 -0
- data/lib/glueby/contract/timestamp.rb +2 -0
- data/lib/glueby/contract/timestamp/syncer.rb +13 -0
- data/lib/glueby/fee_provider/tasks.rb +6 -1
- data/lib/glueby/internal/wallet.rb +23 -4
- data/lib/glueby/internal/wallet/active_record_wallet_adapter.rb +6 -2
- data/lib/glueby/internal/wallet/active_record_wallet_adapter/syncer.rb +14 -0
- data/lib/glueby/internal/wallet/tapyrus_core_wallet_adapter.rb +6 -5
- data/lib/glueby/railtie.rb +14 -0
- data/lib/glueby/version.rb +1 -1
- data/lib/tasks/glueby/block_syncer.rake +29 -0
- data/lib/tasks/glueby/contract/timestamp.rake +3 -25
- data/lib/tasks/glueby/fee_provider.rake +5 -0
- metadata +7 -4
- data/lib/tasks/glueby/contract/block_syncer.rake +0 -36
- data/lib/tasks/glueby/contract/wallet_adapter.rake +0 -42
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fbaba6627d1c34e6a2de2a3861016995481ad53163764a057c25fca123a8750b
|
4
|
+
data.tar.gz: 209020a3b503ac44cc9d4ef51e95d7ce71f17af59b92ffe3bb4863b4ae750604
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
6
|
+
## Features
|
5
7
|
|
6
|
-
|
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
|
-
|
46
|
+
### Setup for Ruby on Rails application development
|
25
47
|
|
26
|
-
|
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
|
-
|
132
|
+
TPC amount is shown as tapyrus unit. 1 TPC = 100000000 tapyrus.
|
29
133
|
|
30
|
-
|
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
|
-
|
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:
|
262
|
+
Run `glueby:block_syncer:start` task to confirm the transaction and update status(unconfirmed -> confirmded).
|
159
263
|
|
160
264
|
```
|
161
|
-
bin/rails glueby:
|
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
|
-
|
3
|
-
|
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
|
@@ -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
|
-
|
103
|
-
|
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
|
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
|
data/lib/glueby/version.rb
CHANGED
@@ -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
|
-
|
17
|
-
|
18
|
-
|
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.
|
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-
|
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
|