@@ -9,6 +9,7 @@ package chaincode
99import (
1010 "encoding/json"
1111 "fmt"
12+ "github.com/hyperledger/fabric-protos-go/ledger/queryresult"
1213 "sort"
1314 "strconv"
1415 "strings"
@@ -949,6 +950,8 @@ func removeBalance(ctx contractapi.TransactionContextInterface, sender string, i
949950 }
950951 defer balanceIterator .Close ()
951952
953+ var deferredDeletions = []func () error {}
954+
952955 // Iterate over keys that store balances and add them to partialBalance until
953956 // either the necessary amount is reached or the keys ended
954957 for balanceIterator .HasNext () && partialBalance < neededAmount {
@@ -972,47 +975,64 @@ func removeBalance(ctx contractapi.TransactionContextInterface, sender string, i
972975 selfRecipientKeyNeedsToBeRemoved = true
973976 selfRecipientKey = queryResponse .Key
974977 } else {
975- err = ctx .GetStub ().DelState (queryResponse .Key )
976- if err != nil {
977- return fmt .Errorf ("failed to delete the state of %v: %v" , queryResponse .Key , err )
978- }
978+ deferredDeletions = append (deferredDeletions , deferredDelete (ctx , queryResponse ))
979979 }
980980 }
981981
982982 if partialBalance < neededAmount {
983983 return fmt .Errorf ("sender has insufficient funds for token %v, needed funds: %v, available fund: %v" , tokenId , neededAmount , partialBalance )
984- } else if partialBalance > neededAmount {
985- // Send the remainder back to the sender
986- remainder , err := sub (partialBalance , neededAmount )
987- if err != nil {
988- return err
989- }
990-
991- if selfRecipientKeyNeedsToBeRemoved {
992- // Set balance for the key that has the same address for sender and recipient
993- err = setBalance (ctx , sender , sender , tokenId , remainder )
984+ } else {
985+ // enough token funds have been found to perform the update
986+ // now we can delete the token entries to supply updated token balances
987+ for _ , deleteFn := range deferredDeletions {
988+ err := deleteFn ()
994989 if err != nil {
995990 return err
996991 }
997- } else {
998- err = addBalance (ctx , sender , sender , tokenId , remainder )
992+ }
993+ if partialBalance > neededAmount {
994+ // Send the remainder back to the sender
995+ remainder , err := sub (partialBalance , neededAmount )
999996 if err != nil {
1000997 return err
1001998 }
1002- }
1003999
1004- } else {
1005- // Delete self recipient key
1006- err = ctx .GetStub ().DelState (selfRecipientKey )
1007- if err != nil {
1008- return fmt .Errorf ("failed to delete the state of %v: %v" , selfRecipientKey , err )
1000+ if selfRecipientKeyNeedsToBeRemoved {
1001+ // Set balance for the key that has the same address for sender and recipient
1002+ err = setBalance (ctx , sender , sender , tokenId , remainder )
1003+ if err != nil {
1004+ return err
1005+ }
1006+ } else {
1007+ err = addBalance (ctx , sender , sender , tokenId , remainder )
1008+ if err != nil {
1009+ return err
1010+ }
1011+ }
1012+
1013+ } else {
1014+ // Delete self recipient key
1015+ err = ctx .GetStub ().DelState (selfRecipientKey )
1016+ if err != nil {
1017+ return fmt .Errorf ("failed to delete the state of %v: %v" , selfRecipientKey , err )
1018+ }
10091019 }
10101020 }
10111021 }
10121022
10131023 return nil
10141024}
10151025
1026+ func deferredDelete (ctx contractapi.TransactionContextInterface , queryResponse * queryresult.KV ) func () error {
1027+ return func () error {
1028+ err := ctx .GetStub ().DelState (queryResponse .Key )
1029+ if err != nil {
1030+ return fmt .Errorf ("failed to delete the state of %v: %v" , queryResponse .Key , err )
1031+ }
1032+ return nil
1033+ }
1034+ }
1035+
10161036func emitTransferSingle (ctx contractapi.TransactionContextInterface , transferSingleEvent TransferSingle ) error {
10171037 transferSingleEventJSON , err := json .Marshal (transferSingleEvent )
10181038 if err != nil {
0 commit comments