// TestElkremBig makes a height 63 (max size possible) tree and tries 10K hashes func TestElkremBig(t *testing.T) { sndr := NewElkremSender(63, wire.DoubleSha256SH([]byte("elktest"))) rcv := NewElkremReceiver(63) SenderSerdesTest(t, &sndr) for n := uint64(0); n < 10000; n++ { sha, err := sndr.Next() if err != nil { t.Fatal(err) } err = rcv.AddNext(sha) if err != nil { t.Fatal(err) } if n%1000 == 999 { t.Logf("stack with %d received hashes\n", n+1) for i, n := range rcv.s { t.Logf("Stack element %d: index %d height %d %s\n", i, n.i, n.h, n.sha.String()) } } } SenderSerdesTest(t, &sndr) ReceiverSerdesTest(t, &rcv) for n := uint64(0); n < 10000; n += 500 { sha, err := rcv.AtIndex(n) if err != nil { t.Fatal(err) } t.Logf("Retreived index %d %s\n", n, sha.String()) } }
// Execute is the main entry point for the command. It's invoked by the parser. func (cmd *blockRegionCmd) Execute(args []string) error { // Setup the global config options and ensure they are valid. if err := setupGlobalConfig(); err != nil { return err } // Ensure expected arguments. if len(args) < 1 { return errors.New("required block hash parameter not specified") } if len(args) < 2 { return errors.New("required start offset parameter not " + "specified") } if len(args) < 3 { return errors.New("required region length parameter not " + "specified") } // Parse arguments. blockHash, err := wire.NewShaHashFromStr(args[0]) if err != nil { return err } startOffset, err := strconv.ParseUint(args[1], 10, 32) if err != nil { return err } regionLen, err := strconv.ParseUint(args[2], 10, 32) if err != nil { return err } // Load the block database. db, err := loadBlockDB() if err != nil { return err } defer db.Close() return db.View(func(tx database.Tx) error { log.Infof("Fetching block region %s<%d:%d>", blockHash, startOffset, startOffset+regionLen-1) region := database.BlockRegion{ Hash: blockHash, Offset: uint32(startOffset), Len: uint32(regionLen), } startTime := time.Now() regionBytes, err := tx.FetchBlockRegion(®ion) if err != nil { return err } log.Infof("Loaded block region in %v", time.Now().Sub(startTime)) log.Infof("Double SHA256: %s", wire.DoubleSha256SH(regionBytes)) log.Infof("Region Hex: %s", hex.EncodeToString(regionBytes)) return nil }) }
// HashMerkleBranches takes two hashes, treated as the left and right tree // nodes, and returns the hash of their concatenation. This is a helper // function used to aid in the generation of a merkle tree. func HashMerkleBranches(left *wire.ShaHash, right *wire.ShaHash) *wire.ShaHash { // Concatenate the left and right nodes. var sha [wire.HashSize * 2]byte copy(sha[:wire.HashSize], left[:]) copy(sha[wire.HashSize:], right[:]) newSha := wire.DoubleSha256SH(sha[:]) return &newSha }
func MakeMerkleParent(left *wire.ShaHash, right *wire.ShaHash) *wire.ShaHash { // dupes can screw things up; CVE-2012-2459. check for them if left != nil && right != nil && left.IsEqual(right) { fmt.Printf("DUP HASH CRASH") return nil } // if left child is nil, output nil. Need this for hard mode. if left == nil { return nil } // if right is nil, hash left with itself if right == nil { right = left } // Concatenate the left and right nodes var sha [64]byte copy(sha[:32], left[:]) copy(sha[32:], right[:]) newSha := wire.DoubleSha256SH(sha[:]) return &newSha }
// MakeMerkleParent ... func MakeMerkleParent(left *wire.ShaHash, right *wire.ShaHash) *wire.ShaHash { // this can screw things up; CVE-2012-2459 if left != nil && right != nil && left.IsEqual(right) { fmt.Printf("DUP HASH CRASH") return nil } // if left chils is nil, output nil. Shouldn't need this? if left == nil { fmt.Printf("L CRASH") return nil } // if right is nil, has left with itself if right == nil { right = left } // Concatenate the left and right nodes var sha [wire.HashSize * 2]byte copy(sha[:wire.HashSize], left[:]) copy(sha[wire.HashSize:], right[:]) newSha := wire.DoubleSha256SH(sha[:]) return &newSha }
// RightSha ... func RightSha(in wire.ShaHash) wire.ShaHash { return wire.DoubleSha256SH(append(in.Bytes(), 0x01)) // sha(sha(in, 1)) }
// LeftSha ... func LeftSha(in wire.ShaHash) wire.ShaHash { return wire.DoubleSha256SH(in.Bytes()) // left is sha(sha(in)) }