From d1fd53f6c75c5333656d605b30af454fc992d56c Mon Sep 17 00:00:00 2001 From: Christopher Tarry Date: Mon, 25 Nov 2024 18:41:28 -0500 Subject: [PATCH] add host announcements in new function outside of addEvents --- explorer/update.go | 72 +++++++++++++++++++++++-------- persist/sqlite/consensus.go | 85 +++++++++++++++++-------------------- 2 files changed, 94 insertions(+), 63 deletions(-) diff --git a/explorer/update.go b/explorer/update.go index a5800c8..9ac7493 100644 --- a/explorer/update.go +++ b/explorer/update.go @@ -52,6 +52,9 @@ type ( Metrics Metrics TreeUpdates []TreeNodeUpdate + HostAnnouncements []chain.HostAnnouncement + V2HostAnnouncements []V2HostAnnouncement + NewSiacoinElements []SiacoinOutput SpentSiacoinElements []SiacoinOutput EphemeralSiacoinElements []SiacoinOutput @@ -216,6 +219,28 @@ func applyChainUpdate(tx UpdateTx, cau chain.ApplyUpdate) error { }) }) + var hostAnnouncements []chain.HostAnnouncement + for _, txn := range cau.Block.Transactions { + for _, arb := range txn.ArbitraryData { + var ha chain.HostAnnouncement + if ha.FromArbitraryData(arb) { + hostAnnouncements = append(hostAnnouncements, ha) + } + } + } + var v2HostAnnouncements []V2HostAnnouncement + for _, txn := range cau.Block.V2Transactions() { + for _, a := range txn.Attestations { + var ha chain.V2HostAnnouncement + if ha.FromAttestation(a) == nil { + v2HostAnnouncements = append(v2HostAnnouncements, V2HostAnnouncement{ + PublicKey: a.PublicKey, + V2HostAnnouncement: ha, + }) + } + } + } + events := AppliedEvents(cau.State, cau.Block, cau) state := UpdateState{ @@ -225,6 +250,9 @@ func applyChainUpdate(tx UpdateTx, cau chain.ApplyUpdate) error { Events: events, TreeUpdates: treeUpdates, + HostAnnouncements: hostAnnouncements, + V2HostAnnouncements: v2HostAnnouncements, + NewSiacoinElements: newSiacoinElements, SpentSiacoinElements: spentSiacoinElements, EphemeralSiacoinElements: ephemeralSiacoinElements, @@ -391,24 +419,34 @@ func revertChainUpdate(tx UpdateTx, cru chain.RevertUpdate, revertedIndex types. func updateMetrics(tx UpdateTx, s UpdateState, metrics Metrics) (Metrics, error) { seenHosts := make(map[types.PublicKey]struct{}) - for _, event := range s.Events { - if event.Data.EventType() == EventTypeTransaction { - txn := event.Data.(*EventTransaction) - for _, host := range txn.HostAnnouncements { - if _, ok := seenHosts[host.PublicKey]; ok { - continue - } + for _, host := range s.HostAnnouncements { + if _, ok := seenHosts[host.PublicKey]; ok { + continue + } - exists, err := tx.HostExists(host.PublicKey) - if err != nil { - return Metrics{}, err - } - if !exists { - // we haven't seen this host yet, increment count - metrics.TotalHosts++ - seenHosts[host.PublicKey] = struct{}{} - } - } + exists, err := tx.HostExists(host.PublicKey) + if err != nil { + return Metrics{}, err + } + if !exists { + // we haven't seen this host yet, increment count + metrics.TotalHosts++ + seenHosts[host.PublicKey] = struct{}{} + } + } + for _, host := range s.V2HostAnnouncements { + if _, ok := seenHosts[host.PublicKey]; ok { + continue + } + + exists, err := tx.HostExists(host.PublicKey) + if err != nil { + return Metrics{}, err + } + if !exists { + // we haven't seen this host yet, increment count + metrics.TotalHosts++ + seenHosts[host.PublicKey] = struct{}{} } } diff --git a/persist/sqlite/consensus.go b/persist/sqlite/consensus.go index 2acd3e8..a244d05 100644 --- a/persist/sqlite/consensus.go +++ b/persist/sqlite/consensus.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "time" "go.sia.tech/core/types" "go.sia.tech/coreutils/chain" @@ -324,6 +325,42 @@ func addTransactionFields(tx *txn, txns []types.Transaction, scDBIds map[types.S return nil } +func addHostAnnouncements(tx *txn, timestamp time.Time, hostAnnouncements []chain.HostAnnouncement, v2HostAnnouncements []explorer.V2HostAnnouncement) error { + var hosts []explorer.Host + for _, announcement := range hostAnnouncements { + hosts = append(hosts, explorer.Host{ + PublicKey: announcement.PublicKey, + NetAddress: announcement.NetAddress, + + KnownSince: timestamp, + LastAnnouncement: timestamp, + }) + } + if len(hosts) > 0 { + if err := addHosts(tx, hosts); err != nil { + return fmt.Errorf("failed to insert host info: %w", err) + } + } + + var v2Hosts []explorer.Host + for _, announcement := range v2HostAnnouncements { + v2Hosts = append(v2Hosts, explorer.Host{ + PublicKey: announcement.PublicKey, + V2NetAddresses: []chain.NetAddress(announcement.V2HostAnnouncement), + + KnownSince: timestamp, + LastAnnouncement: timestamp, + }) + } + if len(v2Hosts) > 0 { + if err := addHosts(tx, v2Hosts); err != nil { + return fmt.Errorf("failed to insert host info: %w", err) + } + } + + return nil +} + type balance struct { sc types.Currency immatureSC types.Currency @@ -649,52 +686,6 @@ func addEvents(tx *txn, scDBIds map[types.SiacoinOutputID]int64, fcDBIds map[exp } defer foundationSubsidyEventStmt.Close() - // Insert/update host announcements if there are any. - // The loop below this one checks if we've already seen an event - // transaction with the same ID before it decides to insert it. Here we - // want to insert regardless to update the last_announcement field in the - // event that we've seen this host before. If the transaction pays a fee - // which most real transactions do then this unnecessary because the txn ID - // will be unique regardless due to the siacoin input but this is more - // technically correct and makes testing easier. - for _, event := range events { - switch v := event.Data.(type) { - case *explorer.EventTransaction: - var hosts []explorer.Host - for _, announcement := range v.HostAnnouncements { - hosts = append(hosts, explorer.Host{ - PublicKey: announcement.PublicKey, - NetAddress: announcement.NetAddress, - - KnownSince: event.Timestamp, - LastAnnouncement: event.Timestamp, - }) - } - if len(hosts) > 0 { - if err := addHosts(tx, hosts); err != nil { - return fmt.Errorf("failed to insert host info: %w", err) - } - } - - case *explorer.EventV2Transaction: - var hosts []explorer.Host - for _, announcement := range v.HostAnnouncements { - hosts = append(hosts, explorer.Host{ - PublicKey: announcement.PublicKey, - V2NetAddresses: []chain.NetAddress(announcement.V2HostAnnouncement), - - KnownSince: event.Timestamp, - LastAnnouncement: event.Timestamp, - }) - } - if len(hosts) > 0 { - if err := addHosts(tx, hosts); err != nil { - return fmt.Errorf("failed to insert host info: %w", err) - } - } - } - } - var buf bytes.Buffer enc := json.NewEncoder(&buf) for _, event := range events { @@ -1082,6 +1073,8 @@ func (ut *updateTx) ApplyIndex(state explorer.UpdateState) error { return fmt.Errorf("ApplyIndex: failed to update state tree: %w", err) } else if err := addMetrics(ut.tx, state); err != nil { return fmt.Errorf("ApplyIndex: failed to update metrics: %w", err) + } else if err := addHostAnnouncements(ut.tx, state.Block.Timestamp, state.HostAnnouncements, state.V2HostAnnouncements); err != nil { + return fmt.Errorf("ApplyIndex: failed to add host announcements: %w", err) } else if err := addEvents(ut.tx, scDBIds, fcDBIds, txnDBIds, v2TxnDBIds, state.Events); err != nil { return fmt.Errorf("ApplyIndex: failed to add events: %w", err) } else if err := updateFileContractIndices(ut.tx, false, state.Metrics.Index, state.FileContractElements); err != nil {