203 lines
6.5 KiB
Go
203 lines
6.5 KiB
Go
|
package tests
|
||
|
|
||
|
import (
|
||
|
"crypto/sha256"
|
||
|
"encoding/hex"
|
||
|
"kerma/models"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/docker/go/canonical/json"
|
||
|
. "github.com/smartystreets/goconvey/convey"
|
||
|
)
|
||
|
|
||
|
func TestTransaction(t *testing.T) {
|
||
|
Convey("Given a new coinbase transaction", t, func() {
|
||
|
height := uint64(1)
|
||
|
transaction := models.Transaction{
|
||
|
Type: "transaction",
|
||
|
Height: &height,
|
||
|
Outputs: []models.Output{
|
||
|
{
|
||
|
Pubkey: "62b7c521cd9211579cf70fd4099315643767b96711febaa5c76dc3daf27c281c",
|
||
|
Value: 50000000000000,
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
Convey("When GetType is called, 'transaction' should be returned", func() {
|
||
|
So(transaction.GetType(), ShouldEqual, "transaction")
|
||
|
})
|
||
|
|
||
|
Convey("When GetEntity is called, the transaction should be returned", func() {
|
||
|
So(transaction.GetEntity(), ShouldResemble, &transaction)
|
||
|
})
|
||
|
|
||
|
Convey("When Validate is called, no error should be returned", func() {
|
||
|
So(transaction.Validate(), ShouldEqual, nil)
|
||
|
})
|
||
|
|
||
|
Convey("When IsCoinbaseTx is called, 'true' should be returned", func() {
|
||
|
So(transaction.IsCoinbaseTx(), ShouldEqual, true)
|
||
|
})
|
||
|
|
||
|
Convey("When IsTxInput is called, 'false' should be returned", func() {
|
||
|
So(transaction.IsTxInput("dasdfasfds"), ShouldEqual, false)
|
||
|
})
|
||
|
|
||
|
Convey("When Hash is called, the hash of the cannonical json and no error should be returned", func() {
|
||
|
transactionJSON, _ := json.MarshalCanonical(transaction)
|
||
|
hashSum := sha256.Sum256(transactionJSON)
|
||
|
|
||
|
res, err := transaction.Hash()
|
||
|
So(hex.EncodeToString(hashSum[:]), ShouldEqual, res)
|
||
|
So(err, ShouldEqual, nil)
|
||
|
})
|
||
|
})
|
||
|
|
||
|
Convey("Given a new regular transaction", t, func() {
|
||
|
transaction := models.Transaction{
|
||
|
Type: "transaction",
|
||
|
Inputs: []models.Input{
|
||
|
{
|
||
|
Outpoint: models.Outpoint{
|
||
|
Index: 0,
|
||
|
Txid: "2fb7adb654b373e85c6b5c596cc110dcb6643ee138768f4aa947e9ddb7d91f8d",
|
||
|
},
|
||
|
Sig: "1bc4c05ec180932f08b95a8b5be308bb7b90c4d047720c4953440ea7cf56ba38b7e3b52ae586b594a6ae6649d8be0ae3d6944ffe9a7c5894622c33b9df276909",
|
||
|
},
|
||
|
},
|
||
|
Outputs: []models.Output{
|
||
|
{
|
||
|
Pubkey: "857debb2084fc8c87dec10d305993e781d9c9dbf6a81762b2f245095ae6b8fb9",
|
||
|
Value: 50,
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
Convey("When GetType is called, 'transaction' should be returned", func() {
|
||
|
So(transaction.GetType(), ShouldEqual, "transaction")
|
||
|
})
|
||
|
|
||
|
Convey("When GetEntity is called, the transaction should be returned", func() {
|
||
|
So(transaction.GetEntity(), ShouldResemble, &transaction)
|
||
|
})
|
||
|
|
||
|
Convey("When Validate is called, no error should be returned", func() {
|
||
|
So(transaction.Validate(), ShouldEqual, nil)
|
||
|
})
|
||
|
|
||
|
Convey("When IsCoinbaseTx is called, 'false' should be returned", func() {
|
||
|
So(transaction.IsCoinbaseTx(), ShouldEqual, false)
|
||
|
})
|
||
|
|
||
|
Convey("When IsTxInput is called with an input, 'true' should be returned", func() {
|
||
|
So(transaction.IsTxInput("2fb7adb654b373e85c6b5c596cc110dcb6643ee138768f4aa947e9ddb7d91f8d"), ShouldEqual, true)
|
||
|
})
|
||
|
|
||
|
Convey("When IsTxInput is called with a non-input, 'false' should be returned", func() {
|
||
|
So(transaction.IsTxInput("dasdfasfds"), ShouldEqual, false)
|
||
|
})
|
||
|
|
||
|
Convey("When Hash is called, the hash of the cannonical json and no error should be returned", func() {
|
||
|
transactionJSON, _ := json.MarshalCanonical(transaction)
|
||
|
hashSum := sha256.Sum256(transactionJSON)
|
||
|
|
||
|
res, err := transaction.Hash()
|
||
|
So(hex.EncodeToString(hashSum[:]), ShouldEqual, res)
|
||
|
So(err, ShouldEqual, nil)
|
||
|
})
|
||
|
|
||
|
Convey("When VerifySign is called with a correct signature, 'true' should be returned", func() {
|
||
|
So(transaction.VerifySign("1bc4c05ec180932f08b95a8b5be308bb7b90c4d047720c4953440ea7cf56ba38b7e3b52ae586b594a6ae6649d8be0ae3d6944ffe9a7c5894622c33b9df276909", "57558a6dae91ac3ab8caf3f543eac9c51cba4ac680ba5ba0d81b5575dc06bc46"), ShouldEqual, true)
|
||
|
})
|
||
|
|
||
|
Convey("When VerifySign is called with an incorrect signature, 'false' should be returned", func() {
|
||
|
So(transaction.VerifySign("", ""), ShouldEqual, false)
|
||
|
})
|
||
|
})
|
||
|
|
||
|
Convey("Given a new incorrect regular transaction", t, func() {
|
||
|
Convey("With two inputs pointing to the same outpoint", func() {
|
||
|
transaction := models.Transaction{
|
||
|
Type: "transaction",
|
||
|
Inputs: []models.Input{
|
||
|
{
|
||
|
Outpoint: models.Outpoint{
|
||
|
Index: 0,
|
||
|
Txid: "2fb7adb654b373e85c6b5c596cc110dcb6643ee138768f4aa947e9ddb7d91f8d",
|
||
|
},
|
||
|
Sig: "1bc4c05ec180932f08b95a8b5be308bb7b90c4d047720c4953440ea7cf56ba38b7e3b52ae586b594a6ae6649d8be0ae3d6944ffe9a7c5894622c33b9df276909",
|
||
|
},
|
||
|
{
|
||
|
Outpoint: models.Outpoint{
|
||
|
Index: 0,
|
||
|
Txid: "2fb7adb654b373e85c6b5c596cc110dcb6643ee138768f4aa947e9ddb7d91f8d",
|
||
|
},
|
||
|
Sig: "1bc4c05ec180932f08b95a8b5be308bb7b90c4d047720c4953440ea7cf56ba38b7e3b52ae586b594a6ae6649d8be0ae3d6944ffe9a7c5894622c33b9df276909",
|
||
|
},
|
||
|
},
|
||
|
Outputs: []models.Output{
|
||
|
{
|
||
|
Pubkey: "857debb2084fc8c87dec10d305993e781d9c9dbf6a81762b2f245095ae6b8fb9",
|
||
|
Value: 50,
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
Convey("When Validate is called, an error should be returned", func() {
|
||
|
So(transaction.Validate().Error(), ShouldEqual, "multiple transaction inputs with same outpoint found")
|
||
|
})
|
||
|
})
|
||
|
|
||
|
Convey("With negative outpoint index value", func() {
|
||
|
transaction := models.Transaction{
|
||
|
Type: "transaction",
|
||
|
Inputs: []models.Input{
|
||
|
{
|
||
|
Outpoint: models.Outpoint{
|
||
|
Index: -10,
|
||
|
Txid: "2fb7adb654b373e85c6b5c596cc110dcb6643ee138768f4aa947e9ddb7d91f8d",
|
||
|
},
|
||
|
Sig: "1bc4c05ec180932f08b95a8b5be308bb7b90c4d047720c4953440ea7cf56ba38b7e3b52ae586b594a6ae6649d8be0ae3d6944ffe9a7c5894622c33b9df276909",
|
||
|
},
|
||
|
},
|
||
|
Outputs: []models.Output{
|
||
|
{
|
||
|
Pubkey: "857debb2084fc8c87dec10d305993e781d9c9dbf6a81762b2f245095ae6b8fb9",
|
||
|
Value: 50,
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
Convey("When Validate is called, an error should be returned", func() {
|
||
|
So(transaction.Validate().Error(), ShouldEqual, "transaction input index cannot be negative")
|
||
|
})
|
||
|
})
|
||
|
|
||
|
Convey("With a pubkey that is not hex string", func() {
|
||
|
transaction := models.Transaction{
|
||
|
Type: "transaction",
|
||
|
Inputs: []models.Input{
|
||
|
{
|
||
|
Outpoint: models.Outpoint{
|
||
|
Index: 0,
|
||
|
Txid: "2fb7adb654b373e85c6b5c596cc110dcb6643ee138768f4aa947e9ddb7d91f8d",
|
||
|
},
|
||
|
Sig: "1bc4c05ec180932f08b95a8b5be308bb7b90c4d047720c4953440ea7cf56ba38b7e3b52ae586b594a6ae6649d8be0ae3d6944ffe9a7c5894622c33b9df276909",
|
||
|
},
|
||
|
},
|
||
|
Outputs: []models.Output{
|
||
|
{
|
||
|
Pubkey: "VeryInvalidPubkeyValueWOWThisIsSoInvalidOhMyGod",
|
||
|
Value: 50,
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
Convey("When Validate is called, an error should be returned", func() {
|
||
|
So(transaction.Validate(), ShouldNotBeNil)
|
||
|
})
|
||
|
})
|
||
|
})
|
||
|
}
|