diff --git a/ledger-core/virtual/execute/execute.go b/ledger-core/virtual/execute/execute.go index 1b62bf88d9..348edcecbc 100644 --- a/ledger-core/virtual/execute/execute.go +++ b/ledger-core/virtual/execute/execute.go @@ -728,6 +728,8 @@ func (s *SMExecute) stepSendOutgoing(ctx smachine.ExecutionContext) smachine.Sta } } else { if s.outgoingSentCounter >= MaxOutgoingSendCount { + // TODO when CallSummary will live longer than one pulse it needs to be updated + s.sendDelegatedRequestFinished(ctx, nil) return ctx.Error(throw.E("outgoing retries limit")) } @@ -927,6 +929,12 @@ func (s *SMExecute) stepSendDelegatedRequestFinished(ctx smachine.ExecutionConte } } + s.sendDelegatedRequestFinished(ctx, lastState) + + return ctx.Stop() +} + +func (s *SMExecute) sendDelegatedRequestFinished(ctx smachine.ExecutionContext, lastState *payload.ObjectState) { msg := payload.VDelegatedRequestFinished{ CallType: s.Payload.CallType, CallFlags: s.Payload.CallFlags, @@ -945,10 +953,9 @@ func (s *SMExecute) stepSendDelegatedRequestFinished(ctx smachine.ExecutionConte } } }).WithoutAutoWakeUp().Start() - - return ctx.Stop() } + func (s *SMExecute) makeNewDescriptor(class reference.Global, memory []byte) descriptor.Object { var prevStateIDBytes []byte objDescriptor := s.execution.ObjectDescriptor diff --git a/ledger-core/virtual/execute/execute.plantuml b/ledger-core/virtual/execute/execute.plantuml index ef493b21f7..7ac5c37e56 100644 --- a/ledger-core/virtual/execute/execute.plantuml +++ b/ledger-core/virtual/execute/execute.plantuml @@ -147,7 +147,6 @@ state "stepSendDelegatedRequestFinished" as T01_S031 T01_S031 : SMExecute T01_S031 --[dotted]> T01_S016 T01_S031 --[dotted]> T01_S001 -T01_S031 --> T01_S011 : PrepareAsync(ctx).WithoutAutoWakeUp() T01_S031 --> [*] state "stepSendOutgoing" as T01_S025 T01_S025 : SMExecute diff --git a/ledger-core/virtual/handlers/vdelegatedrequestfinished.go b/ledger-core/virtual/handlers/vdelegatedrequestfinished.go index e4002af089..f760cc2f4e 100644 --- a/ledger-core/virtual/handlers/vdelegatedrequestfinished.go +++ b/ledger-core/virtual/handlers/vdelegatedrequestfinished.go @@ -45,6 +45,12 @@ type unexpectedVDelegateRequestFinished struct { Ordered bool } +type noLatestStateTolerableVDelegateRequestFinished struct { + *log.Msg `txt:"Tolerable VDelegateRequestFinished on Empty object has no LatestState"` + Object reference.Holder + Request reference.Holder +} + var dSMVDelegatedRequestFinishedInstance smachine.StateMachineDeclaration = &dSMVDelegatedRequestFinished{} type dSMVDelegatedRequestFinished struct { @@ -154,6 +160,15 @@ func (s *SMVDelegatedRequestFinished) updateSharedState( if s.hasLatestState() { state.SetDescriptorDirty(s.latestState()) s.updateObjectState(state) + } else if s.Payload.CallFlags.GetInterference() == contract.CallTolerable && + s.Payload.CallType == payload.CTConstructor && + state.GetState() == object.Empty { + + ctx.Log().Warn(noLatestStateTolerableVDelegateRequestFinished{ + Object: objectRef, + Request: requestRef, + }) + state.SetState(object.Missing) } pendingList := state.PendingTable.GetList(s.Payload.CallFlags.GetInterference()) diff --git a/ledger-core/virtual/integration/contract_calls_test.go b/ledger-core/virtual/integration/contract_calls_test.go index 8c1aee4975..126857b0a4 100644 --- a/ledger-core/virtual/integration/contract_calls_test.go +++ b/ledger-core/virtual/integration/contract_calls_test.go @@ -762,6 +762,8 @@ func TestVirtual_CallContractFromContract_RetryLimit(t *testing.T) { return false }) + typedChecker.VDelegatedRequestFinished.Set(func(finished *payload.VDelegatedRequestFinished) bool { return false }) + } server.WaitIdleConveyor() @@ -776,6 +778,8 @@ func TestVirtual_CallContractFromContract_RetryLimit(t *testing.T) { testutils.WaitSignalsTimed(t, 10*time.Second, server.Journal.WaitAllAsyncCallsDone(), executeStopped, foundError) require.Equal(t, countChangePulse, typedChecker.VCallRequest.Count()) + require.Equal(t, countChangePulse, typedChecker.VDelegatedCallRequest.Count()) + require.Equal(t, 1, typedChecker.VDelegatedRequestFinished.Count()) mc.Finish()