github.com/braveheart12/just@v0.8.7/core/message/logicrunner.go (about)

     1  /*
     2   *    Copyright 2019 Insolar Technologies
     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 message
    18  
    19  import (
    20  	"github.com/insolar/insolar/core"
    21  	"github.com/insolar/insolar/platformpolicy"
    22  )
    23  
    24  // MethodReturnMode ENUM to set when method returns its result
    25  type MethodReturnMode int
    26  
    27  const (
    28  	// ReturnResult - return result as soon as it is ready
    29  	ReturnResult MethodReturnMode = iota
    30  	// ReturnNoWait - call method and return without results
    31  	ReturnNoWait
    32  	// ReturnValidated (not yet) - return result only when it's validated
    33  	// ReturnValidated
    34  )
    35  
    36  type PendingState int
    37  
    38  const (
    39  	PendingUnknown PendingState = iota
    40  	NotPending
    41  	InPending
    42  )
    43  
    44  type IBaseLogicMessage interface {
    45  	core.Message
    46  	GetBaseLogicMessage() *BaseLogicMessage
    47  	GetReference() core.RecordRef
    48  	GetRequest() core.RecordRef
    49  	GetCallerPrototype() *core.RecordRef
    50  }
    51  
    52  // BaseLogicMessage base of event class family, do not use it standalone
    53  type BaseLogicMessage struct {
    54  	Caller          core.RecordRef
    55  	Request         core.RecordRef
    56  	CallerPrototype core.RecordRef
    57  	Nonce           uint64
    58  	Sequence        uint64
    59  }
    60  
    61  func (m *BaseLogicMessage) GetBaseLogicMessage() *BaseLogicMessage {
    62  	return m
    63  }
    64  
    65  func (m *BaseLogicMessage) Type() core.MessageType {
    66  	panic("Virtual")
    67  }
    68  
    69  func (m *BaseLogicMessage) DefaultTarget() *core.RecordRef {
    70  	panic("Virtual")
    71  }
    72  
    73  func (m *BaseLogicMessage) DefaultRole() core.DynamicRole {
    74  	panic("implement me")
    75  }
    76  
    77  func (m *BaseLogicMessage) AllowedSenderObjectAndRole() (*core.RecordRef, core.DynamicRole) {
    78  	panic("implement me")
    79  }
    80  
    81  func (m *BaseLogicMessage) GetReference() core.RecordRef {
    82  	panic("implement me")
    83  }
    84  
    85  func (m *BaseLogicMessage) GetCaller() *core.RecordRef {
    86  	return &m.Caller
    87  }
    88  
    89  func (m *BaseLogicMessage) GetCallerPrototype() *core.RecordRef {
    90  	return &m.CallerPrototype
    91  }
    92  
    93  // GetRequest returns DynamicRoleVirtualExecutor as routing target role.
    94  func (m *BaseLogicMessage) GetRequest() core.RecordRef {
    95  	return m.Request
    96  }
    97  
    98  // ReturnResults - push results of methods
    99  type ReturnResults struct {
   100  	Target   core.RecordRef
   101  	Caller   core.RecordRef
   102  	Sequence uint64
   103  	Reply    core.Reply
   104  	Error    string
   105  }
   106  
   107  func (rr *ReturnResults) Type() core.MessageType {
   108  	return core.TypeReturnResults
   109  }
   110  
   111  func (rr *ReturnResults) GetCaller() *core.RecordRef {
   112  	return &rr.Caller
   113  }
   114  
   115  func (rr *ReturnResults) DefaultTarget() *core.RecordRef {
   116  	return &rr.Target
   117  }
   118  
   119  func (rr *ReturnResults) DefaultRole() core.DynamicRole {
   120  	return core.DynamicRoleVirtualExecutor
   121  }
   122  
   123  func (rr *ReturnResults) AllowedSenderObjectAndRole() (*core.RecordRef, core.DynamicRole) {
   124  	return nil, core.DynamicRoleVirtualExecutor
   125  }
   126  
   127  // CallMethod - Simply call method and return result
   128  type CallMethod struct {
   129  	BaseLogicMessage
   130  	ReturnMode     MethodReturnMode
   131  	ObjectRef      core.RecordRef
   132  	Method         string
   133  	Arguments      core.Arguments
   134  	ProxyPrototype core.RecordRef
   135  }
   136  
   137  // ToMap returns map representation of CallMethod.
   138  // Temporary until ledger.exporter api response reorganization
   139  func (cm *CallMethod) ToMap() (map[string]interface{}, error) {
   140  	msg := make(map[string]interface{})
   141  
   142  	// BaseLogicMessage fields
   143  	msg["Caller"] = cm.BaseLogicMessage.Caller.String()
   144  	msg["Request"] = cm.BaseLogicMessage.Request.String()
   145  	msg["CallerPrototype"] = cm.BaseLogicMessage.CallerPrototype.String()
   146  	msg["Nonce"] = cm.BaseLogicMessage.Nonce
   147  	msg["Sequence"] = cm.BaseLogicMessage.Sequence
   148  
   149  	// CallMethod fields
   150  	msg["ReturnMode"] = cm.ReturnMode
   151  	msg["ObjectRef"] = cm.ObjectRef.String()
   152  	msg["Method"] = cm.Method
   153  	msg["ProxyPrototype"] = cm.ProxyPrototype.String()
   154  	args, err := cm.Arguments.MarshalJSON()
   155  	if err != nil {
   156  		msg["Arguments"] = cm.Arguments
   157  	} else {
   158  		msg["Arguments"] = string(args)
   159  	}
   160  
   161  	return msg, nil
   162  }
   163  
   164  // AllowedSenderObjectAndRole implements interface method
   165  func (cm *CallMethod) AllowedSenderObjectAndRole() (*core.RecordRef, core.DynamicRole) {
   166  	c := cm.GetCaller()
   167  	if c.IsEmpty() {
   168  		return nil, 0
   169  	}
   170  	return c, core.DynamicRoleVirtualExecutor
   171  }
   172  
   173  // DefaultRole returns role for this event
   174  func (*CallMethod) DefaultRole() core.DynamicRole {
   175  	return core.DynamicRoleVirtualExecutor
   176  }
   177  
   178  // DefaultTarget returns of target of this event.
   179  func (cm *CallMethod) DefaultTarget() *core.RecordRef {
   180  	return &cm.ObjectRef
   181  }
   182  
   183  func (cm *CallMethod) GetReference() core.RecordRef {
   184  	return cm.ObjectRef
   185  }
   186  
   187  // Type returns TypeCallMethod.
   188  func (cm *CallMethod) Type() core.MessageType {
   189  	return core.TypeCallMethod
   190  }
   191  
   192  type SaveAs int
   193  
   194  const (
   195  	Child SaveAs = iota
   196  	Delegate
   197  )
   198  
   199  // CallConstructor is a message for calling constructor and obtain its reply
   200  type CallConstructor struct {
   201  	BaseLogicMessage
   202  	ParentRef    core.RecordRef
   203  	SaveAs       SaveAs
   204  	PrototypeRef core.RecordRef
   205  	Method       string
   206  	Arguments    core.Arguments
   207  	PulseNum     core.PulseNumber
   208  }
   209  
   210  // ToMap returns map representation of CallConstructor.
   211  // Temporary until ledger.exporter api response reorganization
   212  func (cc *CallConstructor) ToMap() (map[string]interface{}, error) {
   213  	msg := make(map[string]interface{})
   214  
   215  	// BaseLogicMessage fields
   216  	msg["Caller"] = cc.BaseLogicMessage.Caller.String()
   217  	msg["Request"] = cc.BaseLogicMessage.Request.String()
   218  	msg["CallerPrototype"] = cc.BaseLogicMessage.CallerPrototype.String()
   219  	msg["Nonce"] = cc.BaseLogicMessage.Nonce
   220  	msg["Sequence"] = cc.BaseLogicMessage.Sequence
   221  
   222  	// CallConstructor fields
   223  	msg["ParentRef"] = cc.ParentRef.String()
   224  	msg["SaveAs"] = cc.SaveAs
   225  	msg["PrototypeRef"] = cc.PrototypeRef.String()
   226  	msg["Method"] = cc.Method
   227  	msg["PulseNum"] = cc.PulseNum
   228  	args, err := cc.Arguments.MarshalJSON()
   229  	if err != nil {
   230  		msg["Arguments"] = cc.Arguments
   231  	} else {
   232  		msg["Arguments"] = string(args)
   233  	}
   234  
   235  	return msg, nil
   236  }
   237  
   238  //
   239  func (cc *CallConstructor) AllowedSenderObjectAndRole() (*core.RecordRef, core.DynamicRole) {
   240  	c := cc.GetCaller()
   241  	if c.IsEmpty() {
   242  		return nil, 0
   243  	}
   244  	return c, core.DynamicRoleVirtualExecutor
   245  }
   246  
   247  // DefaultRole returns role for this event
   248  func (*CallConstructor) DefaultRole() core.DynamicRole {
   249  	return core.DynamicRoleVirtualExecutor
   250  }
   251  
   252  // DefaultTarget returns of target of this event.
   253  func (cc *CallConstructor) DefaultTarget() *core.RecordRef {
   254  	if cc.SaveAs == Delegate {
   255  		return &cc.ParentRef
   256  	}
   257  	return genRequest(cc.PulseNum, MustSerializeBytes(cc), cc.Request.Domain())
   258  }
   259  
   260  func (cc *CallConstructor) GetReference() core.RecordRef {
   261  	return *genRequest(cc.PulseNum, MustSerializeBytes(cc), cc.Request.Domain())
   262  }
   263  
   264  // Type returns TypeCallConstructor.
   265  func (cc *CallConstructor) Type() core.MessageType {
   266  	return core.TypeCallConstructor
   267  }
   268  
   269  // TODO rename to executorObjectResult (results?)
   270  type ExecutorResults struct {
   271  	Caller                core.RecordRef
   272  	RecordRef             core.RecordRef
   273  	Requests              []CaseBindRequest
   274  	Queue                 []ExecutionQueueElement
   275  	LedgerHasMoreRequests bool
   276  	Pending               PendingState
   277  }
   278  
   279  type ExecutionQueueElement struct {
   280  	Parcel  core.Parcel
   281  	Request *core.RecordRef
   282  }
   283  
   284  // AllowedSenderObjectAndRole implements interface method
   285  func (er *ExecutorResults) AllowedSenderObjectAndRole() (*core.RecordRef, core.DynamicRole) {
   286  	// TODO need to think - this message can send only Executor of Previous Pulse, this function
   287  	return nil, 0
   288  }
   289  
   290  // DefaultRole returns role for this event
   291  func (er *ExecutorResults) DefaultRole() core.DynamicRole {
   292  	return core.DynamicRoleVirtualExecutor
   293  }
   294  
   295  // DefaultTarget returns of target of this event.
   296  func (er *ExecutorResults) DefaultTarget() *core.RecordRef {
   297  	return &er.RecordRef
   298  }
   299  
   300  func (er *ExecutorResults) Type() core.MessageType {
   301  	return core.TypeExecutorResults
   302  }
   303  
   304  // TODO change after changing pulsar
   305  func (er *ExecutorResults) GetCaller() *core.RecordRef {
   306  	return &er.Caller
   307  }
   308  
   309  func (er *ExecutorResults) GetReference() core.RecordRef {
   310  	return er.RecordRef
   311  }
   312  
   313  type ValidateCaseBind struct {
   314  	Caller    core.RecordRef
   315  	RecordRef core.RecordRef
   316  	Requests  []CaseBindRequest
   317  	Pulse     core.Pulse
   318  }
   319  
   320  type CaseBindRequest struct {
   321  	Parcel         core.Parcel
   322  	Request        core.RecordRef
   323  	MessageBusTape []byte
   324  	Reply          core.Reply
   325  	Error          string
   326  }
   327  
   328  // AllowedSenderObjectAndRole implements interface method
   329  func (vcb *ValidateCaseBind) AllowedSenderObjectAndRole() (*core.RecordRef, core.DynamicRole) {
   330  	return &vcb.RecordRef, core.DynamicRoleVirtualExecutor
   331  }
   332  
   333  // DefaultRole returns role for this event
   334  func (*ValidateCaseBind) DefaultRole() core.DynamicRole {
   335  	return core.DynamicRoleVirtualValidator
   336  }
   337  
   338  // DefaultTarget returns of target of this event.
   339  func (vcb *ValidateCaseBind) DefaultTarget() *core.RecordRef {
   340  	return &vcb.RecordRef
   341  }
   342  
   343  func (vcb *ValidateCaseBind) Type() core.MessageType {
   344  	return core.TypeValidateCaseBind
   345  }
   346  
   347  // TODO change after changing pulsar
   348  func (vcb *ValidateCaseBind) GetCaller() *core.RecordRef {
   349  	return &vcb.Caller // TODO actually it's not right. There is no caller.
   350  }
   351  
   352  func (vcb *ValidateCaseBind) GetReference() core.RecordRef {
   353  	return vcb.RecordRef
   354  }
   355  
   356  func (vcb *ValidateCaseBind) GetPulse() core.Pulse {
   357  	return vcb.Pulse
   358  }
   359  
   360  type ValidationResults struct {
   361  	Caller           core.RecordRef
   362  	RecordRef        core.RecordRef
   363  	PassedStepsCount int
   364  	Error            string
   365  }
   366  
   367  // AllowedSenderObjectAndRole implements interface method
   368  func (vr *ValidationResults) AllowedSenderObjectAndRole() (*core.RecordRef, core.DynamicRole) {
   369  	return &vr.RecordRef, core.DynamicRoleVirtualValidator
   370  }
   371  
   372  // DefaultRole returns role for this event
   373  func (*ValidationResults) DefaultRole() core.DynamicRole {
   374  	return core.DynamicRoleVirtualExecutor
   375  }
   376  
   377  // DefaultTarget returns of target of this event.
   378  func (vr *ValidationResults) DefaultTarget() *core.RecordRef {
   379  	return &vr.RecordRef
   380  }
   381  
   382  func (vr *ValidationResults) Type() core.MessageType {
   383  	return core.TypeValidationResults
   384  }
   385  
   386  // TODO change after changing pulsar
   387  func (vr *ValidationResults) GetCaller() *core.RecordRef {
   388  	return &vr.Caller // TODO actually it's not right. There is no caller.
   389  }
   390  
   391  func (vr *ValidationResults) GetReference() core.RecordRef {
   392  	return vr.RecordRef
   393  }
   394  
   395  var hasher = platformpolicy.NewPlatformCryptographyScheme().ReferenceHasher() // TODO: create message factory
   396  
   397  // GenRequest calculates RecordRef for request message from pulse number and request's payload.
   398  func genRequest(pn core.PulseNumber, payload []byte, domain *core.RecordID) *core.RecordRef {
   399  	ref := core.NewRecordRef(
   400  		*domain,
   401  		*core.NewRecordID(pn, hasher.Hash(payload)),
   402  	)
   403  	return ref
   404  }
   405  
   406  // PendingFinished is sent by the old executor to the current executor
   407  // when pending execution finishes.
   408  type PendingFinished struct {
   409  	Reference core.RecordRef // object pended in executor
   410  }
   411  
   412  func (pf *PendingFinished) GetCaller() *core.RecordRef {
   413  	// Contract that initiated this call
   414  	return &pf.Reference
   415  }
   416  
   417  func (pf *PendingFinished) AllowedSenderObjectAndRole() (*core.RecordRef, core.DynamicRole) {
   418  	// This type of message currently can be send from any node todo: rethink it
   419  	return nil, 0
   420  }
   421  
   422  func (pf *PendingFinished) DefaultRole() core.DynamicRole {
   423  	return core.DynamicRoleVirtualExecutor
   424  }
   425  
   426  func (pf *PendingFinished) DefaultTarget() *core.RecordRef {
   427  	return &pf.Reference
   428  }
   429  
   430  func (pf *PendingFinished) Type() core.MessageType {
   431  	return core.TypePendingFinished
   432  }
   433  
   434  // StillExecuting
   435  type StillExecuting struct {
   436  	Reference core.RecordRef // object we still executing
   437  }
   438  
   439  func (se *StillExecuting) GetCaller() *core.RecordRef {
   440  	return &se.Reference
   441  }
   442  
   443  func (se *StillExecuting) AllowedSenderObjectAndRole() (*core.RecordRef, core.DynamicRole) {
   444  	return nil, 0
   445  }
   446  
   447  func (se *StillExecuting) DefaultRole() core.DynamicRole {
   448  	return core.DynamicRoleVirtualExecutor
   449  }
   450  
   451  func (se *StillExecuting) DefaultTarget() *core.RecordRef {
   452  	return &se.Reference
   453  }
   454  
   455  func (se *StillExecuting) Type() core.MessageType {
   456  	return core.TypeStillExecuting
   457  }