From f0b6b9567ae7d46581d789e73241a2e7522db1d1 Mon Sep 17 00:00:00 2001 From: k-matsuzawa Date: Sun, 7 May 2023 12:12:01 +0900 Subject: [PATCH] feat: add checking initialblockdownload option --- cmd/generateblock/argument.go | 26 +++++++++++-------- cmd/generateblock/environment.go | 19 +++++++------- cmd/generateblock/main.go | 2 ++ docker-compose.yml | 12 +++++++++ generateblock.go | 22 ++++++++++++---- internal/domain/model/blockchaininfo.go | 7 +++-- internal/domain/model/configuration.go | 13 +++++----- internal/domain/repository/blockchain.go | 2 +- internal/domain/service/generate_block.go | 23 +++++++++++----- internal/handler/handler.go | 15 ++++++----- .../infrastructure/repository/blockchain.go | 16 +++++++----- internal/usecase/generate_block.go | 21 ++++++++++++--- 12 files changed, 123 insertions(+), 55 deletions(-) diff --git a/cmd/generateblock/argument.go b/cmd/generateblock/argument.go index f82ce7a..65dff64 100644 --- a/cmd/generateblock/argument.go +++ b/cmd/generateblock/argument.go @@ -9,17 +9,18 @@ const ( ) type argument struct { - Host string `help:"connection host & port"` - FedpegScript string `arg:"-s" help:"fedpeg script on dynafed"` - Pak []string `arg:"-p,separate" help:"pak entries"` - Network string `arg:"-n" help:"network. (bitcoin:mainnet/testnet/regtest, liquid:liquidv1/liquidregtest/elementsregtest)"` - Address string `arg:"-a" help:"bitcoin address for generatetoaddress"` - RpcUserID string `help:"connection rpc userID"` - RpcPassword string `help:"connection rpc password"` - Logging bool `arg:"-l" help:"log output"` - PollingTime time.Duration `arg:"-t" help:"polling duration time"` - GenerateCount uint `arg:"-c" help:"generate count"` - IgnoreEmptyMempool bool `arg:"-m" help:"ignore empty mempool"` + Host string `help:"connection host & port"` + FedpegScript string `arg:"-s" help:"fedpeg script on dynafed"` + Pak []string `arg:"-p,separate" help:"pak entries"` + Network string `arg:"-n" help:"network. (bitcoin:mainnet/testnet/regtest, liquid:liquidv1/liquidregtest/elementsregtest)"` + Address string `arg:"-a" help:"bitcoin address for generatetoaddress"` + RpcUserID string `help:"connection rpc userID"` + RpcPassword string `help:"connection rpc password"` + Logging bool `arg:"-l" help:"log output"` + PollingTime time.Duration `arg:"-t" help:"polling duration time"` + GenerateCount uint `arg:"-c" help:"generate count"` + IgnoreEmptyMempool bool `arg:"-m" help:"ignore empty mempool"` + HasCheckInitialBlkDl bool `arg:"-i" help:"check initial block download flag"` } // Error returns the error string. @@ -55,6 +56,9 @@ func (a *argument) setValueFromEnvironment(env *environment) { if !a.IgnoreEmptyMempool { a.IgnoreEmptyMempool = env.IgnoreEmptyMempool } + if !a.HasCheckInitialBlkDl { + a.HasCheckInitialBlkDl = env.HasCheckInitialBlkDl + } } func (a *argument) Validate() error { diff --git a/cmd/generateblock/environment.go b/cmd/generateblock/environment.go index 39e1ba1..797b589 100644 --- a/cmd/generateblock/environment.go +++ b/cmd/generateblock/environment.go @@ -1,13 +1,14 @@ package main type environment struct { - Host string `env:"GENERATE_BLOCK_CONNECTION_HOST"` - FedpegScript string `env:"DYNAFED_FEDPEG_SCRIPT"` - PakEntries []string `env:"DYNAFED_PAK" envSeparator:","` - Network string `env:"GENERATE_BLOCK_CONNECTION_NETWORK"` - Address string `env:"GENERATE_BLOCK_GENERATETOADDRESS"` - RpcUserID string `env:"CONNECTION_PRC_USERID"` - RpcPassword string `env:"CONNECTION_PRC_PASSWORD"` - GenerateCount uint `env:"GENERATE_BLOCK_COUNT" envDefault:"1"` - IgnoreEmptyMempool bool `env:"IGNORE_EMPTY_MEMPOOL"` + Host string `env:"GENERATE_BLOCK_CONNECTION_HOST"` + FedpegScript string `env:"DYNAFED_FEDPEG_SCRIPT"` + PakEntries []string `env:"DYNAFED_PAK" envSeparator:","` + Network string `env:"GENERATE_BLOCK_CONNECTION_NETWORK"` + Address string `env:"GENERATE_BLOCK_GENERATETOADDRESS"` + RpcUserID string `env:"CONNECTION_PRC_USERID"` + RpcPassword string `env:"CONNECTION_PRC_PASSWORD"` + GenerateCount uint `env:"GENERATE_BLOCK_COUNT" envDefault:"1"` + IgnoreEmptyMempool bool `env:"IGNORE_EMPTY_MEMPOOL"` + HasCheckInitialBlkDl bool `env:"HAS_CHECK_INITIAL_BLK_DL"` } diff --git a/cmd/generateblock/main.go b/cmd/generateblock/main.go index 90455b7..f14ec77 100644 --- a/cmd/generateblock/main.go +++ b/cmd/generateblock/main.go @@ -84,6 +84,7 @@ func main() { argObj.Address, argObj.GenerateCount, argObj.IgnoreEmptyMempool, + argObj.HasCheckInitialBlkDl, ); err != nil { if err == pkgerror.ErrEmptyMempoolTx { logger.Debug("empty mempool tx. skip generate block.") @@ -119,6 +120,7 @@ func run(handle handler.Handler, network string, pollingTime time.Duration) erro argObj.Address, argObj.GenerateCount, argObj.IgnoreEmptyMempool, + argObj.HasCheckInitialBlkDl, ); err != nil { if err == pkgerror.ErrEmptyMempoolTx { logger.Debug("empty mempool tx. skip generate block.") diff --git a/docker-compose.yml b/docker-compose.yml index ea8d9bf..86a010d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -104,6 +104,18 @@ services: - testing_network command: ["generateblock", "-l", "-t", "10s"] + generateblock-elements-loop: + build: + context: . + dockerfile: ./docker/debian11.dockerfile + volumes: + - .:/workspace + working_dir: /workspace/ + environment: *elements-node-env + networks: + - testing_network + command: ["generateblock", "-l", "-t", "10s"] + exec-test: image: ghcr.io/cryptogarageinc/elements-testing:v0.2.5 volumes: diff --git a/generateblock.go b/generateblock.go index 5ae56f6..7d2fbd3 100644 --- a/generateblock.go +++ b/generateblock.go @@ -19,7 +19,8 @@ type Generator struct { handle handler.Handler network string - ignoreEmptyMempool bool + ignoreEmptyMempool bool + hasCheckInitialBlkDl bool } func NewGenerator( @@ -37,12 +38,19 @@ func (g *Generator) WithIgnoreEmptyMempool(ignoreEmptyMempool bool) *Generator { return g } +func (g *Generator) WithCheckInitialBlockDownload(hasCheckInitialBlkDl bool) *Generator { + g.hasCheckInitialBlkDl = hasCheckInitialBlkDl + return g +} + func (g *Generator) GenerateBlock( ctx context.Context, address string, generateCount uint, ) error { - return g.handle.GenerateBlock(ctx, g.network, "", []string{}, address, generateCount, g.ignoreEmptyMempool) + return g.handle.GenerateBlock( + ctx, g.network, "", []string{}, address, generateCount, + g.ignoreEmptyMempool, g.hasCheckInitialBlkDl) } func (g *Generator) GenerateElementsDynafedBlock( @@ -51,7 +59,9 @@ func (g *Generator) GenerateElementsDynafedBlock( pakEntries []string, generateCount uint, ) error { - return g.handle.GenerateBlock(ctx, g.network, fedpegScript, pakEntries, "", generateCount, g.ignoreEmptyMempool) + return g.handle.GenerateBlock( + ctx, g.network, fedpegScript, pakEntries, "", generateCount, + g.ignoreEmptyMempool, g.hasCheckInitialBlkDl) } func GenerateBlock( @@ -62,7 +72,8 @@ func GenerateBlock( generateCount uint, ) error { handle := newHandler(nodeInfo.Host, nodeInfo.RpcUserID, nodeInfo.RpcPassword) - return handle.GenerateBlock(ctx, network, "", []string{}, address, generateCount, false) + return handle.GenerateBlock(ctx, network, "", []string{}, address, + generateCount, false, false) } func GenerateElementsDynafedBlock( @@ -74,7 +85,8 @@ func GenerateElementsDynafedBlock( generateCount uint, ) error { handle := newHandler(nodeInfo.Host, nodeInfo.RpcUserID, nodeInfo.RpcPassword) - return handle.GenerateBlock(ctx, network, fedpegScript, pakEntries, "", generateCount, false) + return handle.GenerateBlock(ctx, network, fedpegScript, pakEntries, "", + generateCount, false, false) } func newHandler( diff --git a/internal/domain/model/blockchaininfo.go b/internal/domain/model/blockchaininfo.go index eeea925..a1826f8 100644 --- a/internal/domain/model/blockchaininfo.go +++ b/internal/domain/model/blockchaininfo.go @@ -1,8 +1,11 @@ package model type BlockChainInfo struct { - Blocks uint64 - BestBlockHash string + Blocks uint64 + BestBlockHash string + IsInitialBlockDownload bool + + // elements only parameters CurrentFedpegScript string ExtensionSpace []string } diff --git a/internal/domain/model/configuration.go b/internal/domain/model/configuration.go index 6430403..211a3e7 100644 --- a/internal/domain/model/configuration.go +++ b/internal/domain/model/configuration.go @@ -51,12 +51,13 @@ func ValidateNetworkType(network string) error { } type Configuration struct { - Network NetworkType - FedpegScript string - PakEntries []string - Address string - GenerateCount uint - IgnoreEmptyMempool bool + Network NetworkType + FedpegScript string + PakEntries []string + Address string + GenerateCount uint + IgnoreEmptyMempool bool + HasCheckInitialBlkDl bool // check the initialblockdownload } func (c *Configuration) GetGenerateCount() uint { diff --git a/internal/domain/repository/blockchain.go b/internal/domain/repository/blockchain.go index b272c7b..8057ee9 100644 --- a/internal/domain/repository/blockchain.go +++ b/internal/domain/repository/blockchain.go @@ -25,7 +25,7 @@ type Blockchain interface { address string, ) (blockHashes []string, err error) GetMempoolTXIDs(ctx context.Context) ([]string, error) - GetBlockChainInfoWithElements( + GetBlockChainInfo( ctx context.Context, ) (*model.BlockChainInfo, error) } diff --git a/internal/domain/service/generate_block.go b/internal/domain/service/generate_block.go index 508d9ed..55172c3 100644 --- a/internal/domain/service/generate_block.go +++ b/internal/domain/service/generate_block.go @@ -14,11 +14,12 @@ type GenerateBlock interface { ) error GenerateToAddress(ctx context.Context, address string) error ExistMempool(ctx context.Context) (bool, error) + IsInitialBlockDownload(ctx context.Context) (bool, error) CompareDynafed( ctx context.Context, fedpegScript string, pakEntries []string, - ) (bool, error) + ) (bool, bool, error) } const ( @@ -63,19 +64,29 @@ func (g *generateBlock) ExistMempool( return len(txIDs) > 0, nil } +func (g *generateBlock) IsInitialBlockDownload( + ctx context.Context, +) (bool, error) { + bi, err := g.blockchainRepo.GetBlockChainInfo(ctx) + if err != nil { + return false, err + } + return bi.IsInitialBlockDownload, nil +} + func (g *generateBlock) CompareDynafed( ctx context.Context, fedpegScript string, pakEntries []string, -) (bool, error) { - bi, err := g.blockchainRepo.GetBlockChainInfoWithElements(ctx) +) (bool, bool, error) { + bi, err := g.blockchainRepo.GetBlockChainInfo(ctx) if err != nil { - return false, err + return false, false, err } if bi.CurrentFedpegScript != fedpegScript || !g.compareSlice(bi.ExtensionSpace, pakEntries) { - return false, nil + return false, bi.IsInitialBlockDownload, nil } - return true, nil + return true, bi.IsInitialBlockDownload, nil } func (g *generateBlock) compareSlice(src []string, dst []string) bool { diff --git a/internal/handler/handler.go b/internal/handler/handler.go index 2d8bdf0..212860c 100644 --- a/internal/handler/handler.go +++ b/internal/handler/handler.go @@ -17,6 +17,7 @@ type Handler interface { address string, generateCount uint, ignoreEmptyMempool bool, + hasCheckInitialBlkDl bool, ) error } @@ -32,6 +33,7 @@ func (h *handler) GenerateBlock( address string, generateCount uint, ignoreEmptyMempool bool, + hasCheckInitialBlkDl bool, ) error { if networkType == "" { return errors.New("networkType is empty") @@ -40,12 +42,13 @@ func (h *handler) GenerateBlock( return err } return h.usecase.GenerateBlock(ctx, &model.Configuration{ - Network: model.NewNetworkType(networkType), - FedpegScript: fedpegScript, - PakEntries: pak, - Address: address, - GenerateCount: generateCount, - IgnoreEmptyMempool: ignoreEmptyMempool, + Network: model.NewNetworkType(networkType), + FedpegScript: fedpegScript, + PakEntries: pak, + Address: address, + GenerateCount: generateCount, + IgnoreEmptyMempool: ignoreEmptyMempool, + HasCheckInitialBlkDl: hasCheckInitialBlkDl, }) } diff --git a/internal/infrastructure/repository/blockchain.go b/internal/infrastructure/repository/blockchain.go index 78d8cce..6c81b93 100644 --- a/internal/infrastructure/repository/blockchain.go +++ b/internal/infrastructure/repository/blockchain.go @@ -86,7 +86,7 @@ func (b *blockchainRpc) GetMempoolTXIDs(ctx context.Context) ([]string, error) { return txIDs, nil } -func (b *blockchainRpc) GetBlockChainInfoWithElements(ctx context.Context) (*model.BlockChainInfo, error) { +func (b *blockchainRpc) GetBlockChainInfo(ctx context.Context) (*model.BlockChainInfo, error) { result, _, err := b.post(ctx, "getblockchaininfo") if err != nil { return nil, err @@ -95,11 +95,15 @@ func (b *blockchainRpc) GetBlockChainInfoWithElements(ctx context.Context) (*mod rawBlockchainInfo := result.(map[string]interface{}) blockchainInfo.Blocks = uint64(rawBlockchainInfo["blocks"].(float64)) blockchainInfo.BestBlockHash = rawBlockchainInfo["bestblockhash"].(string) - blockchainInfo.CurrentFedpegScript = rawBlockchainInfo["current_fedpeg_script"].(string) - extensionSpace := rawBlockchainInfo["extension_space"].([]interface{}) - blockchainInfo.ExtensionSpace = make([]string, len(extensionSpace)) - for i := range extensionSpace { - blockchainInfo.ExtensionSpace[i] = extensionSpace[i].(string) + blockchainInfo.IsInitialBlockDownload = rawBlockchainInfo["initialblockdownload"].(bool) + + if rawBlockchainInfo["current_fedpeg_script"] != nil { + blockchainInfo.CurrentFedpegScript = rawBlockchainInfo["current_fedpeg_script"].(string) + extensionSpace := rawBlockchainInfo["extension_space"].([]interface{}) + blockchainInfo.ExtensionSpace = make([]string, len(extensionSpace)) + for i := range extensionSpace { + blockchainInfo.ExtensionSpace[i] = extensionSpace[i].(string) + } } return blockchainInfo, nil } diff --git a/internal/usecase/generate_block.go b/internal/usecase/generate_block.go index e8bb62f..30b6603 100644 --- a/internal/usecase/generate_block.go +++ b/internal/usecase/generate_block.go @@ -30,14 +30,29 @@ func (g *generateBlock) GenerateBlock( case err != nil: return err case !exist && !config.CanDynafed(): - return pkgerror.ErrEmptyMempoolTx + if config.HasCheckInitialBlkDl { + isInitialBlkDl, err := g.generateBlockService.IsInitialBlockDownload(ctx) + if err != nil { + return err + } else if isInitialBlkDl { + // need to generate block + } else { + return pkgerror.ErrEmptyMempoolTx + } + } else { + return pkgerror.ErrEmptyMempoolTx + } case !exist && config.CanDynafed(): - compare, err := g.generateBlockService.CompareDynafed( + compare, isInitialBlkDl, err := g.generateBlockService.CompareDynafed( ctx, config.FedpegScript, config.PakEntries) if err != nil { return err } else if compare { - return pkgerror.ErrEmptyMempoolTx + if config.HasCheckInitialBlkDl && isInitialBlkDl { + // need to generate block + } else { + return pkgerror.ErrEmptyMempoolTx + } } // need to generate block. }