Skip to content

Commit

Permalink
Merge pull request #16 from mbrandenburger/fab-1.4
Browse files Browse the repository at this point in the history
Add Fabric 1.4 support; also update SGX SDK and nanopb deps
  • Loading branch information
mbrandenburger authored Mar 5, 2019
2 parents e1182f1 + 41c4e6c commit 90c1c23
Show file tree
Hide file tree
Showing 14 changed files with 368 additions and 383 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ deploying and running an example chaincode.
## Requirements

* CMake 3.5.1 or higher
* Go 1.10 or higher
* Install Fabric v1.2 https://github.com/hyperledger/fabric
* Install the Linux SGX SDK v2.1.3 https://github.com/intel/linux-sgx
* Go 1.11 or higher
* Install Fabric v1.4 https://github.com/hyperledger/fabric
* Install the Linux SGX SDK v2.4 https://github.com/intel/linux-sgx
* You also need to install Intel SGX SSL https://github.com/intel/intel-sgx-ssl

### SGX SDK and SSL
Expand Down
46 changes: 14 additions & 32 deletions ecc/vscc/ecc_validation_plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,9 @@ import (

commonerrors "github.com/hyperledger/fabric/common/errors"
"github.com/hyperledger/fabric/core/handlers/validation/api"
. "github.com/hyperledger/fabric/core/handlers/validation/api/capabilities"
. "github.com/hyperledger/fabric/core/handlers/validation/api/identities"
. "github.com/hyperledger/fabric/core/handlers/validation/api/policies"
. "github.com/hyperledger/fabric/core/handlers/validation/api/state"
default_vscc "github.com/hyperledger/fabric/core/handlers/validation/builtin"
defaultvscc "github.com/hyperledger/fabric/core/handlers/validation/builtin"
"github.com/hyperledger/fabric/protos/common"
"github.com/pkg/errors"
)
Expand All @@ -43,7 +41,7 @@ func (*ECCValidationFactory) New() validation.Plugin {
}

type ECCValidation struct {
DefaultTxValidator TransactionValidator
DefaultTxValidator validation.Plugin
ECCTxValidator TransactionValidator
}

Expand Down Expand Up @@ -72,7 +70,7 @@ func (v *ECCValidation) Validate(block *common.Block, namespace string, txPositi
}

