github.com/braveheart12/just@v0.8.7/core/ledger.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 core
    18  
    19  import (
    20  	"context"
    21  )
    22  
    23  const (
    24  	// JetSize is a Jet's size (depth+prefix).
    25  	JetSize = RecordIDSize - PulseNumberSize
    26  	// JetPrefixSize is a Jet's prefix size.
    27  	JetPrefixSize = JetSize - 1
    28  )
    29  
    30  // DynamicRole is number representing a node role.
    31  type DynamicRole int
    32  
    33  const (
    34  	// DynamicRoleUndefined is used for special cases.
    35  	DynamicRoleUndefined = DynamicRole(iota)
    36  	// DynamicRoleVirtualExecutor is responsible for current pulse CPU operations.
    37  	DynamicRoleVirtualExecutor
    38  	// DynamicRoleVirtualValidator is responsible for previous pulse CPU operations.
    39  	DynamicRoleVirtualValidator
    40  	// DynamicRoleLightExecutor is responsible for current pulse Disk operations.
    41  	DynamicRoleLightExecutor
    42  	// DynamicRoleLightValidator is responsible for previous pulse Disk operations.
    43  	DynamicRoleLightValidator
    44  	// DynamicRoleHeavyExecutor is responsible for permanent Disk operations.
    45  	DynamicRoleHeavyExecutor
    46  )
    47  
    48  // IsVirtualRole checks if node role is virtual (validator or executor).
    49  func (r DynamicRole) IsVirtualRole() bool {
    50  	switch r {
    51  	case DynamicRoleVirtualExecutor:
    52  		return true
    53  	case DynamicRoleVirtualValidator:
    54  		return true
    55  	}
    56  	return false
    57  }
    58  
    59  // PulseManager provides Ledger's methods related to Pulse.
    60  //go:generate minimock -i github.com/insolar/insolar/core.PulseManager -o ../testutils -s _mock.go
    61  type PulseManager interface {
    62  	// Set set's new pulse and closes current jet drop. If dry is true, nothing will be saved to storage.
    63  	Set(ctx context.Context, pulse Pulse, persist bool) error
    64  }
    65  
    66  // JetCoordinator provides methods for calculating Jet affinity
    67  // (e.g. to which Jet a message should be sent).
    68  //go:generate minimock -i github.com/insolar/insolar/core.JetCoordinator -o ../testutils -s _mock.go
    69  type JetCoordinator interface {
    70  	// Me returns current node.
    71  	Me() RecordRef
    72  
    73  	// IsAuthorized checks for role on concrete pulse for the address.
    74  	IsAuthorized(ctx context.Context, role DynamicRole, obj RecordID, pulse PulseNumber, node RecordRef) (bool, error)
    75  
    76  	// QueryRole returns node refs responsible for role bound operations for given object and pulse.
    77  	QueryRole(ctx context.Context, role DynamicRole, obj RecordID, pulse PulseNumber) ([]RecordRef, error)
    78  
    79  	VirtualExecutorForObject(ctx context.Context, objID RecordID, pulse PulseNumber) (*RecordRef, error)
    80  	VirtualValidatorsForObject(ctx context.Context, objID RecordID, pulse PulseNumber) ([]RecordRef, error)
    81  
    82  	LightExecutorForObject(ctx context.Context, objID RecordID, pulse PulseNumber) (*RecordRef, error)
    83  	LightValidatorsForObject(ctx context.Context, objID RecordID, pulse PulseNumber) ([]RecordRef, error)
    84  	// LightExecutorForJet calculates light material executor for provided jet.
    85  	LightExecutorForJet(ctx context.Context, jetID RecordID, pulse PulseNumber) (*RecordRef, error)
    86  	LightValidatorsForJet(ctx context.Context, jetID RecordID, pulse PulseNumber) ([]RecordRef, error)
    87  
    88  	Heavy(ctx context.Context, pulse PulseNumber) (*RecordRef, error)
    89  
    90  	IsBeyondLimit(ctx context.Context, currentPN, targetPN PulseNumber) (bool, error)
    91  	NodeForJet(ctx context.Context, jetID RecordID, rootPN, targetPN PulseNumber) (*RecordRef, error)
    92  
    93  	// NodeForObject calculates a node (LME or heavy) for a specific jet for a specific pulseNumber
    94  	NodeForObject(ctx context.Context, objectID RecordID, rootPN, targetPN PulseNumber) (*RecordRef, error)
    95  }
    96  
    97  // ArtifactManager is a high level storage interface.
    98  //go:generate minimock -i github.com/insolar/insolar/core.ArtifactManager -o ../testutils -s _mock.go
    99  type ArtifactManager interface {
   100  	// GenesisRef returns the root record reference.
   101  	//
   102  	// Root record is the parent for all top-level records.
   103  	GenesisRef() *RecordRef
   104  
   105  	// RegisterRequest creates request record in storage.
   106  	RegisterRequest(ctx context.Context, object RecordRef, parcel Parcel) (*RecordID, error)
   107  
   108  	// RegisterValidation marks provided object state as approved or disapproved.
   109  	//
   110  	// When fetching object, validity can be specified.
   111  	RegisterValidation(ctx context.Context, object RecordRef, state RecordID, isValid bool, validationMessages []Message) error
   112  
   113  	// RegisterResult saves VM method call result.
   114  	RegisterResult(ctx context.Context, object, request RecordRef, payload []byte) (*RecordID, error)
   115  
   116  	// GetCode returns code from code record by provided reference according to provided machine preference.
   117  	//
   118  	// This method is used by VM to fetch code for execution.
   119  	GetCode(ctx context.Context, ref RecordRef) (CodeDescriptor, error)
   120  
   121  	// GetObject returns descriptor for provided state.
   122  	//
   123  	// If provided state is nil, the latest state will be returned (with deactivation check). Returned descriptor will
   124  	// provide methods for fetching all related data.
   125  	GetObject(ctx context.Context, head RecordRef, state *RecordID, approved bool) (ObjectDescriptor, error)
   126  
   127  	// GetPendingRequest returns a pending request for object.
   128  	GetPendingRequest(ctx context.Context, objectID RecordID) (Parcel, error)
   129  
   130  	// HasPendingRequests returns true if object has unclosed requests.
   131  	HasPendingRequests(ctx context.Context, object RecordRef) (bool, error)
   132  
   133  	// GetDelegate returns provided object's delegate reference for provided type.
   134  	//
   135  	// Object delegate should be previously created for this object. If object delegate does not exist, an error will
   136  	// be returned.
   137  	GetDelegate(ctx context.Context, head, asType RecordRef) (*RecordRef, error)
   138  
   139  	// GetChildren returns children iterator.
   140  	//
   141  	// During iteration children refs will be fetched from remote source (parent object).
   142  	GetChildren(ctx context.Context, parent RecordRef, pulse *PulseNumber) (RefIterator, error)
   143  
   144  	// DeclareType creates new type record in storage.
   145  	//
   146  	// Type is a contract interface. It contains one method signature.
   147  	DeclareType(ctx context.Context, domain, request RecordRef, typeDec []byte) (*RecordID, error)
   148  
   149  	// DeployCode creates new code record in storage.
   150  	//
   151  	// Code records are used to activate prototype.
   152  	DeployCode(ctx context.Context, domain, request RecordRef, code []byte, machineType MachineType) (*RecordID, error)
   153  
   154  	// ActivatePrototype creates activate object record in storage. Provided prototype reference will be used as objects prototype
   155  	// memory as memory of created object. If memory is not provided, the prototype default memory will be used.
   156  	//
   157  	// Request reference will be this object's identifier and referred as "object head".
   158  	ActivatePrototype(
   159  		ctx context.Context,
   160  		domain, request, parent, code RecordRef,
   161  		memory []byte,
   162  	) (ObjectDescriptor, error)
   163  
   164  	// ActivateObject creates activate object record in storage. If memory is not provided, the prototype default
   165  	// memory will be used.
   166  	//
   167  	// Request reference will be this object's identifier and referred as "object head".
   168  	ActivateObject(
   169  		ctx context.Context,
   170  		domain, request, parent, prototype RecordRef,
   171  		asDelegate bool,
   172  		memory []byte,
   173  	) (ObjectDescriptor, error)
   174  
   175  	// UpdatePrototype creates amend object record in storage. Provided reference should be a reference to the head of
   176  	// the prototype. Provided memory well be the new object memory.
   177  	//
   178  	// Returned reference will be the latest object state (exact) reference.
   179  	UpdatePrototype(
   180  		ctx context.Context,
   181  		domain, request RecordRef,
   182  		obj ObjectDescriptor,
   183  		memory []byte,
   184  		code *RecordRef,
   185  	) (ObjectDescriptor, error)
   186  
   187  	// UpdateObject creates amend object record in storage. Provided reference should be a reference to the head of the
   188  	// object. Provided memory well be the new object memory.
   189  	//
   190  	// Returned reference will be the latest object state (exact) reference.
   191  	UpdateObject(
   192  		ctx context.Context,
   193  		domain, request RecordRef,
   194  		obj ObjectDescriptor,
   195  		memory []byte,
   196  	) (ObjectDescriptor, error)
   197  
   198  	// DeactivateObject creates deactivate object record in storage. Provided reference should be a reference to the head
   199  	// of the object. If object is already deactivated, an error should be returned.
   200  	//
   201  	// Deactivated object cannot be changed.
   202  	DeactivateObject(ctx context.Context, domain, request RecordRef, obj ObjectDescriptor) (*RecordID, error)
   203  
   204  	// State returns hash state for artifact manager.
   205  	State() ([]byte, error)
   206  }
   207  
   208  // CodeDescriptor represents meta info required to fetch all code data.
   209  //go:generate minimock -i github.com/insolar/insolar/core.CodeDescriptor -o ../testutils -s _mock.go
   210  type CodeDescriptor interface {
   211  	// Ref returns reference to represented code record.
   212  	Ref() *RecordRef
   213  
   214  	// MachineType returns code machine type for represented code.
   215  	MachineType() MachineType
   216  
   217  	// Code returns code data.
   218  	Code() ([]byte, error)
   219  }
   220  
   221  // ObjectDescriptor represents meta info required to fetch all object data.
   222  //go:generate minimock -i github.com/insolar/insolar/core.ObjectDescriptor -o ../testutils -s _mock.go
   223  type ObjectDescriptor interface {
   224  	// HeadRef returns head reference to represented object record.
   225  	HeadRef() *RecordRef
   226  
   227  	// StateID returns reference to object state record.
   228  	StateID() *RecordID
   229  
   230  	// Memory fetches object memory from storage.
   231  	Memory() []byte
   232  
   233  	// IsPrototype determines if the object is a prototype.
   234  	IsPrototype() bool
   235  
   236  	// Code returns code reference.
   237  	Code() (*RecordRef, error)
   238  
   239  	// Prototype returns prototype reference.
   240  	Prototype() (*RecordRef, error)
   241  
   242  	// Children returns object's children references.
   243  	Children(pulse *PulseNumber) (RefIterator, error)
   244  
   245  	// ChildPointer returns the latest child for this object.
   246  	ChildPointer() *RecordID
   247  
   248  	// Parent returns object's parent.
   249  	Parent() *RecordRef
   250  }
   251  
   252  // RefIterator is used for iteration over affined children(parts) of container.
   253  type RefIterator interface {
   254  	Next() (*RecordRef, error)
   255  	HasNext() bool
   256  }
   257  
   258  // KV is a generic key/value struct.
   259  type KV struct {
   260  	K []byte
   261  	V []byte
   262  }
   263  
   264  // KVSize returns size of key/value array in bytes.
   265  func KVSize(kvs []KV) (amount int64) {
   266  	for _, kv := range kvs {
   267  		amount += int64(len(kv.K) + len(kv.V))
   268  	}
   269  	return
   270  }
   271  
   272  // StorageExportResult represents storage data view.
   273  type StorageExportResult struct {
   274  	Data     map[string]interface{}
   275  	NextFrom *PulseNumber
   276  	Size     int
   277  }
   278  
   279  // StorageExporter provides methods for fetching data view from storage.
   280  type StorageExporter interface {
   281  	// Export returns data view from storage.
   282  	Export(ctx context.Context, fromPulse PulseNumber, size int) (*StorageExportResult, error)
   283  }
   284  
   285  var (
   286  	// TODOJetID temporary stub for passing jet ID in ledger functions
   287  	// on period Jet ID full implementation
   288  	// TODO: remove it after jets support readyness - @nordicdyno 5.Dec.2018
   289  	TODOJetID = *NewRecordID(PulseNumberJet, nil)
   290  	DomainID  = *NewRecordID(0, nil)
   291  )
   292  
   293  // PulseStorage provides the interface for fetching current pulse of the system
   294  //go:generate minimock -i github.com/insolar/insolar/core.PulseStorage -o ../testutils -s _mock.go
   295  type PulseStorage interface {
   296  	Current(ctx context.Context) (*Pulse, error)
   297  }