Skip to content

Commit 86570ca

Browse files
Merge branch 'master' into alex/storage-doc-guidelines
2 parents 9310821 + 3fad9fe commit 86570ca

File tree

260 files changed

+18342
-3384
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

260 files changed

+18342
-3384
lines changed

.dockerignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# Do not copy the user's project git directory into the container
2+
# it's not needed to build the project, and causes issues when working within git worktrees
3+
.git/
4+
15
integration/localnet/bootstrap/
26
integration/localnet/profiler/
37
integration/localnet/data/

access/api.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ type TransactionsAPI interface {
5757
GetTransactionResultByIndex(ctx context.Context, blockID flow.Identifier, index uint32, encodingVersion entities.EventEncodingVersion) (*accessmodel.TransactionResult, error)
5858
GetTransactionResultsByBlockID(ctx context.Context, blockID flow.Identifier, encodingVersion entities.EventEncodingVersion) ([]*accessmodel.TransactionResult, error)
5959

60-
GetSystemTransaction(ctx context.Context, blockID flow.Identifier) (*flow.TransactionBody, error)
61-
GetSystemTransactionResult(ctx context.Context, blockID flow.Identifier, encodingVersion entities.EventEncodingVersion) (*accessmodel.TransactionResult, error)
60+
GetSystemTransaction(ctx context.Context, txID flow.Identifier, blockID flow.Identifier) (*flow.TransactionBody, error)
61+
GetSystemTransactionResult(ctx context.Context, txID flow.Identifier, blockID flow.Identifier, encodingVersion entities.EventEncodingVersion) (*accessmodel.TransactionResult, error)
6262
}
6363

