Skip to content

Commit

Permalink
Merge pull request #1365 from kaleido-io/fix_tuple
Browse files Browse the repository at this point in the history
v1.2: fix: multiple named tuple result from contract
  • Loading branch information
nguyer committed Jul 11, 2023
2 parents 2248b02 + 4632951 commit eda9463
Show file tree
Hide file tree
Showing 6 changed files with 1,233 additions and 16 deletions.
9 changes: 6 additions & 3 deletions internal/blockchain/ethereum/ethereum.go
Original file line number Diff line number Diff line change
Expand Up @@ -742,11 +742,12 @@ func (e *Ethereum) QueryContract(ctx context.Context, location *fftypes.JSONAny,
if err != nil || !res.IsSuccess() {
return nil, err
}
output := &queryOutput{}
if err = json.Unmarshal(res.Body(), output); err != nil {

var output interface{}
if err = json.Unmarshal(res.Body(), &output); err != nil {
return nil, err
}
return output, nil
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
}

func (e *Ethereum) NormalizeContractLocation(ctx context.Context, location *fftypes.JSONAny) (result *fftypes.JSONAny, err error) {
Expand Down Expand Up @@ -924,6 +925,8 @@ func (e *Ethereum) queryNetworkVersion(ctx context.Context, address string) (ver
}
return 0, err
}

// Leave as queryOutput as it only has one value
output := &queryOutput{}
if err = json.Unmarshal(res.Body(), output); err != nil {
return 0, err
Expand Down
95 changes: 95 additions & 0 deletions internal/blockchain/ethereum/ethereum_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2582,6 +2582,101 @@ func TestQueryContractOK(t *testing.T) {
assert.Equal(t, `{"output":"3"}`, string(j))
}

func TestQueryContractMultipleUnnamedOutputOK(t *testing.T) {
e, cancel := newTestEthereum()
defer cancel()
httpmock.ActivateNonDefault(e.client.GetClient())
defer httpmock.DeactivateAndReset()
location := &Location{
Address: "0x12345",
}
method := testFFIMethod()
errors := testFFIErrors()
params := map[string]interface{}{}
options := map[string]interface{}{
"customOption": "customValue",
}

outputStruct := struct {
Test string `json:"test"`
Value int `json:"value"`
}{
Test: "myvalue",
Value: 3,
}

output := map[string]interface{}{
"output": "foo",
"output1": outputStruct,
"anything": 3,
}

locationBytes, err := json.Marshal(location)
assert.NoError(t, err)
httpmock.RegisterResponder("POST", `http://localhost:12345/`,
func(req *http.Request) (*http.Response, error) {
var body map[string]interface{}
json.NewDecoder(req.Body).Decode(&body)
headers := body["headers"].(map[string]interface{})
assert.Equal(t, "Query", headers["type"])
assert.Equal(t, "customValue", body["customOption"].(string))
assert.Equal(t, "0x12345", body["to"].(string))
return httpmock.NewJsonResponderOrPanic(200, output)(req)
})
result, err := e.QueryContract(context.Background(), fftypes.JSONAnyPtrBytes(locationBytes), method, params, errors, options)
assert.NoError(t, err)
j, err := json.Marshal(result)
assert.NoError(t, err)
assert.Equal(t, `{"anything":3,"output":"foo","output1":{"test":"myvalue","value":3}}`, string(j))
}

func TestQueryContractNamedOutputOK(t *testing.T) {
e, cancel := newTestEthereum()
defer cancel()
httpmock.ActivateNonDefault(e.client.GetClient())
defer httpmock.DeactivateAndReset()
location := &Location{
Address: "0x12345",
}
method := testFFIMethod()
errors := testFFIErrors()
params := map[string]interface{}{}
options := map[string]interface{}{
"customOption": "customValue",
}

outputStruct := struct {
Test string `json:"test"`
Value int `json:"value"`
}{
Test: "myvalue",
Value: 3,
}

output := map[string]interface{}{
"mynamedparam": "foo",
"mynamedstruct": outputStruct,
}

locationBytes, err := json.Marshal(location)
assert.NoError(t, err)
httpmock.RegisterResponder("POST", `http://localhost:12345/`,
func(req *http.Request) (*http.Response, error) {
var body map[string]interface{}
json.NewDecoder(req.Body).Decode(&body)
headers := body["headers"].(map[string]interface{})
assert.Equal(t, "Query", headers["type"])
assert.Equal(t, "customValue", body["customOption"].(string))
assert.Equal(t, "0x12345", body["to"].(string))
return httpmock.NewJsonResponderOrPanic(200, output)(req)
})
result, err := e.QueryContract(context.Background(), fftypes.JSONAnyPtrBytes(locationBytes), method, params, errors, options)
assert.NoError(t, err)
j, err := json.Marshal(result)
assert.NoError(t, err)
assert.Equal(t, `{"mynamedparam":"foo","mynamedstruct":{"test":"myvalue","value":3}}`, string(j))
}

func TestQueryContractInvalidOption(t *testing.T) {
e, cancel := newTestEthereum()
defer cancel()
Expand Down
Loading

0 comments on commit eda9463

Please sign in to comment.