From 0d221d8b431c8a07e11f04cca6f57439741dd743 Mon Sep 17 00:00:00 2001 From: blindchaser Date: Fri, 27 Dec 2024 14:32:52 -0500 Subject: [PATCH 1/3] feat: evm state breakdown for StateKeyPrefix --- tools/cmd/seidb/operations/state_size.go | 62 ++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/tools/cmd/seidb/operations/state_size.go b/tools/cmd/seidb/operations/state_size.go index d8e6a1a..e82acbc 100644 --- a/tools/cmd/seidb/operations/state_size.go +++ b/tools/cmd/seidb/operations/state_size.go @@ -3,6 +3,8 @@ package operations import ( "encoding/json" "fmt" + "sort" + "strings" "github.com/sei-protocol/sei-db/common/logger" "github.com/sei-protocol/sei-db/sc/memiavl" @@ -87,6 +89,66 @@ func PrintStateSize(module string, db *memiavl.DB) error { fmt.Printf("Module %s prefix key size breakdown (bytes): %s \n", moduleName, prefixKeyResult) prefixValueResult, _ := json.MarshalIndent(valueSizeByPrefix, "", " ") fmt.Printf("Module %s prefix value size breakdown (bytes): %s \n", moduleName, prefixValueResult) + + if valueSizeByPrefix["03"] > 0 || keySizeByPrefix["03"] > 0 { + type contractSizeEntry struct { + Address string + KeySize int64 + ValueSize int64 + TotalSize int64 + KeyCount int + } + + contractSizes := make(map[string]*contractSizeEntry) + + // Scan again to collect per-contract statistics + tree.ScanPostOrder(func(node memiavl.Node) bool { + if node.IsLeaf() { + prefix := fmt.Sprintf("%X", node.Key()) + if prefix[:2] == "03" { + // Extract contract address from key (assuming it follows after "03") + addr := prefix[2:42] // Adjust indices based on your key format + if _, exists := contractSizes[addr]; !exists { + contractSizes[addr] = &contractSizeEntry{Address: addr} + } + entry := contractSizes[addr] + entry.KeySize += int64(len(node.Key())) + entry.ValueSize += int64(len(node.Value())) + entry.TotalSize = entry.KeySize + entry.ValueSize + entry.KeyCount++ + } + } + return true + }) + + // Convert to slice and sort + var sortedContracts []contractSizeEntry + for _, info := range contractSizes { + sortedContracts = append(sortedContracts, *info) + } + + sort.Slice(sortedContracts, func(i, j int) bool { + return sortedContracts[i].TotalSize > sortedContracts[j].TotalSize + }) + + fmt.Printf("\nDetailed breakdown for 0x03 prefix (top 20 contracts by total size):\n") + fmt.Printf("%-42s %15s %15s %15s %10s\n", "Contract Address", "Key Size", "Value Size", "Total Size", "Key Count") + fmt.Printf("%s\n", strings.Repeat("-", 100)) + + numToShow := 20 + if len(sortedContracts) < 20 { + numToShow = len(sortedContracts) + } + for i := 0; i < numToShow; i++ { + contract := sortedContracts[i] + fmt.Printf("0x%-40s %15d %15d %15d %10d\n", + contract.Address, + contract.KeySize, + contract.ValueSize, + contract.TotalSize, + contract.KeyCount) + } + } } } return nil From 6e401b956c591c2d8d9affe7b5b3698644cdf7e3 Mon Sep 17 00:00:00 2001 From: blindchaser Date: Mon, 30 Dec 2024 10:41:53 -0500 Subject: [PATCH 2/3] feat: state size print top 20 contracts by total size --- tools/cmd/seidb/operations/state_size.go | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/cmd/seidb/operations/state_size.go b/tools/cmd/seidb/operations/state_size.go index e82acbc..2e880d2 100644 --- a/tools/cmd/seidb/operations/state_size.go +++ b/tools/cmd/seidb/operations/state_size.go @@ -90,6 +90,7 @@ func PrintStateSize(module string, db *memiavl.DB) error { prefixValueResult, _ := json.MarshalIndent(valueSizeByPrefix, "", " ") fmt.Printf("Module %s prefix value size breakdown (bytes): %s \n", moduleName, prefixValueResult) + // Print top 20 contracts by total size if valueSizeByPrefix["03"] > 0 || keySizeByPrefix["03"] > 0 { type contractSizeEntry struct { Address string From 8b7eddfa3a9afa52fcf60f6fd773a1fa2bdc7032 Mon Sep 17 00:00:00 2001 From: blindchaser Date: Mon, 30 Dec 2024 17:07:31 -0500 Subject: [PATCH 3/3] fix --- tools/cmd/seidb/operations/state_size.go | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/tools/cmd/seidb/operations/state_size.go b/tools/cmd/seidb/operations/state_size.go index 2e880d2..e4cb90e 100644 --- a/tools/cmd/seidb/operations/state_size.go +++ b/tools/cmd/seidb/operations/state_size.go @@ -91,6 +91,7 @@ func PrintStateSize(module string, db *memiavl.DB) error { fmt.Printf("Module %s prefix value size breakdown (bytes): %s \n", moduleName, prefixValueResult) // Print top 20 contracts by total size + numToShow := 20 if valueSizeByPrefix["03"] > 0 || keySizeByPrefix["03"] > 0 { type contractSizeEntry struct { Address string @@ -122,22 +123,25 @@ func PrintStateSize(module string, db *memiavl.DB) error { return true }) - // Convert to slice and sort - var sortedContracts []contractSizeEntry - for _, info := range contractSizes { - sortedContracts = append(sortedContracts, *info) + // Convert map to slice in a deterministic way + var addresses []string + for addr := range contractSizes { + addresses = append(addresses, addr) } + // Sort the addresses + sort.Strings(addresses) - sort.Slice(sortedContracts, func(i, j int) bool { - return sortedContracts[i].TotalSize > sortedContracts[j].TotalSize - }) + // Use sorted addresses to build sortedContracts + var sortedContracts []contractSizeEntry + for _, addr := range addresses { + sortedContracts = append(sortedContracts, *contractSizes[addr]) + } fmt.Printf("\nDetailed breakdown for 0x03 prefix (top 20 contracts by total size):\n") fmt.Printf("%-42s %15s %15s %15s %10s\n", "Contract Address", "Key Size", "Value Size", "Total Size", "Key Count") fmt.Printf("%s\n", strings.Repeat("-", 100)) - numToShow := 20 - if len(sortedContracts) < 20 { + if len(sortedContracts) < numToShow { numToShow = len(sortedContracts) } for i := 0; i < numToShow; i++ {