forked from TrueCloudLab/neoneo-go
transaction: forbid serializing invalid transactions
Transaction that has no data is invalid and can't be serialized, so throw an error if someone tries to.
This commit is contained in:
parent
9374c5e7c2
commit
388fed06e5
5 changed files with 25 additions and 14 deletions
|
@ -49,7 +49,7 @@ func TestService_GetVerified(t *testing.T) {
|
||||||
|
|
||||||
p := new(Payload)
|
p := new(Payload)
|
||||||
p.SetType(payload.PrepareRequestType)
|
p.SetType(payload.PrepareRequestType)
|
||||||
p.SetPayload(&prepareRequest{transactionHashes: hashes})
|
p.SetPayload(&prepareRequest{transactionHashes: hashes, minerTx: *newMinerTx(999)})
|
||||||
p.SetValidatorIndex(1)
|
p.SetValidatorIndex(1)
|
||||||
|
|
||||||
priv, _ := getTestValidator(1)
|
priv, _ := getTestValidator(1)
|
||||||
|
|
|
@ -86,8 +86,8 @@ func newDumbBlock() *Block {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Transactions: []*transaction.Transaction{
|
Transactions: []*transaction.Transaction{
|
||||||
{Type: transaction.MinerType},
|
{Type: transaction.MinerType, Data: &transaction.MinerTX{}},
|
||||||
{Type: transaction.IssueType},
|
{Type: transaction.IssueType, Data: &transaction.IssueTX{}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,22 +105,22 @@ func TestBlockVerify(t *testing.T) {
|
||||||
assert.Nil(t, block.Verify())
|
assert.Nil(t, block.Verify())
|
||||||
|
|
||||||
block.Transactions = []*transaction.Transaction{
|
block.Transactions = []*transaction.Transaction{
|
||||||
{Type: transaction.IssueType},
|
{Type: transaction.IssueType, Data: &transaction.IssueTX{}},
|
||||||
{Type: transaction.MinerType},
|
{Type: transaction.MinerType, Data: &transaction.MinerTX{}},
|
||||||
}
|
}
|
||||||
assert.NoError(t, block.RebuildMerkleRoot())
|
assert.NoError(t, block.RebuildMerkleRoot())
|
||||||
assert.NotNil(t, block.Verify())
|
assert.NotNil(t, block.Verify())
|
||||||
|
|
||||||
block.Transactions = []*transaction.Transaction{
|
block.Transactions = []*transaction.Transaction{
|
||||||
{Type: transaction.MinerType},
|
{Type: transaction.IssueType, Data: &transaction.IssueTX{}},
|
||||||
{Type: transaction.MinerType},
|
{Type: transaction.MinerType, Data: &transaction.MinerTX{}},
|
||||||
}
|
}
|
||||||
assert.NoError(t, block.RebuildMerkleRoot())
|
assert.NoError(t, block.RebuildMerkleRoot())
|
||||||
assert.NotNil(t, block.Verify())
|
assert.NotNil(t, block.Verify())
|
||||||
block.Transactions = []*transaction.Transaction{
|
block.Transactions = []*transaction.Transaction{
|
||||||
{Type: transaction.MinerType},
|
{Type: transaction.MinerType, Data: &transaction.MinerTX{}},
|
||||||
{Type: transaction.IssueType},
|
{Type: transaction.IssueType, Data: &transaction.IssueTX{}},
|
||||||
{Type: transaction.IssueType},
|
{Type: transaction.IssueType, Data: &transaction.IssueTX{}},
|
||||||
}
|
}
|
||||||
assert.NotNil(t, block.Verify())
|
assert.NotNil(t, block.Verify())
|
||||||
}
|
}
|
||||||
|
|
|
@ -319,7 +319,7 @@ func TestGetCurrentHeaderHeight_Store(t *testing.T) {
|
||||||
|
|
||||||
func TestStoreAsTransaction(t *testing.T) {
|
func TestStoreAsTransaction(t *testing.T) {
|
||||||
dao := newDao(storage.NewMemoryStore())
|
dao := newDao(storage.NewMemoryStore())
|
||||||
tx := &transaction.Transaction{}
|
tx := &transaction.Transaction{Type: transaction.IssueType, Data: &transaction.IssueTX{}}
|
||||||
hash := tx.Hash()
|
hash := tx.Hash()
|
||||||
err := dao.StoreAsTransaction(tx, 0)
|
err := dao.StoreAsTransaction(tx, 0)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package transaction
|
package transaction
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/crypto/hash"
|
"github.com/CityOfZion/neo-go/pkg/crypto/hash"
|
||||||
|
@ -151,13 +152,15 @@ func (t *Transaction) EncodeBinary(bw *io.BinWriter) {
|
||||||
// encodeHashableFields encodes the fields that are not used for
|
// encodeHashableFields encodes the fields that are not used for
|
||||||
// signing the transaction, which are all fields except the scripts.
|
// signing the transaction, which are all fields except the scripts.
|
||||||
func (t *Transaction) encodeHashableFields(bw *io.BinWriter) {
|
func (t *Transaction) encodeHashableFields(bw *io.BinWriter) {
|
||||||
|
if t.Data == nil {
|
||||||
|
bw.Err = errors.New("transaction has no data")
|
||||||
|
return
|
||||||
|
}
|
||||||
bw.WriteB(byte(t.Type))
|
bw.WriteB(byte(t.Type))
|
||||||
bw.WriteB(byte(t.Version))
|
bw.WriteB(byte(t.Version))
|
||||||
|
|
||||||
// Underlying TXer.
|
// Underlying TXer.
|
||||||
if t.Data != nil {
|
|
||||||
t.Data.EncodeBinary(bw)
|
t.Data.EncodeBinary(bw)
|
||||||
}
|
|
||||||
|
|
||||||
// Attributes
|
// Attributes
|
||||||
bw.WriteArray(t.Attributes)
|
bw.WriteArray(t.Attributes)
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/smartcontract"
|
"github.com/CityOfZion/neo-go/pkg/smartcontract"
|
||||||
"github.com/CityOfZion/neo-go/pkg/util"
|
"github.com/CityOfZion/neo-go/pkg/util"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestWitnessEncodeDecode(t *testing.T) {
|
func TestWitnessEncodeDecode(t *testing.T) {
|
||||||
|
@ -167,3 +168,10 @@ func TestDecodePublishTX(t *testing.T) {
|
||||||
assert.Nil(t, buf.Err)
|
assert.Nil(t, buf.Err)
|
||||||
assert.Equal(t, rawPublishTX, hex.EncodeToString(buf.Bytes()))
|
assert.Equal(t, rawPublishTX, hex.EncodeToString(buf.Bytes()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEncodingTXWithNoData(t *testing.T) {
|
||||||
|
buf := io.NewBufBinWriter()
|
||||||
|
tx := &Transaction{}
|
||||||
|
tx.EncodeBinary(buf.BinWriter)
|
||||||
|
require.Error(t, buf.Err)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue