Skip to content

Commit 012f0b5

Browse files
author
Luis Sanchez
committed
[FAB-1242] Reject messages larger than AbsoluteMaxSize
- Add MaxBytesRule() - Add MaxBytesRule to default standard & system chain filters. Change-Id: I82b74cf8727278867e032f24c9b828c9563c7896 Signed-off-by: Luis Sanchez <[email protected]>
1 parent f68a97e commit 012f0b5

File tree

4 files changed

+114
-3
lines changed

4 files changed

+114
-3
lines changed

orderer/common/filter/filter.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const (
3434
Forward
3535
)
3636

37-
// Rule defines a filter function which accepts, rejects, or forwards (to the next rule) a Envelope
37+
// Rule defines a filter function which accepts, rejects, or forwards (to the next rule) an Envelope
3838
type Rule interface {
3939
// Apply applies the rule to the given Envelope, replying with the Action to take for the message
4040
// If the filter Accepts a message, it should provide a committer to use when writing the message to the chain
@@ -55,7 +55,7 @@ type noopCommitter struct{}
5555
func (nc noopCommitter) Commit() {}
5656
func (nc noopCommitter) Isolated() bool { return false }
5757

58-
// NoopCommitter does nothing on commit and is not isolate
58+
// NoopCommitter does nothing on commit and is not isolated
5959
var NoopCommitter = Committer(noopCommitter{})
6060

6161
// EmptyRejectRule rejects empty messages
@@ -91,7 +91,7 @@ func NewRuleSet(rules []Rule) *RuleSet {
9191
}
9292
}
9393

94-
// Filter applies the rules given for this set in order, returning the committer, nil on valid, or nil, err on invalid
94+
// Apply applies the rules given for this set in order, returning the committer, nil on valid, or nil, err on invalid
9595
func (rs *RuleSet) Apply(message *ab.Envelope) (Committer, error) {
9696
for _, rule := range rs.rules {
9797
action, committer := rule.Apply(message)
+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
Copyright IBM Corp. 2016 All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package sizefilter
18+
19+
import (
20+
"github.com/hyperledger/fabric/orderer/common/filter"
21+
ab "github.com/hyperledger/fabric/protos/common"
22+
logging "github.com/op/go-logging"
23+
)
24+
25+
var logger = logging.MustGetLogger("orderer/common/sizefilter")
26+
27+
// MaxBytesRule rejects messages larger than maxBytes
28+
func MaxBytesRule(maxBytes uint32) filter.Rule {
29+
return &maxBytesRule{maxBytes: maxBytes}
30+
}
31+
32+
type maxBytesRule struct {
33+
maxBytes uint32
34+
}
35+
36+
func (r *maxBytesRule) Apply(message *ab.Envelope) (filter.Action, filter.Committer) {
37+
if size := messageByteSize(message); size > r.maxBytes {
38+
logger.Warningf("%d byte message payload exceeds maximum allowed %d bytes", size, r.maxBytes)
39+
return filter.Reject, nil
40+
}
41+
return filter.Forward, nil
42+
}
43+
44+
func messageByteSize(message *ab.Envelope) uint32 {
45+
return uint32(len(message.Payload) + len(message.Signature))
46+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
Copyright IBM Corp. 2016 All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package sizefilter
18+
19+
import (
20+
"testing"
21+
22+
"github.com/golang/protobuf/proto"
23+
"github.com/hyperledger/fabric/orderer/common/filter"
24+
cb "github.com/hyperledger/fabric/protos/common"
25+
)
26+
27+
func TestMaxBytesRule(t *testing.T) {
28+
dataSize := uint32(100)
29+
maxBytes := calcMessageBytesForPayloadDataSize(dataSize)
30+
rs := filter.NewRuleSet([]filter.Rule{MaxBytesRule(maxBytes), filter.AcceptRule})
31+
32+
t.Run("LessThan", func(t *testing.T) {
33+
_, err := rs.Apply(makeMessage(make([]byte, dataSize-1)))
34+
if err != nil {
35+
t.Fatalf("Should have accepted")
36+
}
37+
})
38+
t.Run("Exact", func(t *testing.T) {
39+
_, err := rs.Apply(makeMessage(make([]byte, dataSize)))
40+
if err != nil {
41+
t.Fatalf("Should have accepted")
42+
}
43+
})
44+
t.Run("TooBig", func(t *testing.T) {
45+
_, err := rs.Apply(makeMessage(make([]byte, dataSize+1)))
46+
if err == nil {
47+
t.Fatalf("Should have rejected")
48+
}
49+
})
50+
}
51+
52+
func calcMessageBytesForPayloadDataSize(dataSize uint32) uint32 {
53+
return messageByteSize(makeMessage(make([]byte, dataSize)))
54+
}
55+
56+
func makeMessage(data []byte) *cb.Envelope {
57+
data, err := proto.Marshal(&cb.Payload{Data: data})
58+
if err != nil {
59+
panic(err)
60+
}
61+
return &cb.Envelope{Payload: data}
62+
}

orderer/multichain/chainsupport.go

+3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/hyperledger/fabric/orderer/common/filter"
2626
"github.com/hyperledger/fabric/orderer/common/sharedconfig"
2727
"github.com/hyperledger/fabric/orderer/common/sigfilter"
28+
"github.com/hyperledger/fabric/orderer/common/sizefilter"
2829
"github.com/hyperledger/fabric/orderer/rawledger"
2930
cb "github.com/hyperledger/fabric/protos/common"
3031
"github.com/hyperledger/fabric/protos/utils"
@@ -138,6 +139,7 @@ func newChainSupport(
138139
func createStandardFilters(configManager configtx.Manager, policyManager policies.Manager, sharedConfig sharedconfig.Manager) *filter.RuleSet {
139140
return filter.NewRuleSet([]filter.Rule{
140141
filter.EmptyRejectRule,
142+
sizefilter.MaxBytesRule(sharedConfig.BatchSize().AbsoluteMaxBytes),
141143
sigfilter.New(sharedConfig.IngressPolicy, policyManager),
142144
configtx.NewFilter(configManager),
143145
filter.AcceptRule,
@@ -149,6 +151,7 @@ func createStandardFilters(configManager configtx.Manager, policyManager policie
149151
func createSystemChainFilters(ml *multiLedger, configManager configtx.Manager, policyManager policies.Manager, sharedConfig sharedconfig.Manager) *filter.RuleSet {
150152
return filter.NewRuleSet([]filter.Rule{
151153
filter.EmptyRejectRule,
154+
sizefilter.MaxBytesRule(sharedConfig.BatchSize().AbsoluteMaxBytes),
152155
sigfilter.New(sharedConfig.IngressPolicy, policyManager),
153156
newSystemChainFilter(ml),
154157
configtx.NewFilter(configManager),

0 commit comments

Comments
 (0)