Skip to content

Commit eda9463

Browse files
authored
Merge pull request #1365 from kaleido-io/fix_tuple
v1.2: fix: multiple named tuple result from contract
2 parents 2248b02 + 4632951 commit eda9463

File tree

6 files changed

+1233
-16
lines changed

6 files changed

+1233
-16
lines changed

internal/blockchain/ethereum/ethereum.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -742,11 +742,12 @@ func (e *Ethereum) QueryContract(ctx context.Context, location *fftypes.JSONAny,
742742
if err != nil || !res.IsSuccess() {
743743
return nil, err
744744
}
745-
output := &queryOutput{}
746-
if err = json.Unmarshal(res.Body(), output); err != nil {
745+
746+
var output interface{}
747+
if err = json.Unmarshal(res.Body(), &output); err != nil {
747748
return nil, err
748749
}
749-
return output, nil
750+
return output, nil // note UNLIKE fabric this is just `output`, not `output.Result` - but either way the top level of what we return to the end user, is whatever the Connector sent us
750751
}
751752

752753
func (e *Ethereum) NormalizeContractLocation(ctx context.Context, location *fftypes.JSONAny) (result *fftypes.JSONAny, err error) {
@@ -924,6 +925,8 @@ func (e *Ethereum) queryNetworkVersion(ctx context.Context, address string) (ver
924925
}
925926
return 0, err
926927
}
928+
929+
// Leave as queryOutput as it only has one value
927930
output := &queryOutput{}
928931
if err = json.Unmarshal(res.Body(), output); err != nil {
929932
return 0, err

internal/blockchain/ethereum/ethereum_test.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2582,6 +2582,101 @@ func TestQueryContractOK(t *testing.T) {
25822582
assert.Equal(t, `{"output":"3"}`, string(j))
25832583
}
25842584

2585+
func TestQueryContractMultipleUnnamedOutputOK(t *testing.T) {
2586+
e, cancel := newTestEthereum()
2587+
defer cancel()
2588+
httpmock.ActivateNonDefault(e.client.GetClient())
2589+
defer httpmock.DeactivateAndReset()
2590+
location := &Location{
2591+
Address: "0x12345",
2592+
}
2593+
method := testFFIMethod()
2594+
errors := testFFIErrors()
2595+
params := map[string]interface{}{}
2596+
options := map[string]interface{}{
2597+
"customOption": "customValue",
2598+
}
2599+
2600+
outputStruct := struct {
2601+
Test string `json:"test"`
2602+
Value int `json:"value"`
2603+
}{
2604+
Test: "myvalue",
2605+
Value: 3,
2606+
}
2607+
2608+
output := map[string]interface{}{
2609+
"output": "foo",
2610+
"output1": outputStruct,
2611+
"anything": 3,
2612+
}
2613+
2614+
locationBytes, err := json.Marshal(location)
2615+
assert.NoError(t, err)
2616+
httpmock.RegisterResponder("POST", `http://localhost:12345/`,
2617+
func(req *http.Request) (*http.Response, error) {
2618+
var body map[string]interface{}
2619+
json.NewDecoder(req.Body).Decode(&body)
2620+
headers := body["headers"].(map[string]interface{})
2621+
assert.Equal(t, "Query", headers["type"])
2622+
assert.Equal(t, "customValue", body["customOption"].(string))
2623+
assert.Equal(t, "0x12345", body["to"].(string))
2624+
return httpmock.NewJsonResponderOrPanic(200, output)(req)
2625+
})
2626+
result, err := e.QueryContract(context.Background(), fftypes.JSONAnyPtrBytes(locationBytes), method, params, errors, options)
2627+
assert.NoError(t, err)
2628+
j, err := json.Marshal(result)
2629+
assert.NoError(t, err)
2630+
assert.Equal(t, `{"anything":3,"output":"foo","output1":{"test":"myvalue","value":3}}`, string(j))
2631+
}
2632+
2633+
func TestQueryContractNamedOutputOK(t *testing.T) {
2634+
e, cancel := newTestEthereum()
2635+
defer cancel()
2636+
httpmock.ActivateNonDefault(e.client.GetClient())
2637+
defer httpmock.DeactivateAndReset()
2638+
location := &Location{
2639+
Address: "0x12345",
2640+
}
2641+
method := testFFIMethod()
2642+
errors := testFFIErrors()
2643+
params := map[string]interface{}{}
2644+
options := map[string]interface{}{
2645+
"customOption": "customValue",
2646+
}
2647+
2648+
outputStruct := struct {
2649+
Test string `json:"test"`
2650+
Value int `json:"value"`
2651+
}{
2652+
Test: "myvalue",
2653+
Value: 3,
2654+
}
2655+
2656+
output := map[string]interface{}{
2657+
"mynamedparam": "foo",
2658+
"mynamedstruct": outputStruct,
2659+
}
2660+
2661+
locationBytes, err := json.Marshal(location)
2662+
assert.NoError(t, err)
2663+
httpmock.RegisterResponder("POST", `http://localhost:12345/`,
2664+
func(req *http.Request) (*http.Response, error) {
2665+
var body map[string]interface{}
2666+
json.NewDecoder(req.Body).Decode(&body)
2667+
headers := body["headers"].(map[string]interface{})
2668+
assert.Equal(t, "Query", headers["type"])
2669+
assert.Equal(t, "customValue", body["customOption"].(string))
2670+
assert.Equal(t, "0x12345", body["to"].(string))
2671+
return httpmock.NewJsonResponderOrPanic(200, output)(req)
2672+
})
2673+
result, err := e.QueryContract(context.Background(), fftypes.JSONAnyPtrBytes(locationBytes), method, params, errors, options)
2674+
assert.NoError(t, err)
2675+
j, err := json.Marshal(result)
2676+
assert.NoError(t, err)
2677+
assert.Equal(t, `{"mynamedparam":"foo","mynamedstruct":{"test":"myvalue","value":3}}`, string(j))
2678+
}
2679+
25852680
func TestQueryContractInvalidOption(t *testing.T) {
25862681
e, cancel := newTestEthereum()
25872682
defer cancel()

0 commit comments

Comments
 (0)