Skip to content
Snippets Groups Projects
Unverified Commit 2119f233 authored by Acha Bill's avatar Acha Bill Committed by GitHub
Browse files

validate max transaction inputs count (#620)

* validate max transaction inputs count

* add tests for tx.InputsCountValid

* fix linting
parent ab0791bc
Branches
Tags
No related merge requests found
...@@ -19,4 +19,6 @@ var ( ...@@ -19,4 +19,6 @@ var (
ErrTransactionDoesNotSpendAllFunds = errors.New("transaction does not spend all funds from inputs") ErrTransactionDoesNotSpendAllFunds = errors.New("transaction does not spend all funds from inputs")
// ErrInvalidTransactionSignature is returned if the signature of a transaction is invalid. // ErrInvalidTransactionSignature is returned if the signature of a transaction is invalid.
ErrInvalidTransactionSignature = errors.New("missing or invalid transaction signature") ErrInvalidTransactionSignature = errors.New("missing or invalid transaction signature")
// ErrMaxTransactionInputCountExceeded is returned if the max number of inputs of the transaction is exceeded.
ErrMaxTransactionInputCountExceeded = errors.New("maximum transaction input count exceeded")
) )
...@@ -1593,6 +1593,11 @@ func (tangle *Tangle) ValidateTransactionToAttach(tx *transaction.Transaction) ( ...@@ -1593,6 +1593,11 @@ func (tangle *Tangle) ValidateTransactionToAttach(tx *transaction.Transaction) (
return return
} }
if !tx.InputsCountValid() {
err = ErrMaxTransactionInputCountExceeded
return
}
if !tx.SignaturesValid() { if !tx.SignaturesValid() {
err = ErrInvalidTransactionSignature err = ErrInvalidTransactionSignature
return return
......
...@@ -20,6 +20,11 @@ var ( ...@@ -20,6 +20,11 @@ var (
ErrMaxDataPayloadSizeExceeded = errors.New("maximum data payload size exceeded") ErrMaxDataPayloadSizeExceeded = errors.New("maximum data payload size exceeded")
) )
const (
// MaxTransactionInputCount is the maximum number of inputs a transaction can have
MaxTransactionInputCount = 100
)
// region IMPLEMENT Transaction //////////////////////////////////////////////////////////////////////////////////////////// // region IMPLEMENT Transaction ////////////////////////////////////////////////////////////////////////////////////////////
// Transaction represents a value transfer for IOTA. It consists out of a number of inputs, a number of outputs and their // Transaction represents a value transfer for IOTA. It consists out of a number of inputs, a number of outputs and their
...@@ -172,6 +177,11 @@ func (transaction *Transaction) SignaturesValid() bool { ...@@ -172,6 +177,11 @@ func (transaction *Transaction) SignaturesValid() bool {
return signaturesValid return signaturesValid
} }
// InputsCountValid returns true if the number of inputs in this transaction is not greater than MaxTransactionInputCount.
func (transaction *Transaction) InputsCountValid() bool {
return transaction.inputs.Size() <= MaxTransactionInputCount
}
// EssenceBytes return the bytes of the transaction excluding the Signatures. These bytes are later signed and used to // EssenceBytes return the bytes of the transaction excluding the Signatures. These bytes are later signed and used to
// generate the Signatures. // generate the Signatures.
func (transaction *Transaction) EssenceBytes() []byte { func (transaction *Transaction) EssenceBytes() []byte {
......
...@@ -204,3 +204,28 @@ func TestPutSignatureInvalid(t *testing.T) { ...@@ -204,3 +204,28 @@ func TestPutSignatureInvalid(t *testing.T) {
// valid signatures expected // valid signatures expected
assert.Equal(t, true, tx.SignaturesValid()) assert.Equal(t, true, tx.SignaturesValid())
} }
func TestInputCounts(t *testing.T) {
tx1 := createTransaction(MaxTransactionInputCount + 1, 1)
assert.False(t, tx1.InputsCountValid())
tx2 := createTransaction(MaxTransactionInputCount - 1, 1)
assert.True(t, tx2.InputsCountValid())
}
func createTransaction(inputCount int, outputCount int) *Transaction {
outputIds := make([]OutputID, 0)
for i := 0; i < inputCount; i++ {
outputIds = append(outputIds, NewOutputID(address.Random(), RandomID()))
}
inputs := NewInputs(outputIds...)
bal := balance.New(balance.ColorIOTA, 1)
outputMap := make(map[address.Address][]*balance.Balance)
for i := 0; i < outputCount; i++ {
outputMap[address.Random()] = []*balance.Balance{bal}
}
outputs := NewOutputs(outputMap)
return New(inputs, outputs)
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment