added more unit tests for claimtrie

This commit is contained in:
Brannon King 2021-08-10 17:08:51 -04:00
parent 132b93713d
commit ade593da33
3 changed files with 644 additions and 7 deletions

View file

@ -21,13 +21,13 @@ jobs:
go-version: ${{ matrix.go }}
- name: Checkout source
uses: actions/checkout@v2
- name: Install coreutils, ICU for macOS
if: matrix.os == 'macos-latest'
run: brew install coreutils icu4c
- name: Build executables
env:
GO111MODULE: "on"
run: go build -trimpath -o artifacts/ --tags use_icu_normalization .
- name: Install coreutils for macOS
if: matrix.os == 'macos-latest'
run: brew install coreutils icu4c
- name: SHA256 sum
run: sha256sum -b artifacts/* > artifacts/chain.sha256
- name: Upload artifacts

View file

@ -72,7 +72,6 @@ func TestFixedHashes(t *testing.T) {
}
func TestNormalizationFork(t *testing.T) {
r := require.New(t)
setup(t)
@ -108,6 +107,10 @@ func TestNormalizationFork(t *testing.T) {
err = ct.AddClaim([]byte("test"), o6, change.NewClaimID(o6), 7)
r.NoError(err)
o7 := wire.OutPoint{Hash: hash, Index: 7}
err = ct.AddSupport([]byte("test"), o7, 11, change.NewClaimID(o6))
r.NoError(err)
err = ct.AppendBlock()
r.NoError(err)
r.NotEqual(merkletrie.EmptyTrieHash[:], ct.MerkleHash()[:])
@ -117,8 +120,8 @@ func TestNormalizationFork(t *testing.T) {
r.NotNil(n.BestClaim)
r.Equal(int32(1), n.TakenOverAt)
o7 := wire.OutPoint{Hash: hash, Index: 7}
err = ct.AddClaim([]byte("aÑEJO"), o7, change.NewClaimID(o7), 8)
o8 := wire.OutPoint{Hash: hash, Index: 8}
err = ct.AddClaim([]byte("aÑEJO"), o8, change.NewClaimID(o8), 8)
r.NoError(err)
err = ct.AppendBlock()
@ -130,6 +133,10 @@ func TestNormalizationFork(t *testing.T) {
r.Equal(3, len(n.Claims))
r.Equal(uint32(1), n.BestClaim.OutPoint.Index)
r.Equal(int32(2), n.TakenOverAt)
n, err = ct.nodeManager.NodeAt(ct.nodeManager.Height(), []byte("test"))
r.NoError(err)
r.Equal(int64(18), n.BestClaim.Amount+n.SupportSums[n.BestClaim.ClaimID.Key()])
}
func TestActivationsOnNormalizationFork(t *testing.T) {
@ -345,3 +352,633 @@ func randomName() []byte {
}
return name
}
func TestClaimReplace(t *testing.T) {
r := require.New(t)
setup(t)
ct, err := New(cfg)
r.NoError(err)
r.NotNil(ct)
defer ct.Close()
hash := chainhash.HashH([]byte{1, 2, 3})
o1 := wire.OutPoint{Hash: hash, Index: 1}
err = ct.AddClaim([]byte("bass"), o1, change.NewClaimID(o1), 8)
r.NoError(err)
o2 := wire.OutPoint{Hash: hash, Index: 2}
err = ct.AddClaim([]byte("basso"), o2, change.NewClaimID(o2), 10)
r.NoError(err)
err = ct.AppendBlock()
r.NoError(err)
n, err := ct.NodeAt(ct.height, []byte("bass"))
r.Equal(o1.String(), n.BestClaim.OutPoint.String())
err = ct.SpendClaim([]byte("bass"), o1, n.BestClaim.ClaimID)
r.NoError(err)
o4 := wire.OutPoint{Hash: hash, Index: 4}
err = ct.AddClaim([]byte("bassfisher"), o4, change.NewClaimID(o4), 12)
r.NoError(err)
err = ct.AppendBlock()
r.NoError(err)
n, err = ct.NodeAt(ct.height, []byte("bass"))
r.NoError(err)
r.True(n == nil || !n.HasActiveBestClaim())
n, err = ct.NodeAt(ct.height, []byte("bassfisher"))
r.Equal(o4.String(), n.BestClaim.OutPoint.String())
}
func TestGeneralClaim(t *testing.T) {
r := require.New(t)
setup(t)
ct, err := New(cfg)
r.NoError(err)
r.NotNil(ct)
defer ct.Close()
err = ct.AppendBlock()
r.NoError(err)
hash := chainhash.HashH([]byte{1, 2, 3})
o1 := wire.OutPoint{Hash: hash, Index: 1}
err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 8)
r.NoError(err)
err = ct.AppendBlock()
r.NoError(err)
err = ct.ResetHeight(ct.height - 1)
r.NoError(err)
n, err := ct.NodeAt(ct.height, []byte("test"))
r.NoError(err)
r.True(n == nil || !n.HasActiveBestClaim())
err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 8)
o2 := wire.OutPoint{Hash: hash, Index: 2}
err = ct.AddClaim([]byte("test"), o2, change.NewClaimID(o2), 8)
r.NoError(err)
err = ct.AppendBlock()
r.NoError(err)
err = ct.ResetHeight(ct.height - 1)
r.NoError(err)
n, err = ct.NodeAt(ct.height, []byte("test"))
r.NoError(err)
r.True(n == nil || !n.HasActiveBestClaim())
err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 8)
r.NoError(err)
err = ct.AppendBlock()
r.NoError(err)
err = ct.AddClaim([]byte("test"), o2, change.NewClaimID(o2), 8)
r.NoError(err)
err = ct.AppendBlock()
r.NoError(err)
err = ct.ResetHeight(ct.height - 2)
r.NoError(err)
n, err = ct.NodeAt(ct.height, []byte("test"))
r.NoError(err)
r.True(n == nil || !n.HasActiveBestClaim())
}
func TestClaimTakeover(t *testing.T) {
r := require.New(t)
setup(t)
param.ActiveParams.ActiveDelayFactor = 1
ct, err := New(cfg)
r.NoError(err)
r.NotNil(ct)
defer ct.Close()
err = ct.AppendBlock()
r.NoError(err)
hash := chainhash.HashH([]byte{1, 2, 3})
o1 := wire.OutPoint{Hash: hash, Index: 1}
err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 8)
r.NoError(err)
for i := 0; i < 10; i++ {
err = ct.AppendBlock()
r.NoError(err)
}
o2 := wire.OutPoint{Hash: hash, Index: 2}
err = ct.AddClaim([]byte("test"), o2, change.NewClaimID(o2), 18)
r.NoError(err)
for i := 0; i < 10; i++ {
err = ct.AppendBlock()
r.NoError(err)
}
n, err := ct.NodeAt(ct.height, []byte("test"))
r.NoError(err)
r.Equal(o1.String(), n.BestClaim.OutPoint.String())
err = ct.AppendBlock()
r.NoError(err)
n, err = ct.NodeAt(ct.height, []byte("test"))
r.NoError(err)
r.Equal(o2.String(), n.BestClaim.OutPoint.String())
err = ct.ResetHeight(ct.height - 1)
r.NoError(err)
n, err = ct.NodeAt(ct.height, []byte("test"))
r.NoError(err)
r.Equal(o1.String(), n.BestClaim.OutPoint.String())
}
func TestSpendClaim(t *testing.T) {
r := require.New(t)
setup(t)
param.ActiveParams.ActiveDelayFactor = 1
ct, err := New(cfg)
r.NoError(err)
r.NotNil(ct)
defer ct.Close()
err = ct.AppendBlock()
r.NoError(err)
hash := chainhash.HashH([]byte{1, 2, 3})
o1 := wire.OutPoint{Hash: hash, Index: 1}
err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 18)
r.NoError(err)
o2 := wire.OutPoint{Hash: hash, Index: 2}
err = ct.AddClaim([]byte("test"), o2, change.NewClaimID(o2), 8)
r.NoError(err)
err = ct.AppendBlock()
r.NoError(err)
err = ct.SpendClaim([]byte("test"), o1, change.NewClaimID(o1))
r.NoError(err)
err = ct.AppendBlock()
r.NoError(err)
n, err := ct.NodeAt(ct.height, []byte("test"))
r.NoError(err)
r.Equal(o2.String(), n.BestClaim.OutPoint.String())
err = ct.ResetHeight(ct.height - 1)
r.NoError(err)
o3 := wire.OutPoint{Hash: hash, Index: 3}
err = ct.AddClaim([]byte("test"), o3, change.NewClaimID(o3), 22)
r.NoError(err)
for i := 0; i < 10; i++ {
err = ct.AppendBlock()
r.NoError(err)
}
o4 := wire.OutPoint{Hash: hash, Index: 4}
err = ct.AddClaim([]byte("test"), o4, change.NewClaimID(o4), 28)
r.NoError(err)
err = ct.AppendBlock()
r.NoError(err)
n, err = ct.NodeAt(ct.height, []byte("test"))
r.NoError(err)
r.Equal(o3.String(), n.BestClaim.OutPoint.String())
err = ct.SpendClaim([]byte("test"), o3, n.BestClaim.ClaimID)
r.NoError(err)
err = ct.AppendBlock()
r.NoError(err)
n, err = ct.NodeAt(ct.height, []byte("test"))
r.NoError(err)
r.Equal(o4.String(), n.BestClaim.OutPoint.String())
err = ct.SpendClaim([]byte("test"), o1, change.NewClaimID(o1))
r.NoError(err)
err = ct.SpendClaim([]byte("test"), o2, change.NewClaimID(o2))
r.NoError(err)
err = ct.SpendClaim([]byte("test"), o3, change.NewClaimID(o3))
r.NoError(err)
err = ct.SpendClaim([]byte("test"), o4, change.NewClaimID(o4))
r.NoError(err)
err = ct.AppendBlock()
r.NoError(err)
n, err = ct.NodeAt(ct.height, []byte("test"))
r.NoError(err)
r.True(n == nil || !n.HasActiveBestClaim())
h := ct.MerkleHash()
r.Equal(merkletrie.EmptyTrieHash.String(), h.String())
}
func TestSupportDelay(t *testing.T) {
r := require.New(t)
setup(t)
param.ActiveParams.ActiveDelayFactor = 1
ct, err := New(cfg)
r.NoError(err)
r.NotNil(ct)
defer ct.Close()
err = ct.AppendBlock()
r.NoError(err)
hash := chainhash.HashH([]byte{1, 2, 3})
o1 := wire.OutPoint{Hash: hash, Index: 1}
err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 18)
r.NoError(err)
o2 := wire.OutPoint{Hash: hash, Index: 2}
err = ct.AddClaim([]byte("test"), o2, change.NewClaimID(o2), 8)
r.NoError(err)
o3 := wire.OutPoint{Hash: hash, Index: 3}
err = ct.AddSupport([]byte("test"), o3, 18, change.NewClaimID(o3)) // using bad ClaimID on purpose
r.NoError(err)
o4 := wire.OutPoint{Hash: hash, Index: 4}
err = ct.AddSupport([]byte("test"), o4, 18, change.NewClaimID(o2))
r.NoError(err)
err = ct.AppendBlock()
r.NoError(err)
n, err := ct.NodeAt(ct.height, []byte("test"))
r.NoError(err)
r.Equal(o2.String(), n.BestClaim.OutPoint.String())
for i := 0; i < 10; i++ {
err = ct.AppendBlock()
r.NoError(err)
}
o5 := wire.OutPoint{Hash: hash, Index: 5}
err = ct.AddSupport([]byte("test"), o5, 18, change.NewClaimID(o1))
r.NoError(err)
err = ct.AppendBlock()
r.NoError(err)
n, err = ct.NodeAt(ct.height, []byte("test"))
r.NoError(err)
r.Equal(o2.String(), n.BestClaim.OutPoint.String())
for i := 0; i < 11; i++ {
err = ct.AppendBlock()
r.NoError(err)
}
n, err = ct.NodeAt(ct.height, []byte("test"))
r.NoError(err)
r.Equal(o1.String(), n.BestClaim.OutPoint.String())
err = ct.ResetHeight(ct.height - 1)
r.NoError(err)
n, err = ct.NodeAt(ct.height, []byte("test"))
r.NoError(err)
r.Equal(o2.String(), n.BestClaim.OutPoint.String())
}
func TestSupportSpending(t *testing.T) {
r := require.New(t)
setup(t)
param.ActiveParams.ActiveDelayFactor = 1
ct, err := New(cfg)
r.NoError(err)
r.NotNil(ct)
defer ct.Close()
err = ct.AppendBlock()
r.NoError(err)
hash := chainhash.HashH([]byte{1, 2, 3})
o1 := wire.OutPoint{Hash: hash, Index: 1}
err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 18)
r.NoError(err)
err = ct.AppendBlock()
r.NoError(err)
o3 := wire.OutPoint{Hash: hash, Index: 3}
err = ct.AddSupport([]byte("test"), o3, 18, change.NewClaimID(o1))
r.NoError(err)
err = ct.SpendClaim([]byte("test"), o1, change.NewClaimID(o1))
r.NoError(err)
err = ct.AppendBlock()
r.NoError(err)
n, err := ct.NodeAt(ct.height, []byte("test"))
r.NoError(err)
r.True(n == nil || !n.HasActiveBestClaim())
}
func TestSupportOnUpdate(t *testing.T) {
r := require.New(t)
setup(t)
param.ActiveParams.ActiveDelayFactor = 1
ct, err := New(cfg)
r.NoError(err)
r.NotNil(ct)
defer ct.Close()
err = ct.AppendBlock()
r.NoError(err)
hash := chainhash.HashH([]byte{1, 2, 3})
o1 := wire.OutPoint{Hash: hash, Index: 1}
err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 18)
r.NoError(err)
err = ct.SpendClaim([]byte("test"), o1, change.NewClaimID(o1))
r.NoError(err)
o2 := wire.OutPoint{Hash: hash, Index: 2}
err = ct.UpdateClaim([]byte("test"), o2, 28, change.NewClaimID(o1))
r.NoError(err)
err = ct.AppendBlock()
r.NoError(err)
n, err := ct.NodeAt(ct.height, []byte("test"))
r.NoError(err)
r.Equal(int64(28), n.BestClaim.Amount)
err = ct.AppendBlock()
r.NoError(err)
err = ct.SpendClaim([]byte("test"), o2, change.NewClaimID(o1))
r.NoError(err)
o3 := wire.OutPoint{Hash: hash, Index: 3}
err = ct.UpdateClaim([]byte("test"), o3, 38, change.NewClaimID(o1))
r.NoError(err)
o4 := wire.OutPoint{Hash: hash, Index: 4}
err = ct.AddSupport([]byte("test"), o4, 2, change.NewClaimID(o1))
r.NoError(err)
o5 := wire.OutPoint{Hash: hash, Index: 5}
err = ct.AddClaim([]byte("test"), o5, change.NewClaimID(o5), 39)
r.NoError(err)
err = ct.AppendBlock()
r.NoError(err)
n, err = ct.NodeAt(ct.height, []byte("test"))
r.NoError(err)
r.Equal(int64(40), n.BestClaim.Amount+n.SupportSums[n.BestClaim.ClaimID.Key()])
err = ct.SpendSupport([]byte("test"), o4, n.BestClaim.ClaimID)
r.NoError(err)
err = ct.AppendBlock()
r.NoError(err)
// NOTE: LBRYcrd did not test that supports can trigger a takeover correctly (and it doesn't work here):
// n, err = ct.NodeAt(ct.height, []byte("test"))
// r.NoError(err)
// r.Equal(int64(39), n.BestClaim.Amount + n.SupportSums[n.BestClaim.ClaimID.Key()])
}
func TestSupportPreservation(t *testing.T) {
r := require.New(t)
setup(t)
param.ActiveParams.ActiveDelayFactor = 1
ct, err := New(cfg)
r.NoError(err)
r.NotNil(ct)
defer ct.Close()
err = ct.AppendBlock()
r.NoError(err)
hash := chainhash.HashH([]byte{1, 2, 3})
o1 := wire.OutPoint{Hash: hash, Index: 1}
o2 := wire.OutPoint{Hash: hash, Index: 2}
o3 := wire.OutPoint{Hash: hash, Index: 3}
o4 := wire.OutPoint{Hash: hash, Index: 4}
o5 := wire.OutPoint{Hash: hash, Index: 5}
err = ct.AddSupport([]byte("test"), o2, 10, change.NewClaimID(o1))
r.NoError(err)
err = ct.AppendBlock()
r.NoError(err)
err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 18)
r.NoError(err)
err = ct.AddClaim([]byte("test"), o3, change.NewClaimID(o3), 7)
r.NoError(err)
for i := 0; i < 10; i++ {
err = ct.AppendBlock()
r.NoError(err)
}
n, err := ct.NodeAt(ct.height, []byte("test"))
r.NoError(err)
r.Equal(int64(28), n.BestClaim.Amount+n.SupportSums[n.BestClaim.ClaimID.Key()])
err = ct.AddSupport([]byte("test"), o4, 10, change.NewClaimID(o1))
r.NoError(err)
err = ct.AddSupport([]byte("test"), o5, 100, change.NewClaimID(o3))
r.NoError(err)
err = ct.AppendBlock()
r.NoError(err)
n, err = ct.NodeAt(ct.height, []byte("test"))
r.NoError(err)
r.Equal(int64(38), n.BestClaim.Amount+n.SupportSums[n.BestClaim.ClaimID.Key()])
for i := 0; i < 10; i++ {
err = ct.AppendBlock()
r.NoError(err)
}
n, err = ct.NodeAt(ct.height, []byte("test"))
r.NoError(err)
r.Equal(int64(107), n.BestClaim.Amount+n.SupportSums[n.BestClaim.ClaimID.Key()])
}
func TestInvalidClaimID(t *testing.T) {
r := require.New(t)
setup(t)
param.ActiveParams.ActiveDelayFactor = 1
ct, err := New(cfg)
r.NoError(err)
r.NotNil(ct)
defer ct.Close()
err = ct.AppendBlock()
r.NoError(err)
hash := chainhash.HashH([]byte{1, 2, 3})
o1 := wire.OutPoint{Hash: hash, Index: 1}
o2 := wire.OutPoint{Hash: hash, Index: 2}
o3 := wire.OutPoint{Hash: hash, Index: 3}
err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 10)
r.NoError(err)
err = ct.AppendBlock()
r.NoError(err)
err = ct.SpendClaim([]byte("test"), o3, change.NewClaimID(o1))
r.NoError(err)
err = ct.UpdateClaim([]byte("test"), o2, 18, change.NewClaimID(o3))
r.NoError(err)
for i := 0; i < 12; i++ {
err = ct.AppendBlock()
r.NoError(err)
}
n, err := ct.NodeAt(ct.height, []byte("test"))
r.NoError(err)
r.Len(n.Claims, 1)
r.Len(n.Supports, 0)
r.Equal(int64(10), n.BestClaim.Amount+n.SupportSums[n.BestClaim.ClaimID.Key()])
}
func TestStableTrieHash(t *testing.T) {
r := require.New(t)
setup(t)
param.ActiveParams.ActiveDelayFactor = 1
param.ActiveParams.AllClaimsInMerkleForkHeight = 8 // changes on this one
ct, err := New(cfg)
r.NoError(err)
r.NotNil(ct)
defer ct.Close()
hash := chainhash.HashH([]byte{1, 2, 3})
o1 := wire.OutPoint{Hash: hash, Index: 1}
err = ct.AddClaim([]byte("test"), o1, change.NewClaimID(o1), 1)
r.NoError(err)
err = ct.AppendBlock()
r.NoError(err)
h := ct.MerkleHash()
r.NotEqual(merkletrie.EmptyTrieHash.String(), h.String())
for i := 0; i < 6; i++ {
err = ct.AppendBlock()
r.NoError(err)
r.Equal(h.String(), ct.MerkleHash().String())
}
err = ct.AppendBlock()
r.NoError(err)
r.NotEqual(h.String(), ct.MerkleHash())
h = ct.MerkleHash()
for i := 0; i < 16; i++ {
err = ct.AppendBlock()
r.NoError(err)
r.Equal(h.String(), ct.MerkleHash().String())
}
}
func TestBlock884431(t *testing.T) {
r := require.New(t)
setup(t)
param.ActiveParams.ActiveDelayFactor = 1
param.ActiveParams.MaxRemovalWorkaroundHeight = 0
param.ActiveParams.AllClaimsInMerkleForkHeight = 0
ct, err := New(cfg)
r.NoError(err)
r.NotNil(ct)
defer ct.Close()
// in this block we have a scenario where we update all the child names
// which, in the old code, caused a trie vertex to be removed
// which, in turn, would trigger a premature takeover
c := byte(10)
add := func(s string, amt int64) wire.OutPoint {
h := chainhash.HashH([]byte{c})
c++
o := wire.OutPoint{Hash: h, Index: 1}
err := ct.AddClaim([]byte(s), o, change.NewClaimID(o), amt)
r.NoError(err)
return o
}
update := func(s string, o wire.OutPoint, amt int64) wire.OutPoint {
err = ct.SpendClaim([]byte(s), o, change.NewClaimID(o))
r.NoError(err)
h := chainhash.HashH([]byte{c})
c++
o2 := wire.OutPoint{Hash: h, Index: 2}
err = ct.UpdateClaim([]byte(s), o2, amt, change.NewClaimID(o))
r.NoError(err)
return o2
}
o1a := add("go", 10)
o1b := add("go", 20)
o2 := add("goop", 10)
o3 := add("gog", 20)
o4a := add("test", 10)
o4b := add("test", 20)
o5 := add("tester", 10)
o6 := add("testing", 20)
for i := 0; i < 10; i++ {
err = ct.AppendBlock()
r.NoError(err)
}
n, err := ct.NodeAt(ct.height, []byte("go"))
r.NoError(err)
r.Equal(o1b.String(), n.BestClaim.OutPoint.String())
n, err = ct.NodeAt(ct.height, []byte("test"))
r.NoError(err)
r.Equal(o4b.String(), n.BestClaim.OutPoint.String())
update("go", o1b, 30)
o10 := update("go", o1a, 40)
update("gog", o3, 30)
update("goop", o2, 30)
update("testing", o6, 30)
o11 := update("test", o4b, 30)
update("test", o4a, 40)
update("tester", o5, 30)
err = ct.AppendBlock()
r.NoError(err)
n, err = ct.NodeAt(ct.height, []byte("go"))
r.NoError(err)
r.Equal(o10.String(), n.BestClaim.OutPoint.String())
n, err = ct.NodeAt(ct.height, []byte("test"))
r.NoError(err)
r.Equal(o11.String(), n.BestClaim.OutPoint.String())
}

View file

@ -197,7 +197,7 @@ func isUpdateClaim(pops []parsedOpcode) bool {
pops[5].opcode.value == OP_2DROP
}
const illegalChars = "=&#:*$@%?/\x00"
const illegalChars = "=&#:*$@%?/;\\\b\n\t\r\x00"
func AllClaimsAreSane(script []byte, enforceSoftFork bool) error {
cs, err := DecodeClaimScript(script)