124 lines
3.5 KiB
Go
124 lines
3.5 KiB
Go
/*
|
|
Copyright IBM Corp. All Rights Reserved.
|
|
|
|
SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
package smartbft_test
|
|
|
|
import (
|
|
"errors"
|
|
"sync/atomic"
|
|
"testing"
|
|
|
|
"github.com/SmartBFT-Go/consensus/pkg/types"
|
|
"github.com/golang/protobuf/proto"
|
|
cb "github.com/hyperledger/fabric-protos-go/common"
|
|
"github.com/hyperledger/fabric/common/flogging"
|
|
"github.com/hyperledger/fabric/orderer/consensus/smartbft"
|
|
"github.com/hyperledger/fabric/orderer/consensus/smartbft/mocks"
|
|
"github.com/hyperledger/fabric/protoutil"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/mock"
|
|
)
|
|
|
|
func TestSigner(t *testing.T) {
|
|
ss := &mocks.SignerSerializer{}
|
|
s := &smartbft.Signer{
|
|
SignerSerializer: ss,
|
|
Logger: flogging.MustGetLogger("test"),
|
|
ID: 3,
|
|
}
|
|
|
|
t.Run("signing fails", func(t *testing.T) {
|
|
ss.On("Sign", mock.Anything).Return(nil, errors.New("foo")).Once()
|
|
assert.PanicsWithValue(t, "Failed signing message: foo", func() {
|
|
s.Sign(nil)
|
|
})
|
|
})
|
|
|
|
t.Run("signing succeeds", func(t *testing.T) {
|
|
ss.On("Sign", mock.Anything).Return([]byte{1, 2, 3}, nil).Once()
|
|
assert.Equal(t, []byte{1, 2, 3}, s.Sign(nil))
|
|
})
|
|
}
|
|
|
|
func TestSignProposal(t *testing.T) {
|
|
ss := &mocks.SignerSerializer{}
|
|
ss.On("Sign", mock.Anything).Return([]byte{1, 2, 3}, nil).Once()
|
|
ss.On("Serialize", mock.Anything).Return([]byte{0, 2, 4, 6}, nil).Once()
|
|
ss.On("NewSignatureHeader", mock.Anything).Return(&cb.SignatureHeader{
|
|
Creator: []byte{0, 2, 4, 6},
|
|
}, nil)
|
|
|
|
s := &smartbft.Signer{
|
|
SignerSerializer: ss,
|
|
Logger: flogging.MustGetLogger("test"),
|
|
ID: 3,
|
|
LastConfigBlockNum: func(_ *cb.Block) uint64 {
|
|
return 10
|
|
},
|
|
}
|
|
|
|
lastBlock := makeNonConfigBlock(19, 10)
|
|
lastConfigBlock := makeConfigBlock(10)
|
|
ledger := &mocks.Ledger{}
|
|
ledger.On("Height").Return(uint64(20))
|
|
ledger.On("Block", uint64(19)).Return(lastBlock)
|
|
ledger.On("Block", uint64(10)).Return(lastConfigBlock)
|
|
|
|
logger := flogging.MustGetLogger("test")
|
|
|
|
assembler := &smartbft.Assembler{
|
|
VerificationSeq: func() uint64 {
|
|
return 0
|
|
},
|
|
Logger: logger,
|
|
RuntimeConfig: &atomic.Value{},
|
|
}
|
|
|
|
rtc := smartbft.RuntimeConfig{
|
|
LastBlock: smartbft.LastBlockFromLedgerOrPanic(ledger, logger),
|
|
LastConfigBlock: smartbft.LastConfigBlockFromLedgerOrPanic(ledger, logger),
|
|
}
|
|
|
|
assembler.RuntimeConfig.Store(rtc)
|
|
|
|
env := protoutil.MarshalOrPanic(&cb.Envelope{Payload: []byte{1, 2, 3, 4, 5}})
|
|
prop := assembler.AssembleProposal(nil, [][]byte{env})
|
|
|
|
sig := s.SignProposal(prop, nil)
|
|
assert.NotNil(t, sig)
|
|
|
|
signature := smartbft.Signature{}
|
|
signature.Unmarshal(sig.Msg)
|
|
|
|
assert.Equal(t, s.ID, sig.ID)
|
|
assert.Equal(t, []byte{1, 2, 3}, sig.Value)
|
|
assert.Equal(t, prop.Header, signature.BlockHeader)
|
|
sigHdr := &cb.SignatureHeader{}
|
|
assert.NoError(t, proto.Unmarshal(signature.IdentifierHeader, sigHdr))
|
|
assert.Nil(t, sigHdr.Creator)
|
|
assert.Equal(t, signature.OrdererBlockMetadata, protoutil.MarshalOrPanic(&cb.OrdererBlockMetadata{
|
|
LastConfig: &cb.LastConfig{Index: 10},
|
|
ConsenterMetadata: prop.Metadata,
|
|
}))
|
|
}
|
|
|
|
func TestSignBadProposal(t *testing.T) {
|
|
ss := &mocks.SignerSerializer{}
|
|
ss.On("Sign", mock.Anything).Return([]byte{1, 2, 3}, nil).Once()
|
|
ss.On("Serialize", mock.Anything).Return([]byte{0, 2, 4, 6}, nil)
|
|
|
|
s := &smartbft.Signer{
|
|
SignerSerializer: ss,
|
|
Logger: flogging.MustGetLogger("test"),
|
|
ID: 3,
|
|
}
|
|
|
|
f := func() {
|
|
s.SignProposal(types.Proposal{}, nil)
|
|
}
|
|
assert.PanicsWithValue(t, "Tried to sign bad proposal: proposal header cannot be nil", f)
|
|
}
|