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