bitxhub/pkg/proof/proof_test.go

247 lines
6.7 KiB
Go

package proof
import (
"crypto/sha256"
"encoding/json"
"testing"
"time"
ruleMgr "github.com/meshplus/bitxhub-core/rule-mgr"
"github.com/meshplus/bitxhub-core/governance"
"github.com/golang/mock/gomock"
appchainMgr "github.com/meshplus/bitxhub-core/appchain-mgr"
"github.com/meshplus/bitxhub-core/validator/mock_validator"
"github.com/meshplus/bitxhub-kit/crypto"
"github.com/meshplus/bitxhub-kit/crypto/asym"
"github.com/meshplus/bitxhub-kit/log"
"github.com/meshplus/bitxhub-kit/types"
"github.com/meshplus/bitxhub-model/constant"
"github.com/meshplus/bitxhub-model/pb"
"github.com/meshplus/bitxhub/internal/executor/contracts"
"github.com/meshplus/bitxhub/internal/ledger/mock_ledger"
"github.com/stretchr/testify/require"
)
const (
from = "0x3f9d18f7c3a6e5e4c0b877fe3e688ab08840b997"
to = "0x3f9d18f7c3a6e5e4c0b877fe3e688ab08840b997"
contract = "0x3f9d18f7c3a6e5e4c0b877fe3e688ab08840b997"
)
func TestVerifyPool_CheckProof(t *testing.T) {
mockCtl := gomock.NewController(t)
mockLedger := mock_ledger.NewMockLedger(mockCtl)
mockEngine := mock_validator.NewMockEngine(mockCtl)
chain := &appchainMgr.Appchain{
ID: from,
Name: "appchain A",
Validators: "",
ConsensusType: "rbft",
ChainType: "fabric",
Desc: "",
Version: "",
PublicKey: "11111",
}
chainData, err := json.Marshal(chain)
require.Nil(t, err)
rl := &ruleMgr.Rule{
Address: contract,
}
rlData, err := json.Marshal(rl)
require.Nil(t, err)
mockLedger.EXPECT().GetState(constant.AppchainMgrContractAddr.Address(), gomock.Any()).Return(true, chainData)
mockLedger.EXPECT().GetState(constant.RuleManagerContractAddr.Address(), gomock.Any()).Return(false, rlData)
mockEngine.EXPECT().Validate(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil).AnyTimes()
vp := New(mockLedger, log.NewWithModule("test_verify"))
vp = &VerifyPool{
ledger: mockLedger,
ve: mockEngine,
logger: log.NewWithModule("test_verify"),
}
engine := vp.ValidationEngine()
require.NotNil(t, engine)
txWithNoIBTP := &pb.BxhTransaction{
From: types.NewAddressByStr(from),
To: types.NewAddressByStr(to),
IBTP: nil,
Extra: nil,
}
txWithNoIBTP.TransactionHash = txWithNoIBTP.Hash()
ok, err := vp.CheckProof(txWithNoIBTP)
require.Nil(t, err)
require.True(t, ok)
txWithNoExtra := &pb.BxhTransaction{
From: types.NewAddressByStr(from),
To: types.NewAddressByStr(to),
IBTP: getIBTP(t, 1, pb.IBTP_RECEIPT_SUCCESS, []byte("1")),
Extra: nil,
}
txWithNoExtra.TransactionHash = txWithNoIBTP.Hash()
ok, err = vp.CheckProof(txWithNoExtra)
require.NotNil(t, err)
require.False(t, ok)
txWithNotEqualProofHash := &pb.BxhTransaction{
From: types.NewAddressByStr(from),
To: types.NewAddressByStr(to),
IBTP: getIBTP(t, 1, pb.IBTP_RECEIPT_SUCCESS, []byte("222")),
Extra: []byte("1"),
}
txWithNotEqualProofHash.TransactionHash = txWithNoIBTP.Hash()
ok, err = vp.CheckProof(txWithNotEqualProofHash)
require.NotNil(t, err)
require.False(t, ok)
proof := []byte("test_proof")
proofHash := sha256.Sum256(proof)
txWithIBTP := &pb.BxhTransaction{
From: types.NewAddressByStr(from),
To: types.NewAddressByStr(to),
IBTP: getIBTP(t, 1, pb.IBTP_RECEIPT_SUCCESS, proofHash[:]),
Extra: proof,
}
txWithIBTP.TransactionHash = txWithIBTP.Hash()
ok, err = vp.CheckProof(txWithIBTP)
require.Nil(t, err)
require.True(t, ok)
proofData, ok := vp.GetProof(*txWithIBTP.Hash())
require.Nil(t, proofData)
require.False(t, ok)
vp.DeleteProof(*txWithIBTP.Hash())
}
func TestVerifyPool_CheckProof2(t *testing.T) {
mockCtl := gomock.NewController(t)
mockEngine := mock_validator.NewMockEngine(mockCtl)
chain := &appchainMgr.Appchain{
Status: governance.GovernanceAvailable,
ID: from,
Name: "appchain" + from,
Validators: "",
ConsensusType: "rbft",
ChainType: "fabric",
Desc: "",
Version: "",
PublicKey: "pubkey",
}
keys := make([]crypto.PrivateKey, 0, 4)
var bv contracts.BxhValidators
addrs := make([]string, 0, 4)
for i := 0; i < 4; i++ {
keyPair, err := asym.GenerateKeyPair(crypto.Secp256k1)
require.Nil(t, err)
keys = append(keys, keyPair)
address, err := keyPair.PublicKey().Address()
require.Nil(t, err)
addrs = append(addrs, address.String())
}
bv.Addresses = addrs
addrsData, err := json.Marshal(bv)
require.Nil(t, err)
mockEngine.EXPECT().Validate(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil).AnyTimes()
ibtp := getIBTP(t, 1, pb.IBTP_RECEIPT_SUCCESS, nil)
ibtpHash := ibtp.Hash()
hash := sha256.Sum256([]byte(ibtpHash.String()))
sign := &pb.SignResponse{Sign: make(map[string][]byte)}
for _, key := range keys {
signData, err := key.Sign(hash[:])
require.Nil(t, err)
address, err := key.PublicKey().Address()
require.Nil(t, err)
ok, err := asym.Verify(crypto.Secp256k1, signData[:], hash[:], *address)
require.Nil(t, err)
require.True(t, ok)
sign.Sign[address.String()] = signData
}
signData, err := sign.Marshal()
require.Nil(t, err)
proof := signData
ok, err := verifyMultiSign(chain, ibtp, nil)
require.NotNil(t, err)
require.False(t, ok)
chain.Validators = string(addrsData)
ok, err = verifyMultiSign(chain, ibtp, proof)
require.Nil(t, err)
require.True(t, ok)
}
func TestVerifyPool_CheckProof3(t *testing.T) {
mockCtl := gomock.NewController(t)
mockLedger := mock_ledger.NewMockLedger(mockCtl)
mockEngine := mock_validator.NewMockEngine(mockCtl)
mockLedger.EXPECT().GetState(constant.AppchainMgrContractAddr.Address(), gomock.Any()).Return(true, []byte("123"))
mockEngine.EXPECT().Validate(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(true, nil).AnyTimes()
vp := VerifyPool{
ledger: mockLedger,
ve: mockEngine,
logger: log.NewWithModule("test_verify"),
}
proof := []byte("test_proof")
proofHash := sha256.Sum256(proof)
txWithIBTP := &pb.BxhTransaction{
From: types.NewAddressByStr(from),
To: types.NewAddressByStr(to),
IBTP: getIBTP(t, 1, pb.IBTP_RECEIPT_SUCCESS, proofHash[:]),
Extra: proof,
}
txWithIBTP.TransactionHash = txWithIBTP.Hash()
ok, err := vp.CheckProof(txWithIBTP)
require.NotNil(t, err)
require.False(t, ok)
}
func getIBTP(t *testing.T, index uint64, typ pb.IBTP_Type, proof []byte) *pb.IBTP {
ct := &pb.Content{
SrcContractId: from,
DstContractId: to,
Func: "set",
Args: [][]byte{[]byte("Alice")},
}
c, err := ct.Marshal()
require.Nil(t, err)
pd := pb.Payload{
Encrypted: false,
Content: c,
}
ibtppd, err := pd.Marshal()
require.Nil(t, err)
return &pb.IBTP{
From: from,
To: to,
Payload: ibtppd,
Index: index,
Type: typ,
Proof: proof,
Timestamp: time.Now().UnixNano(),
}
}