github.com/holochain/holochain-proto@v0.1.0-alpha-26.0.20200915073418-5c83169c9b5b/action_update.go (about) 1 package holochain 2 3 import ( 4 . "github.com/holochain/holochain-proto/hash" 5 peer "github.com/libp2p/go-libp2p-peer" 6 ) 7 8 //------------------------------------------------------------ 9 // Mod 10 11 type APIFnMod struct { 12 action ActionMod 13 } 14 15 func (fn *APIFnMod) Name() string { 16 return fn.action.Name() 17 } 18 19 func (fn *APIFnMod) Args() []Arg { 20 return []Arg{{Name: "entryType", Type: StringArg}, {Name: "entry", Type: EntryArg}, {Name: "replaces", Type: HashArg}} 21 } 22 23 func (fn *APIFnMod) Call(h *Holochain) (response interface{}, err error) { 24 a := &fn.action 25 response, err = h.commitAndShare(a, a.replaces) 26 return 27 } 28 29 type ActionMod struct { 30 entryType string 31 entry Entry 32 header *Header 33 replaces Hash 34 } 35 36 func NewModAction(entryType string, entry Entry, replaces Hash) *ActionMod { 37 a := ActionMod{entryType: entryType, entry: entry, replaces: replaces} 38 return &a 39 } 40 41 func (a *ActionMod) Entry() Entry { 42 return a.entry 43 } 44 45 func (a *ActionMod) EntryType() string { 46 return a.entryType 47 } 48 49 func (a *ActionMod) Name() string { 50 return "mod" 51 } 52 53 func (a *ActionMod) SetHeader(header *Header) { 54 a.header = header 55 } 56 57 func (a *ActionMod) GetHeader() (header *Header) { 58 return a.header 59 } 60 61 func (a *ActionMod) Share(h *Holochain, def *EntryDef) (err error) { 62 if def.isSharingPublic() { 63 // if it's a public entry send the DHT MOD & PUT messages 64 // TODO handle errors better!! 65 h.dht.Change(a.header.EntryLink, PUT_REQUEST, HoldReq{EntryHash: a.header.EntryLink}) 66 h.dht.Change(a.replaces, MOD_REQUEST, HoldReq{RelatedHash: a.replaces, EntryHash: a.header.EntryLink}) 67 } 68 return 69 } 70 71 func (a *ActionMod) SysValidation(h *Holochain, def *EntryDef, pkg *Package, sources []peer.ID) (err error) { 72 switch def.Name { 73 case DNAEntryType: 74 err = ErrNotValidForDNAType 75 return 76 case HeadersEntryType: 77 err = ErrNotValidForHeadersType 78 return 79 case DelEntryType: 80 err = ErrNotValidForDelType 81 return 82 case KeyEntryType: 83 case AgentEntryType: 84 } 85 86 if def.DataFormat == DataFormatLinks { 87 err = ErrModInvalidForLinks 88 return 89 } 90 91 if a.entry == nil { 92 err = ErrNilEntryInvalid 93 return 94 } 95 if a.header == nil { 96 err = ErrModMissingHeader 97 return 98 } 99 if a.replaces.String() == a.header.EntryLink.String() { 100 err = ErrModReplacesHashNotDifferent 101 return 102 } 103 // no need to check for virtual entries on the chain because they aren't there 104 // currently the only virtual entry is the node id 105 /* 106 if !def.IsVirtualEntry() { 107 var header *Header 108 header, err = h.chain.GetEntryHeader(a.replaces) 109 if err != nil { 110 return 111 } 112 if header.Type != a.entryType { 113 err = ErrEntryTypeMismatch 114 return 115 } 116 }*/ 117 err = sysValidateEntry(h, def, a.entry, pkg) 118 return 119 } 120 121 func (a *ActionMod) Receive(dht *DHT, msg *Message) (response interface{}, err error) { 122 //var hashStatus int 123 t := msg.Body.(HoldReq) 124 var holdResp *HoldResp 125 126 err = RunValidationPhase(dht.h, msg.From, VALIDATE_MOD_REQUEST, t.EntryHash, func(resp ValidateResponse) error { 127 a := NewModAction(resp.Type, &resp.Entry, t.RelatedHash) 128 a.header = &resp.Header 129 130 //@TODO what comes back from Validate Mod 131 _, err = dht.h.ValidateAction(a, resp.Type, &resp.Package, []peer.ID{msg.From}) 132 if err != nil { 133 // how do we record an invalid Mod? 134 //@TODO store as REJECTED? 135 } else { 136 err = dht.Mod(msg, t.RelatedHash, t.EntryHash) 137 if err == nil { 138 holdResp, err = dht.MakeHoldResp(msg, StatusLive) 139 } 140 } 141 return err 142 }) 143 if holdResp != nil { 144 response = *holdResp 145 } 146 return 147 } 148 149 func (a *ActionMod) CheckValidationRequest(def *EntryDef) (err error) { 150 return 151 }