enforce mutually-exclusive coveredfields

parent 7a27e6c6
Pipeline #32723198 passed with stages
in 27 minutes and 10 seconds
......@@ -163,15 +163,15 @@ func TestSignTransaction(t *testing.T) {
UnlockHash: types.UnlockHash{},
}},
TransactionSignatures: []types.TransactionSignature{
{ParentID: crypto.Hash(outputs[0].ID)},
{ParentID: crypto.Hash(outputs[1].ID)},
{ParentID: crypto.Hash(outputs[0].ID), CoveredFields: types.CoveredFields{WholeTransaction: true}},
{ParentID: crypto.Hash(outputs[1].ID), CoveredFields: types.CoveredFields{WholeTransaction: true}},
},
}
// sign the first input
signResp, err := testNode.WalletSignPost(txn, []crypto.Hash{txn.TransactionSignatures[0].ParentID})
if err != nil {
t.Fatal("failed to sign the transaction", err)
t.Fatal("failed to sign the transaction:", err)
}
txn = signResp.Transaction
......@@ -185,7 +185,7 @@ func TestSignTransaction(t *testing.T) {
// sign the second input
signResp, err = testNode.WalletSignPost(txn, []crypto.Hash{txn.TransactionSignatures[1].ParentID})
if err != nil {
t.Fatal("failed to sign the transaction", err)
t.Fatal("failed to sign the transaction:", err)
}
txn = signResp.Transaction
......@@ -197,7 +197,7 @@ func TestSignTransaction(t *testing.T) {
// the resulting transaction should be valid; submit it to the tpool and
// mine a block to confirm it
if err := testNode.TransactionPoolRawPost(txn, nil); err != nil {
t.Fatal("failed to add transaction to pool", err)
t.Fatal("failed to add transaction to pool:", err)
}
if err := testNode.MineBlock(); err != nil {
t.Fatal("failed to mine block", err)
......
......@@ -270,15 +270,27 @@ func (t Transaction) validCoveredFields() error {
{cf.TransactionSignatures, len(t.TransactionSignatures)},
}
// Check that all fields are empty if 'WholeTransaction' is set, except
// for the Signatures field which isn't affected.
if cf.WholeTransaction {
// 'WholeTransaction' does not check signatures.
// If WholeTransaction is set, all fields must be
// empty, except TransactionSignatures.
for _, fieldMax := range fieldMaxs[:len(fieldMaxs)-1] {
if len(fieldMax.field) != 0 {
return ErrWholeTransactionViolation
}
}
} else {
// If WholeTransaction is not set, at least one field
// must be non-empty.
allEmpty := true
for _, fieldMax := range fieldMaxs {
if len(fieldMax.field) != 0 {
allEmpty = false
break
}
}
if allEmpty {
return ErrWholeTransactionViolation
}
}
// Check that all fields are sorted, and without repeat values, and
......
......@@ -104,7 +104,7 @@ func TestSortedUnique(t *testing.T) {
}
}
// TestTransactionValidCoveredFields probes the validCoveredFields menthod of
// TestTransactionValidCoveredFields probes the validCoveredFields method of
// the transaction type.
func TestTransactionValidCoveredFields(t *testing.T) {
if testing.Short() {
......@@ -123,13 +123,9 @@ func TestTransactionValidCoveredFields(t *testing.T) {
SiafundOutputs: []SiafundOutput{{}},
MinerFees: []Currency{{}},
ArbitraryData: [][]byte{{'o'}, {'t'}},
TransactionSignatures: []TransactionSignature{
{
CoveredFields: CoveredFields{
WholeTransaction: true,
},
},
},
TransactionSignatures: []TransactionSignature{{
CoveredFields: CoveredFields{WholeTransaction: true},
}},
}
err := txn.validCoveredFields()
if err != nil {
......@@ -175,6 +171,13 @@ func TestTransactionValidCoveredFields(t *testing.T) {
if err != ErrSortedUniqueViolation {
t.Error("Expecting ErrSortedUniqueViolation, got", err)
}
// Clear the CoveredFields completely.
txn.TransactionSignatures[0].CoveredFields = CoveredFields{}
err = txn.validCoveredFields()
if err != ErrWholeTransactionViolation {
t.Error("Expecting ErrWholeTransactionViolation, got", err)
}
}
// TestTransactionValidSignatures probes the validSignatures method of the
......@@ -227,9 +230,9 @@ func TestTransactionValidSignatures(t *testing.T) {
// The second signatures should always work for being unrecognized
// types.
{PublicKeyIndex: 1},
{PublicKeyIndex: 1},
{PublicKeyIndex: 1},
{PublicKeyIndex: 1, CoveredFields: CoveredFields{WholeTransaction: true}},
{PublicKeyIndex: 1, CoveredFields: CoveredFields{WholeTransaction: true}},
{PublicKeyIndex: 1, CoveredFields: CoveredFields{WholeTransaction: true}},
}
txn.TransactionSignatures[1].ParentID[0] = 1
txn.TransactionSignatures[2].ParentID[0] = 2
......@@ -290,7 +293,7 @@ func TestTransactionValidSignatures(t *testing.T) {
txn.SiafundInputs = txn.SiafundInputs[:len(txn.SiafundInputs)-1]
// Add a frivolous signature
txn.TransactionSignatures = append(txn.TransactionSignatures, TransactionSignature{})
txn.TransactionSignatures = append(txn.TransactionSignatures, TransactionSignature{CoveredFields: CoveredFields{WholeTransaction: true}})
err = txn.validSignatures(10)
if err != ErrFrivolousSignature {
t.Error(err)
......@@ -301,7 +304,7 @@ func TestTransactionValidSignatures(t *testing.T) {
// signature. This should get rejected because the always-accepted
// signature has already been used.
tmpTxn0 := txn.TransactionSignatures[0]
txn.TransactionSignatures[0] = TransactionSignature{PublicKeyIndex: 1}
txn.TransactionSignatures[0] = TransactionSignature{PublicKeyIndex: 1, CoveredFields: CoveredFields{WholeTransaction: true}}
err = txn.validSignatures(10)
if err != ErrPublicKeyOveruse {
t.Error(err)
......@@ -315,7 +318,7 @@ func TestTransactionValidSignatures(t *testing.T) {
}
// Try to spend an entropy signature.
txn.TransactionSignatures[0] = TransactionSignature{PublicKeyIndex: 2}
txn.TransactionSignatures[0] = TransactionSignature{PublicKeyIndex: 2, CoveredFields: CoveredFields{WholeTransaction: true}}
err = txn.validSignatures(10)
if err != ErrEntropyKey {
t.Error(err)
......@@ -323,7 +326,7 @@ func TestTransactionValidSignatures(t *testing.T) {
txn.TransactionSignatures[0] = tmpTxn0
// Try to point to a nonexistent public key.
txn.TransactionSignatures[0] = TransactionSignature{PublicKeyIndex: 5}
txn.TransactionSignatures[0] = TransactionSignature{PublicKeyIndex: 5, CoveredFields: CoveredFields{WholeTransaction: true}}
err = txn.validSignatures(10)
if err != ErrInvalidPubKeyIndex {
t.Error(err)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment