-
Notifications
You must be signed in to change notification settings - Fork 90
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge Solution Single Key Value Storage (SKVS) (#3)
Create a solution for protecting against rollback attack. Solution: Single Key Value Storage (SKVS) Just need to apply one line of change in your chaincode main.go to use SKVS solution: ``` secretChaincode, _ := contractapi.NewChaincode(&chaincode.SecretKeeper{}) chaincode := fpc.NewSkvsChaincode(secretChaincode) ``` Skvs solution will store all the key under the main key "SKVS". before: {"Alice": "DataAlice", "Bob": "DataBob"} After: {"SKVS": {"Alice": "DataAlice", "Bob": "DataBob"} } By using this approach we are able to protect against Rollback + key mismatch problem since all the data are now just store under one single key. Special notes for your reviewer: This approach is very user friendly because you just need to change one line of your main application to get the properties of rollback protection. However, which this approach will reduce the performance of FPC a lot because it didn't perform well in concurrent situation because every changes will cause a conflict in their Transactions happened to be in a same block. Thus if developer would like to use this approach will need to make sure your application doesn't required high throughput and will expected it to update once a while. ---- * add singleKVS wrapper * able to save into single key * change to only getState Once * change storing type and add del state * refactor part 1 - private can run * refactor part 2 - skvs run successfully * remove unnecessary logging change back samples Signed-off-by: chenchanglew <[email protected]> Signed-off-by: chenchanglew <[email protected]>
- Loading branch information
1 parent
da44436
commit 5e48d42
Showing
6 changed files
with
137 additions
and
4 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
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,98 @@ | ||
/* | ||
Copyright IBM Corp. All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package enclave_go | ||
|
||
import ( | ||
"encoding/json" | ||
|
||
"github.com/hyperledger/fabric-chaincode-go/shim" | ||
pb "github.com/hyperledger/fabric-protos-go/peer" | ||
) | ||
|
||
type SkvsStubInterface struct { | ||
*FpcStubInterface | ||
allDataOld map[string][]byte | ||
allDataNew map[string][]byte | ||
key string | ||
} | ||
|
||
func NewSkvsStubInterface(stub shim.ChaincodeStubInterface, input *pb.ChaincodeInput, rwset *readWriteSet, sep StateEncryptionFunctions) shim.ChaincodeStubInterface { | ||
logger.Debugf("===== Creating New Skvs Interface =====") | ||
fpcStub := NewFpcStubInterface(stub, input, rwset, sep) | ||
skvsStub := SkvsStubInterface{fpcStub.(*FpcStubInterface), map[string][]byte{}, map[string][]byte{}, "SKVS"} | ||
err := skvsStub.InitSKVS() | ||
if err != nil { | ||
logger.Warningf("Error!! Initializing SKVS failed") | ||
} | ||
return &skvsStub | ||
} | ||
|
||
func (s *SkvsStubInterface) InitSKVS() error { | ||
// get current state, this will only operate once | ||
encValue, err := s.GetPublicState(s.key) | ||
if err != nil { | ||
return nil | ||
} | ||
|
||
if len(encValue) == 0 { | ||
logger.Debugf("SKVS is empty, Initiating.") | ||
} else { | ||
value, err := s.sep.DecryptState(encValue) | ||
if err != nil { | ||
return err | ||
} | ||
logger.Debugf("SKVS has default value, loading current value.") | ||
|
||
err = json.Unmarshal(value, &s.allDataOld) | ||
err = json.Unmarshal(value, &s.allDataNew) | ||
if err != nil { | ||
logger.Errorf("SKVS Json unmarshal error: %s", err) | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func (s *SkvsStubInterface) GetState(key string) ([]byte, error) { | ||
value := s.allDataOld[key] | ||
return value, nil | ||
} | ||
|
||
func (s *SkvsStubInterface) PutState(key string, value []byte) error { | ||
s.allDataNew[key] = value | ||
byteAllData, err := json.Marshal(s.allDataNew) | ||
if err != nil { | ||
return err | ||
} | ||
encValue, err := s.sep.EncryptState(byteAllData) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return s.PutPublicState(s.key, encValue) | ||
} | ||
|
||
func (s *SkvsStubInterface) DelState(key string) error { | ||
delete(s.allDataNew, key) | ||
byteAllData, err := json.Marshal(s.allDataNew) | ||
if err != nil { | ||
return err | ||
} | ||
encValue, err := s.sep.EncryptState(byteAllData) | ||
if err != nil { | ||
return err | ||
} | ||
return s.PutPublicState(s.key, encValue) | ||
} | ||
|
||
func (s *SkvsStubInterface) GetStateByRange(startKey string, endKey string) (shim.StateQueryIteratorInterface, error) { | ||
panic("not implemented") // TODO: Implement | ||
} | ||
|
||
func (s *SkvsStubInterface) GetStateByRangeWithPagination(startKey string, endKey string, pageSize int32, bookmark string) (shim.StateQueryIteratorInterface, *pb.QueryResponseMetadata, error) { | ||
panic("not implemented") // TODO: Implement | ||
} |
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,29 @@ | ||
/* | ||
Copyright IBM Corp. All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package chaincode | ||
|
||
import ( | ||
"github.com/hyperledger/fabric-chaincode-go/shim" | ||
"github.com/hyperledger/fabric-private-chaincode/ecc/chaincode" | ||
"github.com/hyperledger/fabric-private-chaincode/ecc/chaincode/ercc" | ||
"github.com/hyperledger/fabric-private-chaincode/ecc_go/chaincode/enclave_go" | ||
"github.com/hyperledger/fabric-private-chaincode/internal/endorsement" | ||
"github.com/hyperledger/fabric/common/flogging" | ||
) | ||
|
||
var logger = flogging.MustGetLogger("enclave_go") | ||
|
||
func NewSkvsChaincode(cc shim.Chaincode) *chaincode.EnclaveChaincode { | ||
newStubInterfaceFunc := enclave_go.NewSkvsStubInterface | ||
ecc := &chaincode.EnclaveChaincode{ | ||
Enclave: enclave_go.NewEnclaveStub(cc, newStubInterfaceFunc), | ||
Validator: endorsement.NewValidator(), | ||
Extractor: &chaincode.ExtractorImpl{}, | ||
Ercc: &ercc.StubImpl{}, | ||
} | ||
return ecc | ||
} |
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