Ejemplo n.º 1
0
func (n *BitrieNode) ComputeHash() sha.Hash {
	var buffer [96]byte
	n.Bits.Canonicalize(buffer[0:32])
	copy(buffer[32:64], ads.Hash(n.Left).Bytes())
	copy(buffer[64:96], ads.Hash(n.Right).Bytes())
	return sha.Sum(buffer[:])
}
Ejemplo n.º 2
0
func (l *LogTreeNode) ComputeHash() sha.Hash {
	var buffer [68]byte
	binary.LittleEndian.PutUint32(buffer[0:4], uint32(l.Num))
	copy(buffer[4:36], ads.Hash(l.Left).Bytes())
	copy(buffer[36:68], ads.Hash(l.Right).Bytes())
	return sha.Sum(buffer[:])
}
Ejemplo n.º 3
0
func Hash(v ADS) sha.Hash {
	if h := v.CachedHash(); h != nil {
		return *h
	}

	hashable, ok := v.(Hashable)

	var hash sha.Hash
	if ok {
		hash = hashable.ComputeHash()
	} else {
		buffer := GetFromPool()
		defer ReturnToPool(buffer)

		e := Encoder{
			Writer:      buffer,
			Transparent: map[ADS]bool{v: true},
		}
		e.Encode(&v)
		hash = sha.Sum(buffer.Bytes())
	}

	v.SetCachedHash(hash)
	return hash
}
Ejemplo n.º 4
0
func (l *BitrieLeaf) ComputeHash() sha.Hash {
	var buffer [64]byte
	l.Bits.Canonicalize(buffer[0:32])
	if l.Value == nil {
		spew.Dump(l)
	}
	copy(buffer[32:64], ads.Hash(l.Value).Bytes())
	return sha.Sum(buffer[:])
}
Ejemplo n.º 5
0
func ProcessTxnImpl(txn *core.Transaction, txns, regs bitrie.Bitrie, c comp.C) (bitrie.Bitrie, bitrie.Bitrie) {
	c.Use(txn)

	txns = txns.Set(bitrie.MakeBits(txn.ComputeHash()), txn, c)

	if len(txn.MsgTx.TxOut) != 1 {
		return txns, regs
	}

	script := txn.MsgTx.TxOut[0].PkScript
	if len(script) < 1 || script[0] != btcscript.OP_RETURN {
		return txns, regs
	}

	data := script[1:]
	if len(data) != 40 {
		return txns, regs
	}

	if !bytes.Equal(data[0:8], tag) {
		return txns, regs
	}

	loc := bitrie.MakeBits(sha.Sum(data[8:40]))

	ads, found := regs.Get(loc, c)
	claim := ads.(*Claim)

	// two types of txns: register and transfer
	if len(txn.MsgTx.TxIn) == 1 {
		if found {
			return txns, regs
		}

		key := GetKey(txns, txn.MsgTx.TxIn[0].PreviousOutpoint, c)
		regs = regs.Set(loc, &Claim{Key: key}, c)
	}

	if len(txn.MsgTx.TxIn) == 2 {
		if !found {
			return txns, regs
		}

		from := GetKey(txns, txn.MsgTx.TxIn[0].PreviousOutpoint, c)

		if !bytes.Equal(from, claim.Key) {
			return txns, regs
		}

		to := GetKey(txns, txn.MsgTx.TxIn[1].PreviousOutpoint, c)
		regs = regs.Set(loc, &Claim{Key: to}, c)
	}

	return txns, regs
}
Ejemplo n.º 6
0
func ProcessOutputImpl(t *core.Transaction, output *btcwire.TxOut, txns bitrie.Bitrie, c comp.C) bitrie.Bitrie {
	hash := sha.Sum(output.PkScript)

	loc := bitrie.MakeBits(hash)

	x, found := txns.Get(loc, c)
	var tc *TxnChain
	if found {
		tc = x.(*TxnChain)
	} else {
		tc = nil
	}

	tc = &TxnChain{
		Next: tc,
		Txn:  t,
	}
	return txns.Set(loc, tc, c)
}
Ejemplo n.º 7
0
func doRound(elems []Hashable, volatileLeft, volatileRight bool, c comp.C) round {
	N := len(elems)
	kind := make([]int, N)

	left := 0
	right := N - 1

	hashes := make([]sha.Hash, N)
	for i := 0; i < N; i++ {
		hashes[i] = ads.Hash(elems[i])
	}

	for idx := uint(0); ; idx++ {
		if idx > 0 && idx%sha.Bits == 0 {
			for i := 0; i < N; i++ {
				hashes[i] = sha.Sum(hashes[i].Bytes())
			}
		}

		done := true

		if volatileLeft {
			if left < N && kind[left] == unknown && hashes[left].Bit(idx%sha.Bits) == 0 {
				kind[left] = leftFringe
				left++
			}

			if left < N && kind[left] == unknown {
				done = false
			}
		}

		if volatileRight {
			if right >= 0 && kind[right] == unknown && hashes[right].Bit(idx%sha.Bits) == 1 {
				kind[right] = rightFringe
				right--
			}

			if right >= 0 && kind[right] == unknown {
				done = false
			}
		}

		for j := 0; j < N-1; j++ {
			if kind[j] == unknown && kind[j+1] == unknown {
				if hashes[j].Bit(idx%sha.Bits) == 1 && hashes[j+1].Bit(idx%sha.Bits) == 0 {
					kind[j] = mergeLeft
					kind[j+1] = mergeRight
				} else {
					done = false
				}
			}
		}

		if done {
			break
		}
	}

	var r round
	for i := 0; i < N; i++ {
		switch kind[i] {
		case unknown:
			r.center = append(r.center, elems[i])
		case mergeLeft:
			r.center = append(r.center, elems[i].CombineWith(elems[i+1], c))
			i++
		case leftFringe:
			r.leftFringe = append(r.leftFringe, elems[i])
		case rightFringe:
			r.rightFringe = append(r.rightFringe, elems[i])
		}
	}
	return r
}
Ejemplo n.º 8
0
func (n *BitrieNil) ComputeHash() sha.Hash {
	return sha.Sum([]byte{})
}