From 8ef0ef0a4f5437e8f4e5c1d8cb0b7109e3556517 Mon Sep 17 00:00:00 2001 From: Krzysztof Tomecki <152964795+chris-4chain@users.noreply.github.com> Date: Wed, 10 Jan 2024 14:33:59 +0100 Subject: [PATCH 1/8] fix(BUX-461): use_fee_quotes for both arc and mApi --- config.example.yaml | 1 + config/config.go | 11 +++-------- config/defaults.go | 4 +--- config/services.go | 7 ++++--- 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/config.example.yaml b/config.example.yaml index 9b5b5a6b3..ea788db68 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -79,6 +79,7 @@ _nodes: apis: - arc_url: https://arc.gorillapool.io token: + use_fee_quotes: true # Prefixed with "_", because it's unused by default _notifications: enabled: false diff --git a/config/config.go b/config/config.go index 47346fd92..7c8923714 100644 --- a/config/config.go +++ b/config/config.go @@ -148,9 +148,9 @@ type NewRelicConfig struct { // NodesConfig consists of blockchain nodes (such as Minercraft and Arc) configuration type NodesConfig struct { - Protocol NodesProtocol `json:"protocol" mapstructure:"protocol"` - Apis []*MinerAPI `json:"apis" mapstructure:"apis"` - Mapi *MapiConfig `json:"mapi" mapstructure:"mapi"` + Protocol NodesProtocol `json:"protocol" mapstructure:"protocol"` + Apis []*MinerAPI `json:"apis" mapstructure:"apis"` + UseFeeQuotes bool `json:"use_fee_quotes" mapstructure:"use_fee_quotes"` } // MinerAPI holds connection info for a single miner endpoint @@ -163,11 +163,6 @@ type MinerAPI struct { MinerID string `json:"minerid" mapstructure:"minerid"` } -// MapiConfig holds mApi-specific configuration -type MapiConfig struct { - UseFeeQuotes bool `json:"use_fee_quotes" mapstructure:"use_fee_quotes"` -} - // NotificationsConfig is the configuration for notifications type NotificationsConfig struct { // Enabled is the flag that enables notifications service. diff --git a/config/defaults.go b/config/defaults.go index d4a99d123..2f97cb927 100644 --- a/config/defaults.go +++ b/config/defaults.go @@ -124,9 +124,7 @@ func getNodesDefaults() *NodesConfig { MinerID: "03ad780153c47df915b3d2e23af727c68facaca4facd5f155bf5018b979b9aeb83", }, }, - Mapi: &MapiConfig{ - UseFeeQuotes: true, - }, + UseFeeQuotes: true, } } diff --git a/config/services.go b/config/services.go index 860c8c2a2..32674818b 100644 --- a/config/services.go +++ b/config/services.go @@ -191,6 +191,10 @@ func (s *AppServices) loadBux(ctx context.Context, appConfig *AppConfig, testMod options = loadBroadcastClientArc(appConfig, options, logger) } + if appConfig.Nodes.UseFeeQuotes { + options = append(options, bux.WithFeeQuotes()) + } + // Create the new client s.Bux, err = bux.NewClient(ctx, options...) @@ -388,8 +392,5 @@ func loadMinercraftMapi(appConfig *AppConfig, options []bux.ClientOps) []bux.Cli bux.WithMAPI(), bux.WithMinercraftAPIs(appConfig.Nodes.toMinercraftMapi()), ) - if appConfig.Nodes.Mapi != nil && appConfig.Nodes.Mapi.UseFeeQuotes { - options = append(options, bux.WithMinercraftFeeQuotes()) - } return options } From 1a865c9e794b487700b538a2be710548eea9a32c Mon Sep 17 00:00:00 2001 From: Krzysztof Tomecki <152964795+chris-4chain@users.noreply.github.com> Date: Thu, 11 Jan 2024 09:10:04 +0100 Subject: [PATCH 2/8] fix(BUX-461): configurable fee_unit --- config.example.yaml | 3 +++ config/config.go | 13 ++++++++++--- config/services.go | 9 +++++++-- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/config.example.yaml b/config.example.yaml index ea788db68..3f561b444 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -80,6 +80,9 @@ _nodes: - arc_url: https://arc.gorillapool.io token: use_fee_quotes: true + fee_unit: + satoshis: 1 + bytes: 20 # Prefixed with "_", because it's unused by default _notifications: enabled: false diff --git a/config/config.go b/config/config.go index 7c8923714..954761df8 100644 --- a/config/config.go +++ b/config/config.go @@ -148,9 +148,16 @@ type NewRelicConfig struct { // NodesConfig consists of blockchain nodes (such as Minercraft and Arc) configuration type NodesConfig struct { - Protocol NodesProtocol `json:"protocol" mapstructure:"protocol"` - Apis []*MinerAPI `json:"apis" mapstructure:"apis"` - UseFeeQuotes bool `json:"use_fee_quotes" mapstructure:"use_fee_quotes"` + Protocol NodesProtocol `json:"protocol" mapstructure:"protocol"` + Apis []*MinerAPI `json:"apis" mapstructure:"apis"` + UseFeeQuotes bool `json:"use_fee_quotes" mapstructure:"use_fee_quotes"` + FeeUnit *FeeUnitConfig `json:"fee_unit" mapstructure:"fee_unit"` +} + +// FeeUnitConfig reflects the utils.FeeUnit struct with proper annotations for json and mapstructure +type FeeUnitConfig struct { + Satoshis int `json:"satoshis" mapstructure:"satoshis"` + Bytes int `json:"bytes" mapstructure:"bytes"` } // MinerAPI holds connection info for a single miner endpoint diff --git a/config/services.go b/config/services.go index 32674818b..bacc8260b 100644 --- a/config/services.go +++ b/config/services.go @@ -191,8 +191,13 @@ func (s *AppServices) loadBux(ctx context.Context, appConfig *AppConfig, testMod options = loadBroadcastClientArc(appConfig, options, logger) } - if appConfig.Nodes.UseFeeQuotes { - options = append(options, bux.WithFeeQuotes()) + options = append(options, bux.WithFeeQuotes(appConfig.Nodes.UseFeeQuotes)) + + if appConfig.Nodes.FeeUnit != nil { + options = append(options, bux.WithFeeUnit(&utils.FeeUnit{ + Satoshis: appConfig.Nodes.FeeUnit.Satoshis, + Bytes: appConfig.Nodes.FeeUnit.Bytes, + })) } // Create the new client From 43373f6d8491239ea7d1d7bc9ab79a6228e5a53b Mon Sep 17 00:00:00 2001 From: Krzysztof Tomecki <152964795+chris-4chain@users.noreply.github.com> Date: Thu, 11 Jan 2024 13:45:10 +0100 Subject: [PATCH 3/8] fix(BUX-461): validate miners --- config/validate.go | 4 ++++ config/validate_nodes.go | 34 ++++++++++++++++++++++++++++++---- config/validate_nodes_test.go | 23 +++++++++++++++++++++++ 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/config/validate.go b/config/validate.go index 3a91deb1b..cb4af6231 100644 --- a/config/validate.go +++ b/config/validate.go @@ -28,5 +28,9 @@ func (a *AppConfig) Validate() error { return err } + if err = a.Nodes.Validate(); err != nil { + return err + } + return nil } diff --git a/config/validate_nodes.go b/config/validate_nodes.go index 3884f9ad3..efcd33b50 100644 --- a/config/validate_nodes.go +++ b/config/validate_nodes.go @@ -22,18 +22,36 @@ func (n *NodesConfig) Validate() error { // check if at least one mapi url is configured if n.Protocol == NodesProtocolMapi { - found := slices.IndexFunc(n.Apis, func(el *MinerAPI) bool { - return el.MapiURL != "" + anyMapiNode := slices.IndexFunc(n.Apis, func(el *MinerAPI) bool { + return isMapiNode(el) }) - if found == -1 { + if anyMapiNode == -1 { return errors.New("no mapi urls configured") } + + wrongMapiNode := slices.IndexFunc(n.Apis, func(el *MinerAPI) bool { + return isMapiNode(el) && el.MinerID == "" + }) + if wrongMapiNode != -1 { + return errors.New("mapi url configured without miner id") + } + + // check if MinerIDs for mAPI nodes are unique + ids := make(map[string]bool) + for _, el := range n.Apis { + if isMapiNode(el) { + if _, ok := ids[el.MinerID]; ok { + return errors.New("miner ids are not unique") + } + ids[el.MinerID] = true + } + } } // check if at least one arc url is configured if n.Protocol == NodesProtocolArc { found := slices.IndexFunc(n.Apis, func(el *MinerAPI) bool { - return el.ArcURL != "" + return isArcNode(el) }) if found == -1 { return errors.New("no arc urls configured") @@ -42,3 +60,11 @@ func (n *NodesConfig) Validate() error { return nil } + +func isMapiNode(node *MinerAPI) bool { + return node.MapiURL != "" +} + +func isArcNode(node *MinerAPI) bool { + return node.ArcURL != "" +} diff --git a/config/validate_nodes_test.go b/config/validate_nodes_test.go index 151777e98..ae2e37066 100644 --- a/config/validate_nodes_test.go +++ b/config/validate_nodes_test.go @@ -57,4 +57,27 @@ func TestNodesConfig_Validate(t *testing.T) { n.Apis[0].ArcURL = "" assert.Error(t, n.Validate()) }) + + t.Run("mapi url without miner id", func(t *testing.T) { + n := getNodesDefaults() + + n.Protocol = NodesProtocolMapi + n.Apis[0].MapiURL = "http://localhost" + n.Apis[0].MinerID = "" + assert.Error(t, n.Validate()) + }) + + t.Run("mapi url with the same miner id", func(t *testing.T) { + n := getNodesDefaults() + + n.Protocol = NodesProtocolMapi + n.Apis[0].MapiURL = "http://localhost" + n.Apis[0].MinerID = "miner1" + n.Apis = append(n.Apis, &MinerAPI{ + MapiURL: "http://localhost", + MinerID: "miner1", + }) + + assert.Error(t, n.Validate()) + }) } From 7ba62e80573abc288a4ba18f892ef82a291ed662 Mon Sep 17 00:00:00 2001 From: Krzysztof Tomecki <152964795+chris-4chain@users.noreply.github.com> Date: Thu, 11 Jan 2024 14:20:43 +0100 Subject: [PATCH 4/8] refactor(BUX-461): small change after self-review --- config.example.yaml | 2 +- config/validate_nodes.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config.example.yaml b/config.example.yaml index 3f561b444..373296861 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -82,7 +82,7 @@ _nodes: use_fee_quotes: true fee_unit: satoshis: 1 - bytes: 20 + bytes: 1000 # Prefixed with "_", because it's unused by default _notifications: enabled: false diff --git a/config/validate_nodes.go b/config/validate_nodes.go index efcd33b50..d9d6e1db9 100644 --- a/config/validate_nodes.go +++ b/config/validate_nodes.go @@ -20,8 +20,8 @@ func (n *NodesConfig) Validate() error { return errors.New("no miner apis configured") } - // check if at least one mapi url is configured if n.Protocol == NodesProtocolMapi { + // check if at least one mapi url is configured anyMapiNode := slices.IndexFunc(n.Apis, func(el *MinerAPI) bool { return isMapiNode(el) }) From a42f658e659aa4cc079a323c584180500037b9d7 Mon Sep 17 00:00:00 2001 From: Krzysztof Tomecki <152964795+chris-4chain@users.noreply.github.com> Date: Fri, 12 Jan 2024 07:33:31 +0100 Subject: [PATCH 5/8] chore(BUX-461): validation error when neither fee_unit nor use_fee_quotes is configured --- config/validate_nodes.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/validate_nodes.go b/config/validate_nodes.go index d9d6e1db9..1182c1078 100644 --- a/config/validate_nodes.go +++ b/config/validate_nodes.go @@ -58,6 +58,10 @@ func (n *NodesConfig) Validate() error { } } + if !n.UseFeeQuotes && n.FeeUnit == nil { + return errors.New("fee unit is not configured, define nodes.fee_unit or set nodes.use_fee_quotes") + } + return nil } From a5e225d679fde16165cc15e013f47341f4248702 Mon Sep 17 00:00:00 2001 From: Krzysztof Tomecki <152964795+chris-4chain@users.noreply.github.com> Date: Fri, 12 Jan 2024 07:41:54 +0100 Subject: [PATCH 6/8] chore(BUX-461): assume next bux version 0.12.0 --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 0c9602768..dde1e8d67 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.21.5 require ( github.com/99designs/gqlgen v0.17.42 - github.com/BuxOrg/bux v0.11.0 + github.com/BuxOrg/bux v0.12.0 github.com/BuxOrg/bux-models v0.3.0 github.com/bitcoin-sv/go-broadcast-client v0.12.2 github.com/go-ozzo/ozzo-validation v3.6.0+incompatible From 863454adfdf1f8e42cddde07de5d4eca716f6cec Mon Sep 17 00:00:00 2001 From: Krzysztof Tomecki <152964795+chris-4chain@users.noreply.github.com> Date: Fri, 12 Jan 2024 11:55:05 +0100 Subject: [PATCH 7/8] chore(BUX-461): assume next version 0.13.0 --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index dde1e8d67..ce0b36b70 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.21.5 require ( github.com/99designs/gqlgen v0.17.42 - github.com/BuxOrg/bux v0.12.0 + github.com/BuxOrg/bux v0.13.0 github.com/BuxOrg/bux-models v0.3.0 github.com/bitcoin-sv/go-broadcast-client v0.12.2 github.com/go-ozzo/ozzo-validation v3.6.0+incompatible From 3644e3bc743cf7edc3f4cfbb988f03da2415ac6d Mon Sep 17 00:00:00 2001 From: Krzysztof Tomecki <152964795+chris-4chain@users.noreply.github.com> Date: Fri, 12 Jan 2024 13:42:57 +0100 Subject: [PATCH 8/8] chore(BUX-461): go mod tidy with broadcast-client 0.16.0 --- go.mod | 2 +- go.sum | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index ce0b36b70..37cdf03fe 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/99designs/gqlgen v0.17.42 github.com/BuxOrg/bux v0.13.0 github.com/BuxOrg/bux-models v0.3.0 - github.com/bitcoin-sv/go-broadcast-client v0.12.2 + github.com/bitcoin-sv/go-broadcast-client v0.16.0 github.com/go-ozzo/ozzo-validation v3.6.0+incompatible github.com/go-redis/redis/v8 v8.11.5 github.com/gofrs/uuid v4.4.0+incompatible diff --git a/go.sum b/go.sum index d84c31340..7d89cb6b8 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ github.com/99designs/gqlgen v0.17.42 h1:BVWDOb2VVHQC5k3m6oa0XhDnxltLLrU4so7x/u39Zu4= github.com/99designs/gqlgen v0.17.42/go.mod h1:GQ6SyMhwFbgHR0a8r2Wn8fYgEwPxxmndLFPhU63+cJE= -github.com/BuxOrg/bux v0.11.0 h1:8kJAN8H/YAe3vCrnPuEakOvi9OZDPGlj/bnwjFDiMK4= -github.com/BuxOrg/bux v0.11.0/go.mod h1:xwxsYeL726ORudn9DK+PSX2qfpettD7QCTT6gmQ7Drw= +github.com/BuxOrg/bux v0.13.0 h1:ph5JqTJjztOFbC4JPNAW+4KN8w+PXekzK+8ij/2yXEo= +github.com/BuxOrg/bux v0.13.0/go.mod h1:qqsUfSVqp3IJv5NajpoMcHiAouw+40IX7sBBCclhJvo= github.com/BuxOrg/bux-models v0.3.0 h1:+pvpDdYaiIgeOhAO847RK07Vzc+vuUvy2ok/xJevQyg= github.com/BuxOrg/bux-models v0.3.0/go.mod h1:JCpoXxVnKZmCy3rg6nOtLQL5AXh6iEo2tBvcD/qAxEY= github.com/DATA-DOG/go-sqlmock v1.5.1 h1:FK6RCIUSfmbnI/imIICmboyQBkOckutaa6R5YYlLZyo= @@ -30,8 +30,8 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3d github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-sdk-go v1.43.45 h1:2708Bj4uV+ym62MOtBnErm/CDX61C4mFe9V2gXy1caE= github.com/aws/aws-sdk-go v1.43.45/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= -github.com/bitcoin-sv/go-broadcast-client v0.12.2 h1:1xgYPqc0o0iR4UUs1Rcku5ISa4WyHEGrU1TwzYW7zdk= -github.com/bitcoin-sv/go-broadcast-client v0.12.2/go.mod h1:BTmakaAihsGffiIc6FjFIe/tEUcsedWs6GbryZXcpX4= +github.com/bitcoin-sv/go-broadcast-client v0.16.0 h1:KadOLv+i9Y6xAOkHsSl2PIECQ59SpUyYurY6Ysvpz5A= +github.com/bitcoin-sv/go-broadcast-client v0.16.0/go.mod h1:GRAliwumNBjEbLRIEkXqIKJpsgmMfjvlIDqgyw/NoJE= github.com/bitcoin-sv/go-paymail v0.11.0 h1:jEfBLLaUUIxN3WnkU9d6Wj9IUen1Xx09dWUHlz3gTnQ= github.com/bitcoin-sv/go-paymail v0.11.0/go.mod h1:wH4jOVM24y7+OS2rLeJpwzJ73abM2rq/aeKZom0lHSk= github.com/bitcoinschema/go-bitcoin/v2 v2.0.5 h1:Sgh5Eb746Zck/46rFDrZZEXZWyO53fMuWYhNoZa1tck=