Skip to content

Instantly share code, notes, and snippets.

@mdehoog
Created December 23, 2023 02:03
Show Gist options
  • Select an option

  • Save mdehoog/7e59440e91ed208ecc6694ee338e7d86 to your computer and use it in GitHub Desktop.

Select an option

Save mdehoog/7e59440e91ed208ecc6694ee338e7d86 to your computer and use it in GitHub Desktop.
Calculate the total number of ones + non-ones across all txs
package main
import (
"bytes"
"fmt"
"time"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/node"
)
func main() {
nodeCfg := node.DefaultConfig
nodeCfg.Name = "geth"
nodeCfg.DataDir = "/data"
n, err := node.New(&nodeCfg)
if err != nil {
panic(err)
}
defer n.Close()
handles := utils.MakeDatabaseHandles(0)
db, err := n.OpenDatabaseWithFreezer("chaindata", 512, handles, "", "", true)
if err != nil {
panic(err)
}
defer db.Close()
printInterval := 60 * time.Second
ones := uint64(0)
zeroes := uint64(0)
length := uint64(0)
lastPrint := time.Now().Add(-printInterval)
i := uint64(1)
for ; ; i++ {
hash := rawdb.ReadCanonicalHash(db, i)
if bytes.Equal(hash.Bytes(), common.Hash{}.Bytes()) {
break
}
block := rawdb.ReadBlock(db, hash, i)
for _, tx := range block.Transactions() {
if tx.IsDepositTx() {
continue
}
buffer, err := tx.MarshalBinary()
if err != nil {
panic(err)
}
for _, b := range buffer {
if b == 0 {
zeroes++
} else {
ones++
}
}
length += uint64(flzCompressLen(buffer))
}
if time.Since(lastPrint) > printInterval {
lastPrint = time.Now()
fmt.Printf("%d,%d,%d,%d\n", i, zeroes, ones, length)
}
}
fmt.Printf("%d,%d,%d,%d\n", i, zeroes, ones, length)
}
func flzCompressLen(ib []byte) uint32 {
n := uint32(0)
ht := make([]uint32, 8192)
u24 := func(i uint32) uint32 {
return uint32(ib[i]) | (uint32(ib[i+1]) << 8) | (uint32(ib[i+2]) << 16)
}
cmp := func(p uint32, q uint32, e uint32) uint32 {
l := uint32(0)
for e -= q; l < e; l++ {
if ib[p+l] != ib[q+l] {
e = 0
}
}
return l
}
literals := func(r uint32) {
n += 0x21 * (r / 0x20)
r %= 0x20
if r != 0 {
n += r + 1
}
}
match := func(l uint32) {
l--
n += 3 * (l / 262)
if l%262 >= 6 {
n += 3
} else {
n += 2
}
}
hash := func(v uint32) uint32 {
return ((2654435769 * v) >> 19) & 0x1fff
}
setNextHash := func(ip uint32) uint32 {
ht[hash(u24(ip))] = ip
return ip + 1
}
a := uint32(0)
ipLimit := uint32(len(ib)) - 13
for ip := a + 2; ip < ipLimit; {
r := uint32(0)
d := uint32(0)
for {
s := u24(ip)
h := hash(s)
r = ht[h]
ht[h] = ip
d = ip - r
if ip >= ipLimit {
break
}
ip++
if d <= 0x1fff && s == u24(r) {
break
}
}
if ip >= ipLimit {
break
}
ip--
if ip > a {
literals(ip - a)
}
l := cmp(r+3, ip+3, ipLimit+9)
match(l)
ip = setNextHash(setNextHash(ip + l))
a = ip
}
literals(uint32(len(ib)) - a)
return n
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment