github.com/metacurrency/holochain@v0.1.0-alpha-26.0.20200915073418-5c83169c9b5b/action_updateagent.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 "reflect" 8 ) 9 10 //------------------------------------------------------------ 11 // ModAgent 12 13 type APIFnModAgent struct { 14 Identity AgentIdentity 15 Revocation string 16 } 17 18 func (fn *APIFnModAgent) Args() []Arg { 19 return []Arg{{Name: "options", Type: MapArg, MapType: reflect.TypeOf(ModAgentOptions{})}} 20 } 21 22 func (fn *APIFnModAgent) Name() string { 23 return "updateAgent" 24 } 25 func (fn *APIFnModAgent) Call(h *Holochain) (response interface{}, err error) { 26 var ok bool 27 var newAgent LibP2PAgent = *h.agent.(*LibP2PAgent) 28 if fn.Identity != "" { 29 newAgent.identity = fn.Identity 30 ok = true 31 } 32 33 var revocation *SelfRevocation 34 if fn.Revocation != "" { 35 err = newAgent.GenKeys(nil) 36 if err != nil { 37 return 38 } 39 revocation, err = NewSelfRevocation(h.agent.PrivKey(), newAgent.PrivKey(), []byte(fn.Revocation)) 40 if err != nil { 41 return 42 } 43 ok = true 44 } 45 if !ok { 46 err = errors.New("expecting identity and/or revocation option") 47 } else { 48 49 //TODO: synchronize this, what happens if two new agent request come in back to back? 50 h.agent = &newAgent 51 // add a new agent entry and update 52 var agentHash Hash 53 _, agentHash, err = h.AddAgentEntry(revocation) 54 if err != nil { 55 return 56 } 57 h.agentTopHash = agentHash 58 59 // if there was a revocation put the new key to the DHT and then reset the node ID data 60 // TODO make sure this doesn't introduce race conditions in the DHT between new and old identity #284 61 if revocation != nil { 62 err = h.dht.putKey(&newAgent) 63 if err != nil { 64 return 65 } 66 67 // send the modification request for the old key 68 var oldKey, newKey Hash 69 oldPeer := h.nodeID 70 oldKey, err = NewHash(h.nodeIDStr) 71 if err != nil { 72 panic(err) 73 } 74 75 h.nodeID, h.nodeIDStr, err = h.agent.NodeID() 76 if err != nil { 77 return 78 } 79 80 newKey, err = NewHash(h.nodeIDStr) 81 if err != nil { 82 panic(err) 83 } 84 85 // close the old node and add the new node 86 // TODO currently ignoring the error from node.Close() is this OK? 87 h.node.Close() 88 h.createNode() 89 90 h.dht.Change(oldKey, MOD_REQUEST, HoldReq{RelatedHash: oldKey, EntryHash: newKey}) 91 92 warrant, _ := NewSelfRevocationWarrant(revocation) 93 var data []byte 94 data, err = warrant.Encode() 95 if err != nil { 96 return 97 } 98 99 // TODO, this isn't really a DHT send, but a management send, so the key is bogus. have to work this out... 100 h.dht.Change(oldKey, LISTADD_REQUEST, 101 ListAddReq{ 102 ListType: BlockedList, 103 Peers: []string{peer.IDB58Encode(oldPeer)}, 104 WarrantType: SelfRevocationType, 105 Warrant: data, 106 }) 107 108 } 109 110 response = agentHash 111 } 112 return 113 }