293 lines
8.8 KiB
Go
293 lines
8.8 KiB
Go
|
package tests
|
||
|
|
||
|
import (
|
||
|
"crypto/sha256"
|
||
|
"encoding/hex"
|
||
|
"kerma/models"
|
||
|
"testing"
|
||
|
"time"
|
||
|
|
||
|
"github.com/docker/go/canonical/json"
|
||
|
. "github.com/smartystreets/goconvey/convey"
|
||
|
)
|
||
|
|
||
|
func TestBlock(t *testing.T) {
|
||
|
Convey("Given a new block", t, func() {
|
||
|
previd := "00000000a420b7cefa2b7730243316921ed59ffe836e111ca3801f82a4f5360e"
|
||
|
txid := "1bb37b637d07100cd26fc063dfd4c39a7931cc88dae3417871219715a5e374af"
|
||
|
block := models.Block{
|
||
|
Type: "block",
|
||
|
Txids: []string{
|
||
|
txid,
|
||
|
},
|
||
|
Nonce: "c5ee71be4ca85b160d352923a84f86f44b7fc4fe60002214bc1236ceedc5c615",
|
||
|
Previd: &previd,
|
||
|
Created: 1649827795114,
|
||
|
Target: "00000002af000000000000000000000000000000000000000000000000000000",
|
||
|
Miner: "svatsan",
|
||
|
Note: "First block. Yayy, I have 50 bu now!!",
|
||
|
}
|
||
|
|
||
|
Convey("When GetType is called, 'block' should be returned", func() {
|
||
|
So(block.GetType(), ShouldEqual, "block")
|
||
|
})
|
||
|
|
||
|
Convey("When GetEntity is called, the block should be returned", func() {
|
||
|
So(block.GetEntity(), ShouldResemble, &block)
|
||
|
})
|
||
|
|
||
|
Convey("When Validate is called, no error should be returned", func() {
|
||
|
So(block.Validate(), ShouldEqual, nil)
|
||
|
})
|
||
|
|
||
|
Convey("When ContainsTransaction is called with a correct id, 'true' should be returned", func() {
|
||
|
So(block.ContainsTransaction(txid), ShouldEqual, true)
|
||
|
})
|
||
|
|
||
|
Convey("When ContainsTransaction is called with an incorrect id, 'false' should be returned", func() {
|
||
|
So(block.ContainsTransaction("123"), ShouldEqual, false)
|
||
|
})
|
||
|
|
||
|
Convey("When Hash is called, the hash of the cannonical json and no error should be returned", func() {
|
||
|
blockJSON, _ := json.MarshalCanonical(block)
|
||
|
hashSum := sha256.Sum256(blockJSON)
|
||
|
|
||
|
res, err := block.Hash()
|
||
|
So(hex.EncodeToString(hashSum[:]), ShouldEqual, res)
|
||
|
So(err, ShouldEqual, nil)
|
||
|
})
|
||
|
})
|
||
|
|
||
|
Convey("Given the genesis block", t, func() {
|
||
|
block := models.GetGenesisBlock()
|
||
|
gid := "00000000a420b7cefa2b7730243316921ed59ffe836e111ca3801f82a4f5360e"
|
||
|
|
||
|
Convey("When GetID is called, the block id should be correct", func() {
|
||
|
bid := block.GetID()
|
||
|
So(bid, ShouldEqual, gid)
|
||
|
})
|
||
|
|
||
|
Convey("When Validate is called, no error should be returned", func() {
|
||
|
So(block.Validate(), ShouldBeNil)
|
||
|
})
|
||
|
})
|
||
|
|
||
|
Convey("Given a new incorrect block", t, func() {
|
||
|
previd := "00000000a420b7cefa2b7730243316921ed59ffe836e111ca3801f82a4f5360e"
|
||
|
txid := "1bb37b637d07100cd26fc063dfd4c39a7931cc88dae3417871219715a5e374af"
|
||
|
|
||
|
Convey("When the block is a genesis", func() {
|
||
|
block := models.Block{
|
||
|
Type: "block",
|
||
|
Txids: []string{
|
||
|
txid,
|
||
|
},
|
||
|
Nonce: "c5ee71be4ca85b160d352923a84f86f44b7fc4fe60002214bc1236ceedc5c615",
|
||
|
Previd: nil,
|
||
|
Created: 1649827795114,
|
||
|
Target: "reallyillegalgenesisblock",
|
||
|
Miner: "svatsan",
|
||
|
Note: "",
|
||
|
}
|
||
|
|
||
|
Convey("When Validate is called, an error should be returned", func() {
|
||
|
So(block.Validate().Error(), ShouldEqual, "illegal genesis block detected")
|
||
|
})
|
||
|
})
|
||
|
|
||
|
Convey("With an incorrect genesis", func() {
|
||
|
block := models.Block{
|
||
|
Type: "block",
|
||
|
Txids: []string{
|
||
|
txid,
|
||
|
},
|
||
|
Nonce: "c5ee71be4ca85b160d352923a84f86f44b7fc4fe60002214bc1236ceedc5c615",
|
||
|
Previd: &previd,
|
||
|
Created: 1649827795114,
|
||
|
Target: "reallyillegalgenesisblock",
|
||
|
Miner: "svatsan",
|
||
|
Note: "",
|
||
|
}
|
||
|
|
||
|
Convey("When Validate is called, an error should be returned", func() {
|
||
|
So(block.Validate().Error(), ShouldEqual, "incorrect target supplied")
|
||
|
})
|
||
|
})
|
||
|
|
||
|
Convey("With a timestamp before genesis", func() {
|
||
|
block := models.Block{
|
||
|
Type: "block",
|
||
|
Txids: []string{
|
||
|
txid,
|
||
|
},
|
||
|
Nonce: "c5ee71be4ca85b160d352923a84f86f44b7fc4fe60002214bc1236ceedc5c615",
|
||
|
Previd: &previd,
|
||
|
Created: 0,
|
||
|
Target: "00000002af000000000000000000000000000000000000000000000000000000",
|
||
|
Miner: "svatsan",
|
||
|
Note: "",
|
||
|
}
|
||
|
|
||
|
Convey("When Validate is called, an error should be returned", func() {
|
||
|
So(block.Validate().Error(), ShouldEqual, "timestamp before genesis block")
|
||
|
})
|
||
|
})
|
||
|
|
||
|
Convey("With a timestamp in the future", func() {
|
||
|
block := models.Block{
|
||
|
Type: "block",
|
||
|
Txids: []string{
|
||
|
txid,
|
||
|
},
|
||
|
Nonce: "c5ee71be4ca85b160d352923a84f86f44b7fc4fe60002214bc1236ceedc5c615",
|
||
|
Previd: &previd,
|
||
|
Created: time.Now().UnixMilli() + 10000000,
|
||
|
Target: "00000002af000000000000000000000000000000000000000000000000000000",
|
||
|
Miner: "svatsan",
|
||
|
Note: "",
|
||
|
}
|
||
|
|
||
|
Convey("When Validate is called, an error should be returned", func() {
|
||
|
So(block.Validate().Error(), ShouldEqual, "block created in the future")
|
||
|
})
|
||
|
})
|
||
|
|
||
|
Convey("With a miner that is a non-ASCII printible string", func() {
|
||
|
block := models.Block{
|
||
|
Type: "block",
|
||
|
Txids: []string{
|
||
|
txid,
|
||
|
},
|
||
|
Nonce: "c5ee71be4ca85b160d352923a84f86f44b7fc4fe60002214bc1236ceedc5c615",
|
||
|
Previd: &previd,
|
||
|
Created: time.Now().UnixMilli(),
|
||
|
Target: "00000002af000000000000000000000000000000000000000000000000000000",
|
||
|
Miner: "Not@nħCIIStrIng",
|
||
|
Note: "",
|
||
|
}
|
||
|
|
||
|
Convey("When Validate is called, an error should be returned", func() {
|
||
|
So(block.Validate().Error(), ShouldEqual, "miner is not an ascii printable string")
|
||
|
})
|
||
|
})
|
||
|
|
||
|
Convey("With a miner that is more than 128 characters long", func() {
|
||
|
block := models.Block{
|
||
|
Type: "block",
|
||
|
Txids: []string{
|
||
|
txid,
|
||
|
},
|
||
|
Nonce: "c5ee71be4ca85b160d352923a84f86f44b7fc4fe60002214bc1236ceedc5c615",
|
||
|
Previd: &previd,
|
||
|
Created: time.Now().UnixMilli(),
|
||
|
Target: "00000002af000000000000000000000000000000000000000000000000000000",
|
||
|
Miner: "LongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongMinerName",
|
||
|
Note: "",
|
||
|
}
|
||
|
|
||
|
Convey("When Validate is called, an error should be returned", func() {
|
||
|
So(block.Validate().Error(), ShouldEqual, "miner length incorrect")
|
||
|
})
|
||
|
})
|
||
|
|
||
|
Convey("With a note that is a non-ASCII printible string", func() {
|
||
|
block := models.Block{
|
||
|
Type: "block",
|
||
|
Txids: []string{
|
||
|
txid,
|
||
|
},
|
||
|
Nonce: "c5ee71be4ca85b160d352923a84f86f44b7fc4fe60002214bc1236ceedc5c615",
|
||
|
Previd: &previd,
|
||
|
Created: time.Now().UnixMilli(),
|
||
|
Target: "00000002af000000000000000000000000000000000000000000000000000000",
|
||
|
Miner: "",
|
||
|
Note: "Not@nħCIIStrIng",
|
||
|
}
|
||
|
|
||
|
Convey("When Validate is called, an error should be returned", func() {
|
||
|
So(block.Validate().Error(), ShouldEqual, "note is not an ascii printable string")
|
||
|
})
|
||
|
})
|
||
|
|
||
|
Convey("With a note that is more than 128 characters long", func() {
|
||
|
block := models.Block{
|
||
|
Type: "block",
|
||
|
Txids: []string{
|
||
|
txid,
|
||
|
},
|
||
|
Nonce: "c5ee71be4ca85b160d352923a84f86f44b7fc4fe60002214bc1236ceedc5c615",
|
||
|
Previd: &previd,
|
||
|
Created: time.Now().UnixMilli(),
|
||
|
Target: "00000002af000000000000000000000000000000000000000000000000000000",
|
||
|
Miner: "",
|
||
|
Note: "LongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongNote",
|
||
|
}
|
||
|
|
||
|
Convey("When Validate is called, an error should be returned", func() {
|
||
|
So(block.Validate().Error(), ShouldEqual, "note length incorrect")
|
||
|
})
|
||
|
})
|
||
|
|
||
|
Convey("With a non-hex encoded nonce", func() {
|
||
|
block := models.Block{
|
||
|
Type: "block",
|
||
|
Txids: []string{
|
||
|
txid,
|
||
|
},
|
||
|
Nonce: "AReallyIncorrectNonce",
|
||
|
Previd: &previd,
|
||
|
Created: time.Now().UnixMilli(),
|
||
|
Target: "00000002af000000000000000000000000000000000000000000000000000000",
|
||
|
Miner: "",
|
||
|
Note: "",
|
||
|
}
|
||
|
|
||
|
Convey("When Validate is called, an error should be returned", func() {
|
||
|
So(block.Validate().Error(), ShouldNotBeNil)
|
||
|
})
|
||
|
})
|
||
|
|
||
|
Convey("With a non-hex encoded previd", func() {
|
||
|
incorrectPrevId := "incorrectprevid"
|
||
|
|
||
|
block := models.Block{
|
||
|
Type: "block",
|
||
|
Txids: []string{
|
||
|
txid,
|
||
|
},
|
||
|
Nonce: "c5ee71be4ca85b160d352923a84f86f44b7fc4fe60002214bc1236ceedc5c615",
|
||
|
Previd: &incorrectPrevId,
|
||
|
Created: time.Now().UnixMilli(),
|
||
|
Target: "00000002af000000000000000000000000000000000000000000000000000000",
|
||
|
Miner: "",
|
||
|
Note: "",
|
||
|
}
|
||
|
|
||
|
Convey("When Validate is called, an error should be returned", func() {
|
||
|
So(block.Validate().Error(), ShouldNotBeNil)
|
||
|
})
|
||
|
})
|
||
|
|
||
|
Convey("With an incorrect proof-of-work equation", func() {
|
||
|
previd := "00000000a420b7cefa2b7730243316921ed59ffe836e111ca3801f82a4f5360e"
|
||
|
txid := "1bb37b637d07100cd26fc063dfd4c39a7931cc88dae3417871219715a5e37412"
|
||
|
block := models.Block{
|
||
|
Type: "block",
|
||
|
Txids: []string{
|
||
|
txid,
|
||
|
},
|
||
|
Nonce: "c5ee71be4ca85b160d352923a84f86f44b7fc4fe60002214bc1236ceedc5c615",
|
||
|
Previd: &previd,
|
||
|
Created: 1649827795114,
|
||
|
Target: "00000002af000000000000000000000000000000000000000000000000000000",
|
||
|
Miner: "svatsan",
|
||
|
Note: "First block. Yayy, I have 50 bu now!!",
|
||
|
}
|
||
|
|
||
|
Convey("When Validate is called, an error should be returned", func() {
|
||
|
So(block.Validate().Error(), ShouldNotBeNil)
|
||
|
})
|
||
|
})
|
||
|
})
|
||
|
}
|