go_study/fabric-main/orderer/consensus/smartbft/signer_test.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)
}