github.com/braveheart12/just@v0.8.7/ledger/artifactmanager/artifactmanager.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  
    24  	"github.com/pkg/errors"
    25  	"go.opencensus.io/trace"
    26  
    27  	"github.com/insolar/insolar/core"
    28  	"github.com/insolar/insolar/core/message"
    29  	"github.com/insolar/insolar/core/reply"
    30  	"github.com/insolar/insolar/instrumentation/instracer"
    31  	"github.com/insolar/insolar/ledger/storage"
    32  	"github.com/insolar/insolar/ledger/storage/record"
    33  )
    34  
    35  const (
    36  	getChildrenChunkSize = 10 * 1000
    37  	jetMissRetryCount    = 10
    38  )
    39  
    40  // LedgerArtifactManager provides concrete API to storage for processing module.
    41  type LedgerArtifactManager struct {
    42  	DB           storage.DBContext    `inject:""`
    43  	GenesisState storage.GenesisState `inject:""`
    44  	JetStorage   storage.JetStorage   `inject:""`
    45  
    46  	DefaultBus                 core.MessageBus                 `inject:""`
    47  	PlatformCryptographyScheme core.PlatformCryptographyScheme `inject:""`
    48  	PulseStorage               core.PulseStorage               `inject:""`
    49  	JetCoordinator             core.JetCoordinator             `inject:""`
    50  
    51  	getChildrenChunkSize int
    52  	senders              *ledgerArtifactSenders
    53  }
    54  
    55  // State returns hash state for artifact manager.
    56  func (m *LedgerArtifactManager) State() ([]byte, error) {
    57  	// This is a temporary stab to simulate real hash.
    58  	return m.PlatformCryptographyScheme.IntegrityHasher().Hash([]byte{1, 2, 3}), nil
    59  }
    60  
    61  // NewArtifactManger creates new manager instance.
    62  func NewArtifactManger() *LedgerArtifactManager {
    63  	return &LedgerArtifactManager{
    64  		getChildrenChunkSize: getChildrenChunkSize,
    65  		senders:              newLedgerArtifactSenders(),
    66  	}
    67  }
    68  
    69  // GenesisRef returns the root record reference.
    70  //
    71  // Root record is the parent for all top-level records.
    72  func (m *LedgerArtifactManager) GenesisRef() *core.RecordRef {
    73  	return m.GenesisState.GenesisRef()
    74  }
    75  
    76  // RegisterRequest sends message for request registration,
    77  // returns request record Ref if request successfully created or already exists.
    78  func (m *LedgerArtifactManager) RegisterRequest(
    79  	ctx context.Context, obj core.RecordRef, parcel core.Parcel,
    80  ) (*core.RecordID, error) {
    81  	var err error
    82  	ctx, span := instracer.StartSpan(ctx, "artifactmanager.RegisterRequest")
    83  	instrumenter := instrument(ctx, "RegisterRequest").err(&err)
    84  	defer func() {
    85  		if err != nil {
    86  			span.AddAttributes(trace.StringAttribute("error", err.Error()))
    87  		}
    88  		span.End()
    89  		instrumenter.end()
    90  	}()
    91  
    92  	currentPN, err := m.pulse(ctx)
    93  	if err != nil {
    94  		return nil, err
    95  	}
    96  
    97  	rec := &record.RequestRecord{
    98  		Parcel:      message.ParcelToBytes(parcel),
    99  		MessageHash: m.PlatformCryptographyScheme.IntegrityHasher().Hash(message.MustSerializeBytes(parcel.Message())),
   100  		Object:      *obj.Record(),
   101  	}
   102  	recID := record.NewRecordIDFromRecord(
   103  		m.PlatformCryptographyScheme,
   104  		currentPN,
   105  		rec)
   106  	recRef := core.NewRecordRef(*parcel.DefaultTarget().Domain(), *recID)
   107  	id, err := m.setRecord(
   108  		ctx,
   109  		rec,
   110  		*recRef,
   111  	)
   112  	return id, errors.Wrap(err, "[ RegisterRequest ] ")
   113  }
   114  
   115  // GetCode returns code from code record by provided reference according to provided machine preference.
   116  //
   117  // This method is used by VM to fetch code for execution.
   118  func (m *LedgerArtifactManager) GetCode(
   119  	ctx context.Context, code core.RecordRef,
   120  ) (core.CodeDescriptor, error) {
   121  	var err error
   122  	instrumenter := instrument(ctx, "GetCode").err(&err)
   123  	ctx, span := instracer.StartSpan(ctx, "artifactmanager.GetCode")
   124  	defer func() {
   125  		if err != nil {
   126  			span.AddAttributes(trace.StringAttribute("error", err.Error()))
   127  		}
   128  		span.End()
   129  		instrumenter.end()
   130  	}()
   131  
   132  	bus := core.MessageBusFromContext(ctx, m.DefaultBus)
   133  	sender := BuildSender(
   134  		bus.Send,
   135  		m.senders.cachedSender(m.PlatformCryptographyScheme),
   136  		followRedirectSender(bus),
   137  		retryJetSender(m.JetStorage),
   138  	)
   139  
   140  	genericReact, err := sender(ctx, &message.GetCode{Code: code}, nil)
   141  
   142  	if err != nil {
   143  		return nil, err
   144  	}
   145  
   146  	switch rep := genericReact.(type) {
   147  	case *reply.Code:
   148  		desc := CodeDescriptor{
   149  			ctx:         ctx,
   150  			ref:         code,
   151  			machineType: rep.MachineType,
   152  			code:        rep.Code,
   153  		}
   154  		return &desc, nil
   155  	case *reply.Error:
   156  		return nil, rep.Error()
   157  	default:
   158  		return nil, fmt.Errorf("GetCode: unexpected reply: %#v", rep)
   159  	}
   160  }
   161  
   162  // GetObject returns descriptor for provided state.
   163  //
   164  // If provided state is nil, the latest state will be returned (with deactivation check). Returned descriptor will
   165  // provide methods for fetching all related data.
   166  func (m *LedgerArtifactManager) GetObject(
   167  	ctx context.Context,
   168  	head core.RecordRef,
   169  	state *core.RecordID,
   170  	approved bool,
   171  ) (core.ObjectDescriptor, error) {
   172  	var (
   173  		desc *ObjectDescriptor
   174  		err  error
   175  	)
   176  	ctx, span := instracer.StartSpan(ctx, "artifactmanager.Getobject")
   177  	instrumenter := instrument(ctx, "GetObject").err(&err)
   178  	defer func() {
   179  		if err != nil {
   180  			span.AddAttributes(trace.StringAttribute("error", err.Error()))
   181  		}
   182  		span.End()
   183  		if err != nil && err == ErrObjectDeactivated {
   184  			err = nil // megahack: threat it 2xx
   185  		}
   186  		instrumenter.end()
   187  	}()
   188  
   189  	getObjectMsg := &message.GetObject{
   190  		Head:     head,
   191  		State:    state,
   192  		Approved: approved,
   193  	}
   194  
   195  	bus := core.MessageBusFromContext(ctx, m.DefaultBus)
   196  	sender := BuildSender(
   197  		bus.Send,
   198  		followRedirectSender(bus),
   199  		retryJetSender(m.JetStorage),
   200  	)
   201  
   202  	genericReact, err := sender(ctx, getObjectMsg, nil)
   203  	if err != nil {
   204  		return nil, err
   205  	}
   206  
   207  	switch r := genericReact.(type) {
   208  	case *reply.Object:
   209  		desc = &ObjectDescriptor{
   210  			ctx:          ctx,
   211  			am:           m,
   212  			head:         r.Head,
   213  			state:        r.State,
   214  			prototype:    r.Prototype,
   215  			isPrototype:  r.IsPrototype,
   216  			childPointer: r.ChildPointer,
   217  			memory:       r.Memory,
   218  			parent:       r.Parent,
   219  		}
   220  		return desc, err
   221  	case *reply.Error:
   222  		return nil, r.Error()
   223  	default:
   224  		return nil, fmt.Errorf("GetObject: unexpected reply: %#v", genericReact)
   225  	}
   226  }
   227  
   228  // GetPendingRequest returns an unclosed pending request
   229  // It takes an id from current LME
   230  // Then goes either to a light node or heavy node
   231  func (m *LedgerArtifactManager) GetPendingRequest(ctx context.Context, objectID core.RecordID) (core.Parcel, error) {
   232  	var err error
   233  	instrumenter := instrument(ctx, "GetRegisterRequest").err(&err)
   234  	ctx, span := instracer.StartSpan(ctx, "artifactmanager.GetRegisterRequest")
   235  	defer func() {
   236  		if err != nil {
   237  			span.AddAttributes(trace.StringAttribute("error", err.Error()))
   238  		}
   239  		span.End()
   240  		instrumenter.end()
   241  	}()
   242  
   243  	bus := core.MessageBusFromContext(ctx, m.DefaultBus)
   244  	sender := BuildSender(
   245  		bus.Send,
   246  		retryJetSender(m.JetStorage),
   247  	)
   248  
   249  	genericReply, err := sender(ctx, &message.GetPendingRequestID{
   250  		ObjectID: objectID,
   251  	}, nil)
   252  	if err != nil {
   253  		return nil, err
   254  	}
   255  
   256  	var requestID core.RecordID
   257  	switch r := genericReply.(type) {
   258  	case *reply.ID:
   259  		requestID = r.ID
   260  	case *reply.Error:
   261  		return nil, r.Error()
   262  	default:
   263  		return nil, fmt.Errorf("GetPendingRequest: unexpected reply: %#v", genericReply)
   264  	}
   265  
   266  	currentPN, err := m.pulse(ctx)
   267  	if err != nil {
   268  		return nil, err
   269  	}
   270  
   271  	node, err := m.JetCoordinator.NodeForObject(ctx, objectID, currentPN, requestID.Pulse())
   272  	if err != nil {
   273  		return nil, err
   274  	}
   275  
   276  	sender = BuildSender(
   277  		bus.Send,
   278  		retryJetSender(m.JetStorage),
   279  	)
   280  	genericReply, err = sender(
   281  		ctx,
   282  		&message.GetRequest{
   283  			Request: requestID,
   284  		}, &core.MessageSendOptions{
   285  			Receiver: node,
   286  		},
   287  	)
   288  	if err != nil {
   289  		return nil, err
   290  	}
   291  
   292  	switch r := genericReply.(type) {
   293  	case *reply.Request:
   294  		rec := record.DeserializeRecord(r.Record)
   295  		castedRecord, ok := rec.(*record.RequestRecord)
   296  		if !ok {
   297  			return nil, fmt.Errorf("GetPendingRequest: unexpected message: %#v", r)
   298  		}
   299  
   300  		return message.DeserializeParcel(bytes.NewBuffer(castedRecord.Parcel))
   301  	case *reply.Error:
   302  		return nil, r.Error()
   303  	default:
   304  		return nil, fmt.Errorf("GetPendingRequest: unexpected reply: %#v", genericReply)
   305  	}
   306  }
   307  
   308  // HasPendingRequests returns true if object has unclosed requests.
   309  func (m *LedgerArtifactManager) HasPendingRequests(
   310  	ctx context.Context,
   311  	object core.RecordRef,
   312  ) (bool, error) {
   313  	bus := core.MessageBusFromContext(ctx, m.DefaultBus)
   314  	sender := BuildSender(
   315  		bus.Send,
   316  		retryJetSender(m.JetStorage),
   317  	)
   318  
   319  	genericReact, err := sender(ctx, &message.GetPendingRequests{Object: object}, nil)
   320  
   321  	if err != nil {
   322  		return false, err
   323  	}
   324  
   325  	switch rep := genericReact.(type) {
   326  	case *reply.HasPendingRequests:
   327  		return rep.Has, nil
   328  	case *reply.Error:
   329  		return false, rep.Error()
   330  	default:
   331  		return false, fmt.Errorf("HasPendingRequests: unexpected reply: %#v", rep)
   332  	}
   333  }
   334  
   335  // GetDelegate returns provided object's delegate reference for provided prototype.
   336  //
   337  // Object delegate should be previously created for this object. If object delegate does not exist, an error will
   338  // be returned.
   339  func (m *LedgerArtifactManager) GetDelegate(
   340  	ctx context.Context, head, asType core.RecordRef,
   341  ) (*core.RecordRef, error) {
   342  	var err error
   343  	ctx, span := instracer.StartSpan(ctx, "artifactmanager.GetDelegate")
   344  	instrumenter := instrument(ctx, "GetDelegate").err(&err)
   345  	defer func() {
   346  		if err != nil {
   347  			span.AddAttributes(trace.StringAttribute("error", err.Error()))
   348  		}
   349  		span.End()
   350  		instrumenter.end()
   351  	}()
   352  
   353  	bus := core.MessageBusFromContext(ctx, m.DefaultBus)
   354  	sender := BuildSender(bus.Send, followRedirectSender(bus), retryJetSender(m.JetStorage))
   355  	genericReact, err := sender(ctx, &message.GetDelegate{
   356  		Head:   head,
   357  		AsType: asType,
   358  	}, nil)
   359  	if err != nil {
   360  		return nil, err
   361  	}
   362  
   363  	switch rep := genericReact.(type) {
   364  	case *reply.Delegate:
   365  		return &rep.Head, nil
   366  	case *reply.Error:
   367  		return nil, rep.Error()
   368  	default:
   369  		return nil, fmt.Errorf("GetDelegate: unexpected reply: %#v", rep)
   370  	}
   371  }
   372  
   373  // GetChildren returns children iterator.
   374  //
   375  // During iteration children refs will be fetched from remote source (parent object).
   376  func (m *LedgerArtifactManager) GetChildren(
   377  	ctx context.Context, parent core.RecordRef, pulse *core.PulseNumber,
   378  ) (core.RefIterator, error) {
   379  	var err error
   380  
   381  	ctx, span := instracer.StartSpan(ctx, "artifactmanager.GetChildren")
   382  	instrumenter := instrument(ctx, "GetChildren").err(&err)
   383  	defer func() {
   384  		if err != nil {
   385  			span.AddAttributes(trace.StringAttribute("error", err.Error()))
   386  		}
   387  		span.End()
   388  		instrumenter.end()
   389  	}()
   390  
   391  	bus := core.MessageBusFromContext(ctx, m.DefaultBus)
   392  	sender := BuildSender(bus.Send, followRedirectSender(bus), retryJetSender(m.JetStorage))
   393  	iter, err := NewChildIterator(ctx, sender, parent, pulse, m.getChildrenChunkSize)
   394  	return iter, err
   395  }
   396  
   397  // DeclareType creates new type record in storage.
   398  //
   399  // Type is a contract interface. It contains one method signature.
   400  func (m *LedgerArtifactManager) DeclareType(
   401  	ctx context.Context, domain, request core.RecordRef, typeDec []byte,
   402  ) (*core.RecordID, error) {
   403  	var err error
   404  	ctx, span := instracer.StartSpan(ctx, "artifactmanager.DeclareType")
   405  	instrumenter := instrument(ctx, "DeclareType").err(&err)
   406  	defer func() {
   407  		if err != nil {
   408  			span.AddAttributes(trace.StringAttribute("error", err.Error()))
   409  		}
   410  		span.End()
   411  		instrumenter.end()
   412  	}()
   413  
   414  	recid, err := m.setRecord(
   415  		ctx,
   416  		&record.TypeRecord{
   417  			SideEffectRecord: record.SideEffectRecord{
   418  				Domain:  domain,
   419  				Request: request,
   420  			},
   421  			TypeDeclaration: typeDec,
   422  		},
   423  		request,
   424  	)
   425  	return recid, err
   426  }
   427  
   428  // DeployCode creates new code record in storage.
   429  //
   430  // CodeRef records are used to activate prototype or as migration code for an object.
   431  func (m *LedgerArtifactManager) DeployCode(
   432  	ctx context.Context,
   433  	domain core.RecordRef,
   434  	request core.RecordRef,
   435  	code []byte,
   436  	machineType core.MachineType,
   437  ) (*core.RecordID, error) {
   438  	var err error
   439  	ctx, span := instracer.StartSpan(ctx, "artifactmanager.DeployCode")
   440  	instrumenter := instrument(ctx, "DeployCode").err(&err)
   441  	defer func() {
   442  		if err != nil {
   443  			span.AddAttributes(trace.StringAttribute("error", err.Error()))
   444  		}
   445  		span.End()
   446  		instrumenter.end()
   447  	}()
   448  
   449  	currentPN, err := m.pulse(ctx)
   450  	if err != nil {
   451  		return nil, err
   452  	}
   453  
   454  	codeRec := &record.CodeRecord{
   455  		SideEffectRecord: record.SideEffectRecord{
   456  			Domain:  domain,
   457  			Request: request,
   458  		},
   459  		Code:        record.CalculateIDForBlob(m.PlatformCryptographyScheme, currentPN, code),
   460  		MachineType: machineType,
   461  	}
   462  	codeID := record.NewRecordIDFromRecord(m.PlatformCryptographyScheme, currentPN, codeRec)
   463  	codeRef := core.NewRecordRef(*domain.Record(), *codeID)
   464  
   465  	_, err = m.setBlob(ctx, code, *codeRef)
   466  	if err != nil {
   467  		return nil, err
   468  	}
   469  	id, err := m.setRecord(
   470  		ctx,
   471  		codeRec,
   472  		*codeRef,
   473  	)
   474  	if err != nil {
   475  		return nil, err
   476  	}
   477  
   478  	return id, nil
   479  }
   480  
   481  // ActivatePrototype creates activate object record in storage. Provided prototype reference will be used as objects prototype
   482  // memory as memory of created object. If memory is not provided, the prototype default memory will be used.
   483  //
   484  // Request reference will be this object's identifier and referred as "object head".
   485  func (m *LedgerArtifactManager) ActivatePrototype(
   486  	ctx context.Context,
   487  	domain, object, parent, code core.RecordRef,
   488  	memory []byte,
   489  ) (core.ObjectDescriptor, error) {
   490  	var err error
   491  	ctx, span := instracer.StartSpan(ctx, "artifactmanager.ActivatePrototype")
   492  	instrumenter := instrument(ctx, "ActivatePrototype").err(&err)
   493  	defer func() {
   494  		if err != nil {
   495  			span.AddAttributes(trace.StringAttribute("error", err.Error()))
   496  		}
   497  		span.End()
   498  		instrumenter.end()
   499  	}()
   500  	desc, err := m.activateObject(ctx, domain, object, code, true, parent, false, memory)
   501  	return desc, err
   502  }
   503  
   504  // ActivateObject creates activate object record in storage. Provided prototype reference will be used as objects prototype
   505  // memory as memory of created object. If memory is not provided, the prototype default memory will be used.
   506  //
   507  // Request reference will be this object's identifier and referred as "object head".
   508  func (m *LedgerArtifactManager) ActivateObject(
   509  	ctx context.Context,
   510  	domain, object, parent, prototype core.RecordRef,
   511  	asDelegate bool,
   512  	memory []byte,
   513  ) (core.ObjectDescriptor, error) {
   514  	var err error
   515  	ctx, span := instracer.StartSpan(ctx, "artifactmanager.ActivateObject")
   516  	instrumenter := instrument(ctx, "ActivateObject").err(&err)
   517  	defer func() {
   518  		if err != nil {
   519  			span.AddAttributes(trace.StringAttribute("error", err.Error()))
   520  		}
   521  		span.End()
   522  		instrumenter.end()
   523  	}()
   524  	desc, err := m.activateObject(ctx, domain, object, prototype, false, parent, asDelegate, memory)
   525  	return desc, err
   526  }
   527  
   528  // DeactivateObject creates deactivate object record in storage. Provided reference should be a reference to the head
   529  // of the object. If object is already deactivated, an error should be returned.
   530  //
   531  // Deactivated object cannot be changed.
   532  func (m *LedgerArtifactManager) DeactivateObject(
   533  	ctx context.Context, domain, request core.RecordRef, object core.ObjectDescriptor,
   534  ) (*core.RecordID, error) {
   535  	var err error
   536  	ctx, span := instracer.StartSpan(ctx, "artifactmanager.DeactivateObject")
   537  	instrumenter := instrument(ctx, "DeactivateObject").err(&err)
   538  	defer func() {
   539  		if err != nil {
   540  			span.AddAttributes(trace.StringAttribute("error", err.Error()))
   541  		}
   542  		span.End()
   543  		instrumenter.end()
   544  	}()
   545  
   546  	desc, err := m.sendUpdateObject(
   547  		ctx,
   548  		&record.DeactivationRecord{
   549  			SideEffectRecord: record.SideEffectRecord{
   550  				Domain:  domain,
   551  				Request: request,
   552  			},
   553  			PrevState: *object.StateID(),
   554  		},
   555  		*object.HeadRef(),
   556  		nil,
   557  	)
   558  	if err != nil {
   559  		return nil, errors.Wrap(err, "failed to deactivate object")
   560  	}
   561  	return &desc.State, nil
   562  }
   563  
   564  // UpdatePrototype creates amend object record in storage. Provided reference should be a reference to the head of the
   565  // prototype. Provided memory well be the new object memory.
   566  //
   567  // Returned reference will be the latest object state (exact) reference.
   568  func (m *LedgerArtifactManager) UpdatePrototype(
   569  	ctx context.Context,
   570  	domain, request core.RecordRef,
   571  	object core.ObjectDescriptor,
   572  	memory []byte,
   573  	code *core.RecordRef,
   574  ) (core.ObjectDescriptor, error) {
   575  	var err error
   576  	ctx, span := instracer.StartSpan(ctx, "artifactmanager.UpdatePrototype")
   577  	instrumenter := instrument(ctx, "UpdatePrototype").err(&err)
   578  	defer func() {
   579  		if err != nil {
   580  			span.AddAttributes(trace.StringAttribute("error", err.Error()))
   581  		}
   582  		span.End()
   583  		instrumenter.end()
   584  	}()
   585  
   586  	if !object.IsPrototype() {
   587  		err = errors.New("object is not a prototype")
   588  		return nil, err
   589  	}
   590  	desc, err := m.updateObject(ctx, domain, request, object, code, memory)
   591  	return desc, err
   592  }
   593  
   594  // UpdateObject creates amend object record in storage. Provided reference should be a reference to the head of the
   595  // object. Provided memory well be the new object memory.
   596  //
   597  // Returned reference will be the latest object state (exact) reference.
   598  func (m *LedgerArtifactManager) UpdateObject(
   599  	ctx context.Context,
   600  	domain, request core.RecordRef,
   601  	object core.ObjectDescriptor,
   602  	memory []byte,
   603  ) (core.ObjectDescriptor, error) {
   604  	var err error
   605  	ctx, span := instracer.StartSpan(ctx, "artifactmanager.UpdateObject")
   606  	instrumenter := instrument(ctx, "UpdateObject").err(&err)
   607  	defer func() {
   608  		if err != nil {
   609  			span.AddAttributes(trace.StringAttribute("error", err.Error()))
   610  		}
   611  		span.End()
   612  		instrumenter.end()
   613  	}()
   614  
   615  	if object.IsPrototype() {
   616  		err = errors.New("object is not an instance")
   617  		return nil, err
   618  	}
   619  	desc, err := m.updateObject(ctx, domain, request, object, nil, memory)
   620  	return desc, err
   621  }
   622  
   623  // RegisterValidation marks provided object state as approved or disapproved.
   624  //
   625  // When fetching object, validity can be specified.
   626  func (m *LedgerArtifactManager) RegisterValidation(
   627  	ctx context.Context,
   628  	object core.RecordRef,
   629  	state core.RecordID,
   630  	isValid bool,
   631  	validationMessages []core.Message,
   632  ) error {
   633  	var err error
   634  	ctx, span := instracer.StartSpan(ctx, "artifactmanager.RegisterValidation")
   635  	instrumenter := instrument(ctx, "RegisterValidation").err(&err)
   636  	defer func() {
   637  		if err != nil {
   638  			span.AddAttributes(trace.StringAttribute("error", err.Error()))
   639  		}
   640  		span.End()
   641  		instrumenter.end()
   642  	}()
   643  
   644  	msg := message.ValidateRecord{
   645  		Object:             object,
   646  		State:              state,
   647  		IsValid:            isValid,
   648  		ValidationMessages: validationMessages,
   649  	}
   650  
   651  	bus := core.MessageBusFromContext(ctx, m.DefaultBus)
   652  	sender := BuildSender(bus.Send, retryJetSender(m.JetStorage))
   653  	_, err = sender(ctx, &msg, nil)
   654  
   655  	return err
   656  }
   657  
   658  // RegisterResult saves VM method call result.
   659  func (m *LedgerArtifactManager) RegisterResult(
   660  	ctx context.Context, object, request core.RecordRef, payload []byte,
   661  ) (*core.RecordID, error) {
   662  	var err error
   663  	ctx, span := instracer.StartSpan(ctx, "artifactmanager.RegisterResult")
   664  	instrumenter := instrument(ctx, "RegisterResult").err(&err)
   665  	defer func() {
   666  		if err != nil {
   667  			span.AddAttributes(trace.StringAttribute("error", err.Error()))
   668  		}
   669  		span.End()
   670  		instrumenter.end()
   671  	}()
   672  
   673  	recid, err := m.setRecord(
   674  		ctx,
   675  		&record.ResultRecord{
   676  			Object:  *object.Record(),
   677  			Request: request,
   678  			Payload: payload,
   679  		},
   680  		request,
   681  	)
   682  	return recid, err
   683  }
   684  
   685  // pulse returns current PulseNumber for artifact manager
   686  func (m *LedgerArtifactManager) pulse(ctx context.Context) (pn core.PulseNumber, err error) {
   687  	pulse, err := m.PulseStorage.Current(ctx)
   688  	if err != nil {
   689  		return
   690  	}
   691  
   692  	pn = pulse.PulseNumber
   693  	return
   694  }
   695  
   696  func (m *LedgerArtifactManager) activateObject(
   697  	ctx context.Context,
   698  	domain core.RecordRef,
   699  	object core.RecordRef,
   700  	prototype core.RecordRef,
   701  	isPrototype bool,
   702  	parent core.RecordRef,
   703  	asDelegate bool,
   704  	memory []byte,
   705  ) (core.ObjectDescriptor, error) {
   706  	parentDesc, err := m.GetObject(ctx, parent, nil, false)
   707  	if err != nil {
   708  		return nil, err
   709  	}
   710  	currentPN, err := m.pulse(ctx)
   711  	if err != nil {
   712  		return nil, err
   713  	}
   714  
   715  	obj, err := m.sendUpdateObject(
   716  		ctx,
   717  		&record.ObjectActivateRecord{
   718  			SideEffectRecord: record.SideEffectRecord{
   719  				Domain:  domain,
   720  				Request: object,
   721  			},
   722  			ObjectStateRecord: record.ObjectStateRecord{
   723  				Memory:      record.CalculateIDForBlob(m.PlatformCryptographyScheme, currentPN, memory),
   724  				Image:       prototype,
   725  				IsPrototype: isPrototype,
   726  			},
   727  			Parent:     parent,
   728  			IsDelegate: asDelegate,
   729  		},
   730  		object,
   731  		memory,
   732  	)
   733  	if err != nil {
   734  		return nil, errors.Wrap(err, "failed to activate")
   735  	}
   736  
   737  	var (
   738  		prevChild *core.RecordID
   739  		asType    *core.RecordRef
   740  	)
   741  	if parentDesc.ChildPointer() != nil {
   742  		prevChild = parentDesc.ChildPointer()
   743  	}
   744  	if asDelegate {
   745  		asType = &prototype
   746  	}
   747  	_, err = m.registerChild(
   748  		ctx,
   749  		&record.ChildRecord{
   750  			Ref:       object,
   751  			PrevChild: prevChild,
   752  		},
   753  		parent,
   754  		object,
   755  		asType,
   756  	)
   757  	if err != nil {
   758  		return nil, errors.Wrap(err, "failed to register as child while activating")
   759  	}
   760  
   761  	return &ObjectDescriptor{
   762  		ctx:          ctx,
   763  		am:           m,
   764  		head:         obj.Head,
   765  		state:        obj.State,
   766  		prototype:    obj.Prototype,
   767  		childPointer: obj.ChildPointer,
   768  		memory:       memory,
   769  		parent:       obj.Parent,
   770  	}, nil
   771  }
   772  
   773  func (m *LedgerArtifactManager) updateObject(
   774  	ctx context.Context,
   775  	domain, request core.RecordRef,
   776  	object core.ObjectDescriptor,
   777  	code *core.RecordRef,
   778  	memory []byte,
   779  ) (core.ObjectDescriptor, error) {
   780  	var (
   781  		image *core.RecordRef
   782  		err   error
   783  	)
   784  	if object.IsPrototype() {
   785  		if code != nil {
   786  			image = code
   787  		} else {
   788  			image, err = object.Code()
   789  		}
   790  	} else {
   791  		image, err = object.Prototype()
   792  	}
   793  	if err != nil {
   794  		return nil, errors.Wrap(err, "failed to update object")
   795  	}
   796  
   797  	obj, err := m.sendUpdateObject(
   798  		ctx,
   799  		&record.ObjectAmendRecord{
   800  			SideEffectRecord: record.SideEffectRecord{
   801  				Domain:  domain,
   802  				Request: request,
   803  			},
   804  			ObjectStateRecord: record.ObjectStateRecord{
   805  				Image:       *image,
   806  				IsPrototype: object.IsPrototype(),
   807  			},
   808  			PrevState: *object.StateID(),
   809  		},
   810  		*object.HeadRef(),
   811  		memory,
   812  	)
   813  	if err != nil {
   814  		return nil, errors.Wrap(err, "failed to update object")
   815  	}
   816  
   817  	return &ObjectDescriptor{
   818  		ctx:          ctx,
   819  		am:           m,
   820  		head:         obj.Head,
   821  		state:        obj.State,
   822  		prototype:    obj.Prototype,
   823  		childPointer: obj.ChildPointer,
   824  		memory:       memory,
   825  		parent:       obj.Parent,
   826  	}, nil
   827  }
   828  
   829  func (m *LedgerArtifactManager) setRecord(
   830  	ctx context.Context,
   831  	rec record.Record,
   832  	target core.RecordRef,
   833  ) (*core.RecordID, error) {
   834  	bus := core.MessageBusFromContext(ctx, m.DefaultBus)
   835  
   836  	sender := BuildSender(bus.Send, retryJetSender(m.JetStorage))
   837  	genericReply, err := sender(ctx, &message.SetRecord{
   838  		Record:    record.SerializeRecord(rec),
   839  		TargetRef: target,
   840  	}, nil)
   841  
   842  	if err != nil {
   843  		return nil, err
   844  	}
   845  
   846  	switch rep := genericReply.(type) {
   847  	case *reply.ID:
   848  		return &rep.ID, nil
   849  	case *reply.Error:
   850  		return nil, rep.Error()
   851  	default:
   852  		return nil, fmt.Errorf("setRecord: unexpected reply: %#v", rep)
   853  	}
   854  }
   855  
   856  func (m *LedgerArtifactManager) setBlob(
   857  	ctx context.Context,
   858  	blob []byte,
   859  	target core.RecordRef,
   860  ) (*core.RecordID, error) {
   861  
   862  	bus := core.MessageBusFromContext(ctx, m.DefaultBus)
   863  	sender := BuildSender(bus.Send, retryJetSender(m.JetStorage))
   864  	genericReact, err := sender(ctx, &message.SetBlob{
   865  		Memory:    blob,
   866  		TargetRef: target,
   867  	}, nil)
   868  
   869  	if err != nil {
   870  		return nil, err
   871  	}
   872  
   873  	switch rep := genericReact.(type) {
   874  	case *reply.ID:
   875  		return &rep.ID, nil
   876  	case *reply.Error:
   877  		return nil, rep.Error()
   878  	default:
   879  		return nil, fmt.Errorf("setBlob: unexpected reply: %#v", rep)
   880  	}
   881  }
   882  
   883  func (m *LedgerArtifactManager) sendUpdateObject(
   884  	ctx context.Context,
   885  	rec record.Record,
   886  	object core.RecordRef,
   887  	memory []byte,
   888  ) (*reply.Object, error) {
   889  	// TODO: @andreyromancev. 14.01.19. Uncomment when message streaming or validation is ready.
   890  	// genericRep, err := sendAndRetryJet(ctx, m.bus(ctx), m.db, &message.SetBlob{
   891  	// 	TargetRef: object,
   892  	// 	Memory:    memory,
   893  	// }, currentPulse, jetMissRetryCount, nil)
   894  	// if err != nil {
   895  	// 	return nil, errors.Wrap(err, "failed to save object's memory blob")
   896  	// }
   897  	// if _, ok := genericRep.(*reply.ID); !ok {
   898  	// 	return nil, fmt.Errorf("unexpected reply: %#v\n", genericRep)
   899  	// }
   900  
   901  	bus := core.MessageBusFromContext(ctx, m.DefaultBus)
   902  	sender := BuildSender(bus.Send, retryJetSender(m.JetStorage))
   903  	genericReply, err := sender(
   904  		ctx,
   905  		&message.UpdateObject{
   906  			Record: record.SerializeRecord(rec),
   907  			Object: object,
   908  			Memory: memory,
   909  		}, nil)
   910  
   911  	if err != nil {
   912  		return nil, errors.Wrap(err, "UpdateObject message failed")
   913  	}
   914  
   915  	switch rep := genericReply.(type) {
   916  	case *reply.Object:
   917  		return rep, nil
   918  	case *reply.Error:
   919  		return nil, rep.Error()
   920  	default:
   921  		return nil, fmt.Errorf("sendUpdateObject: unexpected reply: %#v", rep)
   922  	}
   923  }
   924  
   925  func (m *LedgerArtifactManager) registerChild(
   926  	ctx context.Context,
   927  	rec record.Record,
   928  	parent core.RecordRef,
   929  	child core.RecordRef,
   930  	asType *core.RecordRef,
   931  ) (*core.RecordID, error) {
   932  	bus := core.MessageBusFromContext(ctx, m.DefaultBus)
   933  	sender := BuildSender(bus.Send, retryJetSender(m.JetStorage))
   934  	genericReact, err := sender(ctx, &message.RegisterChild{
   935  		Record: record.SerializeRecord(rec),
   936  		Parent: parent,
   937  		Child:  child,
   938  		AsType: asType,
   939  	}, nil)
   940  
   941  	if err != nil {
   942  		return nil, err
   943  	}
   944  
   945  	switch rep := genericReact.(type) {
   946  	case *reply.ID:
   947  		return &rep.ID, nil
   948  	case *reply.Error:
   949  		return nil, rep.Error()
   950  	default:
   951  		return nil, fmt.Errorf("registerChild: unexpected reply: %#v", rep)
   952  	}
   953  }