Skip to content

Commit b254b9b

Browse files
committed
[FAB-1984] Remove GetQueryResult from QSCC
In order to control access, all queries will need to go through application chaincode. This change is in response to early v1 feedback. See marbles02 for an example of calling GetQueryResult from application chaincode. In the future if there is capability to place ACL on peer APIs, then it would be possible to expose GetQueryResult as a peer API (or via QSCC). Change-Id: I1613563caf823e45fdfebeaa133f4ec523716cec Signed-off-by: denyeart <[email protected]>
1 parent 9b1bcf5 commit b254b9b

File tree

2 files changed

+0
-110
lines changed

2 files changed

+0
-110
lines changed

core/scc/qscc/querier.go

-95
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,11 @@ limitations under the License.
1717
package qscc
1818

1919
import (
20-
"bytes"
2120
"fmt"
2221
"strconv"
2322

2423
"github.com/op/go-logging"
25-
"github.com/spf13/viper"
2624

27-
commonledger "github.com/hyperledger/fabric/common/ledger"
2825
"github.com/hyperledger/fabric/core/chaincode/shim"
2926
"github.com/hyperledger/fabric/core/ledger"
3027
"github.com/hyperledger/fabric/core/peer"
@@ -37,7 +34,6 @@ import (
3734
// - GetBlockByNumber returns a block
3835
// - GetBlockByHash returns a block
3936
// - GetTransactionByID returns a transaction
40-
// - GetQueryResult returns result of a freeform query
4137
type LedgerQuerier struct {
4238
}
4339

@@ -49,7 +45,6 @@ const (
4945
GetBlockByNumber string = "GetBlockByNumber"
5046
GetBlockByHash string = "GetBlockByHash"
5147
GetTransactionByID string = "GetTransactionByID"
52-
GetQueryResult string = "GetQueryResult"
5348
)
5449

5550
// Init is called once per chain when the chain is created.
@@ -68,11 +63,6 @@ func (e *LedgerQuerier) Init(stub shim.ChaincodeStubInterface) pb.Response {
6863
// # GetBlockByNumber: Return the block specified by block number in args[2]
6964
// # GetBlockByHash: Return the block specified by block hash in args[2]
7065
// # GetTransactionByID: Return the transaction specified by ID in args[2]
71-
// # GetQueryResult: Return the result of executing the specified native
72-
// query string in args[2]. Note that this only works if plugged in database
73-
// supports it. The result is a JSON array in a byte array. Note that error
74-
// may be returned together with a valid partial result as error might occur
75-
// during accummulating records from the ledger
7666
func (e *LedgerQuerier) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
7767
args := stub.GetArgs()
7868

@@ -97,8 +87,6 @@ func (e *LedgerQuerier) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
9787
// TODO: Handle ACL
9888

9989
switch fname {
100-
case GetQueryResult:
101-
return getQueryResult(targetLedger, args[2])
10290
case GetTransactionByID:
10391
return getTransactionByID(targetLedger, args[2])
10492
case GetBlockByNumber:
@@ -112,89 +100,6 @@ func (e *LedgerQuerier) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
112100
return shim.Error(fmt.Sprintf("Requested function %s not found.", fname))
113101
}
114102

115-
// Execute the specified query string
116-
func getQueryResult(vledger ledger.PeerLedger, query []byte) (res pb.Response) {
117-
if query == nil {
118-
return shim.Error("Query string must not be nil.")
119-
}
120-
qstring := string(query)
121-
var qexe ledger.QueryExecutor
122-
var ri commonledger.ResultsIterator
123-
var err error
124-
125-
// We install a recover() to gain control in 2 cases
126-
// 1) bytes.Buffer panics, which happens when out of memory
127-
// This is a safety measure beyond the config limit variable
128-
// 2) plugin db driver might panic
129-
// We recover by stopping the query and return the panic error.
130-
defer func() {
131-
if panicValue := recover(); panicValue != nil {
132-
if qscclogger.IsEnabledFor(logging.DEBUG) {
133-
qscclogger.Debugf("Recovering panic: %s", panicValue)
134-
}
135-
res = shim.Error(fmt.Sprintf("Error recovery: %s", panicValue))
136-
}
137-
}()
138-
139-
if qexe, err = vledger.NewQueryExecutor(); err != nil {
140-
return shim.Error(err.Error())
141-
}
142-
if ri, err = qexe.ExecuteQuery(qstring); err != nil {
143-
return shim.Error(err.Error())
144-
}
145-
defer ri.Close()
146-
147-
limit := viper.GetInt("ledger.state.couchDBConfig.queryLimit")
148-
149-
// buffer is a JSON array containing QueryRecords
150-
var buffer bytes.Buffer
151-
buffer.WriteString("[")
152-
153-
var qresult commonledger.QueryResult
154-
bArrayMemberAlreadyWritten := false
155-
qresult, err = ri.Next()
156-
for r := 0; qresult != nil && err == nil && r < limit; r++ {
157-
if qr, ok := qresult.(*ledger.QueryRecord); ok {
158-
// Add a comma before array members, suppress it for the first array member
159-
if bArrayMemberAlreadyWritten == true {
160-
buffer.WriteString(",")
161-
}
162-
collectRecord(&buffer, qr)
163-
bArrayMemberAlreadyWritten = true
164-
}
165-
qresult, err = ri.Next()
166-
}
167-
168-
buffer.WriteString("]")
169-
170-
// Return what we have accummulated
171-
ret := buffer.Bytes()
172-
return shim.Success(ret)
173-
}
174-
175-
// Append QueryRecord into buffer as a JSON record of the form {namespace, key, record}
176-
// type QueryRecord struct {
177-
// Namespace string
178-
// Key string
179-
// Record []byte
180-
// }
181-
func collectRecord(buffer *bytes.Buffer, rec *ledger.QueryRecord) {
182-
buffer.WriteString("{\"Namespace\":")
183-
buffer.WriteString("\"")
184-
buffer.WriteString(rec.Namespace)
185-
buffer.WriteString("\"")
186-
187-
buffer.WriteString(", \"Key\":")
188-
buffer.WriteString("\"")
189-
buffer.WriteString(rec.Key)
190-
buffer.WriteString("\"")
191-
192-
buffer.WriteString(", \"Record\":")
193-
// Record is a JSON object, so we write as-is
194-
buffer.WriteString(string(rec.Record))
195-
buffer.WriteString("}")
196-
}
197-
198103
func getTransactionByID(vledger ledger.PeerLedger, tid []byte) pb.Response {
199104
if tid == nil {
200105
return shim.Error("Transaction ID must not be nil.")

core/scc/qscc/querier_test.go

-15
Original file line numberDiff line numberDiff line change
@@ -117,18 +117,3 @@ func TestQueryGetBlockByHash(t *testing.T) {
117117
t.Fatalf("qscc GetBlockByHash should have failed with invalid hash: 0")
118118
}
119119
}
120-
121-
func TestQueryGetQueryResult(t *testing.T) {
122-
viper.Set("peer.fileSystemPath", "/var/hyperledger/test7/")
123-
defer os.RemoveAll("/var/hyperledger/test7/")
124-
peer.MockInitialize()
125-
peer.MockCreateChain("mytestchainid7")
126-
127-
e := new(LedgerQuerier)
128-
stub := shim.NewMockStub("LedgerQuerier", e)
129-
qstring := "{\"selector\":{\"key\":\"value\"}}"
130-
args := [][]byte{[]byte(GetQueryResult), []byte("mytestchainid7"), []byte(qstring)}
131-
if res := stub.MockInvoke("1", args); res.Status == shim.OK {
132-
t.Fatalf("qscc GetQueryResult should have failed with invalid query: abc")
133-
}
134-
}

0 commit comments

Comments
 (0)