Skip to content

Commit

Permalink
Merge pull request #1514 from kaleido-io/query-key
Browse files Browse the repository at this point in the history
Allow blank signing key for queries on Ethereum
  • Loading branch information
peterbroadhurst authored May 22, 2024
2 parents c46e718 + 78395b5 commit 514d1e8
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 58 deletions.
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ RUN apk add make=4.4.1-r2 \
gcc=13.2.1_git20231014-r0 \
build-base=0.5-r3 \
curl=8.5.0-r0 \
git=2.43.0-r0
git=2.43.4-r0
WORKDIR /firefly
RUN chgrp -R 0 /firefly \
&& chmod -R g+rwX /firefly \
Expand Down Expand Up @@ -68,7 +68,7 @@ ARG UI_TAG
ARG UI_RELEASE
RUN apk add --update --no-cache \
sqlite=3.44.2-r0 \
postgresql16-client=16.2-r1 \
postgresql16-client=16.3-r0 \
curl=8.5.0-r0 \
jq=1.7.1-r0
WORKDIR /firefly
Expand Down
13 changes: 10 additions & 3 deletions internal/blockchain/ethereum/ethereum.go
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,13 @@ func formatEthAddress(ctx context.Context, key string) (string, error) {
}

func (e *Ethereum) ResolveSigningKey(ctx context.Context, key string, intent blockchain.ResolveKeyIntent) (resolved string, err error) {
// Key may be unset for query intent only
if key == "" {
if intent == blockchain.ResolveKeyIntentQuery {
return "", nil
}
return "", i18n.NewError(ctx, coremsgs.MsgNodeMissingBlockchainKey)
}
if !e.addressResolveAlways {
// If there's no address resolver plugin, or addressResolveAlways is false,
// we check if it's already an ethereum address - in which case we can just return it.
Expand Down Expand Up @@ -643,7 +650,7 @@ func (e *Ethereum) queryContractMethod(ctx context.Context, address, signingKey
return res, nil
}

func (e *Ethereum) buildBatchPinInput(ctx context.Context, version int, namespace string, batch *blockchain.BatchPin) (*abi.Entry, []interface{}) {
func (e *Ethereum) buildBatchPinInput(version int, namespace string, batch *blockchain.BatchPin) (*abi.Entry, []interface{}) {
ethHashes := make([]string, len(batch.Contexts))
for i, v := range batch.Contexts {
ethHashes[i] = ethHexFormatB32(v)
Expand Down Expand Up @@ -688,7 +695,7 @@ func (e *Ethereum) SubmitBatchPin(ctx context.Context, nsOpID, networkNamespace,
return err
}

method, input := e.buildBatchPinInput(ctx, version, networkNamespace, batch)
method, input := e.buildBatchPinInput(version, networkNamespace, batch)

var emptyErrors []*abi.Entry
_, err = e.invokeContractMethod(ctx, ethLocation.Address, signingKey, method, nsOpID, input, emptyErrors, nil)
Expand Down Expand Up @@ -802,7 +809,7 @@ func (e *Ethereum) InvokeContract(ctx context.Context, nsOpID string, signingKey
if batch != nil {
err := e.checkDataSupport(ctx, methodInfo.methodABI)
if err == nil {
method, batchPin := e.buildBatchPinInput(ctx, 2, "", batch)
method, batchPin := e.buildBatchPinInput(2, "", batch)
encoded, err := method.Inputs.EncodeABIDataValuesCtx(ctx, batchPin)
if err == nil {
orderedInput[len(orderedInput)-1] = hex.EncodeToString(encoded)
Expand Down
51 changes: 29 additions & 22 deletions internal/blockchain/ethereum/ethereum_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ func newTestStreamManager(client *resty.Client) *streamManager {
return newStreamManager(client, cache.NewUmanagedCache(context.Background(), 100, 5*time.Minute), defaultBatchSize, defaultBatchTimeout)
}

func mockNetworkVersion(t *testing.T, version int) func(req *http.Request) (*http.Response, error) {
func mockNetworkVersion(version int) func(req *http.Request) (*http.Response, error) {
return func(req *http.Request) (*http.Response, error) {
readBody, _ := req.GetBody()
var body map[string]interface{}
Expand Down Expand Up @@ -591,7 +591,7 @@ func TestEthCacheInitFail(t *testing.T) {
"registeredAs": "firefly",
}),
)
httpmock.RegisterResponder("POST", "http://localhost:12345/", mockNetworkVersion(t, 1))
httpmock.RegisterResponder("POST", "http://localhost:12345/", mockNetworkVersion(1))

e, cancel := newTestEthereum()
resetConf(e)
Expand Down Expand Up @@ -639,7 +639,7 @@ func TestInitOldInstancePathContracts(t *testing.T) {
"registeredAs": "firefly",
}),
)
httpmock.RegisterResponder("POST", "http://localhost:12345/", mockNetworkVersion(t, 1))
httpmock.RegisterResponder("POST", "http://localhost:12345/", mockNetworkVersion(1))

resetConf(e)
utEthconnectConf.Set(ffresty.HTTPConfigURL, "http://localhost:12345")
Expand Down Expand Up @@ -675,7 +675,7 @@ func TestInitOldInstancePathInstances(t *testing.T) {
assert.Equal(t, "es12345/ns1", body["stream"])
return httpmock.NewJsonResponderOrPanic(200, subscription{ID: "sub12345"})(req)
})
httpmock.RegisterResponder("POST", "http://localhost:12345/", mockNetworkVersion(t, 1))
httpmock.RegisterResponder("POST", "http://localhost:12345/", mockNetworkVersion(1))

resetConf(e)
utEthconnectConf.Set(ffresty.HTTPConfigURL, "http://localhost:12345")
Expand Down Expand Up @@ -877,7 +877,7 @@ func TestInitAllExistingStreams(t *testing.T) {

httpmock.RegisterResponder("PATCH", fmt.Sprintf("%s/eventstreams/es12345", httpURL),
httpmock.NewJsonResponderOrPanic(200, &eventStream{ID: "es12345", Name: "topic1/ns1"}))
httpmock.RegisterResponder("POST", fmt.Sprintf("%s/", httpURL), mockNetworkVersion(t, 2))
httpmock.RegisterResponder("POST", fmt.Sprintf("%s/", httpURL), mockNetworkVersion(2))
httpmock.RegisterResponder("POST", fmt.Sprintf("%s/subscriptions", httpURL),
httpmock.NewJsonResponderOrPanic(200, subscription{}))

Expand Down Expand Up @@ -936,7 +936,7 @@ func TestInitAllExistingStreamsV1(t *testing.T) {
}))
httpmock.RegisterResponder("PATCH", fmt.Sprintf("%s/eventstreams/es12345", httpURL),
httpmock.NewJsonResponderOrPanic(200, &eventStream{ID: "es12345", Name: "topic1/ns1"}))
httpmock.RegisterResponder("POST", fmt.Sprintf("%s/", httpURL), mockNetworkVersion(t, 1))
httpmock.RegisterResponder("POST", fmt.Sprintf("%s/", httpURL), mockNetworkVersion(1))
httpmock.RegisterResponder("POST", fmt.Sprintf("%s/subscriptions", httpURL),
httpmock.NewJsonResponderOrPanic(200, subscription{}))

Expand Down Expand Up @@ -994,7 +994,7 @@ func TestInitAllExistingStreamsOld(t *testing.T) {
}))
httpmock.RegisterResponder("PATCH", fmt.Sprintf("%s/eventstreams/es12345", httpURL),
httpmock.NewJsonResponderOrPanic(200, &eventStream{ID: "es12345", Name: "topic1/ns1"}))
httpmock.RegisterResponder("POST", fmt.Sprintf("%s/", httpURL), mockNetworkVersion(t, 1))
httpmock.RegisterResponder("POST", fmt.Sprintf("%s/", httpURL), mockNetworkVersion(1))
httpmock.RegisterResponder("POST", fmt.Sprintf("%s/subscriptions", httpURL),
httpmock.NewJsonResponderOrPanic(200, subscription{}))

Expand Down Expand Up @@ -1052,7 +1052,7 @@ func TestInitAllExistingStreamsInvalidName(t *testing.T) {
}))
httpmock.RegisterResponder("PATCH", fmt.Sprintf("%s/eventstreams/es12345", httpURL),
httpmock.NewJsonResponderOrPanic(200, &eventStream{ID: "es12345", Name: "topic1/ns1"}))
httpmock.RegisterResponder("POST", fmt.Sprintf("%s/", httpURL), mockNetworkVersion(t, 2))
httpmock.RegisterResponder("POST", fmt.Sprintf("%s/", httpURL), mockNetworkVersion(2))
httpmock.RegisterResponder("POST", fmt.Sprintf("%s/subscriptions", httpURL),
httpmock.NewJsonResponderOrPanic(200, subscription{}))

Expand Down Expand Up @@ -1164,7 +1164,7 @@ func TestSubmitBatchPinOK(t *testing.T) {

httpmock.RegisterResponder("POST", `http://localhost:12345/`,
func(req *http.Request) (*http.Response, error) {
res, err := mockNetworkVersion(t, 2)(req)
res, err := mockNetworkVersion(2)(req)
if res != nil || err != nil {
return res, err
}
Expand Down Expand Up @@ -1208,7 +1208,7 @@ func TestSubmitBatchPinV1(t *testing.T) {

httpmock.RegisterResponder("POST", `http://localhost:12345/`,
func(req *http.Request) (*http.Response, error) {
res, err := mockNetworkVersion(t, 1)(req)
res, err := mockNetworkVersion(1)(req)
if res != nil || err != nil {
return res, err
}
Expand Down Expand Up @@ -1278,7 +1278,7 @@ func TestSubmitBatchEmptyPayloadRef(t *testing.T) {

httpmock.RegisterResponder("POST", `http://localhost:12345/`,
func(req *http.Request) (*http.Response, error) {
res, err := mockNetworkVersion(t, 2)(req)
res, err := mockNetworkVersion(2)(req)
if res != nil || err != nil {
return res, err
}
Expand Down Expand Up @@ -1359,7 +1359,7 @@ func TestSubmitBatchPinFail(t *testing.T) {

httpmock.RegisterResponder("POST", `http://localhost:12345/`,
func(req *http.Request) (*http.Response, error) {
res, err := mockNetworkVersion(t, 2)(req)
res, err := mockNetworkVersion(2)(req)
if res != nil || err != nil {
return res, err
}
Expand Down Expand Up @@ -1397,7 +1397,7 @@ func TestSubmitBatchPinError(t *testing.T) {

httpmock.RegisterResponder("POST", `http://localhost:12345/`,
func(req *http.Request) (*http.Response, error) {
res, err := mockNetworkVersion(t, 2)(req)
res, err := mockNetworkVersion(2)(req)
if res != nil || err != nil {
return res, err
}
Expand All @@ -1415,10 +1415,17 @@ func TestVerifyEthAddress(t *testing.T) {
e, cancel := newTestEthereum()
defer cancel()

_, err := e.ResolveSigningKey(context.Background(), "0x12345", blockchain.ResolveKeyIntentSign)
_, err := e.ResolveSigningKey(context.Background(), "", blockchain.ResolveKeyIntentSign)
assert.Regexp(t, "FF10354", err)

key, err := e.ResolveSigningKey(context.Background(), "", blockchain.ResolveKeyIntentQuery)
assert.NoError(t, err)
assert.Empty(t, key)

_, err = e.ResolveSigningKey(context.Background(), "0x12345", blockchain.ResolveKeyIntentSign)
assert.Regexp(t, "FF10141", err)

key, err := e.ResolveSigningKey(context.Background(), "0x2a7c9D5248681CE6c393117E641aD037F5C079F6", blockchain.ResolveKeyIntentSign)
key, err = e.ResolveSigningKey(context.Background(), "0x2a7c9D5248681CE6c393117E641aD037F5C079F6", blockchain.ResolveKeyIntentSign)
assert.NoError(t, err)
assert.Equal(t, "0x2a7c9d5248681ce6c393117e641ad037f5c079f6", key)

Expand Down Expand Up @@ -3547,7 +3554,7 @@ func TestSubmitNetworkAction(t *testing.T) {
defer httpmock.DeactivateAndReset()
httpmock.RegisterResponder("POST", `http://localhost:12345/`,
func(req *http.Request) (*http.Response, error) {
res, err := mockNetworkVersion(t, 2)(req)
res, err := mockNetworkVersion(2)(req)
if res != nil || err != nil {
return res, err
}
Expand Down Expand Up @@ -3576,7 +3583,7 @@ func TestSubmitNetworkActionV1(t *testing.T) {
defer httpmock.DeactivateAndReset()
httpmock.RegisterResponder("POST", `http://localhost:12345/`,
func(req *http.Request) (*http.Response, error) {
res, err := mockNetworkVersion(t, 1)(req)
res, err := mockNetworkVersion(1)(req)
if res != nil || err != nil {
return res, err
}
Expand Down Expand Up @@ -4021,7 +4028,7 @@ func TestAddAndRemoveFireflySubscription(t *testing.T) {
httpmock.NewJsonResponderOrPanic(200, subscription{
ID: "sub1",
}))
httpmock.RegisterResponder("POST", "http://localhost:12345/", mockNetworkVersion(t, 2))
httpmock.RegisterResponder("POST", "http://localhost:12345/", mockNetworkVersion(2))

utEthconnectConf.Set(ffresty.HTTPConfigURL, "http://localhost:12345")
utEthconnectConf.Set(ffresty.HTTPCustomClient, mockedClient)
Expand Down Expand Up @@ -4075,7 +4082,7 @@ func TestAddFireflySubscriptionV1(t *testing.T) {
httpmock.NewJsonResponderOrPanic(200, subscription{
ID: "sub1",
}))
httpmock.RegisterResponder("POST", "http://localhost:12345/", mockNetworkVersion(t, 1))
httpmock.RegisterResponder("POST", "http://localhost:12345/", mockNetworkVersion(1))

utEthconnectConf.Set(ffresty.HTTPConfigURL, "http://localhost:12345")
utEthconnectConf.Set(ffresty.HTTPCustomClient, mockedClient)
Expand Down Expand Up @@ -4120,7 +4127,7 @@ func TestAddFireflySubscriptionEventstreamFail(t *testing.T) {
httpmock.NewJsonResponderOrPanic(200, subscription{
ID: "sub1",
}))
httpmock.RegisterResponder("POST", "http://localhost:12345/", mockNetworkVersion(t, 1))
httpmock.RegisterResponder("POST", "http://localhost:12345/", mockNetworkVersion(1))

utEthconnectConf.Set(ffresty.HTTPConfigURL, "http://localhost:12345")
utEthconnectConf.Set(ffresty.HTTPCustomClient, mockedClient)
Expand Down Expand Up @@ -4161,7 +4168,7 @@ func TestAddFireflySubscriptionQuerySubsFail(t *testing.T) {
httpmock.NewStringResponder(500, `pop`))
httpmock.RegisterResponder("POST", "http://localhost:12345/subscriptions",
httpmock.NewJsonResponderOrPanic(200, subscription{}))
httpmock.RegisterResponder("POST", "http://localhost:12345/", mockNetworkVersion(t, 2))
httpmock.RegisterResponder("POST", "http://localhost:12345/", mockNetworkVersion(2))

utEthconnectConf.Set(ffresty.HTTPConfigURL, "http://localhost:12345")
utEthconnectConf.Set(ffresty.HTTPCustomClient, mockedClient)
Expand Down Expand Up @@ -4245,7 +4252,7 @@ func TestAddFireflySubscriptionGetVersionError(t *testing.T) {
httpmock.NewJsonResponderOrPanic(200, []subscription{}))
httpmock.RegisterResponder("POST", "http://localhost:12345/subscriptions",
httpmock.NewJsonResponderOrPanic(500, `pop`))
httpmock.RegisterResponder("POST", "http://localhost:12345/", mockNetworkVersion(t, 2))
httpmock.RegisterResponder("POST", "http://localhost:12345/", mockNetworkVersion(2))

utEthconnectConf.Set(ffresty.HTTPConfigURL, "http://localhost:12345")
utEthconnectConf.Set(ffresty.HTTPCustomClient, mockedClient)
Expand Down
11 changes: 8 additions & 3 deletions internal/blockchain/fabric/fabric.go
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,11 @@ func (f *Fabric) ResolveSigningKey(ctx context.Context, signingKeyInput string,
// currently pluggable to external identity resolution systems (as is the case for
// ethereum blockchain connectors).

// Key is always required
if signingKeyInput == "" {
return "", i18n.NewError(ctx, coremsgs.MsgNodeMissingBlockchainKey)
}

// we expand the short user name into the fully qualified onchain identity:
// mspid::x509::{ecert DN}::{CA DN} return signingKeyInput, nil
if !fullIdentityPattern.MatchString(signingKeyInput) {
Expand Down Expand Up @@ -646,7 +651,7 @@ func hexFormatB32(b *fftypes.Bytes32) string {
return "0x" + hex.EncodeToString(b[0:32])
}

func (f *Fabric) buildBatchPinInput(ctx context.Context, version int, namespace string, batch *blockchain.BatchPin) (prefixItems []*PrefixItem, pinInput map[string]interface{}) {
func (f *Fabric) buildBatchPinInput(version int, namespace string, batch *blockchain.BatchPin) (prefixItems []*PrefixItem, pinInput map[string]interface{}) {
hashes := make([]string, len(batch.Contexts))
for i, v := range batch.Contexts {
hashes[i] = hexFormatB32(v)
Expand Down Expand Up @@ -687,7 +692,7 @@ func (f *Fabric) SubmitBatchPin(ctx context.Context, nsOpID, networkNamespace, s
return err
}

prefixItems, pinInput := f.buildBatchPinInput(ctx, version, networkNamespace, batch)
prefixItems, pinInput := f.buildBatchPinInput(version, networkNamespace, batch)

input, _ := jsonEncodeInput(pinInput)
_, err = f.invokeContractMethod(ctx, fabricOnChainLocation.Channel, fabricOnChainLocation.Chaincode, batchPinMethodName, signingKey, nsOpID, prefixItems, input, nil)
Expand Down Expand Up @@ -801,7 +806,7 @@ func (f *Fabric) InvokeContract(ctx context.Context, nsOpID string, signingKey s
}

if batch != nil {
_, batchPin := f.buildBatchPinInput(ctx, 2, "", batch)
_, batchPin := f.buildBatchPinInput(2, "", batch)
if input == nil {
input = make(map[string]interface{})
}
Expand Down
Loading

0 comments on commit 514d1e8

Please sign in to comment.