6464
type TransactionStreamAPI interface {

access/mock/api.go

Lines changed: 18 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

access/validator/errors.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,24 @@ func (e DuplicatedSignatureError) Error() string {
7777
return fmt.Sprintf("duplicated signature for key (address: %s, index: %d)", e.Address.String(), e.KeyIndex)
7878
}
7979

80-
// InvalidSignatureError indicates that a transaction contains a signature
80+
// InvalidRawSignatureError indicates that a transaction contains a cryptographic raw signature
8181
// with a wrong format.
82-
type InvalidSignatureError struct {
82+
type InvalidRawSignatureError struct {
8383
Signature flow.TransactionSignature
8484
}
8585

86-
func (e InvalidSignatureError) Error() string {
87-
return fmt.Sprintf("invalid signature: %s", e.Signature)
86+
func (e InvalidRawSignatureError) Error() string {
87+
return fmt.Sprintf("the cryptographic signature within the transaction signature has an invalid format: %s", e.Signature)
88+
}
89+
90+
// InvalidAuthenticationSchemeFormatError indicates that a transaction contains a signature
91+
// with a wrong format.
92+
type InvalidAuthenticationSchemeFormatError struct {
93+
Signature flow.TransactionSignature
94+
}
95+
96+
func (e InvalidAuthenticationSchemeFormatError) Error() string {
97+
return fmt.Sprintf("the transaction signature has invalid extension data: %s", e.Signature)
8898
}
8999

90100
// InvalidTxByteSizeError indicates that a transaction byte size exceeds the maximum.

access/validator/validator.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,20 @@ func (v *TransactionValidator) checkSignatureDuplications(tx *flow.TransactionBo
428428
}
429429

430430
func (v *TransactionValidator) checkSignatureFormat(tx *flow.TransactionBody) error {
431+
for _, signature := range tx.PayloadSignatures {
432+
valid, _ := signature.ValidateExtensionDataAndReconstructMessage(tx.PayloadMessage())
433+
if !valid {
434+
return InvalidAuthenticationSchemeFormatError{Signature: signature}
435+
}
436+
}
437+
438+
for _, signature := range tx.EnvelopeSignatures {
439+
valid, _ := signature.ValidateExtensionDataAndReconstructMessage(tx.EnvelopeMessage())
440+
if !valid {
441+
return InvalidAuthenticationSchemeFormatError{Signature: signature}
442+
}
443+
}
444+
431445
for _, signature := range append(tx.PayloadSignatures, tx.EnvelopeSignatures...) {
432446
// check the format of the signature is valid.
433447
// a valid signature is an ECDSA signature of either P-256 or secp256k1 curve.
@@ -451,7 +465,7 @@ func (v *TransactionValidator) checkSignatureFormat(tx *flow.TransactionBody) er
451465
continue
452466
}
453467

454-
return InvalidSignatureError{Signature: signature}
468+
return InvalidRawSignatureError{Signature: signature}
455469
}
456470

457471
return nil

access/validator/validator_test.go

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ package validator_test
22

33
import (
44
"context"
5+
"encoding/hex"
56
"errors"
67
"testing"
78

89
"github.com/onflow/cadence"
910
"github.com/onflow/cadence/common"
1011
"github.com/stretchr/testify/assert"
1112
"github.com/stretchr/testify/mock"
13+
"github.com/stretchr/testify/require"
1214
"github.com/stretchr/testify/suite"
1315

1416
jsoncdc "github.com/onflow/cadence/encoding/json"
@@ -206,5 +208,102 @@ func (s *TransactionValidatorSuite) TestTransactionValidator_SealedIndexedHeight
206208

207209
err = validator.Validate(context.Background(), &txBody)
208210
assert.NoError(s.T(), err)
211+
}
212+
213+
func (s *TransactionValidatorSuite) TestTransactionValidator_SignatureValidation() {
214+
scriptExecutor := execmock.NewScriptExecutor(s.T())
215+
216+
// setting indexed height to be behind of sealed by bigger number than allowed(DefaultSealedIndexedHeightThreshold)
217+
indexedHeight := s.header.Height - 40
218+
219+
s.blocks.
220+
On("IndexedHeight").
221+
Return(indexedHeight, nil)
222+
223+
validator, err := validator.NewTransactionValidator(s.blocks, s.chain, s.metrics, s.validatorOptions, scriptExecutor)
224+
assert.NoError(s.T(), err)
225+
assert.NotNil(s.T(), validator)
226+
227+
// valid format signature
228+
ecdsaSignatureFixtureStr := "0f9c37c155fbb656d2049a8349a0fcd2dedfe27d1588c2f635f60df2052141c17f2e195790c55ce42c4f73b5cc7e194060fee641818e8d640e69f92d4777518d"
229+
ecdsaSignatureFixture, err := hex.DecodeString(ecdsaSignatureFixtureStr)
230+
require.NoError(s.T(), err)
209231

232+
address := unittest.AddressFixture()
233+
transactionBody := flow.TransactionBody{
234+
Script: []byte("some script"),
235+
Arguments: [][]byte{
236+
[]byte("arg1"),
237+
},
238+
ReferenceBlockID: flow.HashToID([]byte("some block id")),
239+
GasLimit: 1000,
240+
Payer: address,
241+
ProposalKey: flow.ProposalKey{
242+
Address: address,
243+
KeyIndex: 0,
244+
SequenceNumber: 0,
245+
},
246+
Authorizers: []flow.Address{
247+
address,
248+
},
249+
PayloadSignatures: []flow.TransactionSignature{
250+
{
251+
Address: address,
252+
KeyIndex: 0,
253+
Signature: ecdsaSignatureFixture,
254+
SignerIndex: 0,
255+
ExtensionData: unittest.RandomBytes(3),
256+
},
257+
},
258+
EnvelopeSignatures: []flow.TransactionSignature{
259+
{
260+
Address: address,
261+
KeyIndex: 1,
262+
Signature: ecdsaSignatureFixture,
263+
SignerIndex: 0,
264+
ExtensionData: unittest.RandomBytes(3),
265+
},
266+
},
267+
}
268+
269+
// detailed cases of signature validation are tested in model/flow/transaction_test.go
270+
cases := []struct {
271+
payloadSigExtensionData []byte
272+
EnvelopeSigExtensionData []byte
273+
shouldError bool
274+
}{
275+
{
276+
// happy path
277+
payloadSigExtensionData: nil,
278+
EnvelopeSigExtensionData: nil,
279+
shouldError: false,
280+
},
281+
{
282+
// invalid payload transaction
283+
payloadSigExtensionData: []byte{10},
284+
EnvelopeSigExtensionData: nil,
285+
shouldError: true,
286+
}, {
287+
// invalid envelope transaction
288+
payloadSigExtensionData: nil,
289+
EnvelopeSigExtensionData: []byte{10},
290+
shouldError: true,
291+
}, {
292+
// invalid envelope and payload transactions
293+
payloadSigExtensionData: []byte{10},
294+
EnvelopeSigExtensionData: []byte{10},
295+
shouldError: true,
296+
},
297+
}
298+
// test all cases
299+
for _, c := range cases {
300+
transactionBody.PayloadSignatures[0].ExtensionData = c.payloadSigExtensionData
301+
transactionBody.EnvelopeSignatures[0].ExtensionData = c.EnvelopeSigExtensionData
302+
err = validator.Validate(context.Background(), &transactionBody)
303+
if c.shouldError {
304+
assert.Error(s.T(), err)
305+
} else {
306+
assert.NoError(s.T(), err)
307+
}
308+
}
210309
}

0 commit comments

Comments
 (0)