From d6ab3503bc3977b64719027faebd7dc66c2dd42a Mon Sep 17 00:00:00 2001 From: ChronosX88 Date: Thu, 3 Dec 2020 01:18:47 +0400 Subject: [PATCH] Implement payload validation manager --- consensus/pre_prepare_pool.go | 26 +++---------- consensus/validation/filecoin/filecoin.go | 39 +++++++++++++++++++ .../validation/payload_validation_manager.go | 19 +++++++++ 3 files changed, 64 insertions(+), 20 deletions(-) create mode 100644 consensus/validation/filecoin/filecoin.go create mode 100644 consensus/validation/payload_validation_manager.go diff --git a/consensus/pre_prepare_pool.go b/consensus/pre_prepare_pool.go index d33075e..6d1d0ec 100644 --- a/consensus/pre_prepare_pool.go +++ b/consensus/pre_prepare_pool.go @@ -1,13 +1,11 @@ package consensus import ( - "bytes" "fmt" + "github.com/Secured-Finance/dione/consensus/validation" rtypes "github.com/Secured-Finance/dione/rpc/types" - ftypes "github.com/Secured-Finance/dione/rpc/filecoin/types" - oracleEmitter "github.com/Secured-Finance/dione/contracts/oracleemitter" "github.com/Secured-Finance/dione/node" @@ -167,23 +165,11 @@ func (ppp *PrePreparePool) IsValidPrePrepare(prePrepare *types2.Message) bool { } ////////////////////////////////////// - // === verify filecoin message signature === - if consensusMsg.Task.OriginChain == rtypes.RPCTypeFilecoin && consensusMsg.Task.RequestType == "getTransaction" { - var msg ftypes.SignedMessage - if err := msg.UnmarshalCBOR(bytes.NewReader(consensusMsg.Task.Payload)); err != nil { - if err := msg.Message.UnmarshalCBOR(bytes.NewReader(consensusMsg.Task.Payload)); err != nil { - return false - } - } - - if msg.Type == ftypes.MessageTypeSecp256k1 { - if err = sigs.Verify(msg.Signature, msg.Message.From.Bytes(), msg.Message.Cid().Bytes()); err != nil { - logrus.Errorf("Couldn't verify transaction %v", err) - } - return true - } else { - // TODO: BLS Signature verification - return true + // === validate payload by specific-chain checks === + if validationFunc := validation.GetValidationMethod(rtypes.RPCTypeFilecoin, consensusMsg.Task.RequestType); validationFunc != nil { + err := validationFunc(consensusMsg.Task.Payload) + if err != nil { + logrus.Errorf("payload validation has failed: %v", err) } } ///////////////////////////////// diff --git a/consensus/validation/filecoin/filecoin.go b/consensus/validation/filecoin/filecoin.go new file mode 100644 index 0000000..af9322d --- /dev/null +++ b/consensus/validation/filecoin/filecoin.go @@ -0,0 +1,39 @@ +package filecoin + +import ( + "bytes" + + "github.com/Secured-Finance/dione/consensus/validation" + rtypes "github.com/Secured-Finance/dione/rpc/types" + + ftypes "github.com/Secured-Finance/dione/rpc/filecoin/types" + "github.com/Secured-Finance/dione/sigs" + "github.com/sirupsen/logrus" + "golang.org/x/xerrors" +) + +func ValidateGetTransaction(payload []byte) error { + var msg ftypes.SignedMessage + if err := msg.UnmarshalCBOR(bytes.NewReader(payload)); err != nil { + if err := msg.Message.UnmarshalCBOR(bytes.NewReader(payload)); err != nil { + return xerrors.Errorf("cannot unmarshal payload") + } + } + + if msg.Type == ftypes.MessageTypeSecp256k1 { + if err := sigs.Verify(msg.Signature, msg.Message.From.Bytes(), msg.Message.Cid().Bytes()); err != nil { + logrus.Errorf("Couldn't verify transaction %v", err) + return xerrors.Errorf("Couldn't verify transaction: %v") + } + return nil + } else { + // TODO: BLS Signature verification + return nil + } +} + +func init() { + validation.RegisterValidation(rtypes.RPCTypeFilecoin, map[string]func([]byte) error{ + "getTransaction": ValidateGetTransaction, + }) +} diff --git a/consensus/validation/payload_validation_manager.go b/consensus/validation/payload_validation_manager.go new file mode 100644 index 0000000..0eed568 --- /dev/null +++ b/consensus/validation/payload_validation_manager.go @@ -0,0 +1,19 @@ +package validation + +var validations = map[uint8]map[string]func([]byte) error{} // rpcType -> {rpcMethodName -> actual func var} + +func RegisterValidation(typ uint8, methods map[string]func([]byte) error) { + validations[typ] = methods +} + +func GetValidationMethod(typ uint8, methodName string) func([]byte) error { + rpcMethods, ok := validations[typ] + if !ok { + return nil + } + actualMethod, ok := rpcMethods[methodName] + if !ok { + return nil + } + return actualMethod +}