github.com/kchristidis/fabric@v1.0.4-0.20171028114726-837acd08cde1/examples/ccchecker/chaincodes/newkeyperinvoke/shadow/newkeyperinvoke.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  		 http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package shadow
    18  
    19  import (
    20  	"bytes"
    21  	"fmt"
    22  	"sync"
    23  )
    24  
    25  // NewKeyPerInvoke is the shadow implementation for  NewKeyPerInvoke in the parent package
    26  // The shadow provides invoke arguments that are guaranteed to be result in unique ledger
    27  // entries as long as the parameters to GetInvokeArgs are unique
    28  type NewKeyPerInvoke struct {
    29  	sync.Mutex
    30  	state map[string][]byte
    31  }
    32  
    33  //---------- implements ShadowCCIntf functions -------
    34  
    35  //InitShadowCC initializes CC
    36  func (t *NewKeyPerInvoke) InitShadowCC(initArgs []string) {
    37  	t.state = make(map[string][]byte)
    38  }
    39  
    40  //invokeSuccessful sets the state and increments succefull invokes counter
    41  func (t *NewKeyPerInvoke) invokeSuccessful(key []byte, val []byte) {
    42  	t.Lock()
    43  	defer t.Unlock()
    44  	t.state[string(key)] = val
    45  }
    46  
    47  //getState gets the state
    48  func (t *NewKeyPerInvoke) getState(key []byte) ([]byte, bool) {
    49  	t.Lock()
    50  	defer t.Unlock()
    51  	v, ok := t.state[string(key)]
    52  	return v, ok
    53  }
    54  
    55  //OverrideNumInvokes returns the number of invokes shadow wants
    56  //accept users request, no override
    57  func (t *NewKeyPerInvoke) OverrideNumInvokes(numInvokesPlanned int) int {
    58  	return numInvokesPlanned
    59  }
    60  
    61  //GetNumQueries returns the number of queries shadow wants ccchecked to do.
    62  //For our purpose, just do as many queries as there were invokes for.
    63  func (t *NewKeyPerInvoke) GetNumQueries(numInvokesCompletedSuccessfully int) int {
    64  	return numInvokesCompletedSuccessfully
    65  }
    66  
    67  //GetInvokeArgs get args for invoke based on chaincode ID and iteration num
    68  func (t *NewKeyPerInvoke) GetInvokeArgs(ccnum int, iter int) [][]byte {
    69  	args := make([][]byte, 3)
    70  	args[0] = []byte("put")
    71  	args[1] = []byte(fmt.Sprintf("%d_%d", ccnum, iter))
    72  	args[2] = []byte(fmt.Sprintf("%d", ccnum))
    73  
    74  	return args
    75  }
    76  
    77  //PostInvoke store the key/val for later verification
    78  func (t *NewKeyPerInvoke) PostInvoke(args [][]byte, resp []byte) error {
    79  	if len(args) < 3 {
    80  		return fmt.Errorf("invalid number of args posted %d", len(args))
    81  	}
    82  
    83  	if string(args[0]) != "put" {
    84  		return fmt.Errorf("invalid args posted %s", args[0])
    85  	}
    86  
    87  	//the actual CC should have returned OK for success
    88  	if string(resp) != "OK" {
    89  		return fmt.Errorf("invalid response %s", string(resp))
    90  	}
    91  
    92  	t.invokeSuccessful(args[1], args[2])
    93  
    94  	return nil
    95  }
    96  
    97  //Validate the key/val with mem storage
    98  func (t *NewKeyPerInvoke) Validate(args [][]byte, value []byte) error {
    99  	if len(args) < 2 {
   100  		return fmt.Errorf("invalid number of args for validate %d", len(args))
   101  	}
   102  
   103  	if string(args[0]) != "get" {
   104  		return fmt.Errorf("invalid validate function %s", args[0])
   105  	}
   106  
   107  	if v, ok := t.getState(args[1]); !ok {
   108  		return fmt.Errorf("key not found %s", args[1])
   109  	} else if !bytes.Equal(v, value) {
   110  		return fmt.Errorf("expected(%s) but found (%s)", string(v), string(value))
   111  	}
   112  
   113  	return nil
   114  }
   115  
   116  //GetQueryArgs returns the query for the iter to test against
   117  func (t *NewKeyPerInvoke) GetQueryArgs(ccnum int, iter int) [][]byte {
   118  	args := make([][]byte, 2)
   119  	args[0] = []byte("get")
   120  	args[1] = []byte(fmt.Sprintf("%d_%d", ccnum, iter))
   121  	return args
   122  }