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 }