// do defalt vscc
err := v.DefaultTxValidator.Validate(block.Data.Data[txPosition], serializedPolicy.Bytes())
err := v.DefaultTxValidator.Validate(block, namespace, txPosition, actionPosition, contextData...)
if err != nil {
logger.Debugf("block %d, namespace: %s, tx %d validation results is: %v", block.Header.Number, namespace, txPosition, err)
return convertErrorTypeOrPanic(err)
Expand Down Expand Up @@ -102,41 +100,25 @@ func convertErrorTypeOrPanic(err error) error {
}

func (v *ECCValidation) Init(dependencies ...validation.Dependency) error {
var (
d IdentityDeserializer
c Capabilities
sf StateFetcher
pe PolicyEvaluator
)
var sf StateFetcher
for _, dep := range dependencies {
if deserializer, isIdentityDeserializer := dep.(IdentityDeserializer); isIdentityDeserializer {
d = deserializer
}
if capabilities, isCapabilities := dep.(Capabilities); isCapabilities {
c = capabilities
}
if stateFetcher, isStateFetcher := dep.(StateFetcher); isStateFetcher {
sf = stateFetcher
}
if policyEvaluator, isPolicyFetcher := dep.(PolicyEvaluator); isPolicyFetcher {
pe = policyEvaluator
}
}
if sf == nil {
return errors.New("stateFetcher not passed in init")
}
if d == nil {
return errors.New("identityDeserializer not passed in init")
}
if c == nil {
return errors.New("capabilities not passed in init")
return errors.New("ECC-VSCC: stateFetcher not passed in init")
}
if pe == nil {
return errors.New("policy fetcher not passed in init")
}
// use default vscc and our custom ercc vscc
v.DefaultTxValidator = default_vscc.New(c, sf, d, pe)

v.ECCTxValidator = New(sf)

// use default vscc and our custom ecc vscc
factory := &defaultvscc.DefaultValidationFactory{}
v.DefaultTxValidator = factory.New()
err := v.DefaultTxValidator.Init(dependencies...)
if err != nil {
return errors.Errorf("Error while creating default vscc: %s", err)
}

return nil
}
46 changes: 14 additions & 32 deletions ercc/vscc/ercc_validation_plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,9 @@ import (

commonerrors "github.com/hyperledger/fabric/common/errors"
"github.com/hyperledger/fabric/core/handlers/validation/api"
. "github.com/hyperledger/fabric/core/handlers/validation/api/capabilities"
. "github.com/hyperledger/fabric/core/handlers/validation/api/identities"
. "github.com/hyperledger/fabric/core/handlers/validation/api/policies"
. "github.com/hyperledger/fabric/core/handlers/validation/api/state"
default_vscc "github.com/hyperledger/fabric/core/handlers/validation/builtin"
defaultvscc "github.com/hyperledger/fabric/core/handlers/validation/builtin"
"github.com/hyperledger/fabric/protos/common"
"github.com/pkg/errors"
)
Expand All @@ -43,7 +41,7 @@ func (*ERCCValidationFactory) New() validation.Plugin {
}

type ERCCValidation struct {
DefaultTxValidator TransactionValidator
DefaultTxValidator validation.Plugin
ERCCTxValidator TransactionValidator
}

Expand Down Expand Up @@ -72,7 +70,7 @@ func (v *ERCCValidation) Validate(block *common.Block, namespace string, txPosit
}

// do defalt vscc
err := v.DefaultTxValidator.Validate(block.Data.Data[txPosition], serializedPolicy.Bytes())
err := v.DefaultTxValidator.Validate(block, namespace, txPosition, actionPosition, contextData...)
if err != nil {
logger.Debugf("block %d, namespace: %s, tx %d validation results is: %v", block.Header.Number, namespace, txPosition, err)
return convertErrorTypeOrPanic(err)
Expand Down Expand Up @@ -102,41 +100,25 @@ func convertErrorTypeOrPanic(err error) error {
}

func (v *ERCCValidation) Init(dependencies ...validation.Dependency) error {
var (
d IdentityDeserializer
c Capabilities
sf StateFetcher
pe PolicyEvaluator
)
var sf StateFetcher
for _, dep := range dependencies {
if deserializer, isIdentityDeserializer := dep.(IdentityDeserializer); isIdentityDeserializer {
d = deserializer
}
if capabilities, isCapabilities := dep.(Capabilities); isCapabilities {
c = capabilities
}
if stateFetcher, isStateFetcher := dep.(StateFetcher); isStateFetcher {
sf = stateFetcher
}
if policyEvaluator, isPolicyFetcher := dep.(PolicyEvaluator); isPolicyFetcher {
pe = policyEvaluator
}
}
if sf == nil {
return errors.New("stateFetcher not passed in init")
}
if d == nil {
return errors.New("identityDeserializer not passed in init")
}
if c == nil {
return errors.New("capabilities not passed in init")
}
if pe == nil {
return errors.New("policy fetcher not passed in init")
return errors.New("ERCC-VSCC: stateFetcher not passed in init")
}
// use default vscc and our custom ercc vscc
v.DefaultTxValidator = default_vscc.New(c, sf, d, pe)

v.ERCCTxValidator = New(sf)

// use default vscc and our custom ercc vscc
factory := &defaultvscc.DefaultValidationFactory{}
v.DefaultTxValidator = factory.New()
err := v.DefaultTxValidator.Init(dependencies...)
if err != nil {
return errors.Errorf("Error while creating default vscc: %s", err)
}

return nil
}
11 changes: 7 additions & 4 deletions fabric/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,22 @@
To enable SGX support for a Fabric peer start with a fresh copy of Fabric and
apply our patch. https://github.com/hyperledger/fabric

We assume that you are familiar with build Fabric manually otherwise we
We assume that you are familiar with building Fabric manually; otherwise we highly
recommend to spend some time to build Fabric and run a simple network with a
few peers and a ordering service.

## Patch and Build

Clone fabric and checkout the 1.2 release.
Clone fabric and checkout the 1.4 release.

$ git clone https://github.com/hyperledger/fabric.git
$ git checkout release-1.2
$ git checkout release-1.4
$ git apply path-to-this-patch/sgx_support.patch

When building the peer make sure fabric is your ``GOPATH`` and you enable the
plugin feature. Otherwise our custom validation plugins can not be loaded.

$ GO_TAGS=pluginsenabled EXPERIMENTAL=false DOCKER_DYNAMIC_LINK=true make peer
$ GO_TAGS=pluginsenabled make peer

To make your life easier we have prepared an example configuration and an
auction demo. You can copy ``sgxconfig`` to your fabric directory and modify
Expand All @@ -40,6 +40,9 @@ Place your client certificate and your SPID in the ``ias`` folder.
cp client.key /path-to/fabric/sgxconfig/ias/client.key
echo 'YOURSPID' | xxd -r -p > /path-to/fabric/sgxconfig/ias/spid.txt

We currently make use of `unlinkable signatures` for the attestation, thus, when registering with the IAS please choose
unlinkable signatures.

## Run the Auction

Before you continue here build the other components, such as the chaincode
Expand Down
125 changes: 14 additions & 111 deletions fabric/sgx_support.patch
Original file line number Diff line number Diff line change
@@ -1,124 +1,27 @@
diff --git a/core/chaincode/shim/mockstub.go b/core/chaincode/shim/mockstub.go
index acc8200..e808052 100644
--- a/core/chaincode/shim/mockstub.go
+++ b/core/chaincode/shim/mockstub.go
@@ -12,6 +12,7 @@ import (
"container/list"
"fmt"
"strings"
+ "sync"

"github.com/golang/protobuf/ptypes/timestamp"
"github.com/hyperledger/fabric/common/util"
@@ -62,6 +63,10 @@ type MockStub struct {

// channel to store ChaincodeEvents
ChaincodeEventsChannel chan *pb.ChaincodeEvent
+
+ Decorations map[string][]byte
+
+ sync.RWMutex
}

func (stub *MockStub) GetTxID() string {
@@ -137,7 +142,7 @@ func (stub *MockStub) MockInvoke(uuid string, args [][]byte) pb.Response {
}

func (stub *MockStub) GetDecorations() map[string][]byte {
- return nil
+ return stub.Decorations
}

// Invoke this chaincode, also starts and ends a transaction.
@@ -193,6 +198,8 @@ func (stub *MockStub) GetPrivateDataQueryResult(collection, query string) (State

// GetState retrieves the value for a given key from the ledger
func (stub *MockStub) GetState(key string) ([]byte, error) {
+ stub.RLock()
+ defer stub.RUnlock()
value := stub.State[key]
mockLogger.Debug("MockStub", stub.Name, "Getting", key, value)
return value, nil
@@ -200,11 +207,13 @@ func (stub *MockStub) GetState(key string) ([]byte, error) {

// PutState writes the specified `value` and `key` into the ledger.
func (stub *MockStub) PutState(key string, value []byte) error {
- if stub.TxID == "" {
- err := errors.New("cannot PutState without a transactions - call stub.MockTransactionStart()?")
- mockLogger.Errorf("%+v", err)
- return err
- }
+ stub.Lock()
+ defer stub.Unlock()
+ // if stub.TxID == "" {
+ // err := errors.New("cannot PutState without a transactions - call stub.MockTransactionStart()?")
+ // mockLogger.Errorf("%+v", err)
+ // return err
+ // }

mockLogger.Debug("MockStub", stub.Name, "Putting", key, value)
stub.State[key] = value
@@ -244,6 +253,8 @@ func (stub *MockStub) PutState(key string, value []byte) error {

// DelState removes the specified `key` and its value from the ledger.
func (stub *MockStub) DelState(key string) error {
+ stub.Lock()
+ defer stub.Unlock()
mockLogger.Debug("MockStub", stub.Name, "Deleting", key, stub.State[key])
delete(stub.State, key)

@@ -257,6 +268,8 @@ func (stub *MockStub) DelState(key string) error {
}

func (stub *MockStub) GetStateByRange(startKey, endKey string) (StateQueryIteratorInterface, error) {
+ stub.RLock()
+ defer stub.RUnlock()
if err := validateSimpleKeys(startKey, endKey); err != nil {
return nil, err
}
@@ -288,6 +301,8 @@ func (stub *MockStub) GetHistoryForKey(key string) (HistoryQueryIteratorInterfac
//a partial composite key. For a full composite key, an iter with empty response
//would be returned.
func (stub *MockStub) GetStateByPartialCompositeKey(objectType string, attributes []string) (StateQueryIteratorInterface, error) {
+ stub.RLock()
+ defer stub.RUnlock()
partialCompositeKey, err := stub.CreateCompositeKey(objectType, attributes)
if err != nil {
return nil, err
@@ -381,6 +396,7 @@ func NewMockStub(name string, cc Chaincode) *MockStub {
s.Invokables = make(map[string]*MockStub)
s.Keys = list.New()
s.ChaincodeEventsChannel = make(chan *pb.ChaincodeEvent, 100) //define large capacity for non-blocking setEvent calls.
+ s.Decorations = make(map[string][]byte)

return s
}
diff --git a/core/container/dockercontroller/dockercontroller.go b/core/container/dockercontroller/dockercontroller.go
index a6ec99e..e5c1f69 100644
--- a/core/container/dockercontroller/dockercontroller.go
+++ b/core/container/dockercontroller/dockercontroller.go
diff --git i/core/container/dockercontroller/dockercontroller.go w/core/container/dockercontroller/dockercontroller.go
index 2a709ed0b..51df8f7ff 100644
--- i/core/container/dockercontroller/dockercontroller.go
+++ w/core/container/dockercontroller/dockercontroller.go
@@ -168,6 +168,14 @@ func getDockerHostConfig() *docker.HostConfig {
CPUQuota: getInt64("CpuQuota"),
CPUPeriod: getInt64("CpuPeriod"),
BlkioWeight: getInt64("BlkioWeight"),
+ Binds: []string{"/var/run/aesmd:/var/run/aesmd"},
+ Devices: []docker.Device{
+ docker.Device{
+ {
+ PathOnHost: "/dev/isgx",
+ PathInContainer: "/dev/isgx",
+ CgroupPermissions: "rwm",
+ },
+ },
}
}

return hostConfig
@@ -176,7 +184,8 @@ func getDockerHostConfig() *docker.HostConfig {
func (vm *DockerVM) createContainer(ctxt context.Context, client dockerClient,
imageID string, containerID string, args []string,
env []string, attachStdout bool) error {
- config := docker.Config{Cmd: args, Image: imageID, Env: env, AttachStdout: attachStdout, AttachStderr: attachStdout}
+ v := map[string]struct{}{"/var/run/aesmd": {}}
+ config := docker.Config{Cmd: args, Image: imageID, Env: env, AttachStdout: attachStdout, AttachStderr: attachStdout, Volumes: v}
copts := docker.CreateContainerOptions{Name: containerID, Config: &config, HostConfig: getDockerHostConfig()}
dockerLogger.Debugf("Create container: %s", containerID)
_, err := client.CreateContainer(copts)
@@ -182,6 +190,7 @@ func (vm *DockerVM) createContainer(client dockerClient, imageID, containerID st
Env: env,
AttachStdout: attachStdout,
AttachStderr: attachStdout,
+ Volumes: map[string]struct{}{"/var/run/aesmd": {}},
},
HostConfig: getDockerHostConfig(),
})
Loading

0 comments on commit 90c1c23

Please sign in to comment.