change.ClaimID and OutPoint types changed

This commit is contained in:
Brannon King 2021-07-19 16:59:28 -04:00 committed by Roy Lee
parent b6cf5f2665
commit 9937f66b6a
14 changed files with 229 additions and 163 deletions

View file

@ -11,6 +11,7 @@ import (
"github.com/btcsuite/btcutil" "github.com/btcsuite/btcutil"
"github.com/btcsuite/btcd/claimtrie" "github.com/btcsuite/btcd/claimtrie"
"github.com/btcsuite/btcd/claimtrie/change"
"github.com/btcsuite/btcd/claimtrie/node" "github.com/btcsuite/btcd/claimtrie/node"
) )
@ -76,17 +77,17 @@ func (h *handler) handleTxIns(ct *claimtrie.ClaimTrie) error {
return err return err
} }
var id node.ClaimID var id change.ClaimID
name := cs.Name() // name of the previous one (that we're now spending) name := cs.Name() // name of the previous one (that we're now spending)
switch cs.Opcode() { switch cs.Opcode() {
case txscript.OP_CLAIMNAME: // OP code from previous transaction case txscript.OP_CLAIMNAME: // OP code from previous transaction
id = node.NewClaimID(op) // claimID of the previous item now being spent id = change.NewClaimID(op) // claimID of the previous item now being spent
h.spent[id.String()] = node.NormalizeIfNecessary(name, ct.Height()) h.spent[id.Key()] = node.NormalizeIfNecessary(name, ct.Height())
err = ct.SpendClaim(name, op, id) err = ct.SpendClaim(name, op, id)
case txscript.OP_UPDATECLAIM: case txscript.OP_UPDATECLAIM:
copy(id[:], cs.ClaimID()) copy(id[:], cs.ClaimID())
h.spent[id.String()] = node.NormalizeIfNecessary(name, ct.Height()) h.spent[id.Key()] = node.NormalizeIfNecessary(name, ct.Height())
err = ct.SpendClaim(name, op, id) err = ct.SpendClaim(name, op, id)
case txscript.OP_SUPPORTCLAIM: case txscript.OP_SUPPORTCLAIM:
copy(id[:], cs.ClaimID()) copy(id[:], cs.ClaimID())
@ -101,7 +102,7 @@ func (h *handler) handleTxIns(ct *claimtrie.ClaimTrie) error {
func (h *handler) handleTxOuts(ct *claimtrie.ClaimTrie) error { func (h *handler) handleTxOuts(ct *claimtrie.ClaimTrie) error {
for i, txOut := range h.tx.MsgTx().TxOut { for i, txOut := range h.tx.MsgTx().TxOut {
op := wire.NewOutPoint(h.tx.Hash(), uint32(i)) op := *wire.NewOutPoint(h.tx.Hash(), uint32(i))
cs, err := txscript.DecodeClaimScript(txOut.PkScript) cs, err := txscript.DecodeClaimScript(txOut.PkScript)
if err == txscript.ErrNotClaimScript { if err == txscript.ErrNotClaimScript {
continue continue
@ -110,31 +111,31 @@ func (h *handler) handleTxOuts(ct *claimtrie.ClaimTrie) error {
return err return err
} }
var id node.ClaimID var id change.ClaimID
name := cs.Name() name := cs.Name()
amt := txOut.Value amt := txOut.Value
value := cs.Value() value := cs.Value()
switch cs.Opcode() { switch cs.Opcode() {
case txscript.OP_CLAIMNAME: case txscript.OP_CLAIMNAME:
id = node.NewClaimID(*op) id = change.NewClaimID(op)
err = ct.AddClaim(name, *op, id, amt, value) err = ct.AddClaim(name, op, id, amt, value)
case txscript.OP_SUPPORTCLAIM: case txscript.OP_SUPPORTCLAIM:
copy(id[:], cs.ClaimID()) copy(id[:], cs.ClaimID())
err = ct.AddSupport(name, value, *op, amt, id) err = ct.AddSupport(name, value, op, amt, id)
case txscript.OP_UPDATECLAIM: case txscript.OP_UPDATECLAIM:
// old code wouldn't run the update if name or claimID didn't match existing data // old code wouldn't run the update if name or claimID didn't match existing data
// that was a safety feature, but it should have rejected the transaction instead // that was a safety feature, but it should have rejected the transaction instead
// TODO: reject transactions with invalid update commands // TODO: reject transactions with invalid update commands
copy(id[:], cs.ClaimID()) copy(id[:], cs.ClaimID())
normName := node.NormalizeIfNecessary(name, ct.Height()) normName := node.NormalizeIfNecessary(name, ct.Height())
if !bytes.Equal(h.spent[id.String()], normName) { if !bytes.Equal(h.spent[id.Key()], normName) {
fmt.Printf("Invalid update operation: name or ID mismatch for %s, %s\n", normName, id.String()) fmt.Printf("Invalid update operation: name or ID mismatch for %s, %s\n", normName, id.String())
continue continue
} }
delete(h.spent, id.String()) delete(h.spent, id.Key())
err = ct.UpdateClaim(name, *op, amt, id, value) err = ct.UpdateClaim(name, op, amt, id, value)
} }
if err != nil { if err != nil {
return errors.Wrapf(err, "handleTxOuts") return errors.Wrapf(err, "handleTxOuts")

View file

@ -1,5 +1,7 @@
package change package change
import "github.com/btcsuite/btcd/wire"
type ChangeType int type ChangeType int
const ( const (
@ -15,8 +17,8 @@ type Change struct {
Height int32 Height int32
Name []byte Name []byte
ClaimID string // TODO: can we store this and OutPoint as bytes? ClaimID ClaimID
OutPoint string OutPoint wire.OutPoint
Amount int64 Amount int64
Value []byte Value []byte
@ -26,7 +28,7 @@ type Change struct {
SpentChildren map[string]bool SpentChildren map[string]bool
} }
func New(typ ChangeType) Change { func NewChange(typ ChangeType) Change {
return Change{Type: typ} return Change{Type: typ}
} }
@ -36,17 +38,12 @@ func (c Change) SetHeight(height int32) Change {
} }
func (c Change) SetName(name []byte) Change { func (c Change) SetName(name []byte) Change {
c.Name = name c.Name = name // need to clone it?
return c return c
} }
func (c Change) SetClaimID(claimID string) Change { func (c Change) SetOutPoint(op *wire.OutPoint) Change {
c.ClaimID = claimID c.OutPoint = *op
return c
}
func (c Change) SetOutPoint(op string) Change {
c.OutPoint = op
return c return c
} }

View file

@ -0,0 +1,51 @@
package change
import (
"encoding/binary"
"encoding/hex"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
)
// ClaimID represents a Claim's ClaimID.
type ClaimID [20]byte
// NewClaimID returns a Claim ID calculated from Ripemd160(Sha256(OUTPOINT).
func NewClaimID(op wire.OutPoint) (id ClaimID) {
var buffer [chainhash.HashSize + 4]byte // hoping for stack alloc
copy(buffer[:], op.Hash[:])
binary.BigEndian.PutUint32(buffer[chainhash.HashSize:], op.Index)
copy(id[:], btcutil.Hash160(buffer[:]))
return id
}
// NewIDFromString returns a Claim ID from a string.
func NewIDFromString(s string) (id ClaimID, err error) {
if len(s) == 40 {
_, err = hex.Decode(id[:], []byte(s))
} else {
copy(id[:], s)
}
for i, j := 0, len(id)-1; i < j; i, j = i+1, j-1 {
id[i], id[j] = id[j], id[i]
}
return id, err
}
// Key is for in-memory maps
func (id ClaimID) Key() string {
return string(id[:])
}
// String is for anything written to a DB
func (id ClaimID) String() string {
for i, j := 0, len(id)-1; i < j; i, j = i+1, j-1 {
id[i], id[j] = id[j], id[i]
}
return hex.EncodeToString(id[:])
}

View file

@ -161,14 +161,14 @@ func New(cfg config.Config) (*ClaimTrie, error) {
} }
// AddClaim adds a Claim to the ClaimTrie. // AddClaim adds a Claim to the ClaimTrie.
func (ct *ClaimTrie) AddClaim(name []byte, op wire.OutPoint, id node.ClaimID, amt int64, val []byte) error { func (ct *ClaimTrie) AddClaim(name []byte, op wire.OutPoint, id change.ClaimID, amt int64, val []byte) error {
chg := change.Change{ chg := change.Change{
Type: change.AddClaim, Type: change.AddClaim,
Name: name, Name: name,
OutPoint: op.String(), OutPoint: op,
Amount: amt, Amount: amt,
ClaimID: id.String(), ClaimID: id,
Value: val, Value: val,
} }
@ -176,14 +176,14 @@ func (ct *ClaimTrie) AddClaim(name []byte, op wire.OutPoint, id node.ClaimID, am
} }
// UpdateClaim updates a Claim in the ClaimTrie. // UpdateClaim updates a Claim in the ClaimTrie.
func (ct *ClaimTrie) UpdateClaim(name []byte, op wire.OutPoint, amt int64, id node.ClaimID, val []byte) error { func (ct *ClaimTrie) UpdateClaim(name []byte, op wire.OutPoint, amt int64, id change.ClaimID, val []byte) error {
chg := change.Change{ chg := change.Change{
Type: change.UpdateClaim, Type: change.UpdateClaim,
Name: name, Name: name,
OutPoint: op.String(), OutPoint: op,
Amount: amt, Amount: amt,
ClaimID: id.String(), ClaimID: id,
Value: val, Value: val,
} }
@ -191,27 +191,27 @@ func (ct *ClaimTrie) UpdateClaim(name []byte, op wire.OutPoint, amt int64, id no
} }
// SpendClaim spends a Claim in the ClaimTrie. // SpendClaim spends a Claim in the ClaimTrie.
func (ct *ClaimTrie) SpendClaim(name []byte, op wire.OutPoint, id node.ClaimID) error { func (ct *ClaimTrie) SpendClaim(name []byte, op wire.OutPoint, id change.ClaimID) error {
chg := change.Change{ chg := change.Change{
Type: change.SpendClaim, Type: change.SpendClaim,
Name: name, Name: name,
OutPoint: op.String(), OutPoint: op,
ClaimID: id.String(), ClaimID: id,
} }
return ct.forwardNodeChange(chg) return ct.forwardNodeChange(chg)
} }
// AddSupport adds a Support to the ClaimTrie. // AddSupport adds a Support to the ClaimTrie.
func (ct *ClaimTrie) AddSupport(name []byte, value []byte, op wire.OutPoint, amt int64, id node.ClaimID) error { func (ct *ClaimTrie) AddSupport(name []byte, value []byte, op wire.OutPoint, amt int64, id change.ClaimID) error {
chg := change.Change{ chg := change.Change{
Type: change.AddSupport, Type: change.AddSupport,
Name: name, Name: name,
OutPoint: op.String(), OutPoint: op,
Amount: amt, Amount: amt,
ClaimID: id.String(), ClaimID: id,
Value: value, Value: value,
} }
@ -219,13 +219,13 @@ func (ct *ClaimTrie) AddSupport(name []byte, value []byte, op wire.OutPoint, amt
} }
// SpendSupport spends a Support in the ClaimTrie. // SpendSupport spends a Support in the ClaimTrie.
func (ct *ClaimTrie) SpendSupport(name []byte, op wire.OutPoint, id node.ClaimID) error { func (ct *ClaimTrie) SpendSupport(name []byte, op wire.OutPoint, id change.ClaimID) error {
chg := change.Change{ chg := change.Change{
Type: change.SpendSupport, Type: change.SpendSupport,
Name: name, Name: name,
OutPoint: op.String(), OutPoint: op,
ClaimID: id.String(), ClaimID: id,
} }
return ct.forwardNodeChange(chg) return ct.forwardNodeChange(chg)

View file

@ -3,9 +3,9 @@ package claimtrie
import ( import (
"testing" "testing"
"github.com/btcsuite/btcd/claimtrie/change"
"github.com/btcsuite/btcd/claimtrie/config" "github.com/btcsuite/btcd/claimtrie/config"
"github.com/btcsuite/btcd/claimtrie/merkletrie" "github.com/btcsuite/btcd/claimtrie/merkletrie"
"github.com/btcsuite/btcd/claimtrie/node"
"github.com/btcsuite/btcd/claimtrie/param" "github.com/btcsuite/btcd/claimtrie/param"
"github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/chaincfg/chainhash"
@ -52,16 +52,16 @@ func TestFixedHashes(t *testing.T) {
tx3 := buildTx(tx2.TxHash()) tx3 := buildTx(tx2.TxHash())
tx4 := buildTx(tx3.TxHash()) tx4 := buildTx(tx3.TxHash())
err = ct.AddClaim(b("test"), tx1.TxIn[0].PreviousOutPoint, node.NewClaimID(tx1.TxIn[0].PreviousOutPoint), 50, nil) err = ct.AddClaim(b("test"), tx1.TxIn[0].PreviousOutPoint, change.NewClaimID(tx1.TxIn[0].PreviousOutPoint), 50, nil)
r.NoError(err) r.NoError(err)
err = ct.AddClaim(b("test2"), tx2.TxIn[0].PreviousOutPoint, node.NewClaimID(tx2.TxIn[0].PreviousOutPoint), 50, nil) err = ct.AddClaim(b("test2"), tx2.TxIn[0].PreviousOutPoint, change.NewClaimID(tx2.TxIn[0].PreviousOutPoint), 50, nil)
r.NoError(err) r.NoError(err)
err = ct.AddClaim(b("test"), tx3.TxIn[0].PreviousOutPoint, node.NewClaimID(tx3.TxIn[0].PreviousOutPoint), 50, nil) err = ct.AddClaim(b("test"), tx3.TxIn[0].PreviousOutPoint, change.NewClaimID(tx3.TxIn[0].PreviousOutPoint), 50, nil)
r.NoError(err) r.NoError(err)
err = ct.AddClaim(b("tes"), tx4.TxIn[0].PreviousOutPoint, node.NewClaimID(tx4.TxIn[0].PreviousOutPoint), 50, nil) err = ct.AddClaim(b("tes"), tx4.TxIn[0].PreviousOutPoint, change.NewClaimID(tx4.TxIn[0].PreviousOutPoint), 50, nil)
r.NoError(err) r.NoError(err)
err = ct.AppendBlock() err = ct.AppendBlock()
@ -89,27 +89,27 @@ func TestNormalizationFork(t *testing.T) {
hash := chainhash.HashH([]byte{1, 2, 3}) hash := chainhash.HashH([]byte{1, 2, 3})
o1 := wire.OutPoint{Hash: hash, Index: 1} o1 := wire.OutPoint{Hash: hash, Index: 1}
err = ct.AddClaim([]byte("AÑEJO"), o1, node.NewClaimID(o1), 10, nil) err = ct.AddClaim([]byte("AÑEJO"), o1, change.NewClaimID(o1), 10, nil)
r.NoError(err) r.NoError(err)
o2 := wire.OutPoint{Hash: hash, Index: 2} o2 := wire.OutPoint{Hash: hash, Index: 2}
err = ct.AddClaim([]byte("AÑejo"), o2, node.NewClaimID(o2), 5, nil) err = ct.AddClaim([]byte("AÑejo"), o2, change.NewClaimID(o2), 5, nil)
r.NoError(err) r.NoError(err)
o3 := wire.OutPoint{Hash: hash, Index: 3} o3 := wire.OutPoint{Hash: hash, Index: 3}
err = ct.AddClaim([]byte("あてはまる"), o3, node.NewClaimID(o3), 5, nil) err = ct.AddClaim([]byte("あてはまる"), o3, change.NewClaimID(o3), 5, nil)
r.NoError(err) r.NoError(err)
o4 := wire.OutPoint{Hash: hash, Index: 4} o4 := wire.OutPoint{Hash: hash, Index: 4}
err = ct.AddClaim([]byte("Aḿlie"), o4, node.NewClaimID(o4), 5, nil) err = ct.AddClaim([]byte("Aḿlie"), o4, change.NewClaimID(o4), 5, nil)
r.NoError(err) r.NoError(err)
o5 := wire.OutPoint{Hash: hash, Index: 5} o5 := wire.OutPoint{Hash: hash, Index: 5}
err = ct.AddClaim([]byte("TEST"), o5, node.NewClaimID(o5), 5, nil) err = ct.AddClaim([]byte("TEST"), o5, change.NewClaimID(o5), 5, nil)
r.NoError(err) r.NoError(err)
o6 := wire.OutPoint{Hash: hash, Index: 6} o6 := wire.OutPoint{Hash: hash, Index: 6}
err = ct.AddClaim([]byte("test"), o6, node.NewClaimID(o6), 7, nil) err = ct.AddClaim([]byte("test"), o6, change.NewClaimID(o6), 7, nil)
r.NoError(err) r.NoError(err)
err = ct.AppendBlock() err = ct.AppendBlock()
@ -122,7 +122,7 @@ func TestNormalizationFork(t *testing.T) {
r.Equal(int32(1), n.TakenOverAt) r.Equal(int32(1), n.TakenOverAt)
o7 := wire.OutPoint{Hash: hash, Index: 7} o7 := wire.OutPoint{Hash: hash, Index: 7}
err = ct.AddClaim([]byte("aÑEJO"), o7, node.NewClaimID(o7), 8, nil) err = ct.AddClaim([]byte("aÑEJO"), o7, change.NewClaimID(o7), 8, nil)
r.NoError(err) r.NoError(err)
err = ct.AppendBlock() err = ct.AppendBlock()
@ -153,7 +153,7 @@ func TestActivationsOnNormalizationFork(t *testing.T) {
hash := chainhash.HashH([]byte{1, 2, 3}) hash := chainhash.HashH([]byte{1, 2, 3})
o7 := wire.OutPoint{Hash: hash, Index: 7} o7 := wire.OutPoint{Hash: hash, Index: 7}
err = ct.AddClaim([]byte("A"), o7, node.NewClaimID(o7), 1, nil) err = ct.AddClaim([]byte("A"), o7, change.NewClaimID(o7), 1, nil)
r.NoError(err) r.NoError(err)
err = ct.AppendBlock() err = ct.AppendBlock()
r.NoError(err) r.NoError(err)
@ -164,7 +164,7 @@ func TestActivationsOnNormalizationFork(t *testing.T) {
verifyBestIndex(t, ct, "A", 7, 1) verifyBestIndex(t, ct, "A", 7, 1)
o8 := wire.OutPoint{Hash: hash, Index: 8} o8 := wire.OutPoint{Hash: hash, Index: 8}
err = ct.AddClaim([]byte("A"), o8, node.NewClaimID(o8), 2, nil) err = ct.AddClaim([]byte("A"), o8, change.NewClaimID(o8), 2, nil)
r.NoError(err) r.NoError(err)
err = ct.AppendBlock() err = ct.AppendBlock()
r.NoError(err) r.NoError(err)
@ -199,15 +199,15 @@ func TestNormalizationSortOrder(t *testing.T) {
hash := chainhash.HashH([]byte{1, 2, 3}) hash := chainhash.HashH([]byte{1, 2, 3})
o1 := wire.OutPoint{Hash: hash, Index: 1} o1 := wire.OutPoint{Hash: hash, Index: 1}
err = ct.AddClaim([]byte("A"), o1, node.NewClaimID(o1), 1, nil) err = ct.AddClaim([]byte("A"), o1, change.NewClaimID(o1), 1, nil)
r.NoError(err) r.NoError(err)
o2 := wire.OutPoint{Hash: hash, Index: 2} o2 := wire.OutPoint{Hash: hash, Index: 2}
err = ct.AddClaim([]byte("A"), o2, node.NewClaimID(o2), 2, nil) err = ct.AddClaim([]byte("A"), o2, change.NewClaimID(o2), 2, nil)
r.NoError(err) r.NoError(err)
o3 := wire.OutPoint{Hash: hash, Index: 3} o3 := wire.OutPoint{Hash: hash, Index: 3}
err = ct.AddClaim([]byte("a"), o3, node.NewClaimID(o3), 3, nil) err = ct.AddClaim([]byte("a"), o3, change.NewClaimID(o3), 3, nil)
r.NoError(err) r.NoError(err)
err = ct.AppendBlock() err = ct.AppendBlock()
@ -246,11 +246,11 @@ func TestRebuild(t *testing.T) {
hash := chainhash.HashH([]byte{1, 2, 3}) hash := chainhash.HashH([]byte{1, 2, 3})
o1 := wire.OutPoint{Hash: hash, Index: 1} o1 := wire.OutPoint{Hash: hash, Index: 1}
err = ct.AddClaim([]byte("test1"), o1, node.NewClaimID(o1), 1, nil) err = ct.AddClaim([]byte("test1"), o1, change.NewClaimID(o1), 1, nil)
r.NoError(err) r.NoError(err)
o2 := wire.OutPoint{Hash: hash, Index: 2} o2 := wire.OutPoint{Hash: hash, Index: 2}
err = ct.AddClaim([]byte("test2"), o2, node.NewClaimID(o2), 2, nil) err = ct.AddClaim([]byte("test2"), o2, change.NewClaimID(o2), 2, nil)
r.NoError(err) r.NoError(err)
err = ct.AppendBlock() err = ct.AppendBlock()

View file

@ -13,8 +13,6 @@ import (
"github.com/btcsuite/btcd/claimtrie/chain/chainrepo" "github.com/btcsuite/btcd/claimtrie/chain/chainrepo"
"github.com/btcsuite/btcd/claimtrie/change" "github.com/btcsuite/btcd/claimtrie/change"
"github.com/btcsuite/btcd/claimtrie/config" "github.com/btcsuite/btcd/claimtrie/config"
"github.com/btcsuite/btcd/claimtrie/node"
"github.com/cockroachdb/pebble" "github.com/cockroachdb/pebble"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -134,30 +132,22 @@ var chainReplayCmd = &cobra.Command{
} }
for _, chg := range changes { for _, chg := range changes {
claimID, _ := node.NewIDFromString(chg.ClaimID)
switch chg.Type { switch chg.Type {
case change.AddClaim: case change.AddClaim:
op := *node.NewOutPointFromString(chg.OutPoint) err = ct.AddClaim(chg.Name, chg.OutPoint, chg.ClaimID, chg.Amount, chg.Value)
err = ct.AddClaim(chg.Name, op, claimID, chg.Amount, chg.Value)
case change.UpdateClaim: case change.UpdateClaim:
op := *node.NewOutPointFromString(chg.OutPoint) err = ct.UpdateClaim(chg.Name, chg.OutPoint, chg.Amount, chg.ClaimID, chg.Value)
err = ct.UpdateClaim(chg.Name, op, chg.Amount, claimID, chg.Value)
case change.SpendClaim: case change.SpendClaim:
op := *node.NewOutPointFromString(chg.OutPoint) err = ct.SpendClaim(chg.Name, chg.OutPoint, chg.ClaimID)
err = ct.SpendClaim(chg.Name, op, claimID)
case change.AddSupport: case change.AddSupport:
op := *node.NewOutPointFromString(chg.OutPoint) err = ct.AddSupport(chg.Name, chg.Value, chg.OutPoint, chg.Amount, chg.ClaimID)
claimID, _ := node.NewIDFromString(chg.ClaimID)
id := claimID
err = ct.AddSupport(chg.Name, chg.Value, op, chg.Amount, id)
case change.SpendSupport: case change.SpendSupport:
op := *node.NewOutPointFromString(chg.OutPoint) err = ct.SpendSupport(chg.Name, chg.OutPoint, chg.ClaimID)
err = ct.SpendSupport(chg.Name, op, claimID)
default: default:
err = fmt.Errorf("invalid change: %v", chg) err = fmt.Errorf("invalid change: %v", chg)

View file

@ -32,7 +32,7 @@ func changeName(c change.ChangeType) string {
func showChange(chg change.Change) { func showChange(chg change.Change) {
fmt.Printf(">>> Height: %6d: %s for %04s, %d, %s\n", fmt.Printf(">>> Height: %6d: %s for %04s, %d, %s\n",
chg.Height, changeName(chg.Type), chg.ClaimID, chg.Amount, chg.OutPoint) chg.Height, changeName(chg.Type), chg.ClaimID.String(), chg.Amount, chg.OutPoint)
} }
func showClaim(c *node.Claim, n *node.Node) { func showClaim(c *node.Claim, n *node.Node) {
@ -42,12 +42,12 @@ func showClaim(c *node.Claim, n *node.Node) {
} }
fmt.Printf("%s C ID: %s, TXO: %s\n %5d/%-5d, Status: %9s, Amount: %15d, Support Amount: %15d\n", fmt.Printf("%s C ID: %s, TXO: %s\n %5d/%-5d, Status: %9s, Amount: %15d, Support Amount: %15d\n",
mark, c.ClaimID, c.OutPoint, c.AcceptedAt, c.ActiveAt, status[c.Status], c.Amount, n.SupportSums[c.ClaimID]) mark, c.ClaimID.String(), c.OutPoint, c.AcceptedAt, c.ActiveAt, status[c.Status], c.Amount, n.SupportSums[c.ClaimID.Key()])
} }
func showSupport(c *node.Claim) { func showSupport(c *node.Claim) {
fmt.Printf(" S id: %s, op: %s, %5d/%-5d, %9s, amt: %15d\n", fmt.Printf(" S id: %s, op: %s, %5d/%-5d, %9s, amt: %15d\n",
c.ClaimID, c.OutPoint, c.AcceptedAt, c.ActiveAt, status[c.Status], c.Amount) c.ClaimID.String(), c.OutPoint, c.AcceptedAt, c.ActiveAt, status[c.Status], c.Amount)
} }
func showNode(n *node.Node) { func showNode(n *node.Node) {

View file

@ -2,55 +2,15 @@ package node
import ( import (
"bytes" "bytes"
"encoding/binary"
"encoding/hex"
"strconv" "strconv"
"strings" "strings"
"github.com/btcsuite/btcd/claimtrie/param"
"github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/claimtrie/change"
"github.com/btcsuite/btcd/claimtrie/param"
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
) )
// ClaimID represents a Claim's ClaimID.
type ClaimID [20]byte
// NewClaimID returns a Claim ID calculated from Ripemd160(Sha256(OUTPOINT).
func NewClaimID(op wire.OutPoint) ClaimID {
w := bytes.NewBuffer(op.Hash[:])
if err := binary.Write(w, binary.BigEndian, op.Index); err != nil {
panic(err)
}
var id ClaimID
copy(id[:], btcutil.Hash160(w.Bytes()))
return id
}
// NewIDFromString returns a Claim ID from a string.
func NewIDFromString(s string) (ClaimID, error) {
var id ClaimID
_, err := hex.Decode(id[:], []byte(s))
for i, j := 0, len(id)-1; i < j; i, j = i+1, j-1 {
id[i], id[j] = id[j], id[i]
}
return id, err
}
func (id ClaimID) String() string {
for i, j := 0, len(id)-1; i < j; i, j = i+1, j-1 {
id[i], id[j] = id[j], id[i]
}
return hex.EncodeToString(id[:])
}
type Status int type Status int
const ( const (
@ -62,7 +22,7 @@ const (
// Claim defines a structure of stake, which could be a Claim or Support. // Claim defines a structure of stake, which could be a Claim or Support.
type Claim struct { type Claim struct {
OutPoint wire.OutPoint OutPoint wire.OutPoint
ClaimID string ClaimID change.ClaimID
Amount int64 Amount int64
AcceptedAt int32 // when arrived (aka, originally landed in block) AcceptedAt int32 // when arrived (aka, originally landed in block)
ActiveAt int32 // AcceptedAt + actual delay ActiveAt int32 // AcceptedAt + actual delay

View file

@ -1,12 +1,15 @@
package node package node
import "github.com/btcsuite/btcd/wire" import (
"github.com/btcsuite/btcd/claimtrie/change"
"github.com/btcsuite/btcd/wire"
)
type ClaimList []*Claim type ClaimList []*Claim
type comparator func(c *Claim) bool type comparator func(c *Claim) bool
func byID(id string) comparator { func byID(id change.ClaimID) comparator {
return func(c *Claim) bool { return func(c *Claim) bool {
return c.ClaimID == id return c.ClaimID == id
} }

View file

@ -57,13 +57,13 @@ func TestSimpleAddClaim(t *testing.T) {
_, err = m.IncrementHeightTo(10) _, err = m.IncrementHeightTo(10)
r.NoError(err) r.NoError(err)
chg := change.New(change.AddClaim).SetName(name1).SetOutPoint(out1.String()).SetHeight(11) chg := change.NewChange(change.AddClaim).SetName(name1).SetOutPoint(out1).SetHeight(11)
err = m.AppendChange(chg) err = m.AppendChange(chg)
r.NoError(err) r.NoError(err)
_, err = m.IncrementHeightTo(11) _, err = m.IncrementHeightTo(11)
r.NoError(err) r.NoError(err)
chg = chg.SetName(name2).SetOutPoint(out2.String()).SetHeight(12) chg = chg.SetName(name2).SetOutPoint(out2).SetHeight(12)
err = m.AppendChange(chg) err = m.AppendChange(chg)
r.NoError(err) r.NoError(err)
_, err = m.IncrementHeightTo(12) _, err = m.IncrementHeightTo(12)
@ -107,31 +107,31 @@ func TestSupportAmounts(t *testing.T) {
_, err = m.IncrementHeightTo(10) _, err = m.IncrementHeightTo(10)
r.NoError(err) r.NoError(err)
chg := change.New(change.AddClaim).SetName(name1).SetOutPoint(out1.String()).SetHeight(11).SetAmount(3) chg := change.NewChange(change.AddClaim).SetName(name1).SetOutPoint(out1).SetHeight(11).SetAmount(3)
chg.ClaimID = NewClaimID(*out1).String() chg.ClaimID = change.NewClaimID(*out1)
err = m.AppendChange(chg) err = m.AppendChange(chg)
r.NoError(err) r.NoError(err)
chg = change.New(change.AddClaim).SetName(name1).SetOutPoint(out2.String()).SetHeight(11).SetAmount(4) chg = change.NewChange(change.AddClaim).SetName(name1).SetOutPoint(out2).SetHeight(11).SetAmount(4)
chg.ClaimID = NewClaimID(*out2).String() chg.ClaimID = change.NewClaimID(*out2)
err = m.AppendChange(chg) err = m.AppendChange(chg)
r.NoError(err) r.NoError(err)
_, err = m.IncrementHeightTo(11) _, err = m.IncrementHeightTo(11)
r.NoError(err) r.NoError(err)
chg = change.New(change.AddSupport).SetName(name1).SetOutPoint(out3.String()).SetHeight(12).SetAmount(2) chg = change.NewChange(change.AddSupport).SetName(name1).SetOutPoint(out3).SetHeight(12).SetAmount(2)
chg.ClaimID = NewClaimID(*out1).String() chg.ClaimID = change.NewClaimID(*out1)
err = m.AppendChange(chg) err = m.AppendChange(chg)
r.NoError(err) r.NoError(err)
chg = change.New(change.AddSupport).SetName(name1).SetOutPoint(out4.String()).SetHeight(12).SetAmount(2) chg = change.NewChange(change.AddSupport).SetName(name1).SetOutPoint(out4).SetHeight(12).SetAmount(2)
chg.ClaimID = NewClaimID(*out2).String() chg.ClaimID = change.NewClaimID(*out2)
err = m.AppendChange(chg) err = m.AppendChange(chg)
r.NoError(err) r.NoError(err)
chg = change.New(change.SpendSupport).SetName(name1).SetOutPoint(out4.String()).SetHeight(12).SetAmount(2) chg = change.NewChange(change.SpendSupport).SetName(name1).SetOutPoint(out4).SetHeight(12).SetAmount(2)
chg.ClaimID = NewClaimID(*out2).String() chg.ClaimID = change.NewClaimID(*out2)
err = m.AppendChange(chg) err = m.AppendChange(chg)
r.NoError(err) r.NoError(err)
@ -141,7 +141,7 @@ func TestSupportAmounts(t *testing.T) {
n1, err := m.Node(name1) n1, err := m.Node(name1)
r.NoError(err) r.NoError(err)
r.Equal(2, len(n1.Claims)) r.Equal(2, len(n1.Claims))
r.Equal(int64(5), n1.BestClaim.Amount+n1.SupportSums[n1.BestClaim.ClaimID]) r.Equal(int64(5), n1.BestClaim.Amount+n1.SupportSums[n1.BestClaim.ClaimID.Key()])
} }
func TestNodeSort(t *testing.T) { func TestNodeSort(t *testing.T) {
@ -154,14 +154,14 @@ func TestNodeSort(t *testing.T) {
r.True(OutPointLess(*out1, *out3)) r.True(OutPointLess(*out1, *out3))
n := New() n := New()
n.Claims = append(n.Claims, &Claim{OutPoint: *out1, AcceptedAt: 3, Amount: 3, ClaimID: "a"}) n.Claims = append(n.Claims, &Claim{OutPoint: *out1, AcceptedAt: 3, Amount: 3, ClaimID: change.ClaimID{1}})
n.Claims = append(n.Claims, &Claim{OutPoint: *out2, AcceptedAt: 3, Amount: 3, ClaimID: "b"}) n.Claims = append(n.Claims, &Claim{OutPoint: *out2, AcceptedAt: 3, Amount: 3, ClaimID: change.ClaimID{2}})
n.handleExpiredAndActivated(3) n.handleExpiredAndActivated(3)
n.updateTakeoverHeight(3, []byte{}, true) n.updateTakeoverHeight(3, []byte{}, true)
r.Equal(n.Claims.find(byOut(*out1)).OutPoint.String(), n.BestClaim.OutPoint.String()) r.Equal(n.Claims.find(byOut(*out1)).OutPoint.String(), n.BestClaim.OutPoint.String())
n.Claims = append(n.Claims, &Claim{OutPoint: *out3, AcceptedAt: 3, Amount: 3, ClaimID: "c"}) n.Claims = append(n.Claims, &Claim{OutPoint: *out3, AcceptedAt: 3, Amount: 3, ClaimID: change.ClaimID{3}})
n.handleExpiredAndActivated(3) n.handleExpiredAndActivated(3)
n.updateTakeoverHeight(3, []byte{}, true) n.updateTakeoverHeight(3, []byte{}, true)
r.Equal(n.Claims.find(byOut(*out1)).OutPoint.String(), n.BestClaim.OutPoint.String()) r.Equal(n.Claims.find(byOut(*out1)).OutPoint.String(), n.BestClaim.OutPoint.String())
@ -174,10 +174,10 @@ func TestClaimSort(t *testing.T) {
param.ExtendedClaimExpirationTime = 1000 param.ExtendedClaimExpirationTime = 1000
n := New() n := New()
n.Claims = append(n.Claims, &Claim{OutPoint: *out2, AcceptedAt: 3, Amount: 3, ClaimID: "b"}) n.Claims = append(n.Claims, &Claim{OutPoint: *out2, AcceptedAt: 3, Amount: 3, ClaimID: change.ClaimID{2}})
n.Claims = append(n.Claims, &Claim{OutPoint: *out3, AcceptedAt: 3, Amount: 2, ClaimID: "c"}) n.Claims = append(n.Claims, &Claim{OutPoint: *out3, AcceptedAt: 3, Amount: 2, ClaimID: change.ClaimID{3}})
n.Claims = append(n.Claims, &Claim{OutPoint: *out3, AcceptedAt: 4, Amount: 2, ClaimID: "d"}) n.Claims = append(n.Claims, &Claim{OutPoint: *out3, AcceptedAt: 4, Amount: 2, ClaimID: change.ClaimID{4}})
n.Claims = append(n.Claims, &Claim{OutPoint: *out1, AcceptedAt: 3, Amount: 4, ClaimID: "a"}) n.Claims = append(n.Claims, &Claim{OutPoint: *out1, AcceptedAt: 3, Amount: 4, ClaimID: change.ClaimID{1}})
n.SortClaims() n.SortClaims()
r.Equal(int64(4), n.Claims[0].Amount) r.Equal(int64(4), n.Claims[0].Amount)

View file

@ -31,8 +31,6 @@ func (n *Node) HasActiveBestClaim() bool {
func (n *Node) ApplyChange(chg change.Change, delay int32) error { func (n *Node) ApplyChange(chg change.Change, delay int32) error {
out := NewOutPointFromString(chg.OutPoint)
visibleAt := chg.VisibleHeight visibleAt := chg.VisibleHeight
if visibleAt <= 0 { if visibleAt <= 0 {
visibleAt = chg.Height visibleAt = chg.Height
@ -41,7 +39,7 @@ func (n *Node) ApplyChange(chg change.Change, delay int32) error {
switch chg.Type { switch chg.Type {
case change.AddClaim: case change.AddClaim:
c := &Claim{ c := &Claim{
OutPoint: *out, OutPoint: chg.OutPoint,
Amount: chg.Amount, Amount: chg.Amount,
ClaimID: chg.ClaimID, ClaimID: chg.ClaimID,
AcceptedAt: chg.Height, // not tracking original height in this version (but we could) AcceptedAt: chg.Height, // not tracking original height in this version (but we could)
@ -49,14 +47,14 @@ func (n *Node) ApplyChange(chg change.Change, delay int32) error {
Value: chg.Value, Value: chg.Value,
VisibleAt: visibleAt, VisibleAt: visibleAt,
} }
old := n.Claims.find(byOut(*out)) // TODO: remove this after proving ResetHeight works old := n.Claims.find(byOut(chg.OutPoint)) // TODO: remove this after proving ResetHeight works
if old != nil { if old != nil {
fmt.Printf("CONFLICT WITH EXISTING TXO! Name: %s, Height: %d\n", chg.Name, chg.Height) fmt.Printf("CONFLICT WITH EXISTING TXO! Name: %s, Height: %d\n", chg.Name, chg.Height)
} }
n.Claims = append(n.Claims, c) n.Claims = append(n.Claims, c)
case change.SpendClaim: case change.SpendClaim:
c := n.Claims.find(byOut(*out)) c := n.Claims.find(byOut(chg.OutPoint))
if c != nil { if c != nil {
c.setStatus(Deactivated) c.setStatus(Deactivated)
} else if !mispents[fmt.Sprintf("%d_%s", chg.Height, chg.ClaimID)] { } else if !mispents[fmt.Sprintf("%d_%s", chg.Height, chg.ClaimID)] {
@ -74,7 +72,7 @@ func (n *Node) ApplyChange(chg change.Change, delay int32) error {
// Keep its ID, which was generated from the spent claim. // Keep its ID, which was generated from the spent claim.
// And update the rest of properties. // And update the rest of properties.
c.setOutPoint(*out).SetAmt(chg.Amount).SetValue(chg.Value) c.setOutPoint(chg.OutPoint).SetAmt(chg.Amount).SetValue(chg.Value)
c.setStatus(Accepted) // it was Deactivated in the spend (but we only activate at the end of the block) c.setStatus(Accepted) // it was Deactivated in the spend (but we only activate at the end of the block)
// that's because the old code would put all insertions into the "queue" that was processed at block's end // that's because the old code would put all insertions into the "queue" that was processed at block's end
@ -88,7 +86,7 @@ func (n *Node) ApplyChange(chg change.Change, delay int32) error {
} }
case change.AddSupport: case change.AddSupport:
n.Supports = append(n.Supports, &Claim{ n.Supports = append(n.Supports, &Claim{
OutPoint: *out, OutPoint: chg.OutPoint,
Amount: chg.Amount, Amount: chg.Amount,
ClaimID: chg.ClaimID, ClaimID: chg.ClaimID,
AcceptedAt: chg.Height, AcceptedAt: chg.Height,
@ -98,10 +96,10 @@ func (n *Node) ApplyChange(chg change.Change, delay int32) error {
}) })
case change.SpendSupport: case change.SpendSupport:
s := n.Supports.find(byOut(*out)) s := n.Supports.find(byOut(chg.OutPoint))
if s != nil { if s != nil {
if s.Status == Activated { if s.Status == Activated {
n.SupportSums[s.ClaimID] -= s.Amount n.SupportSums[s.ClaimID.Key()] -= s.Amount
} }
// TODO: we could do without this Deactivated flag if we set expiration instead // TODO: we could do without this Deactivated flag if we set expiration instead
// That would eliminate the above Sum update. // That would eliminate the above Sum update.
@ -170,7 +168,7 @@ func (n *Node) handleExpiredAndActivated(height int32) int {
c.setStatus(Activated) c.setStatus(Activated)
changes++ changes++
if sums != nil { if sums != nil {
sums[c.ClaimID] += c.Amount sums[c.ClaimID.Key()] += c.Amount
} }
} }
if c.ExpireAt() <= height || c.Status == Deactivated { if c.ExpireAt() <= height || c.Status == Deactivated {
@ -181,7 +179,7 @@ func (n *Node) handleExpiredAndActivated(height int32) int {
items = items[:len(items)-1] items = items[:len(items)-1]
changes++ changes++
if sums != nil && c.Status != Deactivated { if sums != nil && c.Status != Deactivated {
sums[c.ClaimID] -= c.Amount sums[c.ClaimID.Key()] -= c.Amount
} }
} }
} }
@ -252,9 +250,9 @@ func (n Node) findBestClaim() *Claim {
continue continue
} }
candidateAmount := candidate.Amount + n.SupportSums[candidate.ClaimID] candidateAmount := candidate.Amount + n.SupportSums[candidate.ClaimID.Key()]
if bestAmount <= 0 { if bestAmount <= 0 {
bestAmount = best.Amount + n.SupportSums[best.ClaimID] bestAmount = best.Amount + n.SupportSums[best.ClaimID.Key()]
} }
switch { switch {
@ -292,7 +290,7 @@ func (n *Node) activateAllClaims(height int32) int {
s.setActiveAt(height) // don't necessarily need to change this number? s.setActiveAt(height) // don't necessarily need to change this number?
s.setStatus(Activated) s.setStatus(Activated)
count++ count++
n.SupportSums[s.ClaimID] += s.Amount n.SupportSums[s.ClaimID.Key()] += s.Amount
} }
} }
return count return count
@ -302,8 +300,8 @@ func (n *Node) SortClaims() {
// purposefully sorting by descent // purposefully sorting by descent
sort.Slice(n.Claims, func(j, i int) bool { sort.Slice(n.Claims, func(j, i int) bool {
iAmount := n.Claims[i].Amount + n.SupportSums[n.Claims[i].ClaimID] iAmount := n.Claims[i].Amount + n.SupportSums[n.Claims[i].ClaimID.Key()]
jAmount := n.Claims[j].Amount + n.SupportSums[n.Claims[j].ClaimID] jAmount := n.Claims[j].Amount + n.SupportSums[n.Claims[j].ClaimID.Key()]
switch { switch {
case iAmount < jAmount: case iAmount < jAmount:
return true return true

View file

@ -10,7 +10,7 @@ import (
) )
var ( var (
opStr1 = "0000000000000000000000000000000000000000000000000000000000000000:1" out1 = node.NewOutPointFromString("0000000000000000000000000000000000000000000000000000000000000000:1")
testNodeName1 = []byte("name1") testNodeName1 = []byte("name1")
) )
@ -39,7 +39,7 @@ func testNodeRepo(t *testing.T, repo node.Repo, setup, cleanup func()) {
r := require.New(t) r := require.New(t)
chg := change.New(change.AddClaim).SetName(testNodeName1).SetOutPoint(opStr1) chg := change.NewChange(change.AddClaim).SetName(testNodeName1).SetOutPoint(out1)
testcases := []struct { testcases := []struct {
name string name string

View file

@ -3,16 +3,82 @@ package noderepo
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"reflect"
"sort"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/claimtrie/change" "github.com/btcsuite/btcd/claimtrie/change"
"github.com/btcsuite/btcd/claimtrie/node"
"github.com/btcsuite/btcd/wire"
"github.com/cockroachdb/pebble" "github.com/cockroachdb/pebble"
"github.com/vmihailenco/msgpack/v5" "github.com/vmihailenco/msgpack/v5"
"sort"
) )
type Pebble struct { type Pebble struct {
db *pebble.DB db *pebble.DB
} }
func init() {
claimEncoder := func(e *msgpack.Encoder, v reflect.Value) error {
claim := v.Interface().(change.ClaimID)
return e.EncodeBytes(claim[:])
}
claimDecoder := func(e *msgpack.Decoder, v reflect.Value) error {
data, err := e.DecodeBytes()
if err != nil {
s, err := e.DecodeString()
if err != nil {
return err
}
id, err := change.NewIDFromString(s)
if err != nil {
return err
}
v.Set(reflect.ValueOf(id))
} else {
id := change.ClaimID{}
copy(id[:], data)
v.Set(reflect.ValueOf(id))
}
return nil
}
msgpack.Register(change.ClaimID{}, claimEncoder, claimDecoder)
opEncoder := func(e *msgpack.Encoder, v reflect.Value) error {
op := v.Interface().(wire.OutPoint)
if err := e.EncodeBytes(op.Hash[:]); err != nil {
return err
}
return e.EncodeUint32(op.Index)
}
opDecoder := func(e *msgpack.Decoder, v reflect.Value) error {
data, err := e.DecodeBytes()
if err != nil {
// try the older data:
s, err := e.DecodeString()
if err != nil {
return err
}
op := node.NewOutPointFromString(s)
v.Set(reflect.ValueOf(op))
} else {
index, err := e.DecodeUint32()
if err != nil {
return err
}
hash, err := chainhash.NewHash(data)
if err != nil {
return err
}
op := wire.NewOutPoint(hash, index)
v.Set(reflect.ValueOf(*op))
}
return nil
}
msgpack.Register(wire.OutPoint{}, opEncoder, opDecoder)
}
func NewPebble(path string) (*Pebble, error) { func NewPebble(path string) (*Pebble, error) {
db, err := pebble.Open(path, &pebble.Options{Cache: pebble.NewCache(256 << 20), BytesPerSync: 16 << 20}) db, err := pebble.Open(path, &pebble.Options{Cache: pebble.NewCache(256 << 20), BytesPerSync: 16 << 20})

View file

@ -83,7 +83,7 @@ func (nm *NormalizingManager) addNormalizationForkChangesIfNecessary(height int3
Type: change.AddClaim, Type: change.AddClaim,
Name: norm, Name: norm,
Height: c.AcceptedAt, Height: c.AcceptedAt,
OutPoint: c.OutPoint.String(), OutPoint: c.OutPoint,
ClaimID: c.ClaimID, ClaimID: c.ClaimID,
Amount: c.Amount, Amount: c.Amount,
Value: c.Value, Value: c.Value,
@ -94,7 +94,7 @@ func (nm *NormalizingManager) addNormalizationForkChangesIfNecessary(height int3
Type: change.SpendClaim, Type: change.SpendClaim,
Name: clone, Name: clone,
Height: height, Height: height,
OutPoint: c.OutPoint.String(), OutPoint: c.OutPoint,
}) })
} }
for _, c := range n.Supports { for _, c := range n.Supports {
@ -102,7 +102,7 @@ func (nm *NormalizingManager) addNormalizationForkChangesIfNecessary(height int3
Type: change.AddSupport, Type: change.AddSupport,
Name: norm, Name: norm,
Height: c.AcceptedAt, Height: c.AcceptedAt,
OutPoint: c.OutPoint.String(), OutPoint: c.OutPoint,
ClaimID: c.ClaimID, ClaimID: c.ClaimID,
Amount: c.Amount, Amount: c.Amount,
Value: c.Value, Value: c.Value,
@ -113,7 +113,7 @@ func (nm *NormalizingManager) addNormalizationForkChangesIfNecessary(height int3
Type: change.SpendSupport, Type: change.SpendSupport,
Name: clone, Name: clone,
Height: height, Height: height,
OutPoint: c.OutPoint.String(), OutPoint: c.OutPoint,
}) })
} }