glueby 1.0.0 → 1.1.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.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +3 -4
- data/README.md +3 -3
- data/glueby.gemspec +2 -1
- data/lib/generators/glueby/contract/templates/initializer.rb.erb +8 -8
- data/lib/generators/glueby/contract/templates/key_table.rb.erb +16 -16
- data/lib/generators/glueby/contract/templates/timestamp_table.rb.erb +2 -0
- data/lib/generators/glueby/contract/templates/token_metadata_table.rb.erb +13 -0
- data/lib/generators/glueby/contract/templates/utxo_table.rb.erb +1 -0
- data/lib/generators/glueby/contract/{reissuable_token_generator.rb → token_generator.rb} +12 -1
- data/lib/glueby/block_syncer.rb +97 -97
- data/lib/glueby/configuration.rb +2 -0
- data/lib/glueby/contract/active_record/timestamp.rb +9 -2
- data/lib/glueby/contract/active_record/token_metadata.rb +8 -0
- data/lib/glueby/contract/active_record.rb +1 -0
- data/lib/glueby/contract/fee_estimator/auto.rb +9 -1
- data/lib/glueby/contract/fee_estimator.rb +12 -5
- data/lib/glueby/contract/timestamp/syncer.rb +1 -1
- data/lib/glueby/contract/token.rb +161 -80
- data/lib/glueby/contract/tx_builder.rb +104 -67
- data/lib/glueby/fee_provider/tasks.rb +4 -1
- data/lib/glueby/internal/wallet/abstract_wallet_adapter.rb +26 -0
- data/lib/glueby/internal/wallet/active_record/key.rb +2 -2
- data/lib/glueby/internal/wallet/active_record/utxo.rb +9 -0
- data/lib/glueby/internal/wallet/active_record_wallet_adapter.rb +22 -9
- data/lib/glueby/internal/wallet/errors.rb +1 -0
- data/lib/glueby/internal/wallet/mysql_wallet_adapter.rb +17 -0
- data/lib/glueby/internal/wallet/tapyrus_core_wallet_adapter.rb +1 -1
- data/lib/glueby/internal/wallet.rb +16 -0
- data/lib/glueby/util/digest.rb +23 -0
- data/lib/glueby/utxo_provider/tasks.rb +3 -1
- data/lib/glueby/utxo_provider.rb +56 -9
- data/lib/glueby/version.rb +1 -1
- data/lib/tasks/glueby/block_syncer.rake +7 -0
- metadata +23 -5
@@ -38,10 +38,13 @@ module Glueby
|
|
38
38
|
|
39
39
|
fee_outputs_count_to_be_created.times do
|
40
40
|
txb.pay(address, fee_provider.fixed_fee)
|
41
|
+
sum -= fee_provider.fixed_fee
|
41
42
|
end
|
43
|
+
fee = fee_provider.fixed_fee
|
44
|
+
fee += (sum - fee) if sum - fee < DUST_LIMIT
|
42
45
|
|
43
46
|
tx = txb.change_address(address)
|
44
|
-
.fee(
|
47
|
+
.fee(fee)
|
45
48
|
.build
|
46
49
|
tx = wallet.sign_tx(tx)
|
47
50
|
wallet.broadcast(tx, without_fee_provider: true)
|
@@ -86,6 +86,14 @@ module Glueby
|
|
86
86
|
raise NotImplementedError, "You must implement #{self.class}##{__method__}"
|
87
87
|
end
|
88
88
|
|
89
|
+
# Attempt to lock a specified utxo and update lock_at field
|
90
|
+
#
|
91
|
+
# @param wallet_id [String] The wallet id that is offered by `create_wallet()` method.
|
92
|
+
# @param utxo [Hash] The utxo hash object
|
93
|
+
def lock_unspent(wallet_id, utxo)
|
94
|
+
true
|
95
|
+
end
|
96
|
+
|
89
97
|
# Sign to the transaction with a key in the wallet.
|
90
98
|
#
|
91
99
|
# @param [String] wallet_id - The wallet id that is offered by `create_wallet()` method.
|
@@ -157,6 +165,15 @@ module Glueby
|
|
157
165
|
raise NotImplementedError, "You must implement #{self.class}##{__method__}"
|
158
166
|
end
|
159
167
|
|
168
|
+
# Create pay to contract key
|
169
|
+
# @param [String] wallet_id - The wallet id that is offered by `create_wallet()` method.
|
170
|
+
# @param [Tapyrus::Key] payment_base - The public key used to generate pay to contract public key
|
171
|
+
# @param [String] contents - The data to be used for generating pay-to-contract address
|
172
|
+
# @return [Tapyrus::Key] Key for pay to contract
|
173
|
+
def pay_to_contract_key(wallet_id, payment_base, contents)
|
174
|
+
raise NotImplementedError, "You must implement #{self.class}##{__method__}"
|
175
|
+
end
|
176
|
+
|
160
177
|
# Sign to the pay to contract input
|
161
178
|
# @param [String] wallet_id - The wallet id that is offered by `create_wallet()` method.
|
162
179
|
# @param [Tapyrus::Tx] tx - The tx that has pay to contract input in the inputs list
|
@@ -170,9 +187,18 @@ module Glueby
|
|
170
187
|
# @param [Integer] sighashtype - The sighash flag for each signature that would be produced here.
|
171
188
|
# @return [Tapyrus::Tx]
|
172
189
|
# @raise [Glueby::Internal::Wallet::Errors::InvalidSighashType] when the specified sighashtype is invalid
|
190
|
+
# @raise [Glueby::Internal::Wallet::Errors::InvalidSigner] when the wallet don't have any private key of the specified payment_base
|
173
191
|
def sign_to_pay_to_contract_address(wallet_id, tx, utxo, payment_base, contents, sighashtype: Tapyrus::SIGHASH_TYPE[:all])
|
174
192
|
raise NotImplementedError, "You must implement #{self.class}##{__method__}"
|
175
193
|
end
|
194
|
+
|
195
|
+
# Return if wallet has the address
|
196
|
+
# @param wallet_id [String] The wallet id that is offered by `create_wallet()` method.
|
197
|
+
# @param address [String] address
|
198
|
+
# @return [Boolean] true if the wallet has an address, false otherwise
|
199
|
+
def has_address?(wallet_id, address)
|
200
|
+
raise NotImplementedError, "You must implement #{self.class}##{__method__}"
|
201
|
+
end
|
176
202
|
end
|
177
203
|
end
|
178
204
|
end
|
@@ -20,7 +20,7 @@ module Glueby
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def sign(data)
|
23
|
-
Tapyrus::Key.new(priv_key: self.private_key).sign(data, algo: :schnorr)
|
23
|
+
Tapyrus::Key.new(priv_key: self.private_key, key_type: Tapyrus::Key::TYPES[:compressed]).sign(data, algo: :schnorr)
|
24
24
|
end
|
25
25
|
|
26
26
|
def address
|
@@ -54,7 +54,7 @@ module Glueby
|
|
54
54
|
|
55
55
|
def generate_key
|
56
56
|
key = if private_key
|
57
|
-
Tapyrus::Key.new(priv_key: private_key)
|
57
|
+
Tapyrus::Key.new(priv_key: private_key, key_type: Tapyrus::Key::TYPES[:compressed])
|
58
58
|
else
|
59
59
|
Tapyrus::Key.generate
|
60
60
|
end
|
@@ -8,6 +8,7 @@ module Glueby
|
|
8
8
|
belongs_to :key
|
9
9
|
|
10
10
|
validates :txid, uniqueness: { scope: :index, case_sensitive: false }
|
11
|
+
validate :check_dust_output
|
11
12
|
|
12
13
|
enum status: { init: 0, broadcasted: 1, finalized: 2 }
|
13
14
|
|
@@ -44,6 +45,14 @@ module Glueby
|
|
44
45
|
)
|
45
46
|
end
|
46
47
|
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def check_dust_output
|
52
|
+
if !color_id && value < DUST_LIMIT
|
53
|
+
errors.add(:value, "is less than dust limit(#{DUST_LIMIT})")
|
54
|
+
end
|
55
|
+
end
|
47
56
|
end
|
48
57
|
end
|
49
58
|
end
|
@@ -84,16 +84,15 @@ module Glueby
|
|
84
84
|
|
85
85
|
def balance(wallet_id, only_finalized = true)
|
86
86
|
wallet = AR::Wallet.find_by(wallet_id: wallet_id)
|
87
|
-
utxos = wallet.utxos
|
87
|
+
utxos = wallet.utxos.where(locked_at: nil)
|
88
88
|
utxos = utxos.where(status: :finalized) if only_finalized
|
89
89
|
utxos.sum(&:value)
|
90
90
|
end
|
91
91
|
|
92
92
|
def list_unspent(wallet_id, only_finalized = true, label = nil)
|
93
93
|
wallet = AR::Wallet.find_by(wallet_id: wallet_id)
|
94
|
-
utxos = wallet.utxos
|
94
|
+
utxos = wallet.utxos.where(locked_at: nil)
|
95
95
|
utxos = utxos.where(status: :finalized) if only_finalized
|
96
|
-
|
97
96
|
if [:unlabeled, nil].include?(label)
|
98
97
|
utxos = utxos.where(label: nil)
|
99
98
|
elsif label && (label != :all)
|
@@ -144,7 +143,7 @@ module Glueby
|
|
144
143
|
def create_pubkey(wallet_id)
|
145
144
|
wallet = AR::Wallet.find_by(wallet_id: wallet_id)
|
146
145
|
key = wallet.keys.create(purpose: :receive)
|
147
|
-
Tapyrus::Key.new(pubkey: key.public_key)
|
146
|
+
Tapyrus::Key.new(pubkey: key.public_key, key_type: Tapyrus::Key::TYPES[:compressed])
|
148
147
|
end
|
149
148
|
|
150
149
|
def get_addresses(wallet_id, label = nil)
|
@@ -155,13 +154,17 @@ module Glueby
|
|
155
154
|
end
|
156
155
|
|
157
156
|
def create_pay_to_contract_address(wallet_id, contents)
|
157
|
+
pubkey = create_pubkey(wallet_id)
|
158
|
+
[pay_to_contract_key(wallet_id, pubkey, contents).to_p2pkh, pubkey.pubkey]
|
159
|
+
end
|
160
|
+
|
161
|
+
def pay_to_contract_key(wallet_id, pubkey, contents)
|
158
162
|
# Calculate P + H(P || contents)G
|
159
163
|
group = ECDSA::Group::Secp256k1
|
160
|
-
pubkey = create_pubkey(wallet_id)
|
161
164
|
p = pubkey.to_point # P
|
162
165
|
commitment = create_pay_to_contract_commitment(pubkey, contents)
|
163
166
|
point = p + group.generator.multiply_by_scalar(commitment) # P + H(P || contents)G
|
164
|
-
|
167
|
+
Tapyrus::Key.new(pubkey: point.to_hex(true), key_type: Tapyrus::Key::TYPES[:compressed])
|
165
168
|
end
|
166
169
|
|
167
170
|
def sign_to_pay_to_contract_address(wallet_id, tx, utxo, payment_base, contents)
|
@@ -174,6 +177,12 @@ module Glueby
|
|
174
177
|
tx
|
175
178
|
end
|
176
179
|
|
180
|
+
def has_address?(wallet_id, address)
|
181
|
+
script_pubkey = Tapyrus::Script.parse_from_addr(address)
|
182
|
+
wallet = AR::Wallet.find_by(wallet_id: wallet_id)
|
183
|
+
wallet.keys.exists?(script_pubkey: script_pubkey.to_hex)
|
184
|
+
end
|
185
|
+
|
177
186
|
private
|
178
187
|
|
179
188
|
# Calculate commitment = H(P || contents)
|
@@ -181,22 +190,26 @@ module Glueby
|
|
181
190
|
# @param [String] contents
|
182
191
|
# @return Integer
|
183
192
|
def create_pay_to_contract_commitment(pubkey, contents)
|
193
|
+
contents = (+contents).force_encoding('binary')
|
184
194
|
group = ECDSA::Group::Secp256k1
|
185
195
|
p = pubkey.to_point # P
|
186
|
-
Tapyrus.sha256(p.to_hex(true).htb + contents).bth.to_i(16) % group.order # H(P || contents)
|
196
|
+
Tapyrus.sha256(p.to_hex(true).htb + contents).bth.to_i(16) % group.order # H(P || contents)
|
187
197
|
end
|
188
198
|
|
189
199
|
# @param [String] wallet_id
|
190
200
|
# @param [String] payment_base The public key hex string
|
191
201
|
# @param [String] contents
|
192
202
|
# @return [Tapyrus::Key] pay to contract private key
|
203
|
+
# @raise [Errors::InvalidSigner] raises when the wallet don't have any private key of the specified payment_base
|
193
204
|
def create_pay_to_contract_private_key(wallet_id, payment_base, contents)
|
194
205
|
group = ECDSA::Group::Secp256k1
|
195
206
|
wallet = AR::Wallet.find_by(wallet_id: wallet_id)
|
196
207
|
ar_key = wallet.keys.where(public_key: payment_base).first
|
197
|
-
key
|
208
|
+
raise Errors::InvalidSigner, "The wallet don't have any private key of the specified payment_base" unless ar_key
|
209
|
+
|
210
|
+
key = Tapyrus::Key.new(pubkey: payment_base, key_type: Tapyrus::Key::TYPES[:compressed])
|
198
211
|
commitment = create_pay_to_contract_commitment(key, contents)
|
199
|
-
Tapyrus::Key.new(priv_key: ((ar_key.private_key.to_i(16) + commitment) % group.order).to_even_length_hex) # K + commitment
|
212
|
+
Tapyrus::Key.new(priv_key: ((ar_key.private_key.to_i(16) + commitment) % group.order).to_even_length_hex, key_type: Tapyrus::Key::TYPES[:compressed]) # K + commitment
|
200
213
|
end
|
201
214
|
end
|
202
215
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Glueby
|
4
|
+
module Internal
|
5
|
+
class Wallet
|
6
|
+
class MySQLWalletAdapter < ActiveRecordWalletAdapter
|
7
|
+
def lock_unspent(wallet_id, utxo)
|
8
|
+
ActiveRecord::Base.transaction(joinable: false, requires_new: true) do
|
9
|
+
record = AR::Utxo.lock("FOR UPDATE SKIP LOCKED").find_by(txid: utxo[:txid], index: utxo[:vout], locked_at: nil)
|
10
|
+
record&.update!(locked_at: Time.now)
|
11
|
+
record
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -149,7 +149,7 @@ module Glueby
|
|
149
149
|
perform_as(wallet_id) do |client|
|
150
150
|
address = client.getnewaddress('')
|
151
151
|
info = client.getaddressinfo(address)
|
152
|
-
Tapyrus::Key.new(pubkey: info['pubkey'])
|
152
|
+
Tapyrus::Key.new(pubkey: info['pubkey'], key_type: Tapyrus::Key::TYPES[:compressed])
|
153
153
|
end
|
154
154
|
end
|
155
155
|
|
@@ -31,8 +31,11 @@ module Glueby
|
|
31
31
|
autoload :AR, 'glueby/internal/wallet/active_record'
|
32
32
|
autoload :TapyrusCoreWalletAdapter, 'glueby/internal/wallet/tapyrus_core_wallet_adapter'
|
33
33
|
autoload :ActiveRecordWalletAdapter, 'glueby/internal/wallet/active_record_wallet_adapter'
|
34
|
+
autoload :MySQLWalletAdapter, 'glueby/internal/wallet/mysql_wallet_adapter'
|
34
35
|
autoload :Errors, 'glueby/internal/wallet/errors'
|
35
36
|
|
37
|
+
include GluebyLogger
|
38
|
+
|
36
39
|
class << self
|
37
40
|
def create(wallet_id = nil)
|
38
41
|
begin
|
@@ -91,6 +94,10 @@ module Glueby
|
|
91
94
|
wallet_adapter.list_unspent(id, only_finalized, label)
|
92
95
|
end
|
93
96
|
|
97
|
+
def lock_unspent(utxo)
|
98
|
+
wallet_adapter.lock_unspent(id, utxo)
|
99
|
+
end
|
100
|
+
|
94
101
|
def delete
|
95
102
|
wallet_adapter.delete_wallet(id)
|
96
103
|
end
|
@@ -118,6 +125,7 @@ module Glueby
|
|
118
125
|
# @param [Proc] block The block that is called before broadcasting. It can be used to handle tx that is modified by FeeProvider.
|
119
126
|
def broadcast(tx, without_fee_provider: false, &block)
|
120
127
|
tx = FeeProvider.provide(tx) if !without_fee_provider && Glueby.configuration.fee_provider_bears?
|
128
|
+
logger.info("Try to broadcast a tx (tx payload: #{tx.to_hex} )")
|
121
129
|
wallet_adapter.broadcast(id, tx, &block)
|
122
130
|
tx
|
123
131
|
end
|
@@ -158,10 +166,18 @@ module Glueby
|
|
158
166
|
wallet_adapter.create_pay_to_contract_address(id, contents)
|
159
167
|
end
|
160
168
|
|
169
|
+
def pay_to_contract_key(payment_base, contents)
|
170
|
+
wallet_adapter.pay_to_contract_key(id, payment_base, contents)
|
171
|
+
end
|
172
|
+
|
161
173
|
def sign_to_pay_to_contract_address(tx, utxo, payment_base, contents)
|
162
174
|
wallet_adapter.sign_to_pay_to_contract_address(id, tx, utxo, payment_base, contents)
|
163
175
|
end
|
164
176
|
|
177
|
+
def has_address?(address)
|
178
|
+
wallet_adapter.has_address?(id, address)
|
179
|
+
end
|
180
|
+
|
165
181
|
private
|
166
182
|
|
167
183
|
def wallet_adapter
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Glueby
|
2
|
+
module Util
|
3
|
+
module Digest
|
4
|
+
# Hash content with specified digest algorithm
|
5
|
+
#
|
6
|
+
# @param content [String] content to be hashed
|
7
|
+
# @param digest [Symbol] The symbol represents algorithm used for hashing. :sha256, :double_sha256, :none are available
|
8
|
+
# @return [String] hex string hashed from content
|
9
|
+
def digest_content(content, digest)
|
10
|
+
case digest&.downcase
|
11
|
+
when :sha256
|
12
|
+
Tapyrus.sha256(content).bth
|
13
|
+
when :double_sha256
|
14
|
+
Tapyrus.double_sha256(content).bth
|
15
|
+
when :none
|
16
|
+
content
|
17
|
+
else
|
18
|
+
raise Glueby::Contract::Errors::UnsupportedDigestType
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -15,7 +15,7 @@ module Glueby
|
|
15
15
|
}
|
16
16
|
|
17
17
|
def initialize
|
18
|
-
@utxo_provider = Glueby::UtxoProvider.
|
18
|
+
@utxo_provider = Glueby::UtxoProvider.instance
|
19
19
|
end
|
20
20
|
|
21
21
|
# Create UTXOs for paying tpc
|
@@ -46,6 +46,8 @@ module Glueby
|
|
46
46
|
return if added_outputs == 0
|
47
47
|
|
48
48
|
fee = fee_estimator.fee(Contract::FeeEstimator.dummy_tx(txb.build))
|
49
|
+
fee += (sum - fee) if sum - fee < DUST_LIMIT
|
50
|
+
|
49
51
|
tx = txb.change_address(utxo_provider.address)
|
50
52
|
.fee(fee)
|
51
53
|
.build
|
data/lib/glueby/utxo_provider.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module Glueby
|
2
2
|
class UtxoProvider
|
3
3
|
include Glueby::Contract::TxBuilder
|
4
|
+
include Singleton
|
4
5
|
|
5
6
|
autoload :Tasks, 'glueby/utxo_provider/tasks'
|
6
7
|
|
@@ -63,6 +64,41 @@ module Glueby
|
|
63
64
|
[signed_tx, 0]
|
64
65
|
end
|
65
66
|
|
67
|
+
# Fill inputs in the tx up to target_amount of TPC from UTXO pool
|
68
|
+
# This method should be called before adding change output and script_sig in outputs.
|
69
|
+
# FeeEstimator.dummy_tx returns fee amount to the TX that will be added one TPC input, a change TPC output and
|
70
|
+
# script sigs in outputs.
|
71
|
+
# @param [Tapyrus::Tx] tx The tx that will be filled the inputs
|
72
|
+
# @param [Integer] target_amount The tapyrus amount the tx is expected to be added in this method
|
73
|
+
# @param [Integer] current_amount The tapyrus amount the tx already has in its inputs
|
74
|
+
# @param [Glueby::Contract::FeeEstimator] fee_estimator
|
75
|
+
# @return [Tapyrus::Tx] tx The tx that is added inputs
|
76
|
+
# @return [Integer] fee The final fee after the inputs are filled
|
77
|
+
# @return [Integer] current_amount The final amount of the tx inputs
|
78
|
+
# @return [Array<Hash>] provided_utxos The utxos that are added to the tx inputs
|
79
|
+
def fill_inputs(tx, target_amount: , current_amount: 0, fee_estimator: Contract::FeeEstimator::Fixed.new)
|
80
|
+
fee = fee_estimator.fee(Contract::FeeEstimator.dummy_tx(tx, dummy_input_count: 0))
|
81
|
+
provided_utxos = []
|
82
|
+
|
83
|
+
# If the change output value is less than DUST_LIMIT, tapyrus core returns "dust" error while broadcasting.
|
84
|
+
target_amount += DUST_LIMIT if target_amount < DUST_LIMIT
|
85
|
+
|
86
|
+
while current_amount - fee < target_amount
|
87
|
+
sum, utxos = collect_uncolored_outputs(wallet, fee + target_amount - current_amount, provided_utxos)
|
88
|
+
|
89
|
+
utxos.each do |utxo|
|
90
|
+
tx.inputs << Tapyrus::TxIn.new(out_point: Tapyrus::OutPoint.from_txid(utxo[:txid], utxo[:vout]))
|
91
|
+
provided_utxos << utxo
|
92
|
+
end
|
93
|
+
current_amount += sum
|
94
|
+
|
95
|
+
new_fee = fee_estimator.fee(Contract::FeeEstimator.dummy_tx(tx, dummy_input_count: 0))
|
96
|
+
fee = new_fee
|
97
|
+
end
|
98
|
+
|
99
|
+
[tx, fee, current_amount, provided_utxos]
|
100
|
+
end
|
101
|
+
|
66
102
|
def default_value
|
67
103
|
@default_value ||=
|
68
104
|
(
|
@@ -110,16 +146,27 @@ module Glueby
|
|
110
146
|
end
|
111
147
|
end
|
112
148
|
|
113
|
-
|
114
|
-
|
149
|
+
# Collects and returns TPC UTXOs.
|
150
|
+
# @param [Glueby::Internal::Wallet] wallet The wallet that funds the caller
|
151
|
+
# @param [Integer] amount The target amount which to be collected
|
152
|
+
# @param [Array<Hash>] excludes The exclusion UTXO list. It excludes this UTXOs from the targets that will be collected TPC UTXOs.
|
153
|
+
# @return [Integer] sum The sum amount of the funds
|
154
|
+
# @return [Array<Hash>] outputs The UTXO set of the funds
|
155
|
+
def collect_uncolored_outputs(wallet, amount, excludes = [])
|
156
|
+
utxos = wallet.list_unspent.select do |o|
|
157
|
+
!o[:color_id] &&
|
158
|
+
o[:amount] == default_value &&
|
159
|
+
!excludes.find { |i| i[:txid] == o[:txid] && i[:vout] == o[:vout] }
|
160
|
+
end
|
115
161
|
utxos.shuffle!
|
116
|
-
|
117
|
-
utxos.inject([0, []]) do |sum, output|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
162
|
+
|
163
|
+
utxos.inject([0, []]) do |(sum, outputs), output|
|
164
|
+
if wallet.lock_unspent(output)
|
165
|
+
sum += output[:amount]
|
166
|
+
outputs << output
|
167
|
+
return [sum, outputs] if sum >= amount
|
168
|
+
end
|
169
|
+
[sum, outputs]
|
123
170
|
end
|
124
171
|
raise Glueby::Contract::Errors::InsufficientFunds
|
125
172
|
end
|
data/lib/glueby/version.rb
CHANGED
@@ -25,5 +25,12 @@ namespace :glueby do
|
|
25
25
|
puts "success in synchronization (block height=#{height})"
|
26
26
|
end
|
27
27
|
end
|
28
|
+
|
29
|
+
desc 'Update the block height in Glueby::AR::SystemInformation and do not run Glueby::BlockSyncer. This task is intended to skip the synchronization process until the latest block height.'
|
30
|
+
task :update_height, [] => [:environment] do |_, _|
|
31
|
+
new_height = Glueby::Internal::RPC.client.getblockcount
|
32
|
+
synced_block = Glueby::AR::SystemInformation.synced_block_height
|
33
|
+
synced_block.update(info_value: new_height.to_s)
|
34
|
+
end
|
28
35
|
end
|
29
36
|
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: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- azuchi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-11-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: tapyrus
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.3.1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
26
|
+
version: 0.3.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activerecord
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: mysql2
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: rails
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -88,15 +102,16 @@ files:
|
|
88
102
|
- glueby.gemspec
|
89
103
|
- lib/generators/glueby/contract/block_syncer_generator.rb
|
90
104
|
- lib/generators/glueby/contract/initializer_generator.rb
|
91
|
-
- lib/generators/glueby/contract/reissuable_token_generator.rb
|
92
105
|
- lib/generators/glueby/contract/templates/initializer.rb.erb
|
93
106
|
- lib/generators/glueby/contract/templates/key_table.rb.erb
|
94
107
|
- lib/generators/glueby/contract/templates/reissuable_token_table.rb.erb
|
95
108
|
- lib/generators/glueby/contract/templates/system_information_table.rb.erb
|
96
109
|
- lib/generators/glueby/contract/templates/timestamp_table.rb.erb
|
110
|
+
- lib/generators/glueby/contract/templates/token_metadata_table.rb.erb
|
97
111
|
- lib/generators/glueby/contract/templates/utxo_table.rb.erb
|
98
112
|
- lib/generators/glueby/contract/templates/wallet_table.rb.erb
|
99
113
|
- lib/generators/glueby/contract/timestamp_generator.rb
|
114
|
+
- lib/generators/glueby/contract/token_generator.rb
|
100
115
|
- lib/generators/glueby/contract/wallet_adapter_generator.rb
|
101
116
|
- lib/glueby.rb
|
102
117
|
- lib/glueby/active_record.rb
|
@@ -108,6 +123,7 @@ files:
|
|
108
123
|
- lib/glueby/contract/active_record.rb
|
109
124
|
- lib/glueby/contract/active_record/reissuable_token.rb
|
110
125
|
- lib/glueby/contract/active_record/timestamp.rb
|
126
|
+
- lib/glueby/contract/active_record/token_metadata.rb
|
111
127
|
- lib/glueby/contract/errors.rb
|
112
128
|
- lib/glueby/contract/fee_estimator.rb
|
113
129
|
- lib/glueby/contract/fee_estimator/auto.rb
|
@@ -136,8 +152,10 @@ files:
|
|
136
152
|
- lib/glueby/internal/wallet/active_record_wallet_adapter.rb
|
137
153
|
- lib/glueby/internal/wallet/active_record_wallet_adapter/syncer.rb
|
138
154
|
- lib/glueby/internal/wallet/errors.rb
|
155
|
+
- lib/glueby/internal/wallet/mysql_wallet_adapter.rb
|
139
156
|
- lib/glueby/internal/wallet/tapyrus_core_wallet_adapter.rb
|
140
157
|
- lib/glueby/railtie.rb
|
158
|
+
- lib/glueby/util/digest.rb
|
141
159
|
- lib/glueby/utxo_provider.rb
|
142
160
|
- lib/glueby/utxo_provider/tasks.rb
|
143
161
|
- lib/glueby/version.rb
|