bloom9.go 1.0 KB
Newer Older
1
package types
2

O
obscuren 已提交
3 4
import (
	"math/big"
5

O
obscuren 已提交
6
	"github.com/ethereum/go-ethereum/crypto"
O
obscuren 已提交
7
	"github.com/ethereum/go-ethereum/common"
O
obscuren 已提交
8
	"github.com/ethereum/go-ethereum/state"
O
obscuren 已提交
9 10
)

O
obscuren 已提交
11
func CreateBloom(receipts Receipts) []byte {
O
obscuren 已提交
12
	bin := new(big.Int)
O
obscuren 已提交
13
	for _, receipt := range receipts {
O
obscuren 已提交
14
		bin.Or(bin, LogsBloom(receipt.logs))
15 16
	}

O
obscuren 已提交
17
	return common.LeftPadBytes(bin.Bytes(), 256)
18 19
}

O
obscuren 已提交
20
func LogsBloom(logs state.Logs) *big.Int {
O
obscuren 已提交
21
	bin := new(big.Int)
22
	for _, log := range logs {
23 24 25 26 27
		data := make([][]byte, len(log.Topics())+1)
		data[0] = log.Address()

		for i, topic := range log.Topics() {
			data[i+1] = topic
28
		}
29

30
		for _, b := range data {
O
obscuren 已提交
31
			bin.Or(bin, common.BigD(bloom9(crypto.Sha3(b)).Bytes()))
32 33 34 35 36 37
		}
	}

	return bin
}

O
obscuren 已提交
38 39
func bloom9(b []byte) *big.Int {
	r := new(big.Int)
O
obscuren 已提交
40 41

	for i := 0; i < 16; i += 2 {
O
obscuren 已提交
42
		t := big.NewInt(1)
O
obscuren 已提交
43
		b := uint(b[i+1]) + 1024*(uint(b[i])&1)
O
obscuren 已提交
44
		r.Or(r, t.Lsh(t, b))
45 46 47 48
	}

	return r
}
49 50

func BloomLookup(bin, topic []byte) bool {
O
obscuren 已提交
51
	bloom := common.BigD(bin)
52
	cmp := bloom9(crypto.Sha3(topic))
53 54 55

	return bloom.And(bloom, cmp).Cmp(cmp) == 0
}