246 lines
7.3 KiB
Go
246 lines
7.3 KiB
Go
|
// Copyright 2017-2018 DERO Project. All rights reserved.
|
||
|
// Use of this source code in any form is governed by RESEARCH license.
|
||
|
// license can be found in the LICENSE file.
|
||
|
// GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8
|
||
|
//
|
||
|
//
|
||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
|
||
|
package block
|
||
|
|
||
|
//import "bytes"
|
||
|
import "testing"
|
||
|
import "crypto/rand"
|
||
|
import "encoding/binary"
|
||
|
import "github.com/deroproject/derohe/cryptography/crypto"
|
||
|
|
||
|
// tests whether the purge is working as it should
|
||
|
func Test_blockmini_purge(t *testing.T) {
|
||
|
c := CreateMiniBlockCollection()
|
||
|
|
||
|
for i := 0; i < 10; i++ {
|
||
|
mbl := MiniBlock{Version: 1, Genesis: true, PastCount: 1}
|
||
|
rand.Read(mbl.Nonce[:]) // fill with randomness
|
||
|
binary.BigEndian.PutUint64(mbl.Check[:], uint64(i))
|
||
|
if err, ok := c.InsertMiniBlock(mbl); !ok {
|
||
|
t.Fatalf("error inserting miniblock err: %s", err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
c.PurgeHeight(5) // purge all miniblock <= height 5
|
||
|
|
||
|
if len(c.Collection) != 4 {
|
||
|
t.Fatalf("miniblocks not purged")
|
||
|
}
|
||
|
for _, v := range c.Collection {
|
||
|
if v.Height <= 5 {
|
||
|
t.Fatalf("purge not working correctly")
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// tests whether collision is working correctly
|
||
|
// also tests whether genesis blocks returns connected always
|
||
|
func Test_blockmini_collision(t *testing.T) {
|
||
|
c := CreateMiniBlockCollection()
|
||
|
|
||
|
mbl := MiniBlock{Version: 1, Genesis: true, PastCount: 1}
|
||
|
rand.Read(mbl.Nonce[:]) // fill with randomness
|
||
|
binary.BigEndian.PutUint64(mbl.Check[:], uint64(8))
|
||
|
|
||
|
if !c.IsConnected(mbl) { // even before inserting it should return connectd
|
||
|
t.Fatalf("genesis blocks are already connected")
|
||
|
}
|
||
|
|
||
|
if err, ok := c.InsertMiniBlock(mbl); !ok {
|
||
|
t.Fatalf("error inserting miniblock err: %s", err)
|
||
|
}
|
||
|
|
||
|
if !c.IsAlreadyInserted(mbl) {
|
||
|
t.Fatalf("already inserted block not detected")
|
||
|
}
|
||
|
|
||
|
if c.IsAlreadyInserted(mbl) != c.IsCollision(mbl) {
|
||
|
t.Fatalf("already inserted block not detected")
|
||
|
}
|
||
|
|
||
|
if !c.IsConnected(mbl) {
|
||
|
t.Fatalf("genesis blocks are already connected")
|
||
|
}
|
||
|
if c.CalculateDistance(mbl) != 0 {
|
||
|
t.Fatalf("genesis blocks should always be 0 distance")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// tests whether the timestamp sorting is working as it should
|
||
|
//
|
||
|
func Test_blockmini_timestampsorting(t *testing.T) {
|
||
|
|
||
|
for tries := 0; tries < 10000; tries++ {
|
||
|
c := CreateMiniBlockCollection()
|
||
|
|
||
|
total_count := 10
|
||
|
for i := 0; i < total_count; i++ {
|
||
|
mbl := MiniBlock{Version: 1, Genesis: true, PastCount: 1, Timestamp: uint64(256 - i)}
|
||
|
//rand.Read(mbl.Nonce[:]) // fill with randomness
|
||
|
binary.BigEndian.PutUint64(mbl.Check[:], uint64(i))
|
||
|
if err, ok := c.InsertMiniBlock(mbl); !ok {
|
||
|
t.Fatalf("error inserting miniblock err: %s", err)
|
||
|
}
|
||
|
|
||
|
//t.Logf("presorted %+v", mbl)
|
||
|
}
|
||
|
|
||
|
all_genesis := c.GetAllGenesisMiniBlocks()
|
||
|
|
||
|
if len(all_genesis) != total_count {
|
||
|
panic("corruption")
|
||
|
}
|
||
|
|
||
|
sorted_all_genesis := MiniBlocks_SortByTimeAsc(all_genesis)
|
||
|
|
||
|
for i := 0; i < len(sorted_all_genesis)-1; i++ {
|
||
|
//t.Logf("sorted %+v", sorted_all_genesis[i])
|
||
|
if sorted_all_genesis[i].Timestamp > sorted_all_genesis[i+1].Timestamp {
|
||
|
t.Fatalf("sorting of Timestamp failed")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// insert a miniblock which has timestamp collision
|
||
|
{
|
||
|
mbl := MiniBlock{Version: 1, Genesis: true, PastCount: 1, Timestamp: uint64(254)}
|
||
|
binary.BigEndian.PutUint64(mbl.Check[:], uint64(9900))
|
||
|
if err, ok := c.InsertMiniBlock(mbl); !ok {
|
||
|
t.Fatalf("error inserting miniblock err: %s", err)
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
all_genesis = c.GetAllGenesisMiniBlocks()
|
||
|
if len(all_genesis) != (total_count + 1) {
|
||
|
panic("corruption")
|
||
|
}
|
||
|
|
||
|
sorted_all_genesis = MiniBlocks_SortByTimeAsc(all_genesis)
|
||
|
for i := 0; i < len(sorted_all_genesis)-1; i++ {
|
||
|
//t.Logf("sorted %d %+v", sorted_all_genesis[i].GetMiniID(),sorted_all_genesis[i+1])
|
||
|
if sorted_all_genesis[i].Timestamp > sorted_all_genesis[i+1].Timestamp {
|
||
|
t.Fatalf("sorting of Timestamp failed")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if sorted_all_genesis[total_count-2].Height != 9900 { /// this element will be moved to this, if everything is current
|
||
|
t.Fatalf("test failed %+v", sorted_all_genesis[total_count-2])
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
// tests whether the distance sorting is working as it should
|
||
|
func Test_blockmini_distancesorting(t *testing.T) {
|
||
|
var unsorted []MiniBlock
|
||
|
|
||
|
total_count := 10
|
||
|
for i := 0; i < total_count; i++ {
|
||
|
mbl := MiniBlock{Version: 1, Genesis: true, PastCount: 1, Timestamp: uint64(256 - i), Distance: uint32(256 - i)}
|
||
|
binary.BigEndian.PutUint64(mbl.Check[:], uint64(i))
|
||
|
unsorted = append(unsorted, mbl)
|
||
|
}
|
||
|
|
||
|
// insert a miniblock which has timestamp and distance collision
|
||
|
{
|
||
|
mbl := MiniBlock{Version: 1, Genesis: true, PastCount: 1, Timestamp: uint64(254), Distance: uint32(254)}
|
||
|
mbl.Height = int64(9900)
|
||
|
unsorted = append(unsorted, mbl)
|
||
|
}
|
||
|
|
||
|
sorted_d := MiniBlocks_SortByDistanceDesc(unsorted)
|
||
|
for i := 0; i < len(sorted_d)-1; i++ {
|
||
|
// t.Logf("sorted %d %d %+v", i, sorted_d[i].GetMiniID(),sorted_d[i])
|
||
|
if sorted_d[i].Distance < sorted_d[i+1].Distance {
|
||
|
t.Fatalf("sorting of Distance failed")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if sorted_d[3].Height != 9900 { /// this element will be moved to this, if everything is current
|
||
|
t.Fatalf("test failed %+v", sorted_d[3])
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// tests whether filtering is working as it should
|
||
|
func Test_MiniBlocks_Filter(t *testing.T) {
|
||
|
var mbls []MiniBlock
|
||
|
|
||
|
total_count := uint32(10)
|
||
|
for i := uint32(0); i < total_count; i++ {
|
||
|
mbl := MiniBlock{Version: 1, Genesis: true}
|
||
|
|
||
|
if i%2 == 0 {
|
||
|
mbl.PastCount = 1
|
||
|
mbl.Past[0] = i
|
||
|
} else {
|
||
|
mbl.PastCount = 2
|
||
|
mbl.Past[0] = i
|
||
|
mbl.Past[1] = i + 1
|
||
|
}
|
||
|
binary.BigEndian.PutUint64(mbl.Check[:], uint64(i))
|
||
|
mbls = append(mbls, mbl)
|
||
|
}
|
||
|
|
||
|
for i := uint32(0); i < total_count; i++ {
|
||
|
if i%2 == 0 {
|
||
|
result := MiniBlocks_Filter(mbls, []uint32{i})
|
||
|
if len(result) != 1 {
|
||
|
t.Fatalf("failed filter")
|
||
|
}
|
||
|
if result[0].PastCount != 1 || result[0].Past[0] != i {
|
||
|
t.Fatalf("failed filter")
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
result := MiniBlocks_Filter(mbls, []uint32{i, i + 1})
|
||
|
if len(result) != 1 {
|
||
|
t.Fatalf("failed filter")
|
||
|
}
|
||
|
if result[0].PastCount != 2 || result[0].Past[0] != i || result[0].Past[1] != i+1 {
|
||
|
t.Fatalf("failed filter")
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for i := uint32(0); i < total_count; i++ {
|
||
|
if i%2 == 0 {
|
||
|
var tips [1]crypto.Hash
|
||
|
binary.BigEndian.PutUint32(tips[0][:], i)
|
||
|
result := MiniBlocks_FilterOnlyGenesis(mbls, tips[:])
|
||
|
if len(result) != 1 {
|
||
|
t.Fatalf("failed filter")
|
||
|
}
|
||
|
if result[0].PastCount != 1 || result[0].Past[0] != i {
|
||
|
t.Fatalf("failed filter")
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
var tips [2]crypto.Hash
|
||
|
binary.BigEndian.PutUint32(tips[0][:], i)
|
||
|
binary.BigEndian.PutUint32(tips[1][:], i+1)
|
||
|
result := MiniBlocks_FilterOnlyGenesis(mbls, tips[:])
|
||
|
if len(result) != 1 {
|
||
|
t.Fatalf("failed filter")
|
||
|
}
|
||
|
if result[0].PastCount != 2 || result[0].Past[0] != i || result[0].Past[1] != i+1 {
|
||
|
t.Fatalf("failed filter")
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|