Пример #1
0
func (t *LogTreap) Slice(start, end int32, c comp.C) *seqhash.Hash {
	if t == nil {
		return new(seqhash.Hash)
	}

	c.Use(t)

	if start <= 0 && end >= t.Num {
		return t.SeqHash(c)
	}

	leftCount := t.Left.Count(c)

	h := new(seqhash.Hash)
	if start < leftCount {
		h = seqhash.Merge(h, t.Left.Slice(start, end, c), c)
	}
	if start <= leftCount && end >= leftCount+1 {
		h = seqhash.Merge(h, seqhash.New(t.Value), c)
	}
	if end > leftCount+1 {
		h = seqhash.Merge(h, t.Right.Slice(start-leftCount-1, end-leftCount-1, c), c)
	}
	return h
}
Пример #2
0
func (l *BitrieLeaf) Set(b Bits, value ads.ADS, c comp.C) Bitrie {
	c.Use(l)

	s := SplitPoint(l.Bits, b)

	if s == b.Length {
		return &BitrieLeaf{
			Bits:  b,
			Value: value,
		}
	}

	left := &BitrieLeaf{
		Bits:  b.Cut(s+1, b.Length),
		Value: value,
	}
	right := &BitrieLeaf{
		Bits:  l.Bits.Cut(s+1, l.Bits.Length),
		Value: l.Value,
	}

	if b.Get(s) != 0 {
		left, right = right, left
	}

	return &BitrieNode{
		Bits:  b.Cut(0, s),
		Left:  left,
		Right: right,
	}
}
Пример #3
0
func ProcessTransactionImpl(transaction *Transaction, balances bitrie.Bitrie, c comp.C) bitrie.Bitrie {
	c.Use(transaction, balances)

	for _, input := range transaction.MsgTx.TxIn {
		if (input.PreviousOutpoint.Hash == btcwire.ShaHash{}) {
			continue
		}

		balances = ProcessOutpoint(input.PreviousOutpoint, balances, c)
	}

	loc := bitrie.MakeBits(ads.Hash(transaction))
	x, found := balances.Get(loc, c)
	var oi *OutpointInfo
	if found {
		oi = x.(*OutpointInfo)
	} else {
		oi = &OutpointInfo{}
	}

	c.Use(oi)

	oi = oi.Add(len(transaction.MsgTx.TxOut))
	return balances.Set(loc, oi, c)
}
Пример #4
0
func (h *Hash) Finish(c comp.C) Hashable {
	c.Use(h)

	if h.Empty() {
		return nil
	}

	left := make([]Hashable, 0)
	right := make([]Hashable, 0)

	for i := int8(0); i < h.Height; i++ {
		left = append(left, h.LeftFringes[i]...)
		right = append(h.RightFringes[i], right...)

		left = doRound(left, false, false, c).center
		right = doRound(right, false, false, c).center
	}

	elems := append(append(left, h.Top...), right...)
	for len(elems) > 1 {
		elems = doRound(elems, false, false, c).center
	}

	return elems[0]
}
Пример #5
0
func CombineTree(left, right LogTree, c comp.C) *LogTreeNode {
	c.Use(left, right)
	return &LogTreeNode{
		Num:   left.Count() + right.Count(),
		Left:  left,
		Right: right,
	}
}
Пример #6
0
func (l *LogEntry) Index(idx int32, c comp.C) *LogEntry {
	c.Use(l)

	if idx != 0 {
		panic(idx)
	}
	return l
}
Пример #7
0
func ProcessBlock(block *core.Block, txns, regs bitrie.Bitrie, c comp.C) (bitrie.Bitrie, bitrie.Bitrie) {
	c.Use(block)

	for _, txn := range block.Transactions {
		txns, regs = ProcessTxn(txn.(*core.Transaction), txns, regs, c)
	}

	return txns, regs
}
Пример #8
0
func (t *LogTreap) Count(c comp.C) int32 {
	if t == nil {
		return 0
	}

	c.Use(t)

	return t.Num
}
Пример #9
0
func (l *LogTreeNode) Index(idx int32, c comp.C) *LogEntry {
	c.Use(l)

	c.Use(l.Left)
	if idx < l.Left.Count() {
		return l.Left.Index(idx, c)
	}
	return l.Right.Index(idx-l.Left.Count(), c)
}
Пример #10
0
func ProcessTxnImpl(txn *core.Transaction, txns bitrie.Bitrie, c comp.C) bitrie.Bitrie {
	c.Use(txn)

	for _, output := range txn.MsgTx.TxOut {
		txns = ProcessOutput(txn, output, txns, c)
	}

	return txns
}
Пример #11
0
func ProcessBlock(block *Block, balances bitrie.Bitrie, c comp.C) bitrie.Bitrie {
	c.Use(block)

	for _, transaction := range block.Transactions {
		balances = ProcessTransaction(transaction.(*Transaction), balances, c)
	}

	return balances
}
Пример #12
0
func (l *BitrieLeaf) Delete(b Bits, c comp.C) Bitrie {
	c.Use(l)

	if SplitPoint(l.Bits, b) < l.Bits.Length {
		return l
	}

	return Nil
}
Пример #13
0
func (l *BitrieLeaf) Get(b Bits, c comp.C) (ads.ADS, bool) {
	c.Use(l)

	s := SplitPoint(l.Bits, b)

	if s == b.Length {
		return l.Value, true
	}
	return nil, false
}
Пример #14
0
func CalculateRegsImpl(block *core.Block, c comp.C) (bitrie.Bitrie, bitrie.Bitrie) {
	if block == nil {
		return bitrie.Nil, bitrie.Nil
	}

	c.Use(block)
	txns, regs := CalculateRegs(block.Previous, c)
	txns, regs = ProcessBlock(block, txns, regs, c)
	return txns, regs
}
Пример #15
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
}
Пример #16
0
func CalculateBalancesImpl(block *Block, c comp.C) bitrie.Bitrie {
	if block == nil {
		return bitrie.Nil
	}

	c.Use(block)
	balances := CalculateBalances(block.Previous, c)
	balances = ProcessBlock(block, balances, c)

	return balances
}
Пример #17
0
func CalculateTxnsImpl(block *core.Block, c comp.C) bitrie.Bitrie {
	if block == nil {
		return bitrie.Nil
	}

	c.Use(block)
	txns := CalculateTxns(block.Previous, c)
	txns = ProcessBlock(block, txns, c)

	return txns
}
Пример #18
0
// TODO: make sure seqhash is only encoded when merged != nil....
func (t *LogTreap) SeqHash(c comp.C) *seqhash.Hash {
	if t == nil {
		return new(seqhash.Hash)
	}

	c.Use(t)
	if t.Merged == nil {
		t.Merged = t.computeSeqHash(c)
	}

	return t.Merged
}
Пример #19
0
func BitrieSize(balances bitrie.Bitrie, c comp.C) int {
	c.Use(balances)

	if _, ok := balances.(*bitrie.BitrieLeaf); ok {
		return 1
	}

	if node, ok := balances.(*bitrie.BitrieNode); ok {
		return BitrieSize(node.Left, c) + BitrieSize(node.Right, c)
	}

	log.Panic("wut!")
	return 0
}
Пример #20
0
func (n *BitrieNode) Get(b Bits, c comp.C) (ads.ADS, bool) {
	c.Use(n)

	if SplitPoint(n.Bits, b) < n.Bits.Length {
		return nil, false
	}

	tail := b.Cut(n.Bits.Length+1, b.Length)

	if b.Get(n.Bits.Length) == 0 {
		return n.Left.Get(tail, c)
	} else {
		return n.Right.Get(tail, c)
	}
}
Пример #21
0
func CombineTreap(left, right *LogTreap, c comp.C) *LogTreap {
	if left == nil {
		return right
	} else if right == nil {
		return left
	}

	c.Use(left, right)

	if left.Priority > right.Priority {
		return left.UpdateRight(CombineTreap(left.Right, right, c), c)
	} else {
		return right.UpdateLeft(CombineTreap(left, right.Left, c), c)
	}
}
Пример #22
0
func (n *BitrieNode) Set(b Bits, value ads.ADS, c comp.C) Bitrie {
	c.Use(n)

	s := SplitPoint(n.Bits, b)

	if s < n.Bits.Length {
		var left, right Bitrie
		left = &BitrieLeaf{
			Bits:  b.Cut(s+1, b.Length),
			Value: value,
		}

		right = &BitrieNode{
			Bits:  n.Bits.Cut(s+1, n.Bits.Length),
			Left:  n.Left,
			Right: n.Right,
		}

		if b.Get(s) != 0 {
			left, right = right, left
		}

		return &BitrieNode{
			Bits:  n.Bits.Cut(0, s),
			Left:  left,
			Right: right,
		}
	} else {
		tail := b.Cut(n.Bits.Length+1, b.Length)

		if b.Get(n.Bits.Length) == 0 {
			newLeft := n.Left.Set(tail, value, c)
			return &BitrieNode{
				Bits:  n.Bits,
				Left:  newLeft,
				Right: n.Right,
			}
		} else {
			newRight := n.Right.Set(tail, value, c)
			return &BitrieNode{
				Bits:  n.Bits,
				Left:  n.Left,
				Right: newRight,
			}
		}
	}
}
Пример #23
0
func RandomKey(prefix bitrie.Bits, balances bitrie.Bitrie, c comp.C) bitrie.Bits {
	if leaf, ok := balances.(*bitrie.BitrieLeaf); ok {
		c.Use(leaf)
		return prefix.Cat(leaf.Bits)
	}

	if node, ok := balances.(*bitrie.BitrieNode); ok {
		c.Use(node)
		if rand.Intn(2) == 0 {
			return RandomKey(prefix.Cat(node.Bits).Append(0), node.Left, c)
		} else {
			return RandomKey(prefix.Cat(node.Bits).Append(1), node.Right, c)
		}
	}

	panic(balances)
}
Пример #24
0
func ProcessOutpointImpl(outpoint btcwire.OutPoint, balances bitrie.Bitrie, c comp.C) bitrie.Bitrie {
	loc := bitrie.MakeBits(sha.Hash(outpoint.Hash))

	x, found := balances.Get(loc, c)
	var oi *OutpointInfo
	if found {
		oi = x.(*OutpointInfo)
	} else {
		oi = &OutpointInfo{}
	}

	c.Use(oi)
	oi = oi.Spend(int(outpoint.Index))

	if oi.Empty() {
		return balances.Delete(loc, c)
	} else {
		return balances.Set(loc, oi, c)
	}
}
Пример #25
0
func Resolve(lt LogTree, c comp.C) (*LogEntry, error) {
	c.Use(lt)
	pos := lt.Count() - 1

	expected := make([]*LogEntry, 0)

	for {
		if pos == -1 {
			return nil, nil
		}

		entry := lt.Index(pos, c)
		expected = append(expected, entry)

		c.Use(entry)
		if entry.Type == FunctionEntry {
			break
		} else {
			pos -= entry.Length
			entryEntry := lt.Index(pos, c)
			expected = append(expected, entryEntry)
			pos--
		}
	}

	n := len(expected)
	for i := 0; i < n/2; i++ {
		expected[i], expected[n-1-i] = expected[n-1-i], expected[i]
	}

	resolveC := ResolveC{
		Outer:    c,
		Expected: expected,
	}

	return resolveC.Resolve()
}
Пример #26
0
func Dump(prefix bitrie.Bits, balances bitrie.Bitrie, c comp.C) {
	if leaf, ok := balances.(*bitrie.BitrieLeaf); ok {
		c.Use(leaf)
		c.Use(leaf.Value)
		fmt.Printf("%v: %v\n", hex.EncodeToString(prefix.Cat(leaf.Bits).Bits), leaf.Value.(*OutpointInfo).Count)
	}

	if node, ok := balances.(*bitrie.BitrieNode); ok {
		c.Use(node)
		Dump(prefix.Cat(node.Bits).Append(0), node.Left, c)
		Dump(prefix.Cat(node.Bits).Append(1), node.Right, c)
	}
}
Пример #27
0
func (n *BitrieNode) Delete(b Bits, c comp.C) Bitrie {
	c.Use(n)

	if SplitPoint(n.Bits, b) < n.Bits.Length {
		return n
	}

	tail := b.Cut(n.Bits.Length+1, b.Length)
	if b.Get(n.Bits.Length) == 0 {
		newLeft := n.Left.Delete(tail, c)

		if _, isNil := newLeft.(*BitrieNil); isNil {
			c.Use(n.Right)
			return n.Right.prepend(n.Bits.Append(1))
		} else {
			return &BitrieNode{
				Bits:  n.Bits,
				Left:  newLeft,
				Right: n.Right,
			}
		}
	} else {
		newRight := n.Right.Delete(tail, c)

		if _, isNil := newRight.(*BitrieNil); isNil {
			c.Use(n.Left)
			return n.Left.prepend(n.Bits.Append(0))
		} else {
			return &BitrieNode{
				Bits:  n.Bits,
				Left:  n.Left,
				Right: newRight,
			}
		}
	}
}
Пример #28
0
func Merge(left, right *Hash, c comp.C) *Hash {
	if left != nil {
		c.Use(left)
	}

	if right != nil {
		c.Use(right)
	}

	if left.Empty() {
		return right
	}

	if right.Empty() {
		return left
	}

	Calls++

	merged := Hash{}

	elems := make([]Hashable, 0)

	for {
		if merged.Height < left.Height {
			elems = append(left.RightFringes[merged.Height], elems...)
		} else if merged.Height == left.Height {
			elems = append(left.Top, elems...)
		}

		if merged.Height < right.Height {
			elems = append(elems, right.LeftFringes[merged.Height]...)
		} else if merged.Height == right.Height {
			elems = append(elems, right.Top...)
		}

		if merged.Height >= left.Height && merged.Height >= right.Height && len(elems) == 0 {
			break
		}

		round := doRound(elems, merged.Height >= left.Height, merged.Height >= right.Height, c)
		elems = round.center

		if merged.Height < left.Height {
			merged.LeftFringes = append(merged.LeftFringes, left.LeftFringes[merged.Height])
		} else {
			merged.LeftFringes = append(merged.LeftFringes, round.leftFringe)
		}

		if merged.Height < right.Height {
			merged.RightFringes = append(merged.RightFringes, right.RightFringes[merged.Height])
		} else {
			merged.RightFringes = append(merged.RightFringes, round.rightFringe)
		}

		merged.Height++
	}

	merged.Height--
	merged.Top = append(merged.LeftFringes[merged.Height], merged.RightFringes[merged.Height]...)
	merged.LeftFringes = merged.LeftFringes[:merged.Height]
	merged.RightFringes = merged.RightFringes[:merged.Height]

	return &merged
}
Пример #29
0
func Fib(i int64, c comp.C) int64 {
	return c.Call(fib, i)[0].(int64)
}
Пример #30
0
func CalculateBalances(block *Block, c comp.C) bitrie.Bitrie {
	return c.Call(CalculateBalancesImpl, block)[0].(bitrie.Bitrie)
}