github.com/metacurrency/holochain@v0.1.0-alpha-26.0.20200915073418-5c83169c9b5b/ribosome.go (about) 1 // Copyright (C) 2013-2018, The MetaCurrency Project (Eric Harris-Braun, Arthur Brock, et. al.) 2 // Use of this source code is governed by GPLv3 found in the LICENSE file 3 //---------------------------------------------------------------------------------------- 4 // Ribosome provides an interface for an execution environment interface for chains and their entries 5 // and factory code for creating ribosome instances 6 7 package holochain 8 9 import ( 10 "errors" 11 "fmt" 12 . "github.com/holochain/holochain-proto/hash" 13 "sort" 14 "strings" 15 ) 16 17 type RibosomeFactory func(h *Holochain, zome *Zome) (Ribosome, error) 18 19 const ( 20 21 // calling types 22 23 STRING_CALLING = "string" 24 JSON_CALLING = "json" 25 26 // exposure types for functions 27 28 // ZOME_EXPOSURE is the default and means the function is only exposed for use by other zomes in the app 29 ZOME_EXPOSURE = "" 30 // AUTHENTICATED_EXPOSURE means that the function is only available after authentication (TODO) 31 AUTHENTICATED_EXPOSURE = "auth" 32 // PUBLIC_EXPOSURE means that the function is callable by anyone 33 PUBLIC_EXPOSURE = "public" 34 35 // these constants are for a removed feature, see ChangeAppProperty 36 // @TODO figure out how to remove code over time that becomes obsolete, i.e. for long-dead changes 37 38 ID_PROPERTY = "_id" 39 AGENT_ID_PROPERTY = "_agent_id" 40 AGENT_NAME_PROPERTY = "_agent_name" 41 42 BridgeCaller = 0 43 BridgeCallee = 1 44 BridgeCallerStr = "0" 45 BridgeCalleeStr = "1" 46 47 BundleCancelReasonUserCancel = "userCancel" 48 BundleCancelReasonTimeout = "timeout" 49 50 BundleCancelResponseOK = "" 51 BundleCancelResponseCommit = "commit" 52 53 ValidationFailedErrMsg = "Validation Failed" 54 ) 55 56 var ValidationFailedErr = errors.New(ValidationFailedErrMsg) 57 58 // ValidationFailed creates a validation failed error message 59 func ValidationFailed(msgs ...string) error { 60 if len(msgs) == 0 { 61 return ValidationFailedErr 62 } 63 return errors.New(ValidationFailedErrMsg + ": " + strings.Join(msgs, `, `)) 64 } 65 66 func IsValidationFailedErr(err error) bool { 67 return strings.HasPrefix(err.Error(), ValidationFailedErrMsg) 68 } 69 70 // FunctionDef holds the name and calling type of an DNA exposed function 71 type FunctionDef struct { 72 Name string 73 CallingType string 74 Exposure string 75 } 76 77 // ValidExposure verifies that the function can be called in the given context 78 func (f *FunctionDef) ValidExposure(context string) bool { 79 if f.Exposure == PUBLIC_EXPOSURE { 80 return true 81 } 82 return f.Exposure == context 83 } 84 85 // Ribosome type abstracts the functions of code execution environments 86 type Ribosome interface { 87 Type() string 88 ValidateAction(action Action, def *EntryDef, pkg *ValidationPackage, sources []string) (err error) 89 ValidatePackagingRequest(action ValidatingAction, def *EntryDef) (req PackagingReq, err error) 90 ChainGenesis() error 91 BridgeGenesis(side int, dnaHash Hash, data string) error 92 Receive(from string, msg string) (response string, err error) 93 Call(fn *FunctionDef, params interface{}) (interface{}, error) 94 Run(code string) (result interface{}, err error) 95 RunAsyncSendResponse(response AppMsg, callback string, callbackID string) (result interface{}, err error) 96 BundleCanceled(reason string) (response string, err error) 97 } 98 99 var ribosomeFactories = make(map[string]RibosomeFactory) 100 101 // RegisterRibosome sets up a Ribosome to be used by the CreateRibosome function 102 func RegisterRibosome(name string, factory RibosomeFactory) { 103 if factory == nil { 104 panic(fmt.Sprintf("Ribosome factory for type %s does not exist.", name)) 105 } 106 _, registered := ribosomeFactories[name] 107 if registered { 108 panic(fmt.Sprintf("Ribosome factory for type %s already registered. ", name)) 109 } 110 ribosomeFactories[name] = factory 111 } 112 113 // RegisterBultinRibosomes adds the built in ribosome types to the factory hash 114 func RegisterBultinRibosomes() { 115 RegisterRibosome(ZygoRibosomeType, NewZygoRibosome) 116 RegisterRibosome(JSRibosomeType, NewJSRibosome) 117 } 118 119 // CreateRibosome returns a new Ribosome of the given type 120 func CreateRibosome(h *Holochain, zome *Zome) (Ribosome, error) { 121 122 factory, ok := ribosomeFactories[zome.RibosomeType] 123 if !ok { 124 // Factory has not been registered. 125 // Make a list of all available ribosome factories for error. 126 var available []string 127 for k := range ribosomeFactories { 128 available = append(available, k) 129 } 130 sort.Strings(available) 131 return nil, fmt.Errorf("Invalid ribosome name. Must be one of: %s", strings.Join(available, ", ")) 132 } 133 134 return factory(h, zome) 135 }