github.com/metacurrency/holochain@v0.1.0-alpha-26.0.20200915073418-5c83169c9b5b/action_put.go (about)

     1  package holochain
     2  
     3  import (
     4  	peer "github.com/libp2p/go-libp2p-peer"
     5  )
     6  
     7  //------------------------------------------------------------
     8  // Put
     9  
    10  type ActionPut struct {
    11  	entryType string
    12  	entry     Entry
    13  	header    *Header
    14  }
    15  
    16  func NewPutAction(entryType string, entry Entry, header *Header) *ActionPut {
    17  	a := ActionPut{entryType: entryType, entry: entry, header: header}
    18  	return &a
    19  }
    20  
    21  func (a *ActionPut) Name() string {
    22  	return "put"
    23  }
    24  
    25  func (a *ActionPut) SysValidation(h *Holochain, def *EntryDef, pkg *Package, sources []peer.ID) (err error) {
    26  	err = sysValidateEntry(h, def, a.entry, pkg)
    27  	return
    28  }
    29  
    30  func (a *ActionPut) Receive(dht *DHT, msg *Message) (response interface{}, err error) {
    31  	t := msg.Body.(HoldReq)
    32  	var holdResp *HoldResp
    33  
    34  	// check to see if we are already holding this hash
    35  	var status int
    36  	_, _, _, status, err = dht.Get(t.EntryHash, StatusAny, GetMaskEntryType) //TODO should be a getmask for just Status
    37  	if err == nil {
    38  		holdResp, err = dht.MakeHoldResp(msg, status)
    39  		response = *holdResp
    40  		return
    41  	}
    42  	if err != ErrHashNotFound {
    43  		return
    44  	}
    45  
    46  	err = RunValidationPhase(dht.h, msg.From, VALIDATE_PUT_REQUEST, t.EntryHash, func(resp ValidateResponse) error {
    47  		a := NewPutAction(resp.Type, &resp.Entry, &resp.Header)
    48  		_, err := dht.h.ValidateAction(a, a.entryType, &resp.Package, []peer.ID{msg.From})
    49  
    50  		var status int
    51  		if err != nil {
    52  			dht.dlog.Logf("Put %v rejected: %v", t.EntryHash, err)
    53  			status = StatusRejected
    54  		} else {
    55  			status = StatusLive
    56  		}
    57  		entry := resp.Entry
    58  		var b []byte
    59  		b, err = entry.Marshal()
    60  		if err == nil {
    61  			err = dht.Put(msg, resp.Type, t.EntryHash, msg.From, b, status)
    62  		}
    63  		if err == nil {
    64  			holdResp, err = dht.MakeHoldResp(msg, status)
    65  		}
    66  		return err
    67  	})
    68  
    69  	r := dht.h.RedundancyFactor()
    70  	if r == 0 {
    71  		r = CloserPeerCount
    72  	}
    73  
    74  	closest := dht.h.node.betterPeersForHash(&t.EntryHash, msg.From, true, r)
    75  	if len(closest) > 0 {
    76  		err = nil
    77  		resp := CloserPeersResp{}
    78  		resp.CloserPeers = dht.h.node.peers2PeerInfos(closest)
    79  		response = resp
    80  		return
    81  	} else {
    82  		if holdResp != nil {
    83  			response = *holdResp
    84  		}
    85  	}
    86  	return
    87  }
    88  
    89  func (a *ActionPut) CheckValidationRequest(def *EntryDef) (err error) {
    90  	return
    91  }