@@ -321,15 +321,15 @@ func (self *ContractManager) contractStatus(contractStatus *ContractStatus) {
321321func (self * ContractManager ) Receive (source TransferPath , frames []* protocol.Frame , provideMode protocol.ProvideMode ) {
322322 if source .IsControlSource () {
323323 for _ , frame := range frames {
324- self .handleControlFrame (frame )
324+ self .handleControlFrame (nil , frame )
325325 }
326326 }
327327}
328328
329- func (self * ContractManager ) handleControlFrame (frame * protocol.Frame ) error {
329+ func (self * ContractManager ) handleControlFrame (createContractKey * ContractKey , frame * protocol.Frame ) error {
330330 switch frame .MessageType {
331331 case protocol .MessageType_TransferCreateContractResult :
332- contracts , contractErrors := self .parseControlFrame (frame )
332+ contracts , contractErrors := self .parseControlFrame (createContractKey , frame )
333333 for contractKey , contract := range contracts {
334334 c := func () error {
335335 err := self .addContract (contractKey , contract )
@@ -400,68 +400,71 @@ func (self *ContractManager) handleControlFrame(frame *protocol.Frame) error {
400400}
401401
402402// frames are verified before calling to be from source ControlId
403- func (self * ContractManager ) parseControlFrame (frame * protocol.Frame ) (
403+ func (self * ContractManager ) parseControlFrame (createContractKey * ContractKey , frame * protocol.Frame ) (
404404 contracts map [ContractKey ]* protocol.Contract ,
405405 contractErrors map [ContractKey ]protocol.ContractError ,
406406) {
407407 contracts = map [ContractKey ]* protocol.Contract {}
408408 contractErrors = map [ContractKey ]protocol.ContractError {}
409409
410410 addResult := func (v * protocol.CreateContractResult ) {
411- contractKey := ContractKey {}
412- if v .CreateContract != nil {
413- contractKey .CompanionContract = v .CreateContract .Companion
414- if v .CreateContract .ForceStream != nil {
415- contractKey .ForceStream = * v .CreateContract .ForceStream
411+ var contractKey * ContractKey
412+ if createContractKey != nil {
413+ contractKey = createContractKey
414+ } else if createContract := v .CreateContract ; createContract != nil {
415+ contractKey = & ContractKey {}
416+ var err error
417+ contractKey .Destination , err = TransferPathFromBytes (
418+ nil ,
419+ createContract .DestinationId ,
420+ nil ,
421+ )
422+ if err != nil {
423+ return
416424 }
417- if v .CreateContract .IntermediaryIds != nil {
418- if intermediaryIds , err := MultiHopIdFromBytes (v .CreateContract .IntermediaryIds ); err == nil {
425+ contractKey .CompanionContract = createContract .Companion
426+ if createContract .ForceStream != nil {
427+ contractKey .ForceStream = * createContract .ForceStream
428+ }
429+ if createContract .IntermediaryIds != nil {
430+ if intermediaryIds , err := MultiHopIdFromBytes (createContract .IntermediaryIds ); err == nil {
419431 contractKey .IntermediaryIds = intermediaryIds
420432 }
421433 }
422434 }
423435
424436 if contractError := v .Error ; contractError != nil {
425- if v .CreateContract != nil {
426- var err error
427- contractKey .Destination , err = TransferPathFromBytes (
428- nil ,
429- v .CreateContract .DestinationId ,
430- v .CreateContract .StreamId ,
431- )
432- if err != nil {
433- return
434- }
437+ if contractKey != nil {
438+ contractErrors [* contractKey ] = * contractError
439+ } else {
440+ glog .Infof ("[contract]error with unassociated contract = %s\n " , contractError )
435441 }
436- contractErrors [contractKey ] = * contractError
437442 } else if contract := v .Contract ; contract != nil {
438443 storedContract := & protocol.StoredContract {}
439444 err := ProtoUnmarshal (contract .StoredContractBytes , storedContract )
440445 if err != nil {
441446 return
442447 }
443448
444- if v .CreateContract != nil {
445- var err error
446- contractKey .Destination , err = TransferPathFromBytes (
447- nil ,
448- v .CreateContract .DestinationId ,
449- v .CreateContract .StreamId ,
450- )
451- if err != nil {
452- return
453- }
454- } else {
449+ if contractKey == nil && self .settings .LegacyCreateContract {
450+ // this only makes sense for legacy contracts
451+ contractKey = & ContractKey {}
455452 contractKey .Destination , err = TransferPathFromBytes (
456453 nil ,
457454 storedContract .DestinationId ,
458- storedContract . StreamId ,
455+ nil ,
459456 )
460457 if err != nil {
461458 return
462459 }
463460 }
464- contracts [contractKey ] = contract
461+
462+ if contractKey != nil {
463+ contracts [* contractKey ] = contract
464+ } else {
465+ // this contract can't be associated (TODO close it)
466+ glog .Errorf ("[contract]unassociated contract %s\n " , Id (storedContract .ContractId ))
467+ }
465468 }
466469 }
467470
@@ -806,18 +809,11 @@ func (self *ContractManager) addContract(contractKey ContractKey, contract *prot
806809 return err
807810 }
808811
809- path , err := TransferPathFromBytes (
810- storedContract .SourceId ,
811- storedContract .DestinationId ,
812- storedContract .StreamId ,
813- )
814- if err != nil {
815- return err
812+ if Id (storedContract .SourceId ) != self .client .ClientId () {
813+ return fmt .Errorf ("Contract source must be this client: %s<>%s" , Id (storedContract .SourceId ), self .client .ClientId ())
816814 }
817815
818- if ! path .IsStream () && path .SourceId != self .client .ClientId () {
819- return fmt .Errorf ("Contract source must be this client: %s<>%s" , path .SourceId , self .client .ClientId ())
820- }
816+ glog .V (1 ).Infof ("[contract]add %s %s\n " , self .client .ClientId (), contractKey .Destination )
821817
822818 func () {
823819 contractQueue := self .openContractQueue (contractKey )
@@ -838,7 +834,6 @@ func (self *ContractManager) CreateContract(contractKey ContractKey, contractSeq
838834 createContract := & protocol.CreateContract {
839835 DestinationId : contractKey .Destination .DestinationId .Bytes (),
840836 IntermediaryIds : contractKey .IntermediaryIds .Bytes (),
841- StreamId : contractKey .Destination .StreamId .Bytes (),
842837 TransferByteCount : uint64 (self .contractByteCount (contractSeqIndex , minByteCount )),
843838 Companion : contractKey .CompanionContract ,
844839 ForceStream : & contractKey .ForceStream ,
@@ -852,11 +847,16 @@ func (self *ContractManager) CreateContract(contractKey ContractKey, contractSeq
852847 glog .Infof ("[contract]could not create contract frame = %s" , err )
853848 return
854849 }
850+
851+ glog .V (1 ).Infof ("[contract]create %s %s\n " , self .client .ClientId (), contractKey .Destination )
852+
855853 self .client .ClientOob ().SendControl (
856854 []* protocol.Frame {frame },
857855 func (resultFrames []* protocol.Frame , err error ) {
858856 if err == nil {
859- self .Receive (SourceId (ControlId ), resultFrames , protocol .ProvideMode_Network )
857+ for _ , resultFrame := range resultFrames {
858+ self .handleControlFrame (& contractKey , resultFrame )
859+ }
860860 } else {
861861 select {
862862 case <- self .client .Done ():
@@ -978,11 +978,16 @@ func (self *ContractManager) Flush(resetUsedContractIds bool) []Id {
978978 self .mutex .Lock ()
979979 defer self .mutex .Unlock ()
980980
981+ glog .V (1 ).Infof ("[contract]flush %s %s\n " , self .client .ClientId (), maps .Keys (self .destinationContracts ))
982+
981983 contracts := []* protocol.Contract {}
982- for _ , contractQueue := range self .destinationContracts {
984+ for contractKey , contractQueue := range self .destinationContracts {
983985 for _ , contract := range contractQueue .Flush (resetUsedContractIds ) {
984986 contracts = append (contracts , contract )
985987 }
988+ if contractQueue .IsDone () {
989+ delete (self .destinationContracts , contractKey )
990+ }
986991 }
987992 return contracts
988993 }()
@@ -1119,7 +1124,7 @@ func (self *contractQueue) Add(contract *protocol.Contract, storedContract *prot
11191124 glog .V (2 ).Infof ("[contract]add update existing %s\n " , contractId )
11201125 self .contracts [contractId ] = contract
11211126 self .updateMonitor .NotifyAll ()
1122- } else if ! self .usedContractIds [contractId ] {
1127+ } else if ! self .trackUsedContracts || ! self . usedContractIds [contractId ] {
11231128 glog .V (2 ).Infof ("[contract]add %s\n " , contractId )
11241129 if self .trackUsedContracts {
11251130 self .usedContractIds [contractId ] = true
0 commit comments