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 }