glueby 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: feaf2f20c90016badb4f10ca4028c87567f204cdfcdf2dee7d68a7dddbe1af8a
|
4
|
+
data.tar.gz: a7a68472e21a22901b9a1a1d42b12d77c5e12a86cb6086f1fd7d0dd9dafde7b2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9bc1d2d57bbb1e928b30ffefb0d3ae383c9832d0293b5987b74c3ee8cae17466ada78bc0dc60096ee76212e455e12badaee1be80741ffe4f59c79191d1bed67b
|
7
|
+
data.tar.gz: 89d17b7f01272bd5bfabe47cba0a8b776ad6ff1932de3eecdd61372da2ab89cbe3eb0410661d22aaa1743be0a58b023f97ab64503653e9cac11d56fb71c6b93f
|
data/.github/workflows/ruby.yml
CHANGED
@@ -18,16 +18,15 @@ jobs:
|
|
18
18
|
runs-on: ubuntu-latest
|
19
19
|
strategy:
|
20
20
|
matrix:
|
21
|
-
ruby-version: ["2.6", "2.7", "3.0"]
|
21
|
+
ruby-version: ["2.6", "2.7", "3.0", "3.1"]
|
22
22
|
|
23
23
|
steps:
|
24
|
-
- run: docker pull tapyrus/tapyrusd:
|
24
|
+
- run: docker pull tapyrus/tapyrusd:v0.5.1
|
25
25
|
- uses: actions/checkout@v2
|
26
26
|
- name: Set up Ruby
|
27
27
|
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
28
28
|
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
29
|
-
|
30
|
-
uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
|
29
|
+
uses: ruby/setup-ruby@v1
|
31
30
|
with:
|
32
31
|
ruby-version: ${{ matrix.ruby-version }}
|
33
32
|
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
data/README.md
CHANGED
@@ -72,7 +72,7 @@ Or install it yourself as:
|
|
72
72
|
|
73
73
|
Starts tapryusd container
|
74
74
|
|
75
|
-
$ docker run -d --name 'tapyrus_node_dev' -p 12381:12381 -e GENESIS_BLOCK_WITH_SIG='0100000000000000000000000000000000000000000000000000000000000000000000002b5331139c6bc8646bb4e5737c51378133f70b9712b75548cb3c05f9188670e7440d295e7300c5640730c4634402a3e66fb5d921f76b48d8972a484cc0361e66ef74f45e012103af80b90d25145da28c583359beb47b21796b2fe1a23c1511e443e7a64dfdb27d40e05f064662d6b9acf65ae416379d82e11a9b78cdeb3a316d1057cd2780e3727f70a61f901d10acbe349cd11e04aa6b4351e782c44670aefbe138e99a5ce75ace01010000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100f2052a010000001976a91445d405b9ed450fec89044f9b7a99a4ef6fe2cd3f88ac00000000' tapyrus/tapyrusd:
|
75
|
+
$ docker run -d --name 'tapyrus_node_dev' -p 12381:12381 -e GENESIS_BLOCK_WITH_SIG='0100000000000000000000000000000000000000000000000000000000000000000000002b5331139c6bc8646bb4e5737c51378133f70b9712b75548cb3c05f9188670e7440d295e7300c5640730c4634402a3e66fb5d921f76b48d8972a484cc0361e66ef74f45e012103af80b90d25145da28c583359beb47b21796b2fe1a23c1511e443e7a64dfdb27d40e05f064662d6b9acf65ae416379d82e11a9b78cdeb3a316d1057cd2780e3727f70a61f901d10acbe349cd11e04aa6b4351e782c44670aefbe138e99a5ce75ace01010000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100f2052a010000001976a91445d405b9ed450fec89044f9b7a99a4ef6fe2cd3f88ac00000000' tapyrus/tapyrusd:v0.5.1
|
76
76
|
|
77
77
|
4. Modify the glueby configuration
|
78
78
|
|
@@ -93,9 +93,9 @@ Or install it yourself as:
|
|
93
93
|
$ rails g glueby:contract:block_syncer
|
94
94
|
$ rails g glueby:contract:wallet_adapter
|
95
95
|
|
96
|
-
If you want to use
|
96
|
+
If you want to use token or timestamp, you need to do below generators.
|
97
97
|
|
98
|
-
$ rails g glueby:contract:
|
98
|
+
$ rails g glueby:contract:token
|
99
99
|
$ rails g glueby:contract:timestamp
|
100
100
|
|
101
101
|
Then, run the migrations.
|
data/glueby.gemspec
CHANGED
@@ -26,8 +26,9 @@ 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.
|
29
|
+
spec.add_runtime_dependency 'tapyrus', '>= 0.3.1'
|
30
30
|
spec.add_runtime_dependency 'activerecord', '~> 6.1.3'
|
31
31
|
spec.add_development_dependency 'sqlite3'
|
32
|
+
spec.add_development_dependency 'mysql2'
|
32
33
|
spec.add_development_dependency 'rails', '~> 6.1.3'
|
33
34
|
end
|
@@ -1,8 +1,8 @@
|
|
1
|
-
# Edit configuration for connection to tapyrus core
|
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
|
6
|
-
|
7
|
-
# Uncomment next line when using timestamp feature
|
8
|
-
# Glueby::BlockSyncer.register_syncer(Glueby::Contract::Timestamp::Syncer)
|
1
|
+
# Edit configuration for connection to tapyrus core
|
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
|
6
|
+
|
7
|
+
# Uncomment next line when using timestamp feature
|
8
|
+
# Glueby::BlockSyncer.register_syncer(Glueby::Contract::Timestamp::Syncer)
|
@@ -1,16 +1,16 @@
|
|
1
|
-
class CreateKey < ActiveRecord::Migration<%= migration_version %>
|
2
|
-
def change
|
3
|
-
create_table :glueby_keys<%= table_options %> do |t|
|
4
|
-
t.string :private_key
|
5
|
-
t.string :public_key
|
6
|
-
t.string :script_pubkey
|
7
|
-
t.string :label, index: true
|
8
|
-
t.integer :purpose
|
9
|
-
t.belongs_to :wallet
|
10
|
-
t.timestamps
|
11
|
-
end
|
12
|
-
|
13
|
-
add_index :glueby_keys, [:script_pubkey], unique: true
|
14
|
-
add_index :glueby_keys, [:private_key], unique: true
|
15
|
-
end
|
16
|
-
end
|
1
|
+
class CreateKey < ActiveRecord::Migration<%= migration_version %>
|
2
|
+
def change
|
3
|
+
create_table :glueby_keys<%= table_options %> do |t|
|
4
|
+
t.string :private_key
|
5
|
+
t.string :public_key
|
6
|
+
t.string :script_pubkey
|
7
|
+
t.string :label, index: true
|
8
|
+
t.integer :purpose
|
9
|
+
t.belongs_to :wallet
|
10
|
+
t.timestamps
|
11
|
+
end
|
12
|
+
|
13
|
+
add_index :glueby_keys, [:script_pubkey], unique: true
|
14
|
+
add_index :glueby_keys, [:private_key], unique: true
|
15
|
+
end
|
16
|
+
end
|
@@ -7,6 +7,8 @@ class CreateTimestamp < ActiveRecord::Migration<%= migration_version %>
|
|
7
7
|
t.string :prefix
|
8
8
|
t.string :wallet_id
|
9
9
|
t.integer :timestamp_type, null: false, default: 0
|
10
|
+
t.integer :block_height, index: true
|
11
|
+
t.integer :block_time, index: true
|
10
12
|
t.string :p2c_address
|
11
13
|
t.string :payment_base
|
12
14
|
t.bigint :prev_id
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class CreateTokenMetadata < ActiveRecord::Migration<%= migration_version %>
|
2
|
+
def change
|
3
|
+
create_table :glueby_token_metadata<%= table_options %> do |t|
|
4
|
+
t.text :metadata, null: false
|
5
|
+
t.string :color_id, null: false
|
6
|
+
t.string :p2c_address, null: false
|
7
|
+
t.string :payment_base, null: false
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
|
11
|
+
add_index :glueby_token_metadata, [:color_id], unique: true
|
12
|
+
end
|
13
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Glueby
|
2
2
|
module Contract
|
3
|
-
class
|
3
|
+
class TokenGenerator < Rails::Generators::Base
|
4
4
|
include ::Rails::Generators::Migration
|
5
5
|
include Glueby::Generator::MigrateGenerator
|
6
6
|
extend Glueby::Generator::MigrateGenerator::ClassMethod
|
@@ -10,6 +10,17 @@ module Glueby
|
|
10
10
|
def create_migration_file
|
11
11
|
migration_dir = File.expand_path("db/migrate")
|
12
12
|
|
13
|
+
if self.class.migration_exists?(migration_dir, "create_token_metadata")
|
14
|
+
::Kernel.warn "Migration already exists: create_token_metadata"
|
15
|
+
else
|
16
|
+
migration_template(
|
17
|
+
"token_metadata_table.rb.erb",
|
18
|
+
"db/migrate/create_token_metadata.rb",
|
19
|
+
migration_version: migration_version,
|
20
|
+
table_options: table_options,
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
13
24
|
if self.class.migration_exists?(migration_dir, "create_reissuable_token")
|
14
25
|
::Kernel.warn "Migration already exists: create_reissuable_token"
|
15
26
|
else
|
data/lib/glueby/block_syncer.rb
CHANGED
@@ -1,98 +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
|
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
98
|
end
|
data/lib/glueby/configuration.rb
CHANGED
@@ -31,6 +31,8 @@ module Glueby
|
|
31
31
|
Glueby::Internal::Wallet.wallet_adapter = Glueby::Internal::Wallet::TapyrusCoreWalletAdapter.new
|
32
32
|
when :activerecord
|
33
33
|
Glueby::Internal::Wallet.wallet_adapter = Glueby::Internal::Wallet::ActiveRecordWalletAdapter.new
|
34
|
+
when :mysql
|
35
|
+
Glueby::Internal::Wallet.wallet_adapter = Glueby::Internal::Wallet::MySQLWalletAdapter.new
|
34
36
|
else
|
35
37
|
raise 'Not implemented'
|
36
38
|
end
|
@@ -94,7 +94,7 @@ module Glueby
|
|
94
94
|
# @raise [Glueby::Contract::Errors::PrevTimestampAlreadyUpdated] If the previous timestamp was already updated
|
95
95
|
def save_with_broadcast!(fee_estimator: Glueby::Contract::FeeEstimator::Fixed.new, utxo_provider: nil)
|
96
96
|
validate_prev!
|
97
|
-
utxo_provider = Glueby::UtxoProvider.
|
97
|
+
utxo_provider = Glueby::UtxoProvider.instance if !utxo_provider && Glueby.configuration.use_utxo_provider?
|
98
98
|
|
99
99
|
funding_tx, tx, p2c_address, payment_base = create_txs(fee_estimator, utxo_provider)
|
100
100
|
|
@@ -121,6 +121,7 @@ module Glueby
|
|
121
121
|
rescue Tapyrus::RPC::Error,
|
122
122
|
Internal::Wallet::Errors::WalletAlreadyLoaded,
|
123
123
|
Internal::Wallet::Errors::WalletNotFound,
|
124
|
+
Glueby::Internal::Wallet::Errors::InvalidSigner,
|
124
125
|
Errors::InsufficientFunds => e
|
125
126
|
errors.add(:base, "failed to broadcast (id=#{id}, reason=#{e.message})")
|
126
127
|
raise Errors::FailedToBroadcast, "failed to broadcast (id=#{id}, reason=#{e.message})"
|
@@ -175,7 +176,7 @@ module Glueby
|
|
175
176
|
def validate_prev
|
176
177
|
validate_prev!
|
177
178
|
true
|
178
|
-
rescue Errors::ArgumentError
|
179
|
+
rescue Errors::ArgumentError, Glueby::Internal::Wallet::Errors::InvalidSigner
|
179
180
|
false
|
180
181
|
end
|
181
182
|
|
@@ -205,6 +206,12 @@ module Glueby
|
|
205
206
|
errors.add(:prev_id, message)
|
206
207
|
raise Errors::PrevTimestampAlreadyUpdated, message
|
207
208
|
end
|
209
|
+
|
210
|
+
if prev.wallet_id != wallet_id
|
211
|
+
message = "The previous timestamp(id: #{prev_id}) was created by the different user"
|
212
|
+
errors.add(:prev_id, message)
|
213
|
+
raise Glueby::Internal::Wallet::Errors::InvalidSigner, message
|
214
|
+
end
|
208
215
|
end
|
209
216
|
end
|
210
217
|
end
|
@@ -4,6 +4,7 @@ module Glueby
|
|
4
4
|
module Contract
|
5
5
|
module AR
|
6
6
|
autoload :ReissuableToken, 'glueby/contract/active_record/reissuable_token'
|
7
|
+
autoload :TokenMetadata, 'glueby/contract/active_record/token_metadata'
|
7
8
|
autoload :Timestamp, 'glueby/contract/active_record/timestamp'
|
8
9
|
end
|
9
10
|
end
|
@@ -26,7 +26,15 @@ module Glueby
|
|
26
26
|
private
|
27
27
|
|
28
28
|
def estimate_fee(tx)
|
29
|
-
((tx.
|
29
|
+
fee = ((tx.size / 1000.0) * fee_rate).ceil
|
30
|
+
|
31
|
+
# TODO: Eliminate the below block after https://github.com/chaintope/tapyrus-core/issues/191 will be done.
|
32
|
+
if tx.outputs.find(&:colored?)
|
33
|
+
# Tapyrus Core requires more over 1 from the just amount fee if the tx has colored outputs
|
34
|
+
fee + 1
|
35
|
+
else
|
36
|
+
fee
|
37
|
+
end
|
30
38
|
end
|
31
39
|
end
|
32
40
|
end
|
@@ -11,17 +11,24 @@ module Glueby
|
|
11
11
|
estimate_fee(tx)
|
12
12
|
end
|
13
13
|
|
14
|
-
# Add dummy inputs and outputs to tx
|
15
|
-
|
14
|
+
# Add dummy inputs and outputs to tx.
|
15
|
+
# Fee Estimation needs the actual tx size when it will be broadcasted to the blockchain network.
|
16
|
+
#
|
17
|
+
# @param [Tapyrus::Tx] tx The tx that is the target to be estimated fees
|
18
|
+
# @param [Integer] dummy_input_count The number of dummy inputs to be added before the estimation.
|
19
|
+
# @return [Tapyrus::Tx]
|
20
|
+
def dummy_tx(tx, dummy_input_count: 1)
|
16
21
|
dummy = Tapyrus::Tx.parse_from_payload(tx.to_payload)
|
17
22
|
|
18
23
|
# dummy input for tpc
|
19
|
-
|
20
|
-
|
24
|
+
dummy_input_count.times do
|
25
|
+
out_point = Tapyrus::OutPoint.new('00' * 32, 0)
|
26
|
+
dummy.inputs << Tapyrus::TxIn.new(out_point: out_point)
|
27
|
+
end
|
21
28
|
|
22
29
|
# Add script_sig to all intpus
|
23
30
|
dummy.inputs.each do |input|
|
24
|
-
input.script_sig = Tapyrus::Script.parse_from_payload('
|
31
|
+
input.script_sig = Tapyrus::Script.parse_from_payload(('00' * 100).htb)
|
25
32
|
end
|
26
33
|
|
27
34
|
# dummy output to return change
|
@@ -5,7 +5,7 @@ module Glueby
|
|
5
5
|
def block_sync(block)
|
6
6
|
Glueby::Contract::AR::Timestamp
|
7
7
|
.where(txid: block.transactions.map(&:txid), status: :unconfirmed)
|
8
|
-
.update_all(status: :confirmed)
|
8
|
+
.update_all(status: :confirmed, block_height: block.height, block_time: block.header.time)
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|