github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/pkg/index/bloom_test.go (about)

     1  // Copyright 2021 The TrueBlocks Authors. All rights reserved.
     2  // Use of this source code is governed by a license that can
     3  // be found in the LICENSE file.
     4  
     5  package index
     6  
     7  import (
     8  	"fmt"
     9  	"testing"
    10  
    11  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/base"
    12  	"github.com/ethereum/go-ethereum/common/hexutil"
    13  )
    14  
    15  func Test_Bloom(t *testing.T) {
    16  	tests := []struct {
    17  		Addr   base.Address
    18  		Parts  [5]string
    19  		Values [5]uint32
    20  		Bits   [5]uint32
    21  		Insert bool
    22  	}{
    23  		{
    24  			Addr:   base.HexToAddress("0x0371a82e4a9d0a4312f3ee2ac9c6958512891372"),
    25  			Parts:  [5]string{"0371a82e", "4a9d0a43", "12f3ee2a", "c9c69585", "12891372"},
    26  			Values: [5]uint32{57780270, 1251805763, 317976106, 3385234821, 310973298},
    27  			Bits:   [5]uint32{108590, 854595, 257578, 431493, 594802},
    28  			Insert: true,
    29  		},
    30  		{
    31  			Addr:   base.HexToAddress("0x3d493c51a916f86d6d1c04824b3a7431e61a3ca3"),
    32  			Parts:  [5]string{"3d493c51", "a916f86d", "6d1c0482", "4b3a7431", "e61a3ca3"},
    33  			Values: [5]uint32{1028209745, 2836854893, 1830552706, 1262122033, 3860479139},
    34  			Bits:   [5]uint32{605265, 456813, 787586, 685105, 670883},
    35  			Insert: true,
    36  		},
    37  		{
    38  			Addr:   base.HexToAddress("0xe1c15164dcfe79431f8421b5a311a829cf0907f3"),
    39  			Parts:  [5]string{"e1c15164", "dcfe7943", "1f8421b5", "a311a829", "cf0907f3"},
    40  			Values: [5]uint32{3787542884, 3707664707, 528753077, 2735843369, 3473475571},
    41  			Bits:   [5]uint32{86372, 948547, 270773, 108585, 591859},
    42  			Insert: true,
    43  		},
    44  		{
    45  			Addr:   base.HexToAddress("0x1296d3bb6dc0efbae431a12939fc15b2823db49b"),
    46  			Parts:  [5]string{"1296d3bb", "6dc0efba", "e431a129", "39fc15b2", "823db49b"},
    47  			Values: [5]uint32{311874491, 1841360826, 3828457769, 972821938, 2185082011},
    48  			Bits:   [5]uint32{447419, 61370, 106793, 791986, 898203},
    49  			Insert: true,
    50  		},
    51  		{
    52  			Addr:   base.HexToAddress("0xd09022c48298f268c2c431dadb9ca4c2534d9c1c"),
    53  			Parts:  [5]string{"d09022c4", "8298f268", "c2c431da", "db9ca4c2", "534d9c1c"},
    54  			Values: [5]uint32{3499107012, 2191061608, 3267637722, 3684476098, 1397595164},
    55  			Bits:   [5]uint32{8900, 586344, 274906, 828610, 891932},
    56  			Insert: true,
    57  		},
    58  		{
    59  			Addr:   base.HexToAddress("0x1296d3bb6dc0efbae431a12939fc15b2823db79b"),
    60  			Parts:  [5]string{"1296d3bb", "6dc0efba", "e431a129", "39fc15b2", "823db79b"},
    61  			Values: [5]uint32{311874491, 1841360826, 3828457769, 972821938, 2185082779},
    62  			Bits:   [5]uint32{447419, 61370, 106793, 791986, 898971},
    63  			Insert: false,
    64  		},
    65  		{
    66  			Addr:   base.HexToAddress("0xd09022c48298f268c2c431dadb9ca4c2534d9c1e"),
    67  			Parts:  [5]string{"d09022c4", "8298f268", "c2c431da", "db9ca4c2", "534d9c1e"},
    68  			Values: [5]uint32{3499107012, 2191061608, 3267637722, 3684476098, 1397595166},
    69  			Bits:   [5]uint32{8900, 586344, 274906, 828610, 891934},
    70  			Insert: false,
    71  		},
    72  		{
    73  			Addr:   base.HexToAddress("0x0341a82e4a9d0a4312f3ee2ac9c6958512891342"),
    74  			Parts:  [5]string{"0341a82e", "4a9d0a43", "12f3ee2a", "c9c69585", "12891342"},
    75  			Values: [5]uint32{54634542, 1251805763, 317976106, 3385234821, 310973250},
    76  			Bits:   [5]uint32{108590, 854595, 257578, 431493, 594754},
    77  			Insert: false,
    78  		},
    79  		{
    80  			Addr:   base.HexToAddress("0x3d493c51a916f86d6d1c04824b3a4431e61a3ca3"),
    81  			Parts:  [5]string{"3d493c51", "a916f86d", "6d1c0482", "4b3a4431", "e61a3ca3"},
    82  			Values: [5]uint32{1028209745, 2836854893, 1830552706, 1262109745, 3860479139},
    83  			Bits:   [5]uint32{605265, 456813, 787586, 672817, 670883},
    84  			Insert: false,
    85  		},
    86  		{
    87  			Addr:   base.HexToAddress("0xe1c15164dcfe49431f8421b5a311a829cf0904f3"),
    88  			Parts:  [5]string{"e1c15164", "dcfe4943", "1f8421b5", "a311a829", "cf0904f3"},
    89  			Values: [5]uint32{3787542884, 3707652419, 528753077, 2735843369, 3473474803},
    90  			Bits:   [5]uint32{86372, 936259, 270773, 108585, 591091},
    91  			Insert: false,
    92  		},
    93  	}
    94  
    95  	bloom := Bloom{}
    96  	for _, tt := range tests {
    97  		if tt.Insert {
    98  			bloom.InsertAddress(tt.Addr)
    99  		}
   100  	}
   101  
   102  	expectedLit := []uint64{
   103  		8900, 61370, 86372, 106793, 108585, 108590, 257578,
   104  		270773, 274906, 431493, 447419, 456813, 586344, 591859,
   105  		594802, 605265, 670883, 685105, 787586, 791986, 828610,
   106  		854595, 891932, 898203, 948547,
   107  	}
   108  
   109  	nBlooms, nInserted, nBitsLit, nBitsNotLit, sz, bitsLit := bloom.getStats()
   110  	fmt.Println(nBlooms, nInserted, nBitsLit, nBitsNotLit, sz, bitsLit)
   111  
   112  	if len(bitsLit) != len(expectedLit) {
   113  		t.Error("mismatched lengths -- expected:", len(expectedLit), "got:", len(bitsLit))
   114  
   115  	} else {
   116  		for i, bit := range bitsLit {
   117  			if bit != expectedLit[i] {
   118  				t.Error("mismatched bit lit -- expected:", expectedLit[i], "got:", bitsLit[i])
   119  			}
   120  		}
   121  	}
   122  
   123  	for _, tt := range tests {
   124  		if tt.Insert && !bloom.isMemberBytes(tt.Addr) {
   125  			t.Error("address should be member, but isn't", tt.Addr.Hex())
   126  
   127  		} else if !tt.Insert && bloom.isMemberBytes(tt.Addr) { // && !tt.FalsePositive {
   128  			t.Error("address should not be member, but is (ignores false positives)", tt.Addr.Hex())
   129  		}
   130  
   131  		fmt.Println(hexutil.Encode(tt.Addr.Bytes()), bloom.isMemberBytes(tt.Addr))
   132  	}
   133  }
   134  
   135  func (bl *Bloom) getStats() (nBlooms uint64, nInserted uint64, nBitsLit uint64, nBitsNotLit uint64, sz uint64, bitsLit []uint64) {
   136  	bitsLit = []uint64{}
   137  	sz += 4
   138  	nBlooms = uint64(bl.Count)
   139  	for _, bf := range bl.Blooms {
   140  		nInserted += uint64(bf.NInserted)
   141  		sz += 4 + uint64(len(bf.Bytes))
   142  		for bitPos := 0; bitPos < len(bf.Bytes)*8; bitPos++ {
   143  			tester := bitChecker{bit: uint32(bitPos), bytes: bf.Bytes}
   144  			if bl.isBitLit(&tester) {
   145  				nBitsLit++
   146  				bitsLit = append(bitsLit, uint64(bitPos))
   147  			} else {
   148  				nBitsNotLit++
   149  				// fmt.Printf("%d", b)
   150  			}
   151  		}
   152  	}
   153  	return
   154  }
   155  
   156  func (bl *Bloom) isMemberBytes(addr base.Address) bool {
   157  	whichBits := bl.addressToBits(addr)
   158  	for _, bb := range bl.Blooms {
   159  		var tester = bitChecker{bytes: bb.Bytes, whichBits: whichBits}
   160  		if bl.isMember(&tester) {
   161  			return true
   162  		}
   163  	}
   164  	return false
   165  }