github.com/metacurrency/holochain@v0.1.0-alpha-26.0.20200915073418-5c83169c9b5b/action_link.go (about) 1 package holochain 2 3 import ( 4 "errors" 5 . "github.com/holochain/holochain-proto/hash" 6 peer "github.com/libp2p/go-libp2p-peer" 7 ) 8 9 //------------------------------------------------------------ 10 // Link 11 12 type ActionLink struct { 13 entryType string 14 links []Link 15 validationBase Hash 16 } 17 18 func NewLinkAction(entryType string, links []Link) *ActionLink { 19 a := ActionLink{entryType: entryType, links: links} 20 return &a 21 } 22 23 func (a *ActionLink) Name() string { 24 return "link" 25 } 26 27 func (a *ActionLink) SysValidation(h *Holochain, def *EntryDef, pkg *Package, sources []peer.ID) (err error) { 28 if def.DataFormat != DataFormatLinks { 29 err = errors.New("action only valid for links entry type") 30 } 31 //@TODO what sys level links validation? That they are all valid hash format for the DNA? 32 return 33 } 34 35 func (a *ActionLink) Receive(dht *DHT, msg *Message) (response interface{}, err error) { 36 t := msg.Body.(HoldReq) 37 var holdResp *HoldResp 38 39 err = RunValidationPhase(dht.h, msg.From, VALIDATE_LINK_REQUEST, t.EntryHash, func(resp ValidateResponse) error { 40 var le LinksEntry 41 le, err = LinksEntryFromJSON(resp.Entry.Content().(string)) 42 if err != nil { 43 return err 44 } 45 46 a := NewLinkAction(resp.Type, le.Links) 47 a.validationBase = t.RelatedHash 48 _, err = dht.h.ValidateAction(a, a.entryType, &resp.Package, []peer.ID{msg.From}) 49 //@TODO this is "one bad apple spoils the lot" because the app 50 // has no way to tell us not to link certain of the links. 51 // we need to extend the return value of the app to be able to 52 // have it reject a subset of the links. 53 if err != nil { 54 // how do we record an invalid linking? 55 //@TODO store as REJECTED 56 } else { 57 base := t.RelatedHash.String() 58 for _, l := range le.Links { 59 if base == l.Base { 60 if l.LinkAction == DelLinkAction { 61 err = dht.DelLink(msg, base, l.Link, l.Tag) 62 } else { 63 err = dht.PutLink(msg, base, l.Link, l.Tag) 64 } 65 } 66 } 67 if err == nil { 68 holdResp, err = dht.MakeHoldResp(msg, StatusLive) 69 } 70 } 71 return err 72 }) 73 74 if holdResp != nil { 75 response = *holdResp 76 } 77 return 78 } 79 80 func (a *ActionLink) CheckValidationRequest(def *EntryDef) (err error) { 81 if def.DataFormat != DataFormatLinks { 82 err = errors.New("hash not of a linking entry") 83 } 84 return 85 }