fixed quotation currency inference

This commit is contained in:
Stephan D
2026-03-04 04:50:31 +01:00
parent 9b794a3065
commit de07b9a792
35 changed files with 928 additions and 182 deletions

View File

@@ -51,6 +51,12 @@ func (i *Imp) initDependencies(cfg *config) *clientDependencies {
i.discoveryClients = newDiscoveryClientResolver(i.logger, i.discoveryReg)
deps.gatewayResolver = discoveryChainGatewayResolver{resolver: i.discoveryClients}
deps.gatewayInvokeResolver = discoveryGatewayInvokeResolver{resolver: i.discoveryClients}
ledgerClient, ledgerErr := i.discoveryClients.LedgerClient(context.Background())
if ledgerErr != nil {
i.logger.Warn("Failed to initialise ledger client from discovery", zap.Error(ledgerErr))
} else {
deps.ledgerClient = ledgerClient
}
} else if i != nil && i.logger != nil {
i.logger.Warn("Discovery registry unavailable; chain gateway clients disabled")
}

View File

@@ -11,9 +11,11 @@ import (
"time"
chainclient "github.com/tech/sendico/gateway/chain/client"
ledgerclient "github.com/tech/sendico/ledger/client"
"github.com/tech/sendico/pkg/discovery"
"github.com/tech/sendico/pkg/merrors"
"github.com/tech/sendico/pkg/mlogger"
"github.com/tech/sendico/pkg/mservice"
"go.uber.org/zap"
)
@@ -35,7 +37,9 @@ type discoveryClientResolver struct {
mu sync.Mutex
chainClients map[string]chainclient.Client
chainClients map[string]chainclient.Client
ledgerClient ledgerclient.Client
ledgerEndpoint discoveryEndpoint
lastSelection map[string]string
lastMissing map[string]time.Time
@@ -66,6 +70,10 @@ func (r *discoveryClientResolver) Close() {
}
delete(r.chainClients, key)
}
if r.ledgerClient != nil {
_ = r.ledgerClient.Close()
r.ledgerClient = nil
}
}
type discoveryGatewayInvokeResolver struct {
@@ -130,6 +138,43 @@ func (r *discoveryClientResolver) ChainClientByNetwork(ctx context.Context, netw
return r.ChainClientByInvokeURI(ctx, entry.InvokeURI)
}
func (r *discoveryClientResolver) LedgerClient(ctx context.Context) (ledgerclient.Client, error) {
entry, ok := r.findLedgerEntry()
if !ok {
return nil, merrors.NoData("discovery: ledger service unavailable")
}
endpoint, err := parseDiscoveryEndpoint(entry.InvokeURI)
if err != nil {
r.logMissing("ledger", "invalid ledger invoke uri", entry.InvokeURI, err)
return nil, err
}
if ctx == nil {
ctx = context.Background()
}
r.mu.Lock()
defer r.mu.Unlock()
if r.ledgerClient == nil || r.ledgerEndpoint.key() != endpoint.key() || r.ledgerEndpoint.address != endpoint.address {
if r.ledgerClient != nil {
_ = r.ledgerClient.Close()
r.ledgerClient = nil
}
client, dialErr := ledgerclient.New(ctx, ledgerclient.Config{
Address: endpoint.address,
Insecure: endpoint.insecure,
})
if dialErr != nil {
r.logMissing("ledger", "failed to dial ledger service", endpoint.raw, dialErr)
return nil, dialErr
}
r.ledgerClient = client
r.ledgerEndpoint = endpoint
}
return r.ledgerClient, nil
}
func (r *discoveryClientResolver) findChainEntry(network string) (*discovery.RegistryEntry, bool) {
if r == nil || r.registry == nil {
r.logMissing("chain", "discovery registry unavailable", "", nil)
@@ -172,6 +217,44 @@ func (r *discoveryClientResolver) findChainEntry(network string) (*discovery.Reg
return &entry, true
}
func (r *discoveryClientResolver) findLedgerEntry() (*discovery.RegistryEntry, bool) {
if r == nil || r.registry == nil {
r.logMissing("ledger", "discovery registry unavailable", "", nil)
return nil, false
}
entries := r.registry.List(time.Now(), true)
matches := make([]discovery.RegistryEntry, 0)
for _, entry := range entries {
if !strings.EqualFold(strings.TrimSpace(entry.Service), string(mservice.Ledger)) {
continue
}
if strings.TrimSpace(entry.InvokeURI) == "" {
continue
}
matches = append(matches, entry)
}
if len(matches) == 0 {
r.logMissing("ledger", "discovery ledger entry missing", "", nil)
return nil, false
}
sort.Slice(matches, func(i, j int) bool {
if matches[i].RoutingPriority != matches[j].RoutingPriority {
return matches[i].RoutingPriority > matches[j].RoutingPriority
}
if matches[i].ID != matches[j].ID {
return matches[i].ID < matches[j].ID
}
return matches[i].InstanceID < matches[j].InstanceID
})
entry := matches[0]
entryKey := discoveryEntryKey(entry)
r.logSelection("ledger", entryKey, entry)
return &entry, true
}
func (r *discoveryClientResolver) logSelection(key, entryKey string, entry discovery.RegistryEntry) {
if r == nil {
return

View File

@@ -51,6 +51,9 @@ func (i *Imp) Start() error {
if i.deps.oracleClient != nil {
opts = append(opts, quotesvc.WithOracleClient(i.deps.oracleClient))
}
if i.deps.ledgerClient != nil {
opts = append(opts, quotesvc.WithLedgerClient(i.deps.ledgerClient))
}
if i.deps.gatewayResolver != nil {
opts = append(opts, quotesvc.WithChainGatewayResolver(i.deps.gatewayResolver))
}

View File

@@ -2,6 +2,7 @@ package serverimp
import (
oracleclient "github.com/tech/sendico/fx/oracle/client"
ledgerclient "github.com/tech/sendico/ledger/client"
quotesvc "github.com/tech/sendico/payments/quotation/internal/service/quotation"
"github.com/tech/sendico/payments/storage"
"github.com/tech/sendico/pkg/discovery"
@@ -20,6 +21,7 @@ type clientDependencies struct {
feesConn *grpc.ClientConn
feesClient feesv1.FeeEngineClient
oracleClient oracleclient.Client
ledgerClient ledgerclient.Client
gatewayResolver quotesvc.ChainGatewayResolver
gatewayInvokeResolver quotesvc.GatewayInvokeResolver
}