Skip to content

Commit

Permalink
Merge pull request #564 from lightninglabs/use-sync-config
Browse files Browse the repository at this point in the history
Use federation sync config in syncer
  • Loading branch information
Roasbeef authored Oct 12, 2023
2 parents d7c9a25 + 45ffa99 commit e614ff9
Show file tree
Hide file tree
Showing 14 changed files with 660 additions and 96 deletions.
6 changes: 6 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@ type Config struct {

UniverseStats universe.Telemetry

// UniversePublicAccess is flag which, If true, and the Universe server
// is on a public interface, valid proof from remote parties will be
// accepted, and proofs will be queryable by remote parties.
// This applies to federation syncing as well as RPC insert and query.
UniversePublicAccess bool

Prometheus monitoring.PrometheusConfig

// LogWriter is the root logger that all of the daemon's subloggers are
Expand Down
2 changes: 1 addition & 1 deletion itest/assertions.go
Original file line number Diff line number Diff line change
Expand Up @@ -1286,7 +1286,7 @@ func AssertUniverseAssetStats(t *testing.T, node *tapdHarness,
eventStats, err := node.QueryEvents(ctxb, &unirpc.QueryEventsRequest{})
require.NoError(t, err)

todayStr := time.Now().Format("2006-01-02")
todayStr := time.Now().UTC().Format("2006-01-02")
require.Len(t, eventStats.Events, 1)

s := eventStats.Events[0]
Expand Down
5 changes: 5 additions & 0 deletions itest/tapd_harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,11 @@ func newTapdHarness(t *testing.T, ht *harnessTest, cfg tapdConfig,
TLSPath: cfg.LndNode.Cfg.TLSCertPath,
}

// Ensure valid proof from tapd nodes will be accepted, and proofs will
// be queryable by other tapd nodes. This applies to federation syncing
// as well as RPC insert and query.
tapCfg.Universe.PublicAccess = true

cfgLogger := tapCfg.LogWriter.GenSubLogger("CONF", nil)
finalCfg, err := tapcfg.ValidateConfig(tapCfg, cfgLogger)
if err != nil {
Expand Down
9 changes: 5 additions & 4 deletions itest/universe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,11 +199,12 @@ func testUniverseSync(t *harnessTest) {

assetIdFixedSize := fn.ToArray[[32]byte](firstAssetID)

firstAssetAmount := rpcSimpleAssets[0].Amount
nodeHash := firstAssetUniMssmtRoot.NodeHash()
leaf := mssmt.NewLeafNode(
nodeHash[:], firstAssetAmount,
)

// For the multiverse tree, the top level leaf node (inserted into the
// top level tree) is actually just an accumulator value, so this we
// use a value of 1 here.
leaf := mssmt.NewLeafNode(nodeHash[:], 1)

verifyProofResult := mssmt.VerifyMerkleProof(
assetIdFixedSize, leaf, multiverseInclusionProof,
Expand Down
133 changes: 103 additions & 30 deletions rpcserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -2706,11 +2706,23 @@ func (r *rpcServer) AssetRoots(ctx context.Context,
UniverseRoots: make(map[string]*unirpc.UniverseRoot),
}

// Retrieve config for use in filtering asset roots based on sync export
// settings.
syncConfigs, err := r.cfg.UniverseFederation.QuerySyncConfigs(ctx)
if err != nil {
return nil, err
}

// For each universe root, marshal it into the RPC form, taking care to
// specify the proper universe ID.
for _, assetRoot := range assetRoots {
idStr := assetRoot.ID.String()

// Skip this asset if it's not configured for sync export.
if !syncConfigs.IsSyncExportEnabled(assetRoot.ID) {
continue
}

resp.UniverseRoots[idStr], err = marshalUniverseRoot(assetRoot)
if err != nil {
return nil, err
Expand Down Expand Up @@ -2844,6 +2856,17 @@ func (r *rpcServer) QueryAssetRoots(ctx context.Context,

universeID.ProofType = universe.ProofTypeIssuance

// Ensure proof export is enabled for the given universe.
syncConfigs, err := r.cfg.UniverseFederation.QuerySyncConfigs(ctx)
if err != nil {
return nil, err
}

if !syncConfigs.IsSyncExportEnabled(universeID) {
return nil, fmt.Errorf("proof export is disabled for the " +
"given universe")
}

issuanceRoot, err := r.cfg.BaseUniverse.RootNode(ctx, universeID)
if err != nil {
// Do not return at this point if the error only indicates that
Expand Down Expand Up @@ -3210,49 +3233,74 @@ func (r *rpcServer) QueryProof(ctx context.Context,
rpcsLog.Debugf("[QueryProof]: fetching proof at (universeID=%v, "+
"leafKey=%x)", universeID, leafKey.UniverseKey())

// Keep a record of whether the proof type was specified by the client.
unspecifiedArgProofType :=
universeID.ProofType == universe.ProofTypeUnspecified
if unspecifiedArgProofType {
// The target proof type was unspecified. Assume that the proof
// type is a transfer proof (more transfer proofs exist then
// issuance proofs).
universeID.ProofType = universe.ProofTypeTransfer
// Retrieve proof export config for the given universe.
syncConfigs, err := r.cfg.UniverseFederation.QuerySyncConfigs(ctx)
if err != nil {
return nil, err
}

// Attempt to fetch the proof from the base universe.
proofs, err := r.cfg.BaseUniverse.FetchIssuanceProof(
ctx, universeID, leafKey,
)
// If we were unable to find a proof, and the proof type was originally
// unspecified, then we'll try again with the other proof type.
if unspecifiedArgProofType &&
errors.Is(err, universe.ErrNoUniverseProofFound) {
var candidateIDs []universe.Identifier

if universeID.ProofType == universe.ProofTypeUnspecified {
// If the proof type is unspecified, then we'll attempt to
// retrieve both the issuance and transfer proofs. We gather the
// corresponding universe IDs into a candidate set.
universeID.ProofType = universe.ProofTypeIssuance
if syncConfigs.IsSyncExportEnabled(universeID) {
candidateIDs = append(candidateIDs, universeID)
}

// The proof type was originally unspecified by the client. We
// will therefore try again with the other proof type.
switch universeID.ProofType {
case universe.ProofTypeTransfer:
universeID.ProofType = universe.ProofTypeIssuance
case universe.ProofTypeIssuance:
universeID.ProofType = universe.ProofTypeTransfer
universeID.ProofType = universe.ProofTypeTransfer
if syncConfigs.IsSyncExportEnabled(universeID) {
candidateIDs = append(candidateIDs, universeID)
}
} else {
// Otherwise, we'll only attempt to retrieve the proof for the
// specified proof type. But first we'll check that proof export
// is enabled for the given universe.
if !syncConfigs.IsSyncExportEnabled(universeID) {
return nil, fmt.Errorf("proof export is disabled for " +
"the given universe")
}

candidateIDs = append(candidateIDs, universeID)
}

// If no candidate IDs were applicable then our config must have
// disabled proof export for the given universe.
if len(candidateIDs) == 0 {
return nil, fmt.Errorf("proof export is disabled for the " +
"given universe")
}

// Attempt to retrieve the proof given the candidate set of universe
// IDs.
var proofs []*universe.Proof
for i := range candidateIDs {
candidateID := candidateIDs[i]

proofs, err = r.cfg.BaseUniverse.FetchIssuanceProof(
ctx, universeID, leafKey,
ctx, candidateID, leafKey,
)
if err != nil {
if errors.Is(err, universe.ErrNoUniverseProofFound) {
continue
}

rpcsLog.Debugf("[QueryProof]: error querying for "+
"proof at (universeID=%v, leafKey=%x)",
universeID, leafKey.UniverseKey())
return nil, err
}

// At this point we've found a proof, so we'll break out of the
// loop. We don't need to attempt to retrieve a proof for any
// other candidate IDs.
break
}
if err != nil {
rpcsLog.Debugf("[QueryProof]: error querying for proof at "+
"(universeID=%v, leafKey=%x)", universeID,
leafKey.UniverseKey())
return nil, err

if len(proofs) == 0 {
return nil, universe.ErrNoUniverseProofFound
}

// TODO(roasbeef): query may return multiple proofs, if allow key to
Expand Down Expand Up @@ -3332,6 +3380,17 @@ func (r *rpcServer) InsertProof(ctx context.Context,
return nil, err
}

// Ensure proof insert is enabled for the given universe.
syncConfigs, err := r.cfg.UniverseFederation.QuerySyncConfigs(ctx)
if err != nil {
return nil, err
}

if !syncConfigs.IsSyncInsertEnabled(universeID) {
return nil, fmt.Errorf("proof insert is disabled for the " +
"given universe")
}

rpcsLog.Debugf("[InsertProof]: inserting proof at "+
"(universeID=%v, leafKey=%x)", universeID,
leafKey.UniverseKey())
Expand Down Expand Up @@ -3462,10 +3521,24 @@ func (r *rpcServer) SyncUniverse(ctx context.Context,

uniAddr := universe.NewServerAddrFromStr(req.UniverseHost)

// Obtain the general and universe specific federation sync configs.
queryFedSyncConfigs := r.cfg.FederationDB.QueryFederationSyncConfigs
globalConfigs, uniSyncConfigs, err := queryFedSyncConfigs(ctx)
if err != nil {
return nil, fmt.Errorf("unable to query federation sync "+
"config(s): %w", err)
}

syncConfigs := universe.SyncConfigs{
GlobalSyncConfigs: globalConfigs,
UniSyncConfigs: uniSyncConfigs,
}

// TODO(roasbeef): add layer of indirection in front of?
// * just interface interaction
// TODO(ffranr): Sync via the FederationEnvoy rather than syncer.
universeDiff, err := r.cfg.UniverseSyncer.SyncUniverse(
ctx, uniAddr, syncMode, syncTargets...,
ctx, uniAddr, syncMode, syncConfigs, syncTargets...,
)
if err != nil {
return nil, fmt.Errorf("unable to sync universe: %w", err)
Expand Down
8 changes: 8 additions & 0 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,14 @@ func (s *Server) initialize(interceptorChain *rpcperms.InterceptorChain) error {
"federation: %v", err)
}

if s.cfg.UniversePublicAccess {
err := s.cfg.UniverseFederation.SetAllowPublicAccess()
if err != nil {
return fmt.Errorf("unable to set public access "+
"for universe federation: %v", err)
}
}

// Now we have created all dependencies necessary to populate and
// start the RPC server.
if err := s.rpcServer.Start(); err != nil {
Expand Down
4 changes: 2 additions & 2 deletions tapcfg/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,9 @@ type LndConfig struct {
type UniverseConfig struct {
SyncInterval time.Duration `long:"syncinterval" description:"Amount of time to wait between universe syncs"`

AcceptRemoteProofs bool `long:"accept-remote-proofs" description:"If true, then if the Universe server is on a public interface, valid proof from remote parties will be accepted"`

FederationServers []string `long:"federationserver" description:"The host:port of a Universe server peer with. These servers will be added as the default set of federation servers. Can be specified multiple times."`

PublicAccess bool `long:"public-access" description:"If true, and the Universe server is on a public interface, valid proof from remote parties will be accepted, and proofs will be queryable by remote parties. This applies to federation syncing as well as RPC insert and query."`
}

// Config is the main config for the tapd cli command.
Expand Down
11 changes: 6 additions & 5 deletions tapcfg/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,11 +341,12 @@ func genServerConfig(cfg *Config, cfgLogger btclog.Logger,
ErrChan: mainErrChan,
},
),
BaseUniverse: baseUni,
UniverseSyncer: universeSyncer,
UniverseFederation: universeFederation,
UniverseStats: universeStats,
LogWriter: cfg.LogWriter,
BaseUniverse: baseUni,
UniverseSyncer: universeSyncer,
UniverseFederation: universeFederation,
UniverseStats: universeStats,
UniversePublicAccess: cfg.Universe.PublicAccess,
LogWriter: cfg.LogWriter,
DatabaseConfig: &tap.DatabaseConfig{
RootKeyStore: tapdb.NewRootKeyStore(rksDB),
MintingStore: assetMintingStore,
Expand Down
Loading

0 comments on commit e614ff9

Please sign in to comment.