From eeb5a8d5c33725d344686af655414b362e0eff6e Mon Sep 17 00:00:00 2001 From: Faye Amacker <33205765+fxamacker@users.noreply.github.com> Date: Mon, 13 Jan 2025 14:44:40 -0600 Subject: [PATCH 1/6] Bump stats package version and refactor --- cmd/util/cmd/checkpoint-collect-stats/cmd.go | 126 ++++-------------- .../checkpoint-collect-stats/stats_utils.go | 58 ++++++++ go.mod | 2 +- go.sum | 4 +- 4 files changed, 90 insertions(+), 100 deletions(-) create mode 100644 cmd/util/cmd/checkpoint-collect-stats/stats_utils.go diff --git a/cmd/util/cmd/checkpoint-collect-stats/cmd.go b/cmd/util/cmd/checkpoint-collect-stats/cmd.go index c6c96f51eb3..0031adf78b8 100644 --- a/cmd/util/cmd/checkpoint-collect-stats/cmd.go +++ b/cmd/util/cmd/checkpoint-collect-stats/cmd.go @@ -8,7 +8,6 @@ import ( "strings" "sync" - "github.com/montanaflynn/stats" "github.com/pkg/profile" "github.com/rs/zerolog" "github.com/rs/zerolog/log" @@ -59,6 +58,10 @@ const ( blockHashListBucketKeyPrefix = "BlockHashListBucket" ) +// percentiles are Tukey's seven-number summary (without +// the 0 and 100 because min and max are always included). +var percentiles = []float64{12.5, 25.0, 50.0, 75.0, 87.5} + var Cmd = &cobra.Command{ Use: "checkpoint-collect-stats", Short: "collects stats on tries stored in a checkpoint, or payloads from a payloads file", @@ -109,17 +112,9 @@ type PayloadStats struct { } type RegisterStatsByTypes struct { - Type string `json:"type"` - Counts uint64 `json:"counts"` - ValueSizeTotal float64 `json:"value_size_total"` - ValueSizeMin float64 `json:"value_size_min"` - ValueSize25thPercentile float64 `json:"value_size_25th_percentile"` - ValueSizeMedian float64 `json:"value_size_median"` - ValueSize75thPercentile float64 `json:"value_size_75th_percentile"` - ValueSize95thPercentile float64 `json:"value_size_95th_percentile"` - ValueSize99thPercentile float64 `json:"value_size_99th_percentile"` - ValueSizeMax float64 `json:"value_size_max"` - SubTypes []RegisterStatsByTypes `json:"subtypes,omitempty"` + Type string `json:"type"` + stats + SubTypes []RegisterStatsByTypes `json:"subtypes,omitempty"` } type PayloadInfo struct { @@ -130,17 +125,10 @@ type PayloadInfo struct { } type AccountStats struct { - AccountCount uint64 `json:"total_account_count"` - AccountSizeMin float64 `json:"account_size_min"` - AccountSize25thPercentile float64 `json:"account_size_25th_percentile"` - AccountSizeMedian float64 `json:"account_size_median"` - AccountSize75thPercentile float64 `json:"account_size_75th_percentile"` - AccountSize95thPercentile float64 `json:"account_size_95th_percentile"` - AccountSize99thPercentile float64 `json:"account_size_99th_percentile"` - AccountSizeMax float64 `json:"account_size_max"` - ServiceAccount *AccountInfo `json:"service_account,omitempty"` - EVMAccount *AccountInfo `json:"evm_account,omitempty"` - TopN []*AccountInfo `json:"largest_accounts"` + stats + ServiceAccount *AccountInfo `json:"service_account,omitempty"` + EVMAccount *AccountInfo `json:"evm_account,omitempty"` + TopN []*AccountInfo `json:"largest_accounts"` } type AccountInfo struct { @@ -245,7 +233,7 @@ func run(*cobra.Command, []string) { go func() { defer wg.Done() - statsByTypes := getStats(valueSizesByType) + statsByTypes := getRegisterStats(valueSizesByType) // Sort top N largest payloads by payload size in descending order slices.SortFunc(largestPayloads.Tree, func(a, b PayloadInfo) int { @@ -283,24 +271,17 @@ func run(*cobra.Command, []string) { return cmp.Compare(b.PayloadSize, a.PayloadSize) }) - stats := getTypeStats("", accountSizesSlice) + stats := getValueStats(accountSizesSlice, percentiles) evmAccountAddress := systemcontracts.SystemContractsForChain(chainID).EVMStorage.Address serviceAccountAddress := serviceAccountAddressForChain(chainID) acctStats := &AccountStats{ - AccountCount: uint64(len(accountsSlice)), - ServiceAccount: accounts[string(serviceAccountAddress[:])], - EVMAccount: accounts[string(evmAccountAddress[:])], - TopN: accountsSlice[:flagTopN], - AccountSizeMin: stats.ValueSizeMin, - AccountSize25thPercentile: stats.ValueSize25thPercentile, - AccountSizeMedian: stats.ValueSizeMedian, - AccountSize75thPercentile: stats.ValueSize75thPercentile, - AccountSize95thPercentile: stats.ValueSize95thPercentile, - AccountSize99thPercentile: stats.ValueSize99thPercentile, - AccountSizeMax: stats.ValueSizeMax, + stats: stats, + ServiceAccount: accounts[string(serviceAccountAddress[:])], + EVMAccount: accounts[string(evmAccountAddress[:])], + TopN: accountsSlice[:flagTopN], } writeStats(accountStatsReportName, acctStats) @@ -404,69 +385,17 @@ func getPayloadStatsFromCheckpoint(payloadCallBack func(payload *ledger.Payload) return ledgerStats } -func getTypeStats(t string, values []float64) RegisterStatsByTypes { - sum, err := stats.Sum(values) - if err != nil { - log.Fatal().Err(err).Msg("cannot compute the sum of values") - } - - min, err := stats.Min(values) - if err != nil { - log.Fatal().Err(err).Msg("cannot compute the min of values") - } - - percentile25, err := stats.Percentile(values, 25) - if err != nil { - log.Fatal().Err(err).Msg("cannot compute the 25th percentile of values") - } - - median, err := stats.Median(values) - if err != nil { - log.Fatal().Err(err).Msg("cannot compute the median of values") - } - - percentile75, err := stats.Percentile(values, 75) - if err != nil { - log.Fatal().Err(err).Msg("cannot compute the 75th percentile of values") - } - - percentile95, err := stats.Percentile(values, 95) - if err != nil { - log.Fatal().Err(err).Msg("cannot compute the 95th percentile of values") - } - - percentile99, err := stats.Percentile(values, 99) - if err != nil { - log.Fatal().Err(err).Msg("cannot compute the 99th percentile of values") - } - - max, err := stats.Max(values) - if err != nil { - log.Fatal().Err(err).Msg("cannot compute the max of values") - } - - return RegisterStatsByTypes{ - Type: t, - Counts: uint64(len(values)), - ValueSizeTotal: sum, - ValueSizeMin: min, - ValueSize25thPercentile: percentile25, - ValueSizeMedian: median, - ValueSize75thPercentile: percentile75, - ValueSize95thPercentile: percentile95, - ValueSize99thPercentile: percentile99, - ValueSizeMax: max, - } -} - -func getStats(valueSizesByType sizesByType) []RegisterStatsByTypes { +func getRegisterStats(valueSizesByType sizesByType) []RegisterStatsByTypes { domainStats := make([]RegisterStatsByTypes, 0, len(util.StorageMapDomains)) var allDomainSizes []float64 statsByTypes := make([]RegisterStatsByTypes, 0, len(valueSizesByType)) for t, values := range valueSizesByType { - stats := getTypeStats(t, values) + stats := RegisterStatsByTypes{ + Type: t, + stats: getValueStats(values, percentiles), + } if isDomainType(t) { domainStats = append(domainStats, stats) @@ -476,19 +405,22 @@ func getStats(valueSizesByType sizesByType) []RegisterStatsByTypes { } } - allDomainStats := getTypeStats("domain", allDomainSizes) - allDomainStats.SubTypes = domainStats + allDomainStats := RegisterStatsByTypes{ + Type: "domain", + stats: getValueStats(allDomainSizes, percentiles), + SubTypes: domainStats, + } statsByTypes = append(statsByTypes, allDomainStats) // Sort domain stats by payload count in descending order slices.SortFunc(allDomainStats.SubTypes, func(a, b RegisterStatsByTypes) int { - return cmp.Compare(b.Counts, a.Counts) + return cmp.Compare(b.Count, a.Count) }) // Sort stats by payload count in descending order slices.SortFunc(statsByTypes, func(a, b RegisterStatsByTypes) int { - return cmp.Compare(b.Counts, a.Counts) + return cmp.Compare(b.Count, a.Count) }) return statsByTypes diff --git a/cmd/util/cmd/checkpoint-collect-stats/stats_utils.go b/cmd/util/cmd/checkpoint-collect-stats/stats_utils.go new file mode 100644 index 00000000000..3483ed1dc70 --- /dev/null +++ b/cmd/util/cmd/checkpoint-collect-stats/stats_utils.go @@ -0,0 +1,58 @@ +package checkpoint_collect_stats + +import ( + "cmp" + "slices" + + statslib "github.com/montanaflynn/stats" + "github.com/rs/zerolog/log" +) + +type percentileValue struct { + Percentile float64 `json:"percentile"` + Value float64 `json:"value"` +} + +type stats struct { + Count uint64 `json:"count"` + Sum float64 `json:"sum"` + Min float64 `json:"min"` + Max float64 `json:"max"` + Percentiles []percentileValue +} + +func getValueStats(values []float64, percentiles []float64) stats { + if len(values) == 0 { + return stats{} + } + + describe, err := statslib.Describe(values, true, &percentiles) + if err != nil { + log.Fatal().Err(err).Msg("cannot describe values") + } + + sum, err := statslib.Sum(values) + if err != nil { + log.Fatal().Err(err).Msg("cannot compute sum of values") + } + + percentileValues := make([]percentileValue, len(describe.DescriptionPercentiles)) + for i, pv := range describe.DescriptionPercentiles { + percentileValues[i] = percentileValue{ + Percentile: pv.Percentile, + Value: pv.Value, + } + } + + slices.SortFunc(percentileValues, func(a, b percentileValue) int { + return cmp.Compare(a.Percentile, b.Percentile) + }) + + return stats{ + Count: uint64(len(values)), + Sum: sum, + Min: describe.Min, + Max: describe.Max, + Percentiles: percentileValues, + } +} diff --git a/go.mod b/go.mod index eacd5e0ded0..ddfb061d66a 100644 --- a/go.mod +++ b/go.mod @@ -43,7 +43,7 @@ require ( github.com/libp2p/go-libp2p-kad-dht v0.25.2 github.com/libp2p/go-libp2p-kbucket v0.6.3 github.com/libp2p/go-libp2p-pubsub v0.10.0 - github.com/montanaflynn/stats v0.7.0 + github.com/montanaflynn/stats v0.7.1 github.com/multiformats/go-multiaddr v0.12.2 github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/multiformats/go-multihash v0.2.3 diff --git a/go.sum b/go.sum index 15ec48eea52..f699408c4eb 100644 --- a/go.sum +++ b/go.sum @@ -847,8 +847,8 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/montanaflynn/stats v0.7.0 h1:r3y12KyNxj/Sb/iOE46ws+3mS1+MZca1wlHQFPsY/JU= -github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= +github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE= +github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= From 86bc7aa59b90a8b6daebfe2d390b3e5fc678bc46 Mon Sep 17 00:00:00 2001 From: Faye Amacker <33205765+fxamacker@users.noreply.github.com> Date: Mon, 13 Jan 2025 15:14:32 -0600 Subject: [PATCH 2/6] Refactor stats util --- .../checkpoint-collect-stats/account_stats.go | 58 +++++++++++++++++++ cmd/util/cmd/checkpoint-collect-stats/cmd.go | 49 +--------------- 2 files changed, 61 insertions(+), 46 deletions(-) create mode 100644 cmd/util/cmd/checkpoint-collect-stats/account_stats.go diff --git a/cmd/util/cmd/checkpoint-collect-stats/account_stats.go b/cmd/util/cmd/checkpoint-collect-stats/account_stats.go new file mode 100644 index 00000000000..5d2e38c8845 --- /dev/null +++ b/cmd/util/cmd/checkpoint-collect-stats/account_stats.go @@ -0,0 +1,58 @@ +package checkpoint_collect_stats + +import ( + "cmp" + "slices" + + "github.com/onflow/flow-go/fvm/systemcontracts" + "github.com/onflow/flow-go/model/flow" +) + +type AccountStats struct { + stats + ServiceAccount *AccountInfo `json:"service_account,omitempty"` + EVMAccount *AccountInfo `json:"evm_account,omitempty"` + TopN []*AccountInfo `json:"largest_accounts"` +} + +type AccountInfo struct { + Address string `json:"address"` + PayloadCount uint64 `json:"payload_count"` + PayloadSize uint64 `json:"payload_size"` +} + +func getAccountStatus( + chainID flow.ChainID, + accounts map[string]*AccountInfo, +) AccountStats { + accountsSlice := make([]*AccountInfo, 0, len(accounts)) + accountSizesSlice := make([]float64, 0, len(accounts)) + + for _, acct := range accounts { + accountsSlice = append(accountsSlice, acct) + accountSizesSlice = append(accountSizesSlice, float64(acct.PayloadSize)) + } + + // Sort accounts by payload size in descending order + slices.SortFunc(accountsSlice, func(a, b *AccountInfo) int { + return cmp.Compare(b.PayloadSize, a.PayloadSize) + }) + + stats := getValueStats(accountSizesSlice, percentiles) + + evmAccountAddress := systemcontracts.SystemContractsForChain(chainID).EVMStorage.Address + + serviceAccountAddress := serviceAccountAddressForChain(chainID) + + return AccountStats{ + stats: stats, + ServiceAccount: accounts[string(serviceAccountAddress[:])], + EVMAccount: accounts[string(evmAccountAddress[:])], + TopN: accountsSlice[:flagTopN], + } +} + +func serviceAccountAddressForChain(chainID flow.ChainID) flow.Address { + sc := systemcontracts.SystemContractsForChain(chainID) + return sc.FlowServiceAccount.Address +} diff --git a/cmd/util/cmd/checkpoint-collect-stats/cmd.go b/cmd/util/cmd/checkpoint-collect-stats/cmd.go index 0031adf78b8..232fad677d3 100644 --- a/cmd/util/cmd/checkpoint-collect-stats/cmd.go +++ b/cmd/util/cmd/checkpoint-collect-stats/cmd.go @@ -20,7 +20,6 @@ import ( "github.com/onflow/flow-go/cmd/util/ledger/util" "github.com/onflow/flow-go/fvm/evm/emulator/state" "github.com/onflow/flow-go/fvm/evm/handler" - "github.com/onflow/flow-go/fvm/systemcontracts" "github.com/onflow/flow-go/ledger" "github.com/onflow/flow-go/ledger/common/pathfinder" "github.com/onflow/flow-go/ledger/complete" @@ -124,19 +123,6 @@ type PayloadInfo struct { Size uint64 `json:"size"` } -type AccountStats struct { - stats - ServiceAccount *AccountInfo `json:"service_account,omitempty"` - EVMAccount *AccountInfo `json:"evm_account,omitempty"` - TopN []*AccountInfo `json:"largest_accounts"` -} - -type AccountInfo struct { - Address string `json:"address"` - PayloadCount uint64 `json:"payload_count"` - PayloadSize uint64 `json:"payload_size"` -} - type sizesByType map[string][]float64 func run(*cobra.Command, []string) { @@ -198,7 +184,7 @@ func run(*cobra.Command, []string) { totalPayloadCount++ // Update payload sizes by type - typ := getType(key) + typ := getRegisterType(key) valueSizesByType[typ] = append(valueSizesByType[typ], float64(valueSize)) // Update top N largest payloads @@ -258,31 +244,7 @@ func run(*cobra.Command, []string) { go func() { defer wg.Done() - accountsSlice := make([]*AccountInfo, 0, len(accounts)) - accountSizesSlice := make([]float64, 0, len(accounts)) - - for _, acct := range accounts { - accountsSlice = append(accountsSlice, acct) - accountSizesSlice = append(accountSizesSlice, float64(acct.PayloadSize)) - } - - // Sort accounts by payload size in descending order - slices.SortFunc(accountsSlice, func(a, b *AccountInfo) int { - return cmp.Compare(b.PayloadSize, a.PayloadSize) - }) - - stats := getValueStats(accountSizesSlice, percentiles) - - evmAccountAddress := systemcontracts.SystemContractsForChain(chainID).EVMStorage.Address - - serviceAccountAddress := serviceAccountAddressForChain(chainID) - - acctStats := &AccountStats{ - stats: stats, - ServiceAccount: accounts[string(serviceAccountAddress[:])], - EVMAccount: accounts[string(evmAccountAddress[:])], - TopN: accountsSlice[:flagTopN], - } + acctStats := getAccountStatus(chainID, accounts) writeStats(accountStatsReportName, acctStats) }() @@ -438,7 +400,7 @@ func isDomainType(typ string) bool { return strings.HasPrefix(typ, domainTypePrefix) } -func getType(key ledger.Key) string { +func getRegisterType(key ledger.Key) string { k := key.KeyParts[1].Value kstr := string(k) @@ -491,8 +453,3 @@ func getType(key ledger.Key) string { return "others" } - -func serviceAccountAddressForChain(chainID flow.ChainID) flow.Address { - sc := systemcontracts.SystemContractsForChain(chainID) - return sc.FlowServiceAccount.Address -} From 54e27a5fd038d08afdc047a9d6b801c9084a705f Mon Sep 17 00:00:00 2001 From: Faye Amacker <33205765+fxamacker@users.noreply.github.com> Date: Mon, 13 Jan 2025 18:35:42 -0600 Subject: [PATCH 3/6] Add account format to checkpoint-collect-stats util --- .../checkpoint-collect-stats/account_stats.go | 70 ++++++++++++++++--- cmd/util/cmd/checkpoint-collect-stats/cmd.go | 39 ++++++++++- .../checkpoint-collect-stats/stats_utils.go | 2 +- 3 files changed, 98 insertions(+), 13 deletions(-) diff --git a/cmd/util/cmd/checkpoint-collect-stats/account_stats.go b/cmd/util/cmd/checkpoint-collect-stats/account_stats.go index 5d2e38c8845..f3349d8b5e5 100644 --- a/cmd/util/cmd/checkpoint-collect-stats/account_stats.go +++ b/cmd/util/cmd/checkpoint-collect-stats/account_stats.go @@ -4,21 +4,48 @@ import ( "cmp" "slices" + "github.com/rs/zerolog/log" + "github.com/onflow/flow-go/fvm/systemcontracts" "github.com/onflow/flow-go/model/flow" ) +type accountFormat uint8 + +const ( + accountFormatUnknown accountFormat = iota + accountFormatV1 + accountFormatV2 +) + +func (format accountFormat) MarshalJSON() ([]byte, error) { + switch format { + case accountFormatV1: + return []byte("\"v1\""), nil + + case accountFormatV2: + return []byte("\"v2\""), nil + + default: + return []byte("\"unknown\""), nil + } +} + type AccountStats struct { stats - ServiceAccount *AccountInfo `json:"service_account,omitempty"` - EVMAccount *AccountInfo `json:"evm_account,omitempty"` - TopN []*AccountInfo `json:"largest_accounts"` + FormatV1Count int `json:"account_format_v1_count"` + FormatV2Count int `json:"account_format_v2_count"` + AccountsInFormatV2 []string `json:"accounts_in_format_v2,omitempty"` + ServiceAccount *AccountInfo `json:"service_account,omitempty"` + EVMAccount *AccountInfo `json:"evm_account,omitempty"` + TopN []*AccountInfo `json:"largest_accounts"` } type AccountInfo struct { - Address string `json:"address"` - PayloadCount uint64 `json:"payload_count"` - PayloadSize uint64 `json:"payload_size"` + Address string `json:"address"` + Format accountFormat `json:"account_format"` + PayloadCount uint64 `json:"payload_count"` + PayloadSize uint64 `json:"payload_size"` } func getAccountStatus( @@ -28,9 +55,26 @@ func getAccountStatus( accountsSlice := make([]*AccountInfo, 0, len(accounts)) accountSizesSlice := make([]float64, 0, len(accounts)) + var accountsInFormatV2 []string + var accountFormatV1Count, accountFormatV2Count int + for _, acct := range accounts { accountsSlice = append(accountsSlice, acct) accountSizesSlice = append(accountSizesSlice, float64(acct.PayloadSize)) + + switch acct.Format { + case accountFormatV1: + accountFormatV1Count++ + + case accountFormatV2: + accountFormatV2Count++ + accountsInFormatV2 = append(accountsInFormatV2, acct.Address) + + default: + if acct.Address != "" { + log.Info().Msgf("found account without account register nor domain register: %x", acct.Address) + } + } } // Sort accounts by payload size in descending order @@ -38,6 +82,9 @@ func getAccountStatus( return cmp.Compare(b.PayloadSize, a.PayloadSize) }) + // Sort accounts in format v2 + slices.SortFunc(accountsInFormatV2, cmp.Compare) + stats := getValueStats(accountSizesSlice, percentiles) evmAccountAddress := systemcontracts.SystemContractsForChain(chainID).EVMStorage.Address @@ -45,10 +92,13 @@ func getAccountStatus( serviceAccountAddress := serviceAccountAddressForChain(chainID) return AccountStats{ - stats: stats, - ServiceAccount: accounts[string(serviceAccountAddress[:])], - EVMAccount: accounts[string(evmAccountAddress[:])], - TopN: accountsSlice[:flagTopN], + stats: stats, + FormatV1Count: accountFormatV1Count, + FormatV2Count: accountFormatV2Count, + AccountsInFormatV2: accountsInFormatV2, + ServiceAccount: accounts[string(serviceAccountAddress[:])], + EVMAccount: accounts[string(evmAccountAddress[:])], + TopN: accountsSlice[:flagTopN], } } diff --git a/cmd/util/cmd/checkpoint-collect-stats/cmd.go b/cmd/util/cmd/checkpoint-collect-stats/cmd.go index 232fad677d3..7bbf919a4e3 100644 --- a/cmd/util/cmd/checkpoint-collect-stats/cmd.go +++ b/cmd/util/cmd/checkpoint-collect-stats/cmd.go @@ -45,6 +45,12 @@ const ( accountStatsReportName = "account-stats" ) +const ( + // NOTE: this constant is defined in github.com/onflow/cadence/runtime/storage.go + // Use this contant directly from cadence runtime package after dependency is updated. + AccountStorageKey = "stored" +) + const ( domainTypePrefix = "domain " payloadChannelBufferSize = 100_000 @@ -97,7 +103,7 @@ func init() { "Enable memory profiling") } -type Stats struct { +type LedgerStats struct { LedgerStats *complete.LedgerStats `json:",omitempty"` PayloadStats *PayloadStats } @@ -206,6 +212,21 @@ func run(*cobra.Command, []string) { } account.PayloadCount++ account.PayloadSize += uint64(size) + + // Update account format + if isAccountRegister(key) { + if account.Format == accountFormatV1 { + log.Error().Msgf("found account register while domain register exists for %x", address) + } else { + account.Format = accountFormatV2 + } + } else if isDomainRegister(key) { + if account.Format == accountFormatV2 { + log.Error().Msgf("found domain register while account register exists for %x", address) + } else { + account.Format = accountFormatV1 + } + } } // At this point, all payload are processed. @@ -226,7 +247,7 @@ func run(*cobra.Command, []string) { return cmp.Compare(b.Size, a.Size) }) - stats := &Stats{ + stats := &LedgerStats{ LedgerStats: ledgerStats, PayloadStats: &PayloadStats{ TotalPayloadCount: totalPayloadCount, @@ -400,6 +421,18 @@ func isDomainType(typ string) bool { return strings.HasPrefix(typ, domainTypePrefix) } +func isDomainRegister(key ledger.Key) bool { + k := key.KeyParts[1].Value + kstr := string(k) + return slices.Contains(util.StorageMapDomains, kstr) +} + +func isAccountRegister(key ledger.Key) bool { + k := key.KeyParts[1].Value + kstr := string(k) + return kstr == AccountStorageKey +} + func getRegisterType(key ledger.Key) string { k := key.KeyParts[1].Value kstr := string(k) @@ -414,6 +447,8 @@ func getRegisterType(key ledger.Key) string { } switch kstr { + case AccountStorageKey: + return "account" case flow.ContractNamesKey: return "contract names" case flow.AccountStatusKey: diff --git a/cmd/util/cmd/checkpoint-collect-stats/stats_utils.go b/cmd/util/cmd/checkpoint-collect-stats/stats_utils.go index 3483ed1dc70..a45bea98219 100644 --- a/cmd/util/cmd/checkpoint-collect-stats/stats_utils.go +++ b/cmd/util/cmd/checkpoint-collect-stats/stats_utils.go @@ -17,8 +17,8 @@ type stats struct { Count uint64 `json:"count"` Sum float64 `json:"sum"` Min float64 `json:"min"` - Max float64 `json:"max"` Percentiles []percentileValue + Max float64 `json:"max"` } func getValueStats(values []float64, percentiles []float64) stats { From 72e6e6235fa52735213ac027443d351b3ba38efe Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Thu, 9 Jan 2025 13:00:16 +0200 Subject: [PATCH 4/6] Trigger OnLog tracer hooks upon successful call & tx results --- fvm/evm/emulator/emulator.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/fvm/evm/emulator/emulator.go b/fvm/evm/emulator/emulator.go index 9aa39df69ff..7bf11e22f91 100644 --- a/fvm/evm/emulator/emulator.go +++ b/fvm/evm/emulator/emulator.go @@ -127,6 +127,14 @@ func (bl *BlockView) DirectCall(call *types.DirectCall) (res *types.Result, err err == nil && res != nil { proc.evm.Config.Tracer.OnTxEnd(res.Receipt(), res.ValidationError) } + + // call OnLog tracer hook, upon successful call result + if proc.evm.Config.Tracer.OnLog != nil && + err == nil && res != nil { + for _, log := range res.Logs { + proc.evm.Config.Tracer.OnLog(log) + } + } }() } @@ -191,6 +199,15 @@ func (bl *BlockView) RunTransaction( proc.evm.Config.Tracer.OnTxEnd(res.Receipt(), res.ValidationError) } + // call OnLog tracer hook, upon successful tx result + if proc.evm.Config.Tracer != nil && + proc.evm.Config.Tracer.OnLog != nil && + res != nil { + for _, log := range res.Logs { + proc.evm.Config.Tracer.OnLog(log) + } + } + return res, nil } @@ -243,6 +260,15 @@ func (bl *BlockView) BatchRunTransactions(txs []*gethTypes.Transaction) ([]*type res != nil { proc.evm.Config.Tracer.OnTxEnd(res.Receipt(), res.ValidationError) } + + // call OnLog tracer hook, upon successful tx result + if proc.evm.Config.Tracer != nil && + proc.evm.Config.Tracer.OnLog != nil && + res != nil { + for _, log := range res.Logs { + proc.evm.Config.Tracer.OnLog(log) + } + } } // finalize after all the batch transactions are executed to save resources From 57c9b511d5f6c466ebb6bcc3e4040a790f331d3e Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Mon, 3 Feb 2025 13:16:43 -0800 Subject: [PATCH 5/6] update ci's lint action to latest version --- .github/workflows/ci.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a5dd0450e55..52c7cf8f516 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,14 +46,12 @@ jobs: run: go generate ./... working-directory: ${{ matrix.dir }} - name: Run golangci-lint - uses: golangci/golangci-lint-action@v3 + uses: golangci/golangci-lint-action@v6 with: # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version. version: v1.63 args: -v working-directory: ${{ matrix.dir }} - # https://github.com/golangci/golangci-lint-action/issues/244 - skip-cache: true tidy: name: Tidy From 2fb2a18b3f31facc21f337cd87f126be02a86242 Mon Sep 17 00:00:00 2001 From: Peter Argue <89119817+peterargue@users.noreply.github.com> Date: Mon, 3 Feb 2025 13:36:00 -0800 Subject: [PATCH 6/6] upgrade actions/*, retry, codecov --- .../test-monitor-process-results/action.yml | 4 +- .github/workflows/builds.yml | 4 +- .github/workflows/cd.yml | 4 +- .github/workflows/ci.yml | 58 +++++++++---------- .github/workflows/flaky-test-monitor.yml | 16 ++--- .github/workflows/tools.yml | 4 +- 6 files changed, 45 insertions(+), 45 deletions(-) diff --git a/.github/workflows/actions/test-monitor-process-results/action.yml b/.github/workflows/actions/test-monitor-process-results/action.yml index ea62e2f9c20..7565e6ab20e 100644 --- a/.github/workflows/actions/test-monitor-process-results/action.yml +++ b/.github/workflows/actions/test-monitor-process-results/action.yml @@ -42,13 +42,13 @@ runs: uses: 'google-github-actions/setup-gcloud@v2' - name: Upload results to BigQuery (skipped tests) - uses: nick-fields/retry@v2 + uses: nick-fields/retry@v3 with: timeout_minutes: 1 max_attempts: 3 command: bq load --source_format=NEWLINE_DELIMITED_JSON $BIGQUERY_DATASET.$BIGQUERY_TABLE $SKIPPED_TESTS_FILE tools/test_monitor/schemas/skipped_tests_schema.json - name: Upload results to BigQuery (test run) - uses: nick-fields/retry@v2 + uses: nick-fields/retry@v3 with: timeout_minutes: 2 max_attempts: 3 diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index e6932b42a15..29420e2a3a8 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -98,12 +98,12 @@ jobs: steps: - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version: ${{ env.GO_VERSION }} - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: ref: ${{ inputs.tag }} diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 8d11337f2c9..d9b29547058 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -24,12 +24,12 @@ jobs: environment: Production Docker Registry steps: - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 timeout-minutes: 10 # fail fast. sometimes this step takes an extremely long time with: go-version: ${{ env.GO_VERSION }} - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: ref: ${{ inputs.tag }} # Provide Google Service Account credentials to Github Action, allowing interaction with the Google Container Registry diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 52c7cf8f516..204731e8f3c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,9 +35,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 timeout-minutes: 10 # fail fast. sometimes this step takes an extremely long time with: go-version: ${{ env.GO_VERSION }} @@ -58,7 +58,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup private build environment if: ${{ vars.PRIVATE_BUILDS_SUPPORTED == 'true' }} @@ -67,7 +67,7 @@ jobs: cadence_deploy_key: ${{ secrets.CADENCE_DEPLOY_KEY }} - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 timeout-minutes: 10 # fail fast. sometimes this step takes an extremely long time with: go-version: ${{ env.GO_VERSION }} @@ -84,9 +84,9 @@ jobs: dynamic-matrix: ${{ steps.set-test-matrix.outputs.dynamicMatrix }} steps: - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 timeout-minutes: 10 # fail fast. sometimes this step takes an extremely long time with: go-version: ${{ env.GO_VERSION }} @@ -102,9 +102,9 @@ jobs: dynamic-matrix: ${{ steps.set-test-matrix.outputs.dynamicMatrix }} steps: - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 timeout-minutes: 10 # fail fast. sometimes this step takes an extremely long time with: go-version: ${{ env.GO_VERSION }} @@ -120,9 +120,9 @@ jobs: dynamic-matrix: ${{ steps.set-test-matrix.outputs.dynamicMatrix }} steps: - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 timeout-minutes: 10 # fail fast. sometimes this step takes an extremely long time with: go-version: ${{ env.GO_VERSION }} @@ -142,7 +142,7 @@ jobs: runs-on: ${{ matrix.targets.runner }} steps: - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup private build environment if: ${{ vars.PRIVATE_BUILDS_SUPPORTED == 'true' }} @@ -151,7 +151,7 @@ jobs: cadence_deploy_key: ${{ secrets.CADENCE_DEPLOY_KEY }} - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 timeout-minutes: 10 # fail fast. sometimes this step takes an extremely long time with: go-version: ${{ env.GO_VERSION }} @@ -159,7 +159,7 @@ jobs: - name: Setup tests (${{ matrix.targets.name }}) run: VERBOSE=1 make -e GO_TEST_PACKAGES="${{ matrix.targets.packages }}" install-tools - name: Run tests (${{ matrix.targets.name }}) - uses: nick-fields/retry@v2 + uses: nick-fields/retry@v3 with: timeout_minutes: 35 max_attempts: 5 @@ -168,7 +168,7 @@ jobs: #env: # RACE_DETECTOR: 1 - name: Upload coverage report - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@v5 timeout-minutes: 1 continue-on-error: true with: @@ -188,7 +188,7 @@ jobs: runs-on: ${{ matrix.targets.runner }} steps: - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup private build environment if: ${{ vars.PRIVATE_BUILDS_SUPPORTED == 'true' }} @@ -197,7 +197,7 @@ jobs: cadence_deploy_key: ${{ secrets.CADENCE_DEPLOY_KEY }} - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 timeout-minutes: 10 # fail fast. sometimes this step takes an extremely long time with: go-version: ${{ env.GO_VERSION }} @@ -205,7 +205,7 @@ jobs: - name: Setup tests (${{ matrix.targets.name }}) run: VERBOSE=1 make -e GO_TEST_PACKAGES="${{ matrix.targets.packages }}" install-tools - name: Run tests (${{ matrix.targets.name }}) - uses: nick-fields/retry@v2 + uses: nick-fields/retry@v3 with: timeout_minutes: 35 max_attempts: 5 @@ -214,7 +214,7 @@ jobs: #env: # RACE_DETECTOR: 1 - name: Upload coverage report - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@v5 timeout-minutes: 1 continue-on-error: true with: @@ -230,7 +230,7 @@ jobs: CADENCE_DEPLOY_KEY: ${{ secrets.CADENCE_DEPLOY_KEY }} steps: - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: # all tags are needed for integration tests fetch-depth: 0 @@ -242,7 +242,7 @@ jobs: cadence_deploy_key: ${{ secrets.CADENCE_DEPLOY_KEY }} - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 timeout-minutes: 10 # fail fast. sometimes this step takes an extremely long time with: go-version: ${{ env.GO_VERSION }} @@ -265,7 +265,7 @@ jobs: gcr.io/flow-container-registry/execution-corrupted:latest \ gcr.io/flow-container-registry/verification-corrupted:latest > flow-docker-images.tar - name: Cache Docker images - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: flow-docker-images.tar # use the workflow run id as part of the cache key to ensure these docker images will only be used for a single workflow run @@ -283,7 +283,7 @@ jobs: steps: - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup private build environment if: ${{ vars.PRIVATE_BUILDS_SUPPORTED == 'true' }} @@ -292,7 +292,7 @@ jobs: cadence_deploy_key: ${{ secrets.CADENCE_DEPLOY_KEY }} - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 timeout-minutes: 10 # fail fast. sometimes this step takes an extremely long time with: go-version: ${{ env.GO_VERSION }} @@ -300,7 +300,7 @@ jobs: - name: Setup tests (${{ matrix.targets.name }}) run: VERBOSE=1 make -e GO_TEST_PACKAGES="${{ matrix.targets.packages }}" install-tools - name: Run tests (${{ matrix.targets.name }}) - uses: nick-fields/retry@v2 + uses: nick-fields/retry@v3 with: timeout_minutes: 35 max_attempts: 5 @@ -309,7 +309,7 @@ jobs: #env: # RACE_DETECTOR: 1 - name: Upload coverage report - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@v5 timeout-minutes: 1 continue-on-error: true with: @@ -380,7 +380,7 @@ jobs: runs-on: ${{ matrix.runner }} steps: - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: # all tags are needed for integration tests fetch-depth: 0 @@ -392,13 +392,13 @@ jobs: cadence_deploy_key: ${{ secrets.CADENCE_DEPLOY_KEY }} - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 timeout-minutes: 10 # fail fast. sometimes this step takes an extremely long time with: go-version: ${{ env.GO_VERSION }} cache: true - name: Load cached Docker images - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: flow-docker-images.tar # use the same cache key as the docker-build job @@ -409,7 +409,7 @@ jobs: # TODO(rbtz): re-enable when we fix exisiting races. #env: # RACE_DETECTOR: 1 - uses: nick-fields/retry@v2 + uses: nick-fields/retry@v3 with: timeout_minutes: 35 max_attempts: 5 diff --git a/.github/workflows/flaky-test-monitor.yml b/.github/workflows/flaky-test-monitor.yml index e6ee0a4585f..96d1d6482fd 100644 --- a/.github/workflows/flaky-test-monitor.yml +++ b/.github/workflows/flaky-test-monitor.yml @@ -37,9 +37,9 @@ jobs: dynamic-matrix: ${{ steps.set-test-matrix.outputs.dynamicMatrix }} steps: - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version: ${{ env.GO_VERSION }} cache: true @@ -58,9 +58,9 @@ jobs: runs-on: ubuntu-20.04 steps: - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version: ${{ env.GO_VERSION }} cache: true @@ -100,9 +100,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version: ${{ env.GO_VERSION }} cache: true @@ -160,12 +160,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: # all tags are needed for integration tests fetch-depth: 0 - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version: ${{ env.GO_VERSION }} cache: true diff --git a/.github/workflows/tools.yml b/.github/workflows/tools.yml index 1a7327c3ea7..c8042af3d68 100644 --- a/.github/workflows/tools.yml +++ b/.github/workflows/tools.yml @@ -32,11 +32,11 @@ jobs: with: project_id: flow - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version: ${{ env.GO_VERSION }} - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: # to accurately get the version tag fetch-depth: 0