github.com/braveheart12/just@v0.8.7/ledger/artifactmanager/handler.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 artifactmanager 18 19 import ( 20 "bytes" 21 "context" 22 "fmt" 23 "time" 24 25 "github.com/insolar/insolar/core/delegationtoken" 26 "github.com/insolar/insolar/ledger/storage/nodes" 27 "github.com/pkg/errors" 28 "go.opencensus.io/stats" 29 "go.opencensus.io/tag" 30 31 "github.com/insolar/insolar/instrumentation/inslogger" 32 "github.com/insolar/insolar/instrumentation/insmetrics" 33 "github.com/insolar/insolar/ledger/recentstorage" 34 "github.com/insolar/insolar/ledger/storage/jet" 35 36 "github.com/insolar/insolar/configuration" 37 "github.com/insolar/insolar/core" 38 "github.com/insolar/insolar/core/message" 39 "github.com/insolar/insolar/core/reply" 40 "github.com/insolar/insolar/instrumentation/hack" 41 "github.com/insolar/insolar/ledger/storage" 42 "github.com/insolar/insolar/ledger/storage/index" 43 "github.com/insolar/insolar/ledger/storage/record" 44 ) 45 46 // MessageHandler processes messages for local storage interaction. 47 type MessageHandler struct { 48 RecentStorageProvider recentstorage.Provider `inject:""` 49 Bus core.MessageBus `inject:""` 50 PlatformCryptographyScheme core.PlatformCryptographyScheme `inject:""` 51 JetCoordinator core.JetCoordinator `inject:""` 52 CryptographyService core.CryptographyService `inject:""` 53 DelegationTokenFactory core.DelegationTokenFactory `inject:""` 54 HeavySync core.HeavySync `inject:""` 55 PulseStorage core.PulseStorage `inject:""` 56 JetStorage storage.JetStorage `inject:""` 57 DropStorage storage.DropStorage `inject:""` 58 ObjectStorage storage.ObjectStorage `inject:""` 59 Nodes nodes.Accessor `inject:""` 60 PulseTracker storage.PulseTracker `inject:""` 61 DBContext storage.DBContext `inject:""` 62 HotDataWaiter HotDataWaiter `inject:""` 63 64 certificate core.Certificate 65 replayHandlers map[core.MessageType]core.MessageHandler 66 conf *configuration.Ledger 67 middleware *middleware 68 jetTreeUpdater *jetTreeUpdater 69 isHeavy bool 70 } 71 72 // NewMessageHandler creates new handler. 73 func NewMessageHandler(conf *configuration.Ledger, certificate core.Certificate) *MessageHandler { 74 return &MessageHandler{ 75 certificate: certificate, 76 replayHandlers: map[core.MessageType]core.MessageHandler{}, 77 conf: conf, 78 } 79 } 80 81 func instrumentHandler(name string) Handler { 82 return func(handler core.MessageHandler) core.MessageHandler { 83 return func(ctx context.Context, p core.Parcel) (core.Reply, error) { 84 // TODO: add tags to log 85 inslog := inslogger.FromContext(ctx) 86 start := time.Now() 87 code := "2xx" 88 ctx = insmetrics.InsertTag(ctx, tagMethod, name) 89 90 repl, err := handler(ctx, p) 91 92 latency := time.Since(start) 93 if err != nil { 94 code = "5xx" 95 inslog.Errorf("AM's handler %v returns error: %v", name, err) 96 } 97 inslog.Debugf("measured time of AM method %v is %v", name, latency) 98 99 ctx = insmetrics.ChangeTags( 100 ctx, 101 tag.Insert(tagMethod, name), 102 tag.Insert(tagResult, code), 103 ) 104 stats.Record(ctx, statCalls.M(1), statLatency.M(latency.Nanoseconds()/1e6)) 105 106 return repl, err 107 } 108 } 109 } 110 111 // Init initializes handlers and middleware. 112 func (h *MessageHandler) Init(ctx context.Context) error { 113 m := newMiddleware(h) 114 h.middleware = m 115 116 h.jetTreeUpdater = newJetTreeUpdater(h.Nodes, h.JetStorage, h.Bus, h.JetCoordinator) 117 118 h.isHeavy = h.certificate.GetRole() == core.StaticRoleHeavyMaterial 119 120 // core.StaticRoleUnknown - genesis 121 if h.certificate.GetRole() == core.StaticRoleLightMaterial || h.certificate.GetRole() == core.StaticRoleUnknown { 122 h.setHandlersForLight(m) 123 h.setReplayHandlers(m) 124 } 125 126 if h.isHeavy { 127 h.setHandlersForHeavy(m) 128 } 129 130 return nil 131 } 132 133 func (h *MessageHandler) setHandlersForLight(m *middleware) { 134 // Generic. 135 h.Bus.MustRegister(core.TypeGetCode, BuildMiddleware(h.handleGetCode)) 136 137 h.Bus.MustRegister(core.TypeGetObject, 138 BuildMiddleware(h.handleGetObject, 139 instrumentHandler("handleGetObject"), 140 m.addFieldsToLogger, 141 m.checkJet, 142 m.waitForHotData)) 143 144 h.Bus.MustRegister(core.TypeGetDelegate, 145 BuildMiddleware(h.handleGetDelegate, 146 instrumentHandler("handleGetDelegate"), 147 m.addFieldsToLogger, 148 m.checkJet, 149 m.waitForHotData)) 150 151 h.Bus.MustRegister(core.TypeGetChildren, 152 BuildMiddleware(h.handleGetChildren, 153 instrumentHandler("handleGetChildren"), 154 m.addFieldsToLogger, 155 m.checkJet, 156 m.waitForHotData)) 157 158 h.Bus.MustRegister(core.TypeSetRecord, 159 BuildMiddleware(h.handleSetRecord, 160 instrumentHandler("handleSetRecord"), 161 m.addFieldsToLogger, 162 m.checkJet, 163 m.waitForHotData)) 164 165 h.Bus.MustRegister(core.TypeUpdateObject, 166 BuildMiddleware(h.handleUpdateObject, 167 instrumentHandler("handleUpdateObject"), 168 m.addFieldsToLogger, 169 m.checkJet, 170 m.waitForHotData)) 171 172 h.Bus.MustRegister(core.TypeRegisterChild, 173 BuildMiddleware(h.handleRegisterChild, 174 instrumentHandler("handleRegisterChild"), 175 m.addFieldsToLogger, 176 m.checkJet, 177 m.waitForHotData)) 178 179 h.Bus.MustRegister(core.TypeSetBlob, 180 BuildMiddleware(h.handleSetBlob, 181 instrumentHandler("handleSetBlob"), 182 m.addFieldsToLogger, 183 m.checkJet, 184 m.waitForHotData)) 185 186 h.Bus.MustRegister(core.TypeGetObjectIndex, 187 BuildMiddleware(h.handleGetObjectIndex, 188 instrumentHandler("handleGetObjectIndex"), 189 m.addFieldsToLogger, 190 m.checkJet, 191 m.waitForHotData)) 192 193 h.Bus.MustRegister(core.TypeGetPendingRequests, 194 BuildMiddleware(h.handleHasPendingRequests, 195 instrumentHandler("handleHasPendingRequests"), 196 m.addFieldsToLogger, 197 m.checkJet, 198 m.waitForHotData)) 199 200 h.Bus.MustRegister(core.TypeGetJet, 201 BuildMiddleware(h.handleGetJet, 202 instrumentHandler("handleGetJet"))) 203 204 h.Bus.MustRegister(core.TypeHotRecords, 205 BuildMiddleware(h.handleHotRecords, 206 instrumentHandler("handleHotRecords"), 207 m.releaseHotDataWaiters)) 208 209 h.Bus.MustRegister( 210 core.TypeGetRequest, 211 BuildMiddleware( 212 h.handleGetRequest, 213 instrumentHandler("handleGetRequest"), 214 m.checkJet, 215 ), 216 ) 217 218 h.Bus.MustRegister( 219 core.TypeGetPendingRequestID, 220 BuildMiddleware( 221 h.handleGetPendingRequestID, 222 instrumentHandler("handleGetPendingRequestID"), 223 m.checkJet, 224 ), 225 ) 226 227 // Validation. 228 h.Bus.MustRegister(core.TypeValidateRecord, 229 BuildMiddleware(h.handleValidateRecord, 230 m.addFieldsToLogger, 231 m.checkJet)) 232 233 h.Bus.MustRegister(core.TypeValidationCheck, 234 BuildMiddleware(h.handleValidationCheck, 235 m.addFieldsToLogger, 236 m.checkJet)) 237 238 h.Bus.MustRegister(core.TypeJetDrop, 239 BuildMiddleware(h.handleJetDrop, 240 m.addFieldsToLogger, 241 m.checkJet)) 242 } 243 func (h *MessageHandler) setReplayHandlers(m *middleware) { 244 // Generic. 245 h.replayHandlers[core.TypeGetCode] = BuildMiddleware(h.handleGetCode, m.addFieldsToLogger) 246 h.replayHandlers[core.TypeGetObject] = BuildMiddleware(h.handleGetObject, m.addFieldsToLogger, m.checkJet) 247 h.replayHandlers[core.TypeGetDelegate] = BuildMiddleware(h.handleGetDelegate, m.addFieldsToLogger, m.checkJet) 248 h.replayHandlers[core.TypeGetChildren] = BuildMiddleware(h.handleGetChildren, m.addFieldsToLogger, m.checkJet) 249 h.replayHandlers[core.TypeSetRecord] = BuildMiddleware(h.handleSetRecord, m.addFieldsToLogger, m.checkJet) 250 h.replayHandlers[core.TypeUpdateObject] = BuildMiddleware(h.handleUpdateObject, m.addFieldsToLogger, m.checkJet) 251 h.replayHandlers[core.TypeRegisterChild] = BuildMiddleware(h.handleRegisterChild, m.addFieldsToLogger, m.checkJet) 252 h.replayHandlers[core.TypeSetBlob] = BuildMiddleware(h.handleSetBlob, m.addFieldsToLogger, m.checkJet) 253 h.replayHandlers[core.TypeGetObjectIndex] = BuildMiddleware(h.handleGetObjectIndex, m.addFieldsToLogger, m.checkJet) 254 h.replayHandlers[core.TypeGetPendingRequests] = BuildMiddleware(h.handleHasPendingRequests, m.addFieldsToLogger, m.checkJet) 255 h.replayHandlers[core.TypeGetJet] = BuildMiddleware(h.handleGetJet) 256 257 // Validation. 258 h.replayHandlers[core.TypeValidateRecord] = BuildMiddleware(h.handleValidateRecord, m.addFieldsToLogger, m.checkJet) 259 h.replayHandlers[core.TypeValidationCheck] = BuildMiddleware(h.handleValidationCheck, m.addFieldsToLogger, m.checkJet) 260 } 261 func (h *MessageHandler) setHandlersForHeavy(m *middleware) { 262 // Heavy. 263 h.Bus.MustRegister(core.TypeHeavyStartStop, 264 BuildMiddleware(h.handleHeavyStartStop, 265 instrumentHandler("handleHeavyStartStop"))) 266 267 h.Bus.MustRegister(core.TypeHeavyReset, 268 BuildMiddleware(h.handleHeavyReset, 269 instrumentHandler("handleHeavyReset"))) 270 271 h.Bus.MustRegister(core.TypeHeavyPayload, 272 BuildMiddleware(h.handleHeavyPayload, 273 instrumentHandler("handleHeavyPayload"))) 274 275 // Generic. 276 h.Bus.MustRegister(core.TypeGetCode, 277 BuildMiddleware(h.handleGetCode)) 278 279 h.Bus.MustRegister(core.TypeGetObject, 280 BuildMiddleware(h.handleGetObject, 281 instrumentHandler("handleGetObject"), 282 m.zeroJetForHeavy)) 283 284 h.Bus.MustRegister(core.TypeGetDelegate, 285 BuildMiddleware(h.handleGetDelegate, 286 instrumentHandler("handleGetDelegate"), 287 m.zeroJetForHeavy)) 288 289 h.Bus.MustRegister(core.TypeGetChildren, 290 BuildMiddleware(h.handleGetChildren, 291 instrumentHandler("handleGetChildren"), 292 m.zeroJetForHeavy)) 293 294 h.Bus.MustRegister(core.TypeGetObjectIndex, 295 BuildMiddleware(h.handleGetObjectIndex, 296 instrumentHandler("handleGetObjectIndex"), 297 m.zeroJetForHeavy)) 298 299 h.Bus.MustRegister( 300 core.TypeGetRequest, 301 BuildMiddleware(h.handleGetRequest, 302 instrumentHandler("handleGetRequest"), 303 m.zeroJetForHeavy)) 304 } 305 306 func (h *MessageHandler) handleSetRecord(ctx context.Context, parcel core.Parcel) (core.Reply, error) { 307 if h.isHeavy { 308 return nil, errors.New("heavy updates are forbidden") 309 } 310 311 msg := parcel.Message().(*message.SetRecord) 312 rec := record.DeserializeRecord(msg.Record) 313 jetID := jetFromContext(ctx) 314 315 calculatedID := record.NewRecordIDFromRecord(h.PlatformCryptographyScheme, parcel.Pulse(), rec) 316 317 switch r := rec.(type) { 318 case record.Request: 319 if h.RecentStorageProvider.Count() > h.conf.PendingRequestsLimit { 320 return &reply.Error{ErrType: reply.ErrTooManyPendingRequests}, nil 321 } 322 recentStorage := h.RecentStorageProvider.GetPendingStorage(ctx, jetID) 323 recentStorage.AddPendingRequest(ctx, r.GetObject(), *calculatedID) 324 case *record.ResultRecord: 325 recentStorage := h.RecentStorageProvider.GetPendingStorage(ctx, jetID) 326 recentStorage.RemovePendingRequest(ctx, r.Object, *r.Request.Record()) 327 } 328 329 id, err := h.ObjectStorage.SetRecord(ctx, jetID, parcel.Pulse(), rec) 330 if err == storage.ErrOverride { 331 inslogger.FromContext(ctx).WithField("type", fmt.Sprintf("%T", rec)).Warn("set record override") 332 id = calculatedID 333 } else if err != nil { 334 return nil, err 335 } 336 337 return &reply.ID{ID: *id}, nil 338 } 339 340 func (h *MessageHandler) handleSetBlob(ctx context.Context, parcel core.Parcel) (core.Reply, error) { 341 if h.isHeavy { 342 return nil, errors.New("heavy updates are forbidden") 343 } 344 345 msg := parcel.Message().(*message.SetBlob) 346 jetID := jetFromContext(ctx) 347 calculatedID := record.CalculateIDForBlob(h.PlatformCryptographyScheme, parcel.Pulse(), msg.Memory) 348 349 _, err := h.ObjectStorage.GetBlob(ctx, jetID, calculatedID) 350 if err == nil { 351 return &reply.ID{ID: *calculatedID}, nil 352 } 353 if err != nil && err != core.ErrNotFound { 354 return nil, err 355 } 356 357 id, err := h.ObjectStorage.SetBlob(ctx, jetID, parcel.Pulse(), msg.Memory) 358 if err == nil { 359 return &reply.ID{ID: *id}, nil 360 } 361 if err == storage.ErrOverride { 362 return &reply.ID{ID: *calculatedID}, nil 363 } 364 return nil, err 365 } 366 367 func (h *MessageHandler) handleGetCode(ctx context.Context, parcel core.Parcel) (core.Reply, error) { 368 msg := parcel.Message().(*message.GetCode) 369 jetID := *jet.NewID(0, nil) 370 371 codeRec, err := h.getCode(ctx, msg.Code.Record()) 372 if err == core.ErrNotFound { 373 // We don't have code record. Must be on another node. 374 node, err := h.JetCoordinator.NodeForJet(ctx, jetID, parcel.Pulse(), msg.Code.Record().Pulse()) 375 if err != nil { 376 return nil, err 377 } 378 return reply.NewGetCodeRedirect(h.DelegationTokenFactory, parcel, node) 379 } 380 if err != nil { 381 return nil, err 382 } 383 code, err := h.ObjectStorage.GetBlob(ctx, jetID, codeRec.Code) 384 if err != nil { 385 return nil, err 386 } 387 388 rep := reply.Code{ 389 Code: code, 390 MachineType: codeRec.MachineType, 391 } 392 393 return &rep, nil 394 } 395 396 func (h *MessageHandler) handleGetObject( 397 ctx context.Context, parcel core.Parcel, 398 ) (core.Reply, error) { 399 msg := parcel.Message().(*message.GetObject) 400 jetID := jetFromContext(ctx) 401 logger := inslogger.FromContext(ctx).WithFields(map[string]interface{}{ 402 "object": msg.Head.Record().DebugString(), 403 "pulse": parcel.Pulse(), 404 }) 405 406 if !h.isHeavy { 407 h.RecentStorageProvider.GetIndexStorage(ctx, jetID).AddObject(ctx, *msg.Head.Record()) 408 } 409 410 // Fetch object index. If not found redirect. 411 idx, err := h.ObjectStorage.GetObjectIndex(ctx, jetID, msg.Head.Record(), false) 412 if err == core.ErrNotFound { 413 if h.isHeavy { 414 return nil, fmt.Errorf("failed to fetch index for %s", msg.Head.Record().String()) 415 } 416 417 logger.Debug("failed to fetch index (fetching from heavy)") 418 node, err := h.JetCoordinator.Heavy(ctx, parcel.Pulse()) 419 if err != nil { 420 return nil, err 421 } 422 idx, err = h.saveIndexFromHeavy(ctx, jetID, msg.Head, node) 423 if err != nil { 424 return nil, errors.Wrap(err, "failed to fetch index from heavy") 425 } 426 } else if err != nil { 427 return nil, errors.Wrapf(err, "failed to fetch object index %s", msg.Head.Record().String()) 428 } 429 430 // Determine object state id. 431 var stateID *core.RecordID 432 if msg.State != nil { 433 stateID = msg.State 434 } else { 435 if msg.Approved { 436 stateID = idx.LatestStateApproved 437 } else { 438 stateID = idx.LatestState 439 } 440 } 441 if stateID == nil { 442 return &reply.Error{ErrType: reply.ErrStateNotAvailable}, nil 443 } 444 445 var ( 446 stateJet *core.RecordID 447 ) 448 if h.isHeavy { 449 stateJet = &jetID 450 } else { 451 var actual bool 452 onHeavy, err := h.JetCoordinator.IsBeyondLimit(ctx, parcel.Pulse(), stateID.Pulse()) 453 if err != nil { 454 return nil, err 455 } 456 if onHeavy { 457 node, err := h.JetCoordinator.Heavy(ctx, parcel.Pulse()) 458 if err != nil { 459 return nil, err 460 } 461 logger.WithFields(map[string]interface{}{ 462 "state": stateID.DebugString(), 463 "going_to": node.String(), 464 }).Debug("fetching object (on heavy)") 465 466 obj, err := h.fetchObject(ctx, msg.Head, *node, stateID) 467 if err != nil { 468 if err == core.ErrDeactivated { 469 return &reply.Error{ErrType: reply.ErrDeactivated}, nil 470 } 471 return nil, err 472 } 473 474 return &reply.Object{ 475 Head: msg.Head, 476 State: *stateID, 477 Prototype: obj.Prototype, 478 IsPrototype: obj.IsPrototype, 479 ChildPointer: idx.ChildPointer, 480 Parent: idx.Parent, 481 Memory: obj.Memory, 482 }, nil 483 } 484 485 stateJet, actual = h.JetStorage.FindJet(ctx, stateID.Pulse(), *msg.Head.Record()) 486 if !actual { 487 actualJet, err := h.jetTreeUpdater.fetchJet(ctx, *msg.Head.Record(), stateID.Pulse()) 488 if err != nil { 489 return nil, err 490 } 491 stateJet = actualJet 492 } 493 } 494 495 // Fetch state record. 496 rec, err := h.ObjectStorage.GetRecord(ctx, *stateJet, stateID) 497 if err == core.ErrNotFound { 498 if h.isHeavy { 499 return nil, fmt.Errorf("failed to fetch state for %v. jet: %v, state: %v", msg.Head.Record(), stateJet.DebugString(), stateID.DebugString()) 500 } 501 // The record wasn't found on the current node. Return redirect to the node that contains it. 502 // We get Jet tree for pulse when given state was added. 503 node, err := h.JetCoordinator.NodeForJet(ctx, *stateJet, parcel.Pulse(), stateID.Pulse()) 504 if err != nil { 505 return nil, err 506 } 507 logger.WithFields(map[string]interface{}{ 508 "state": stateID.DebugString(), 509 "going_to": node.String(), 510 }).Debug("fetching object (record not found)") 511 512 obj, err := h.fetchObject(ctx, msg.Head, *node, stateID) 513 if err != nil { 514 if err == core.ErrDeactivated { 515 return &reply.Error{ErrType: reply.ErrDeactivated}, nil 516 } 517 return nil, err 518 } 519 520 return &reply.Object{ 521 Head: msg.Head, 522 State: *stateID, 523 Prototype: obj.Prototype, 524 IsPrototype: obj.IsPrototype, 525 ChildPointer: idx.ChildPointer, 526 Parent: idx.Parent, 527 Memory: obj.Memory, 528 }, nil 529 } 530 if err != nil { 531 return nil, err 532 } 533 state, ok := rec.(record.ObjectState) 534 if !ok { 535 return nil, errors.New("invalid object record") 536 } 537 if state.State() == record.StateDeactivation { 538 return &reply.Error{ErrType: reply.ErrDeactivated}, nil 539 } 540 541 var childPointer *core.RecordID 542 if idx.ChildPointer != nil { 543 childPointer = idx.ChildPointer 544 } 545 rep := reply.Object{ 546 Head: msg.Head, 547 State: *stateID, 548 Prototype: state.GetImage(), 549 IsPrototype: state.GetIsPrototype(), 550 ChildPointer: childPointer, 551 Parent: idx.Parent, 552 } 553 554 if state.GetMemory() != nil { 555 rep.Memory, err = h.ObjectStorage.GetBlob(ctx, *stateJet, state.GetMemory()) 556 if err != nil { 557 return nil, errors.Wrap(err, "failed to fetch blob") 558 } 559 } 560 561 return &rep, nil 562 } 563 564 func (h *MessageHandler) handleHasPendingRequests(ctx context.Context, parcel core.Parcel) (core.Reply, error) { 565 msg := parcel.Message().(*message.GetPendingRequests) 566 jetID := jetFromContext(ctx) 567 568 for _, reqID := range h.RecentStorageProvider.GetPendingStorage(ctx, jetID).GetRequestsForObject(*msg.Object.Record()) { 569 if reqID.Pulse() < parcel.Pulse() { 570 return &reply.HasPendingRequests{Has: true}, nil 571 } 572 } 573 574 return &reply.HasPendingRequests{Has: false}, nil 575 } 576 577 func (h *MessageHandler) handleGetJet(ctx context.Context, parcel core.Parcel) (core.Reply, error) { 578 msg := parcel.Message().(*message.GetJet) 579 580 jetID, actual := h.JetStorage.FindJet(ctx, msg.Pulse, msg.Object) 581 582 return &reply.Jet{ID: *jetID, Actual: actual}, nil 583 } 584 585 func (h *MessageHandler) handleGetDelegate(ctx context.Context, parcel core.Parcel) (core.Reply, error) { 586 msg := parcel.Message().(*message.GetDelegate) 587 jetID := jetFromContext(ctx) 588 589 if !h.isHeavy { 590 h.RecentStorageProvider.GetIndexStorage(ctx, jetID).AddObject(ctx, *msg.Head.Record()) 591 } 592 593 idx, err := h.ObjectStorage.GetObjectIndex(ctx, jetID, msg.Head.Record(), false) 594 if err == core.ErrNotFound { 595 if h.isHeavy { 596 return nil, fmt.Errorf("failed to fetch index for %v", msg.Head.Record()) 597 } 598 599 heavy, err := h.JetCoordinator.Heavy(ctx, parcel.Pulse()) 600 if err != nil { 601 return nil, err 602 } 603 idx, err = h.saveIndexFromHeavy(ctx, jetID, msg.Head, heavy) 604 if err != nil { 605 return nil, errors.Wrap(err, "failed to fetch index from heavy") 606 } 607 } else if err != nil { 608 return nil, errors.Wrap(err, "failed to fetch object index") 609 } 610 611 delegateRef, ok := idx.Delegates[msg.AsType] 612 if !ok { 613 return nil, errors.New("the object has no delegate for this type") 614 } 615 616 rep := reply.Delegate{ 617 Head: delegateRef, 618 } 619 620 return &rep, nil 621 } 622 623 func (h *MessageHandler) handleGetChildren( 624 ctx context.Context, parcel core.Parcel, 625 ) (core.Reply, error) { 626 msg := parcel.Message().(*message.GetChildren) 627 jetID := jetFromContext(ctx) 628 629 if !h.isHeavy { 630 h.RecentStorageProvider.GetIndexStorage(ctx, jetID).AddObject(ctx, *msg.Parent.Record()) 631 } 632 633 idx, err := h.ObjectStorage.GetObjectIndex(ctx, jetID, msg.Parent.Record(), false) 634 if err == core.ErrNotFound { 635 if h.isHeavy { 636 return nil, fmt.Errorf("failed to fetch index for %v", msg.Parent.Record()) 637 } 638 639 heavy, err := h.JetCoordinator.Heavy(ctx, parcel.Pulse()) 640 if err != nil { 641 return nil, err 642 } 643 idx, err = h.saveIndexFromHeavy(ctx, jetID, msg.Parent, heavy) 644 if err != nil { 645 return nil, errors.Wrap(err, "failed to fetch index from heavy") 646 } 647 if idx.ChildPointer == nil { 648 return &reply.Children{Refs: nil, NextFrom: nil}, nil 649 } 650 } else if err != nil { 651 return nil, errors.Wrap(err, "failed to fetch object index") 652 } 653 654 var ( 655 refs []core.RecordRef 656 currentChild *core.RecordID 657 ) 658 659 // Counting from specified child or the latest. 660 if msg.FromChild != nil { 661 currentChild = msg.FromChild 662 } else { 663 currentChild = idx.ChildPointer 664 } 665 666 // The object has no children. 667 if currentChild == nil { 668 return &reply.Children{Refs: nil, NextFrom: nil}, nil 669 } 670 671 var childJet *core.RecordID 672 if h.isHeavy { 673 childJet = &jetID 674 } else { 675 var actual bool 676 onHeavy, err := h.JetCoordinator.IsBeyondLimit(ctx, parcel.Pulse(), currentChild.Pulse()) 677 if err != nil { 678 return nil, err 679 } 680 if onHeavy { 681 node, err := h.JetCoordinator.Heavy(ctx, parcel.Pulse()) 682 if err != nil { 683 return nil, err 684 } 685 return reply.NewGetChildrenRedirect(h.DelegationTokenFactory, parcel, node, *currentChild) 686 } 687 688 childJet, actual = h.JetStorage.FindJet(ctx, currentChild.Pulse(), *msg.Parent.Record()) 689 if !actual { 690 actualJet, err := h.jetTreeUpdater.fetchJet(ctx, *msg.Parent.Record(), currentChild.Pulse()) 691 if err != nil { 692 return nil, err 693 } 694 childJet = actualJet 695 } 696 } 697 698 // Try to fetch the first child. 699 _, err = h.ObjectStorage.GetRecord(ctx, *childJet, currentChild) 700 if err == core.ErrNotFound { 701 if h.isHeavy { 702 return nil, fmt.Errorf("failed to fetch child for %v. jet: %v, state: %v", msg.Parent.Record(), childJet.DebugString(), currentChild.DebugString()) 703 } 704 node, err := h.JetCoordinator.NodeForJet(ctx, *childJet, parcel.Pulse(), currentChild.Pulse()) 705 if err != nil { 706 return nil, err 707 } 708 return reply.NewGetChildrenRedirect(h.DelegationTokenFactory, parcel, node, *currentChild) 709 } 710 711 if err != nil { 712 return nil, errors.Wrap(err, "failed to fetch child") 713 } 714 715 counter := 0 716 for currentChild != nil { 717 // We have enough results. 718 if counter >= msg.Amount { 719 return &reply.Children{Refs: refs, NextFrom: currentChild}, nil 720 } 721 counter++ 722 723 rec, err := h.ObjectStorage.GetRecord(ctx, *childJet, currentChild) 724 // We don't have this child reference. Return what was collected. 725 if err == core.ErrNotFound { 726 return &reply.Children{Refs: refs, NextFrom: currentChild}, nil 727 } 728 if err != nil { 729 return nil, errors.New("failed to retrieve children") 730 } 731 732 childRec, ok := rec.(*record.ChildRecord) 733 if !ok { 734 return nil, errors.New("failed to retrieve children") 735 } 736 currentChild = childRec.PrevChild 737 738 // Skip records later than specified pulse. 739 recPulse := childRec.Ref.Record().Pulse() 740 if msg.FromPulse != nil && recPulse > *msg.FromPulse { 741 continue 742 } 743 refs = append(refs, childRec.Ref) 744 } 745 746 return &reply.Children{Refs: refs, NextFrom: nil}, nil 747 } 748 749 func (h *MessageHandler) handleGetRequest(ctx context.Context, parcel core.Parcel) (core.Reply, error) { 750 jetID := jetFromContext(ctx) 751 msg := parcel.Message().(*message.GetRequest) 752 753 rec, err := h.ObjectStorage.GetRecord(ctx, jetID, &msg.Request) 754 if err != nil { 755 return nil, errors.New("failed to fetch request") 756 } 757 758 req, ok := rec.(*record.RequestRecord) 759 if !ok { 760 return nil, errors.New("failed to decode request") 761 } 762 763 rep := reply.Request{ 764 ID: msg.Request, 765 Record: record.SerializeRecord(req), 766 } 767 768 return &rep, nil 769 } 770 771 func (h *MessageHandler) handleGetPendingRequestID(ctx context.Context, parcel core.Parcel) (core.Reply, error) { 772 jetID := jetFromContext(ctx) 773 msg := parcel.Message().(*message.GetPendingRequestID) 774 775 requests := h.RecentStorageProvider.GetPendingStorage(ctx, jetID).GetRequestsForObject(msg.ObjectID) 776 if len(requests) == 0 { 777 return &reply.Error{ErrType: reply.ErrNoPendingRequests}, nil 778 } 779 780 rep := reply.ID{ 781 ID: requests[0], 782 } 783 784 return &rep, nil 785 } 786 787 func (h *MessageHandler) handleUpdateObject(ctx context.Context, parcel core.Parcel) (core.Reply, error) { 788 if h.isHeavy { 789 return nil, errors.New("heavy updates are forbidden") 790 } 791 792 msg := parcel.Message().(*message.UpdateObject) 793 jetID := jetFromContext(ctx) 794 logger := inslogger.FromContext(ctx).WithFields(map[string]interface{}{ 795 "object": msg.Object.Record().DebugString(), 796 "pulse": parcel.Pulse(), 797 }) 798 799 rec := record.DeserializeRecord(msg.Record) 800 state, ok := rec.(record.ObjectState) 801 if !ok { 802 return nil, errors.New("wrong object state record") 803 } 804 805 h.RecentStorageProvider.GetIndexStorage(ctx, jetID).AddObject(ctx, *msg.Object.Record()) 806 807 // FIXME: temporary fix. If we calculate blob id on the client, pulse can change before message sending and this 808 // id will not match the one calculated on the server. 809 blobID, err := h.ObjectStorage.SetBlob(ctx, jetID, parcel.Pulse(), msg.Memory) 810 if err != nil { 811 return nil, errors.Wrap(err, "failed to set blob") 812 } 813 814 switch s := state.(type) { 815 case *record.ObjectActivateRecord: 816 s.Memory = blobID 817 case *record.ObjectAmendRecord: 818 s.Memory = blobID 819 } 820 821 var idx *index.ObjectLifeline 822 err = h.DBContext.Update(ctx, func(tx *storage.TransactionManager) error { 823 var err error 824 idx, err = tx.GetObjectIndex(ctx, jetID, msg.Object.Record(), true) 825 // No index on our node. 826 if err == core.ErrNotFound { 827 if state.State() == record.StateActivation { 828 // We are activating the object. There is no index for it anywhere. 829 idx = &index.ObjectLifeline{State: record.StateUndefined} 830 } else { 831 logger.Debug("failed to fetch index (fetching from heavy)") 832 // We are updating object. Index should be on the heavy executor. 833 heavy, err := h.JetCoordinator.Heavy(ctx, parcel.Pulse()) 834 if err != nil { 835 return err 836 } 837 idx, err = h.saveIndexFromHeavy(ctx, jetID, msg.Object, heavy) 838 if err != nil { 839 return errors.Wrap(err, "failed to fetch index from heavy") 840 } 841 } 842 } else if err != nil { 843 return err 844 } 845 846 if err = validateState(idx.State, state.State()); err != nil { 847 return err 848 } 849 850 recID := record.NewRecordIDFromRecord(h.PlatformCryptographyScheme, parcel.Pulse(), rec) 851 852 // Index exists and latest record id does not match (preserving chain consistency). 853 // For the case when vm can't save or send result to another vm and it tries to update the same record again 854 if idx.LatestState != nil && !state.PrevStateID().Equal(idx.LatestState) && idx.LatestState != recID { 855 return errors.New("invalid state record") 856 } 857 858 id, err := tx.SetRecord(ctx, jetID, parcel.Pulse(), rec) 859 if err == storage.ErrOverride { 860 logger.WithField("type", fmt.Sprintf("%T", rec)).Warn("set record override (#1)") 861 id = recID 862 } else if err != nil { 863 return err 864 } 865 idx.LatestState = id 866 idx.State = state.State() 867 if state.State() == record.StateActivation { 868 idx.Parent = state.(*record.ObjectActivateRecord).Parent 869 } 870 871 idx.LatestUpdate = parcel.Pulse() 872 return tx.SetObjectIndex(ctx, jetID, msg.Object.Record(), idx) 873 }) 874 if err != nil { 875 if err == ErrObjectDeactivated { 876 return &reply.Error{ErrType: reply.ErrDeactivated}, nil 877 } 878 return nil, err 879 } 880 881 logger.WithField("state", idx.LatestState.DebugString()).Debug("saved object") 882 883 rep := reply.Object{ 884 Head: msg.Object, 885 State: *idx.LatestState, 886 Prototype: state.GetImage(), 887 IsPrototype: state.GetIsPrototype(), 888 ChildPointer: idx.ChildPointer, 889 Parent: idx.Parent, 890 } 891 return &rep, nil 892 } 893 894 func (h *MessageHandler) handleRegisterChild(ctx context.Context, parcel core.Parcel) (core.Reply, error) { 895 if h.isHeavy { 896 return nil, errors.New("heavy updates are forbidden") 897 } 898 899 logger := inslogger.FromContext(ctx) 900 901 msg := parcel.Message().(*message.RegisterChild) 902 jetID := jetFromContext(ctx) 903 rec := record.DeserializeRecord(msg.Record) 904 childRec, ok := rec.(*record.ChildRecord) 905 if !ok { 906 return nil, errors.New("wrong child record") 907 } 908 909 h.RecentStorageProvider.GetIndexStorage(ctx, jetID).AddObject(ctx, *msg.Parent.Record()) 910 911 var child *core.RecordID 912 err := h.DBContext.Update(ctx, func(tx *storage.TransactionManager) error { 913 idx, err := h.ObjectStorage.GetObjectIndex(ctx, jetID, msg.Parent.Record(), false) 914 if err == core.ErrNotFound { 915 heavy, err := h.JetCoordinator.Heavy(ctx, parcel.Pulse()) 916 if err != nil { 917 return err 918 } 919 idx, err = h.saveIndexFromHeavy(ctx, jetID, msg.Parent, heavy) 920 if err != nil { 921 return errors.Wrap(err, "failed to fetch index from heavy") 922 } 923 } else if err != nil { 924 return err 925 } 926 927 recID := record.NewRecordIDFromRecord(h.PlatformCryptographyScheme, parcel.Pulse(), childRec) 928 929 // Children exist and pointer does not match (preserving chain consistency). 930 // For the case when vm can't save or send result to another vm and it tries to update the same record again 931 if idx.ChildPointer != nil && !childRec.PrevChild.Equal(idx.ChildPointer) && idx.ChildPointer != recID { 932 return errors.New("invalid child record") 933 } 934 935 child, err = tx.SetRecord(ctx, jetID, parcel.Pulse(), childRec) 936 if err == storage.ErrOverride { 937 logger.WithField("type", fmt.Sprintf("%T", rec)).Warn("set record override (#2)") 938 child = recID 939 } else if err != nil { 940 return err 941 } 942 943 idx.ChildPointer = child 944 if msg.AsType != nil { 945 idx.Delegates[*msg.AsType] = msg.Child 946 } 947 idx.LatestUpdate = parcel.Pulse() 948 err = tx.SetObjectIndex(ctx, jetID, msg.Parent.Record(), idx) 949 if err != nil { 950 return err 951 } 952 953 return nil 954 }) 955 956 if err != nil { 957 return nil, err 958 } 959 960 return &reply.ID{ID: *child}, nil 961 } 962 963 func (h *MessageHandler) handleJetDrop(ctx context.Context, parcel core.Parcel) (core.Reply, error) { 964 msg := parcel.Message().(*message.JetDrop) 965 966 if !hack.SkipValidation(ctx) { 967 for _, parcelBuff := range msg.Messages { 968 jetDropMsg, err := message.Deserialize(bytes.NewBuffer(parcelBuff)) 969 if err != nil { 970 return nil, err 971 } 972 handler, ok := h.replayHandlers[jetDropMsg.Type()] 973 if !ok { 974 return nil, errors.New("unknown message type") 975 } 976 977 _, err = handler(ctx, &message.Parcel{Msg: jetDropMsg}) 978 if err != nil { 979 return nil, err 980 } 981 } 982 } 983 984 err := h.JetStorage.AddJets(ctx, msg.JetID) 985 if err != nil { 986 return nil, err 987 } 988 989 h.JetStorage.UpdateJetTree( 990 ctx, parcel.Pulse(), true, msg.JetID, 991 ) 992 993 return &reply.OK{}, nil 994 } 995 996 func (h *MessageHandler) handleValidateRecord(ctx context.Context, parcel core.Parcel) (core.Reply, error) { 997 if h.isHeavy { 998 return nil, errors.New("heavy updates are forbidden") 999 } 1000 1001 msg := parcel.Message().(*message.ValidateRecord) 1002 jetID := jetFromContext(ctx) 1003 1004 err := h.DBContext.Update(ctx, func(tx *storage.TransactionManager) error { 1005 idx, err := tx.GetObjectIndex(ctx, jetID, msg.Object.Record(), true) 1006 if err == core.ErrNotFound { 1007 heavy, err := h.JetCoordinator.Heavy(ctx, parcel.Pulse()) 1008 if err != nil { 1009 return err 1010 } 1011 idx, err = h.saveIndexFromHeavy(ctx, jetID, msg.Object, heavy) 1012 if err != nil { 1013 return errors.Wrap(err, "failed to fetch index from heavy") 1014 } 1015 } else if err != nil { 1016 return err 1017 } 1018 1019 // Find node that has this state. 1020 node, err := h.JetCoordinator.NodeForJet(ctx, jetID, parcel.Pulse(), msg.Object.Record().Pulse()) 1021 if err != nil { 1022 return err 1023 } 1024 1025 // Send checking message. 1026 genericReply, err := h.Bus.Send(ctx, &message.ValidationCheck{ 1027 Object: msg.Object, 1028 ValidatedState: msg.State, 1029 LatestStateApproved: idx.LatestStateApproved, 1030 }, &core.MessageSendOptions{ 1031 Receiver: node, 1032 }) 1033 if err != nil { 1034 return err 1035 } 1036 switch genericReply.(type) { 1037 case *reply.OK: 1038 if msg.IsValid { 1039 idx.LatestStateApproved = &msg.State 1040 } else { 1041 idx.LatestState = idx.LatestStateApproved 1042 } 1043 idx.LatestUpdate = parcel.Pulse() 1044 err = tx.SetObjectIndex(ctx, jetID, msg.Object.Record(), idx) 1045 if err != nil { 1046 return errors.Wrap(err, "failed to save object index") 1047 } 1048 case *reply.NotOK: 1049 return errors.New("validation sequence integrity failure") 1050 default: 1051 return errors.New("handleValidateRecord: unexpected reply") 1052 } 1053 1054 return nil 1055 }) 1056 if err != nil { 1057 return nil, err 1058 } 1059 1060 return &reply.OK{}, nil 1061 } 1062 1063 func (h *MessageHandler) handleGetObjectIndex(ctx context.Context, parcel core.Parcel) (core.Reply, error) { 1064 msg := parcel.Message().(*message.GetObjectIndex) 1065 jetID := jetFromContext(ctx) 1066 1067 idx, err := h.ObjectStorage.GetObjectIndex(ctx, jetID, msg.Object.Record(), true) 1068 if err != nil { 1069 return nil, errors.Wrap(err, "failed to fetch object index") 1070 } 1071 1072 buf, err := index.EncodeObjectLifeline(idx) 1073 if err != nil { 1074 return nil, errors.Wrap(err, "failed to serialize index") 1075 } 1076 1077 return &reply.ObjectIndex{Index: buf}, nil 1078 } 1079 1080 func (h *MessageHandler) handleValidationCheck(ctx context.Context, parcel core.Parcel) (core.Reply, error) { 1081 msg := parcel.Message().(*message.ValidationCheck) 1082 jetID := jetFromContext(ctx) 1083 1084 rec, err := h.ObjectStorage.GetRecord(ctx, jetID, &msg.ValidatedState) 1085 if err != nil { 1086 return nil, errors.Wrap(err, "failed to fetch state record") 1087 } 1088 state, ok := rec.(record.ObjectState) 1089 if !ok { 1090 return nil, errors.New("failed to fetch state record") 1091 } 1092 approved := msg.LatestStateApproved 1093 validated := state.PrevStateID() 1094 if !approved.Equal(validated) && approved != nil && validated != nil { 1095 return &reply.NotOK{}, nil 1096 } 1097 1098 return &reply.OK{}, nil 1099 } 1100 1101 func (h *MessageHandler) getCode(ctx context.Context, id *core.RecordID) (*record.CodeRecord, error) { 1102 jetID := *jet.NewID(0, nil) 1103 1104 rec, err := h.ObjectStorage.GetRecord(ctx, jetID, id) 1105 if err != nil { 1106 return nil, err 1107 } 1108 codeRec, ok := rec.(*record.CodeRecord) 1109 if !ok { 1110 return nil, errors.Wrap(ErrInvalidRef, "failed to retrieve code record") 1111 } 1112 1113 return codeRec, nil 1114 } 1115 1116 func validateState(old record.State, new record.State) error { 1117 if old == record.StateDeactivation { 1118 return ErrObjectDeactivated 1119 } 1120 if old == record.StateUndefined && new != record.StateActivation { 1121 return errors.New("object is not activated") 1122 } 1123 if old != record.StateUndefined && new == record.StateActivation { 1124 return errors.New("object is already activated") 1125 } 1126 return nil 1127 } 1128 1129 func (h *MessageHandler) saveIndexFromHeavy( 1130 ctx context.Context, jetID core.RecordID, obj core.RecordRef, heavy *core.RecordRef, 1131 ) (*index.ObjectLifeline, error) { 1132 genericReply, err := h.Bus.Send(ctx, &message.GetObjectIndex{ 1133 Object: obj, 1134 }, &core.MessageSendOptions{ 1135 Receiver: heavy, 1136 }) 1137 if err != nil { 1138 return nil, errors.Wrap(err, "failed to send") 1139 } 1140 rep, ok := genericReply.(*reply.ObjectIndex) 1141 if !ok { 1142 return nil, fmt.Errorf("failed to fetch object index: unexpected reply type %T (reply=%+v)", genericReply, genericReply) 1143 } 1144 idx, err := index.DecodeObjectLifeline(rep.Index) 1145 if err != nil { 1146 return nil, errors.Wrap(err, "failed to decode") 1147 } 1148 1149 err = h.ObjectStorage.SetObjectIndex(ctx, jetID, obj.Record(), idx) 1150 if err != nil { 1151 return nil, errors.Wrap(err, "failed to save") 1152 } 1153 return idx, nil 1154 } 1155 1156 func (h *MessageHandler) fetchObject( 1157 ctx context.Context, obj core.RecordRef, node core.RecordRef, stateID *core.RecordID, 1158 ) (*reply.Object, error) { 1159 sender := BuildSender( 1160 h.Bus.Send, 1161 followRedirectSender(h.Bus), 1162 retryJetSender(h.JetStorage), 1163 ) 1164 genericReply, err := sender( 1165 ctx, 1166 &message.GetObject{ 1167 Head: obj, 1168 Approved: false, 1169 State: stateID, 1170 }, 1171 &core.MessageSendOptions{ 1172 Receiver: &node, 1173 Token: &delegationtoken.GetObjectRedirectToken{}, 1174 }, 1175 ) 1176 if err != nil { 1177 return nil, errors.Wrap(err, "failed to fetch object state") 1178 } 1179 if rep, ok := genericReply.(*reply.Error); ok { 1180 return nil, rep.Error() 1181 } 1182 1183 rep, ok := genericReply.(*reply.Object) 1184 if !ok { 1185 return nil, fmt.Errorf("failed to fetch object state: unexpected reply type %T (reply=%+v)", genericReply, genericReply) 1186 } 1187 return rep, nil 1188 } 1189 1190 func (h *MessageHandler) handleHotRecords(ctx context.Context, parcel core.Parcel) (core.Reply, error) { 1191 if h.isHeavy { 1192 return nil, errors.New("heavy updates are forbidden") 1193 } 1194 1195 logger := inslogger.FromContext(ctx) 1196 1197 msg := parcel.Message().(*message.HotData) 1198 // FIXME: check split signatures. 1199 jetID := *msg.Jet.Record() 1200 1201 logger.WithFields(map[string]interface{}{ 1202 "jet": jetID.DebugString(), 1203 }).Info("received hot data") 1204 1205 err := h.DropStorage.SetDrop(ctx, msg.DropJet, &msg.Drop) 1206 if err == storage.ErrOverride { 1207 err = nil 1208 } 1209 if err != nil { 1210 return nil, errors.Wrapf(err, "[jet]: drop error (pulse: %v)", msg.Drop.Pulse) 1211 } 1212 1213 err = h.DropStorage.SetDropSizeHistory(ctx, msg.DropJet, msg.JetDropSizeHistory) 1214 if err != nil { 1215 return nil, errors.Wrap(err, "[ handleHotRecords ] Can't SetDropSizeHistory") 1216 } 1217 1218 pendingStorage := h.RecentStorageProvider.GetPendingStorage(ctx, jetID) 1219 logger.Debugf("received %d pending requests", len(msg.PendingRequests)) 1220 1221 var notificationList []core.RecordID 1222 for objID, objContext := range msg.PendingRequests { 1223 if !objContext.Active { 1224 notificationList = append(notificationList, objID) 1225 } 1226 1227 objContext.Active = false 1228 pendingStorage.SetContextToObject(ctx, objID, objContext) 1229 } 1230 1231 go func() { 1232 for _, objID := range notificationList { 1233 go func(objID core.RecordID) { 1234 rep, err := h.Bus.Send(ctx, &message.AbandonedRequestsNotification{ 1235 Object: objID, 1236 }, nil) 1237 1238 if err != nil { 1239 logger.Error("failed to notify about pending requests") 1240 return 1241 } 1242 if _, ok := rep.(*reply.OK); !ok { 1243 logger.Error("received unexpected reply on pending notification") 1244 } 1245 }(objID) 1246 } 1247 }() 1248 1249 indexStorage := h.RecentStorageProvider.GetIndexStorage(ctx, jetID) 1250 for id, meta := range msg.RecentObjects { 1251 decodedIndex, err := index.DecodeObjectLifeline(meta.Index) 1252 if err != nil { 1253 logger.Error(err) 1254 continue 1255 } 1256 1257 err = h.ObjectStorage.SetObjectIndex(ctx, jetID, &id, decodedIndex) 1258 if err != nil { 1259 logger.Error(err) 1260 continue 1261 } 1262 1263 indexStorage.AddObjectWithTLL(ctx, id, meta.TTL) 1264 } 1265 1266 h.JetStorage.UpdateJetTree( 1267 ctx, msg.PulseNumber, true, jetID, 1268 ) 1269 1270 h.jetTreeUpdater.releaseJet(ctx, jetID, msg.PulseNumber) 1271 1272 err = h.JetStorage.AddJets(ctx, jetID) 1273 if err != nil { 1274 logger.Error(errors.Wrap(err, "couldn't add jet")) 1275 return nil, err 1276 } 1277 1278 return &reply.OK{}, nil 1279 }