-
Notifications
You must be signed in to change notification settings - Fork 8.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
FAB-514 Default endorser,validator system chaincodes
For now, these scc are no-ops, are used to check the interfaces between endorsers and committers for the end-to-end skeleton. Over time, we will add signature and actual validation of blocks Handles JIRA issue https://jira.hyperledger.org/browse/FAB-514 (patch 3 redid goimports for importsysccs) Change-Id: I7a35ed87f83c82f14b1675b955ed5521e7fbda70 Signed-off-by: tuand27613 <tdang@us.ibm.com>
- Loading branch information
1 parent
03c4a70
commit 3f2cb2c
Showing
6 changed files
with
315 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/* | ||
Copyright IBM Corp. 2016 All Rights Reserved. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package escc | ||
|
||
import ( | ||
"errors" | ||
|
||
"github.com/hyperledger/fabric/core/chaincode/shim" | ||
//"github.com/hyperledger/fabric/core/crypto" | ||
) | ||
|
||
// EndorserOneValidSignature implements the default endorsement policy, which is to | ||
// sign the proposal hash and the read-write set | ||
type EndorserOneValidSignature struct { | ||
} | ||
|
||
// Init is called once when the chaincode started the first time | ||
func (e *EndorserOneValidSignature) Init(stub shim.ChaincodeStubInterface) ([]byte, error) { | ||
// best practice to do nothing (or very little) in Init | ||
return nil, nil | ||
} | ||
|
||
// Invoke is called to endorse the specified Proposal | ||
// For now, we sign the input and return the endorsed result. Later we can expand | ||
// the chaincode to provide more sophisticate policy processing such as enabling | ||
// policy specification to be coded as a transaction of the chaincode and Client | ||
// could select which policy to use for endorsement using parameter | ||
// @return signature of Action object or error | ||
// Note that Peer calls this function with 3 arguments, where args[0] is the | ||
// function name and args[1] is the Action object and args[2] is Proposal object | ||
func (e *EndorserOneValidSignature) Invoke(stub shim.ChaincodeStubInterface) ([]byte, error) { | ||
// args[0] - function name (not used now) | ||
// args[1] - serialized Action object | ||
// args[2] - serialized Proposal object (not used) | ||
args := stub.GetArgs() | ||
if len(args) < 3 { | ||
return nil, errors.New("Incorrect number of arguments") | ||
} | ||
|
||
if args[1] == nil { | ||
return nil, errors.New("Action object is null") | ||
} | ||
|
||
// TODO: since we are just trying to get the end-to-end happy path going, we return a fake signed proposal | ||
// Once the scc interface is updated to have a pointer to the peer SecHelper, we will compute the actual signature | ||
return []byte("true"), nil | ||
//return crypto.sign(args[1]) | ||
} | ||
|
||
// Query is here to satisfy the Chaincode interface. We don't need it for this system chaincode | ||
func (e *EndorserOneValidSignature) Query(stub shim.ChaincodeStubInterface) ([]byte, error) { | ||
return nil, nil | ||
} |
72 changes: 72 additions & 0 deletions
72
core/system_chaincode/escc/endorser_onevalidsignature_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/* | ||
Copyright IBM Corp. 2016 All Rights Reserved. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
package escc | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/golang/protobuf/proto" | ||
"github.com/hyperledger/fabric/core/chaincode/shim" | ||
pb "github.com/hyperledger/fabric/protos" | ||
) | ||
|
||
func TestInit(t *testing.T) { | ||
e := new(EndorserOneValidSignature) | ||
stub := shim.NewMockStub("endorseronevalidsignature", e) | ||
|
||
if _, err := stub.MockInit("1", nil); err != nil { | ||
fmt.Println("Init failed", err) | ||
t.FailNow() | ||
} | ||
} | ||
|
||
func TestInvoke(t *testing.T) { | ||
e := new(EndorserOneValidSignature) | ||
stub := shim.NewMockStub("endorseronevalidsignature", e) | ||
|
||
// Failed path: Not enough parameters | ||
args := [][]byte{[]byte("test")} | ||
if _, err := stub.MockInvoke("1", args); err == nil { | ||
t.Fatalf("escc invoke should have failed with invalid number of args: %v", args) | ||
} | ||
|
||
// Failed path: action struct is null | ||
args = [][]byte{[]byte("test"), []byte("action"), []byte("proposal")} | ||
args[1] = nil | ||
if _, err := stub.MockInvoke("1", args); err == nil { | ||
fmt.Println("Invoke", args, "failed", err) | ||
t.Fatalf("escc invoke should have failed with Action object is null. args: %v", args) | ||
} | ||
|
||
// Successful path | ||
args = [][]byte{[]byte("dv"), mockAction(), mockProposal()} | ||
if _, err := stub.MockInvoke("1", args); err != nil { | ||
t.Fatalf("escc invoke failed with: %v", err) | ||
} | ||
// TODO: Check sig here when we actually sign | ||
} | ||
|
||
func mockAction() []byte { | ||
action := &pb.Action{} | ||
action.ProposalHash = []byte("123") | ||
action.SimulationResult = []byte("read-write set") | ||
payload, _ := proto.Marshal(action) | ||
return payload | ||
} | ||
func mockProposal() []byte { | ||
return []byte("proposal") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/* | ||
Copyright IBM Corp. 2016 All Rights Reserved. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package vscc | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
|
||
"github.com/golang/protobuf/proto" | ||
"github.com/hyperledger/fabric/core/chaincode/shim" | ||
//"github.com/hyperledger/fabric/core/crypto" | ||
pb "github.com/hyperledger/fabric/protos" | ||
) | ||
|
||
// ValidatorOneValidSignature implements the default transaction validation policy, | ||
// which is to check the correctness of the read-write set and the endorsement | ||
// signatures | ||
type ValidatorOneValidSignature struct { | ||
} | ||
|
||
// Init is called once when the chaincode started the first time | ||
func (vscc *ValidatorOneValidSignature) Init(stub shim.ChaincodeStubInterface) ([]byte, error) { | ||
// best practice to do nothing (or very little) in Init | ||
return nil, nil | ||
} | ||
|
||
// Invoke is called to validate the specified block of transactions | ||
// This validation system chaincode will check the read-write set validity and at least 1 | ||
// correct endorsement. Later we can create more validation system | ||
// chaincodes to provide more sophisticated policy processing such as enabling | ||
// policy specification to be coded as a transaction of the chaincode and the client | ||
// selecting which policy to use for validation using parameter function | ||
// @return serialized Block of valid and invalid transactions indentified | ||
// Note that Peer calls this function with 2 arguments, where args[0] is the | ||
// function name and args[1] is the block | ||
func (vscc *ValidatorOneValidSignature) Invoke(stub shim.ChaincodeStubInterface) ([]byte, error) { | ||
// args[0] - function name (not used now) | ||
// args[1] - serialized Block object, which contains orderred transactions | ||
args := stub.GetArgs() | ||
if len(args) < 2 { | ||
return nil, errors.New("Incorrect number of arguments") | ||
} | ||
|
||
if args[1] == nil { | ||
return nil, errors.New("No block to validate") | ||
} | ||
|
||
block := &pb.Block2{} | ||
if err := proto.Unmarshal(args[1], block); err != nil { | ||
return nil, fmt.Errorf("Could not unmarshal block: %s", err) | ||
} | ||
|
||
// block.messages is an array, so we can deterministically iterate and | ||
// validate each transaction in order | ||
for _, v := range block.Transactions { | ||
tx := &pb.Transaction{} | ||
|
||
// Note: for v1, we do not have encrypted blocks | ||
|
||
if err := proto.Unmarshal(v, tx); err != nil { | ||
vscc.invalidate(tx) | ||
} else { | ||
vscc.validate(tx) | ||
} | ||
} | ||
|
||
// TODO: fill in after we get the end-to-end v1 skeleton working. Mocked returned value for now | ||
return args[1], nil | ||
} | ||
|
||
// Query is here to satisfy the Chaincode interface. We don't need it for this system chaincode | ||
func (vscc *ValidatorOneValidSignature) Query(stub shim.ChaincodeStubInterface) ([]byte, error) { | ||
return nil, nil | ||
} | ||
|
||
func (vscc *ValidatorOneValidSignature) validate(tx *pb.Transaction) { | ||
// TODO: fill in after we get the end-to-end v1 skeleton working | ||
} | ||
|
||
func (vscc *ValidatorOneValidSignature) invalidate(tx *pb.Transaction) { | ||
// TODO: fill in after we get the end-to-end v1 skeleton working | ||
} |
62 changes: 62 additions & 0 deletions
62
core/system_chaincode/vscc/validator_onevalidsignature_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/* | ||
Copyright IBM Corp. 2016 All Rights Reserved. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
package vscc | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/golang/protobuf/proto" | ||
"github.com/hyperledger/fabric/core/chaincode/shim" | ||
pb "github.com/hyperledger/fabric/protos" | ||
) | ||
|
||
func TestInit(t *testing.T) { | ||
v := new(ValidatorOneValidSignature) | ||
stub := shim.NewMockStub("validatoronevalidsignature", v) | ||
|
||
if _, err := stub.MockInit("1", nil); err != nil { | ||
t.Fatalf("vscc init failed with %v", err) | ||
} | ||
} | ||
|
||
func TestInvoke(t *testing.T) { | ||
v := new(ValidatorOneValidSignature) | ||
stub := shim.NewMockStub("validatoronevalidsignature", v) | ||
|
||
// Failed path: Invalid arguments | ||
args := [][]byte{[]byte("dv")} | ||
if _, err := stub.MockInvoke("1", args); err == nil { | ||
t.Fatalf("vscc invoke should have returned incorrect number of args: %v", args) | ||
} | ||
|
||
args = [][]byte{[]byte("dv"), []byte("tx")} | ||
args[1] = nil | ||
if _, err := stub.MockInvoke("1", args); err == nil { | ||
t.Fatalf("vscc invoke should have returned no block to validate. Input args: %v", args) | ||
} | ||
|
||
// Successful path | ||
args = [][]byte{[]byte("dv"), mockBlock()} | ||
if _, err := stub.MockInvoke("1", args); err != nil { | ||
t.Fatalf("vscc invoke failed with: %v", err) | ||
} | ||
} | ||
|
||
func mockBlock() []byte { | ||
block := &pb.Block2{} | ||
payload, _ := proto.Marshal(block) | ||
return payload | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters