예제 #1
0
파일: thread.go 프로젝트: utamaro/core
func (t *Thread) updateLink(n *merkledag.Node, stamp time.Time) func(bool, *merkledag.Node) (bool, error) {
	return func(exist bool, prev *merkledag.Node) (bool, error) {
		if exist {
			return false, nil
		}
		pren, err := getLinkName(prev)
		if log.If(err) {
			return false, err
		}
		if pren != nil {
			log.Println(pren.stamp)
			pn := pren.string()
			raw, errr := prev.GetNodeLink(pn)
			if log.If(errr) {
				return false, errr
			}
			if errr := n.AddRawLink(pn, raw); log.If(errr) {
				return false, errr
			}
			if errr := prev.RemoveNodeLink(pn); log.If(errr) {
				return false, errr
			}
		}
		name := &linkName{stamp: stamp}
		log.Println(name.stamp)

		if err := prev.AddNodeLink(name.string(), n); log.If(err) {
			return false, err
		}
		log.If(err)
		return true, err
	}
}
예제 #2
0
파일: init_repo.go 프로젝트: utamaro/core
func doInit(out io.Writer, repoRoot string, force bool, empty bool, nBitsForKeypair int) error {
	log.Println("initializing ipfs node at ", repoRoot)

	if err := checkWriteable(repoRoot); err != nil {
		return err
	}

	if fsrepo.IsInitialized(repoRoot) && !force {
		log.Println("repo already exists")
		return nil
	}

	conf, err := config.Init(out, nBitsForKeypair)
	if err != nil {
		return err
	}

	if fsrepo.IsInitialized(repoRoot) {
		if err := fsrepo.Remove(repoRoot); err != nil {
			return err
		}
	}

	if err := fsrepo.Init(repoRoot, conf); err != nil {
		return err
	}

	if !empty {
		if err := addDefaultAssets(out, repoRoot); err != nil {
			return err
		}
	}

	return initializeIpnsKeyspace(repoRoot)
}
예제 #3
0
파일: thread.go 프로젝트: utamaro/core
//Slice returns sorted records slice.
//if insufficient number it returns atmost records slice.
func (t *Thread) Slice(from, to int, spam slice.Key) (record.Records, error) {
	sl := make(record.Records, 0, to-from)
	troot, err := t.self.GetDAGNode(t.root)
	log.Println(t.root)
	if log.If(err) {
		return nil, err
	}
	root, err := t.next(troot)
	if log.If(err) {
		return nil, err
	}
	for i := 0; root != nil && i < to; i++ {
		kkk, _ := root.Key()
		if spam != nil {
			if _, exist := spam[kkk]; exist {
				log.Println(kkk, "is regarded as spam")
				i--
				continue
			}
		}
		if i >= from {
			r, errr := t.toRecord(root)
			if log.If(errr) {
				return nil, errr
			}
			sl = append(sl, r)
		}
		root, err = t.next(root)
		if log.If(err) {
			return nil, err
		}
	}
	return sl, nil
}
예제 #4
0
파일: thread.go 프로젝트: utamaro/core
//Add adds record r and return true is thread was changed.
func (t *Thread) Add(r *record.Record) (bool, error) {
	if t.name != r.Thread {
		err := errors.New("thread name unmatch")
		log.Println(err)
		return false, err
	}
	rn, err := t.self.GetDAGNode(r.Key)
	if log.If(err) {
		return false, err
	}
	n := &merkledag.Node{}
	if err := n.AddNodeLink("contents", rn); log.If(err) {
		return false, err
	}
	nsign := &merkledag.Node{Data: r.Sign}
	if err := n.AddNodeLink("sign", nsign); log.If(err) {
		return false, err
	}
	troot, err := t.self.GetDAGNode(t.root)
	if log.If(err) {
		return false, err
	}
	troot, err = t.search(troot, r.Stamp, t.updateLink(n, r.Stamp))
	if log.If(err) {
		return false, err
	}
	log.Println(t.root)
	if troot != nil {
		t.root, err = t.self.AddDAGNode(troot, false)
	}
	log.Println(t.root)
	log.If(err)
	return troot != nil, err
}
예제 #5
0
파일: peer.go 프로젝트: utamaro/core
//nameResolve resole name hash using IPNS.
func (p *Peer) nameResolve() (key.Key, error) {
	log.Println("resolving", p.ID.Pretty())
	pt, err := p.myself.ipfsNode.Namesys.Resolve(p.myself.ctx, "/ipns/"+p.ID.Pretty())
	if log.If(err) {
		return "", err
	}
	log.Println("resolved", pt)
	seg := pt.Segments()
	return key.B58KeyDecode(seg[len(seg)-1]), nil
}
예제 #6
0
파일: thread_list.go 프로젝트: utamaro/core
//Merge merges all records in list which has key and returns true if updated .
func (l *List) Merge(tkey key.Key) (bool, error) {
	if l.key == tkey {
		log.Println("same key,nothing to do")
		return false, nil
	}
	root, err := l.self.GetDAGNode(l.key)
	if log.If(err) {
		return false, err
	}
	troot, err := l.self.GetDAGNode(tkey)
	if log.If(err) {
		return false, err
	}
	var t *Thread
	updated := false
	for _, link := range troot.Links {
		var k key.Key
		if th, errr := l.self.GetLinkedNode(root, link.Name); errr == nil {
			k, err = th.Key()
			if log.If(err) {
				return false, err
			}
		}
		t, err = New(l.self, link.Name, k)
		if log.If(err) {
			return false, err
		}
		kk := key.Key(link.Hash)
		if k == kk {
			continue
		}
		log.Println("adding to " + link.Name)
		u, errr := t.Merge(kk)
		if log.If(errr) {
			return false, err
		}
		if !u {
			continue
		}
		tn, errr := t.self.GetDAGNode(t.Key())
		if log.If(errr) {
			return false, errr
		}
		root, errr = root.UpdateNodeLink(link.Name, tn)
		if log.If(errr) {
			return false, errr
		}
		updated = true
	}
	if updated {
		l.key, err = l.self.AddDAGNode(root, false)
		log.If(err)
	}
	return updated, err
}
예제 #7
0
파일: self.go 프로젝트: utamaro/core
//NewSelf make repo if needed ,starts daemon and returns Self obj.
func NewSelf(cfg *config.Config, rootPath string) *Self {
	InitRepo(cfg.IpfsRepo)
	n := &merkledag.Node{}
	k, err := n.Key()
	log.IfFatal(err)
	//workaround "ERROR    bitswap: failed to find any peer in table"
	i := 0
	var node *core.IpfsNode
	var ctx context.Context
	var cancel context.CancelFunc
	for i = 0; i < 10; i++ {
		log.Println("setting up node...")
		r, err := fsrepo.Open(cfg.IpfsRepo)
		log.IfFatal(err)
		ctx, cancel = context.WithCancel(context.Background())
		node, err = core.NewNode(ctx, &core.BuildCfg{
			Repo:   r,
			Online: true,
		})
		log.IfFatal(err)
		if err := node.Routing.Provide(ctx, k); log.If(err) {
			cancel()
			log.If(node.Close())
			log.Println("retrying...")
			continue
		}
		break
	}
	if i == 10 {
		log.Fatal("cannot provide a key to network")
	}
	self := &Self{
		RootPath: rootPath,
		ipfsNode: node,
		ctx:      ctx,
		cancel:   cancel,
		cfg:      cfg,
	}
	self.follow = FromStringSlice(cfg.FollowPeers, self)
	parent, err := self.ToPeer().GetDAGNode("")
	if log.If(err) {
		parent = &merkledag.Node{}
	}
	self.myIpns, err = parent.Key()
	log.IfFatal(err)
	if _, err = parent.GetNodeLink(rootPath); err != nil {
		log.Println("initializing DAGs for saving status")
		self.makeInitNodes(parent)
	}
	return self
}
예제 #8
0
파일: self.go 프로젝트: utamaro/core
//StartListen starts listening and calls accept fucn if accepted.
func (m *Self) StartListen(accept func(net.Stream) error) error {
	list, err := corenet.Listen(m.ipfsNode, "/app/"+m.RootPath)
	if log.If(err) {
		return err
	}
	log.Printf("starting to listen at peer: %s\n", m.ipfsNode.Identity.Pretty())
	go func() {
		for {
			con, err := list.Accept()
			defer func() {
				log.If(con.Close())
			}()
			if log.If(err) {
				continue
			}
			peer := con.Conn().RemotePeer()
			log.Printf("Connection from: %s\n", peer)
			p, err := FromBytes([]byte(peer), m)
			if log.If(err) {
				continue
			}
			if !p.IsAllowed() {
				log.Println(p, "denifed")
				continue
			}
			log.If(accept(con))
		}
	}()
	return nil
}
예제 #9
0
파일: self.go 프로젝트: utamaro/core
//LoadInitPeers loads init peers from the setting.
func (m *Self) LoadInitPeers() Peers {
	peers := make(Peers)
	for _, p := range m.cfg.InitPeers.GetData() {
		pe, errr := New(p, m)
		log.Println("peer name", p)
		log.IfFatal(errr)
		peers.Add(pe)
	}
	log.Println("loaded init peers")
	if len(peers) == 0 {
		log.Println("Warning: no peers in init_peers.txt")
	}
	err := m.WritePeers(peers)
	log.IfFatal(err)
	return peers
}
예제 #10
0
파일: manager.go 프로젝트: utamaro/core
//New reeturns Manager obj.
func New(cfg *config.Config, rootPath string) (*Manager, error) {
	self := peer.NewSelf(cfg, rootPath)
	m := &Manager{
		self: self,
	}
	p := self.ToPeer()
	recent, err := p.ReadRecent()
	if log.If(err) {
		log.Println(err)
	}
	m.recent, err = thread.NewList(self, recent)
	m.peers, err = p.ReadPeers()
	log.If(err)
	if len(m.peers) == 0 {
		m.peers = self.LoadInitPeers()
	}
	m.tags, err = p.ReadTags()
	log.If(err)
	m.spams, err = p.ReadSpams()
	log.If(err)
	m.readThreads = self.ReadThreads()
	if err := self.StartListen(m.accept); log.If(err) {
		return nil, err
	}
	go func() {
		for {
			m.cron()
			time.Sleep(time.Hour)
		}
	}()
	return m, nil
}
예제 #11
0
파일: self.go 프로젝트: utamaro/core
//WritePeersToDAG writes peer list and returns merkledag key.
func (m *Self) WritePeersToDAG(peers Peers, kprev key.Key) (key.Key, error) {
	log.Println("writing peers prev:", kprev)
	var nodes NodesProto
	nodes.Id = make([][]byte, len(peers))
	i := 0
	for _, p := range peers {
		nodes.Id[i] = []byte(p.ID)
		i++
	}
	dat, err := proto.Marshal(&nodes)
	if log.If(err) {
		return "", err
	}
	n := &merkledag.Node{Data: dat}
	if kprev != "" {
		prev, errr := m.GetDAGNode(kprev)
		if log.If(errr) {
			return "", errr
		}
		if err = n.AddNodeLink("prev", prev); log.If(err) {
			return "", err
		}
	}
	k, err := m.AddDAGNode(n, true)
	if log.If(err) {
		return "", err
	}
	return k, nil
}
예제 #12
0
파일: self.go 프로젝트: utamaro/core
//GetDAGNode returns merkledag node.
func (m *Self) GetDAGNode(k key.Key) (*merkledag.Node, error) {
	log.Println("get dag node key", k)
	n, err := m.ipfsNode.DAG.Get(m.ctx, k)
	if log.If(err) {
		return nil, err
	}
	return n, nil
}
예제 #13
0
파일: peer.go 프로젝트: utamaro/core
func (p *Peer) readDAG(pt string, obj proto.Message) error {
	log.Println("reading DAG from", pt)
	pa := p.myself.RootPath + "/" + pt
	n, err := p.GetDAGNode(pa)
	if log.If(err) {
		return err
	}
	return proto.Unmarshal(n.Data, obj)
}
예제 #14
0
파일: record.go 프로젝트: utamaro/core
//check checks the record. i.e. check that it has valid Stamp, Thread, and valid pubKey if Signed.
func (r *Record) check(mustSigned bool) error {
	if r.Stamp.UnixNano() <= 0 || r.Stamp.After(time.Now()) {
		err := errors.New("Stamp not found")
		log.Println(err)
		return err
	}
	if r.Thread == "" {
		err := errors.New("Thread not found")
		log.Println(err)
		return err
	}
	if mustSigned && r.Sign == nil {
		err := errors.New("not Signed")
		log.Println(err)
		return err
	}
	if r.Sign == nil {
		return nil
	}
	pubKey := r.Contents["pubkey"]
	if pubKey == nil {
		err := errors.New("no pubKey")
		log.Println(err)
		return err
	}
	pk, err := crypto.UnmarshalPublicKey(pubKey)
	if log.If(err) {
		return err
	}
	ok, err := pk.Verify([]byte(r.Key), r.Sign)
	if err == nil && !ok {
		err = errors.New("Sign unmatched")
	}
	if log.If(err) {
		return err
	}
	/*	if !r.self.cfg.RegSpam.Check(r.Contents) {
			err := errors.New("regarded as spam")
			log.Println(err)
			return err
		}
	*/
	return nil
}
예제 #15
0
파일: link_name.go 프로젝트: utamaro/core
func fromString(datastr string) (*linkName, error) {
	if !strings.HasPrefix(datastr, linkNamePrefix) {
		err := errors.New("don't have fixed prefix")
		log.Println(err)
		return nil, err
	}
	data := []byte(datastr[len(linkNamePrefix):])
	if len(data) != lenName {
		err := errors.New("illegal length of data")
		log.Println(err)
		return nil, err
	}
	stamp := time.Unix(0, int64(binary.BigEndian.Uint64(data)))
	log.Println(stamp)
	l := &linkName{
		stamp: stamp,
	}
	return l, nil
}
예제 #16
0
파일: peer.go 프로젝트: utamaro/core
//GetDAGNode gets dag node from path ph.
func (p *Peer) GetDAGNode(ph string) (*merkledag.Node, error) {
	log.Println("getting dag from", ph)
	k, err := p.nameResolve()
	if log.If(err) {
		return nil, err
	}
	node, err := p.myself.GetPathNode(k, ph)
	log.If(err)
	return node, err
}
예제 #17
0
파일: manager.go 프로젝트: utamaro/core
func (m *Manager) broadcast(prev key.Key) error {
	log.Println("broadcasting...")
	m.mutex.RLock()
	defer m.mutex.RUnlock()
	const numcasts = 5
	var err error
	num := 0
	var peers peer.Peers
	for ; prev != ""; num++ {
		var p peer.Peers
		p, prev, err = m.self.ReadPeersFromDAG(prev)
		if log.If(err) {
			return err
		}
		peers.Extend(p)
	}
	var pf float32 = 1
	for i := 0; i < num; i++ {
		pf *= 0.7
	}
	pf = 0.8*pf + 0.2
	rand.Seed(time.Now().UnixNano())
	if pf < rand.Float32() {
		log.Println("Pf < rand")
		return nil
	}
	ps := m.peers.Excludes(peers, numcasts)
	pk, err := m.self.WritePeersToDAG(ps, prev)
	if log.If(err) {
		return err
	}
	for _, p := range ps {
		log.Println("broadcasting", p)
		go func(p *peer.Peer) {
			_, err = m.self.ExchangeRecent(p, m.recent.Key(), pk)
			log.If(err)
		}(p)
	}
	return nil
}
예제 #18
0
파일: record.go 프로젝트: utamaro/core
//Equals returns true if r==r2
func (r *Record) Equals(r2 *Record) bool {
	if r.Thread != r2.Thread {
		log.Println("unmatched threadname")
		return false
	}
	if bytes.Compare(r.Sign, r2.Sign) != 0 {
		log.Println("unmatched sign")
		return false
	}
	if !r.Stamp.Equal(r2.Stamp) {
		log.Println("unmatched stamp")
		return false
	}
	if r.self != r2.self {
		log.Println("unmatched self")
		return false
	}
	if len(r.Contents) != len(r2.Contents) {
		log.Println("unmatched contents length")
		return false
	}
	for k, v := range r.Contents {
		v2, exist := r2.Contents[k]
		if !exist || bytes.Compare(v, v2) != 0 {
			log.Println("unmatched contents", k)
			return false
		}
	}
	return true
}
예제 #19
0
파일: manager.go 프로젝트: utamaro/core
//AddPeer adds one peer and writes keys of peers
func (m *Manager) AddPeer(peer *peer.Peer) error {
	m.mutex.Lock()
	defer m.mutex.Unlock()
	if !peer.IsAllowed() {
		errr := errors.New("denied")
		log.Println(errr)
		return errr
	}
	if !peer.IsAllowed() || !m.peers.Add(peer) {
		return nil
	}
	return m.self.WritePeers(m.peers)
}
예제 #20
0
파일: self.go 프로젝트: utamaro/core
//AddDAGNode adds dagNode and returns key
func (m *Self) AddDAGNode(dagNode *merkledag.Node, pin bool) (key.Key, error) {
	if err := m.ipfsNode.DAG.AddRecursive(dagNode); log.If(err) {
		return "", err
	}
	k, err := dagNode.Key()
	if log.If(err) {
		return "", err
	}
	log.Println("added DAG", k.B58String())
	if pin {
		err = m.ipfsNode.Pinning.Pin(m.ctx, dagNode, true)
	}
	log.If(err)
	return k, err
}
예제 #21
0
파일: thread.go 프로젝트: utamaro/core
func (t *Thread) next(root *merkledag.Node) (*merkledag.Node, error) {
	var err error
	link, err := getLinkName(root)
	if log.If(err) {
		return nil, err
	}
	if link == nil {
		return nil, nil
	}
	log.Println(link.stamp)
	root, err = t.self.GetLinkedNode(root, link.string())
	if log.If(err) {
		return nil, err
	}
	return root, nil
}
예제 #22
0
파일: thread.go 프로젝트: utamaro/core
//Search serrches nearest and bigger than  record r.
func (t *Thread) Search(stamp time.Time) (*merkledag.Node, bool, error) {
	troot, err := t.self.GetDAGNode(t.root)
	if log.If(err) {
		return nil, false, err
	}
	var dag *merkledag.Node
	var found bool
	_, err = t.search(troot, stamp, func(exist bool, n *merkledag.Node) (bool, error) {
		log.Println("!!!")
		found = exist
		dag = n
		return false, nil
	})
	log.If(err)
	return dag, found, err
}
예제 #23
0
파일: manager.go 프로젝트: utamaro/core
//AddPeers adds peers and writes keys of peers
func (m *Manager) AddPeers(peers peer.Peers) error {
	m.mutex.Lock()
	defer m.mutex.Unlock()
	added := false
	for _, peer := range peers {
		if !peer.IsAllowed() {
			err := errors.New("denied")
			log.Println(err)
			continue
		}
		added = added || m.peers.Add(peer)
	}
	if !added {
		return nil
	}
	return m.self.WritePeers(m.peers)
}
예제 #24
0
파일: thread.go 프로젝트: utamaro/core
//New returns Thread obj.
func New(self *peer.Self, name string, root key.Key) (*Thread, error) {
	if root == "" {
		var err error
		r := merkledag.Node{}
		root, err = r.Key()
		if log.If(err) {
			return nil, err
		}
		log.Println("root key", root)
	}
	t := &Thread{
		self: self,
		name: name,
		root: root,
	}
	return t, nil
}
예제 #25
0
파일: thread.go 프로젝트: utamaro/core
//Merge adds records from merkledag key and returns true if thread was changed.
func (t *Thread) Merge(key key.Key) (bool, error) {
	from, err := t.self.GetDAGNode(key)
	if log.If(err) {
		return false, err
	}
	root, err := t.next(from)
	if log.If(err) {
		return false, err
	}
	updated := false
	for root != nil {
		r, err := t.toRecord(root)
		if log.If(err) {
			return updated, err
		}
		n, found, err := t.Search(r.Stamp)
		if log.If(err) {
			return updated, err
		}
		nk, err := n.Key()
		if log.If(err) {
			return updated, err
		}
		rk, err := root.Key()
		if log.If(err) {
			return updated, err
		}
		if nk == rk {
			return updated, nil
		}
		if !found {
			u, errr := t.Add(r)
			if log.If(errr) {
				return updated, errr
			}
			log.Println("added")
			updated = updated || u
		}
		root, err = t.next(root)
		if log.If(err) {
			return updated, err
		}
	}
	return updated, nil
}
예제 #26
0
파일: config.go 프로젝트: utamaro/core
//Load fills a struct cfg which usually embeds Config struct from the json file.
func Load(appl, p string, cfg interface{}) {
	files := []string{p, "file", "/usr/local/etc/" + appl, "/etc/" + appl}
	usr, err := user.Current()
	if err == nil {
		files = append(files, path.Join(usr.HomeDir, "."+appl))
	}
	for _, f := range files {
		if f == "" {
			continue
		}
		f = filepath.Join(f, appl+".json")
		dat, errr := ioutil.ReadFile(f)
		if errr != nil {
			continue
		}
		log.Println("loading config from", f)
		log.IfFatal(json.Unmarshal(dat, cfg))
	}
}
예제 #27
0
파일: self.go 프로젝트: utamaro/core
//ReadPeersFromDAG reads peer list from merkledag keyed k.
func (m *Self) ReadPeersFromDAG(k key.Key) (Peers, key.Key, error) {
	log.Println("reading peer DAG", k)
	var ps NodesProto
	n, err := m.GetDAGNode(k)
	if log.If(err) {
		return nil, "", err
	}
	if err := proto.Unmarshal(n.Data, &ps); log.If(err) {
		return nil, "", err
	}
	p, err := fromProto(ps, m)
	if log.If(err) {
		return nil, "", err
	}
	var prevkey key.Key
	prev, err := n.GetNodeLink("prev")
	if err == nil {
		prevkey = key.Key(prev.Hash)
	}
	return p, prevkey, nil
}
예제 #28
0
파일: self.go 프로젝트: utamaro/core
//GetPathNode searches merkledag from root key  to path recursively.
func (m *Self) GetPathNode(root key.Key, pt string) (*merkledag.Node, error) {
	var err error
	n, err := m.GetDAGNode(root)
	if log.If(err) {
		return nil, err
	}
	for _, s := range strings.Split(pt, "/") {
		if s == "" || s == "." {
			continue
		}
		n, err = n.GetLinkedNode(m.ctx, m.ipfsNode.DAG, s)
		if log.If(err) {
			return nil, err
		}
		if n == nil {
			err = errors.New("merkledag is nil")
			log.Println(err)
			return nil, err
		}
	}
	return n, nil
}
예제 #29
0
파일: talk.go 프로젝트: utamaro/core
//ReadRequest reads hash of recent ahd peers DAG from con.
func ReadRequest(con net.Stream) (key.Key, key.Key, error) {
	rdat, err := ioutil.ReadAll(con)
	if log.If(err) {
		return "", "", err
	}
	var rmsg Msg
	if err := proto.Unmarshal(rdat, &rmsg); log.If(err) {
		return "", "", err
	}
	if *rmsg.Type != Type_Recent {
		err := errors.New("undefined type")
		log.Println(err)
		return "", "", err
	}
	var r, p key.Key
	if rmsg.Recent != nil {
		r = key.Key(rmsg.Recent)
	}
	if rmsg.Peers != nil {
		p = key.Key(rmsg.Peers)
	}
	return r, p, nil
}
예제 #30
0
파일: init_repo.go 프로젝트: utamaro/core
func initializeIpnsKeyspace(repoRoot string) error {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	r, err := fsrepo.Open(repoRoot)
	if log.If(err) { // NB: repo is owned by the node
		return err
	}

	nd, err := core.NewNode(ctx, &core.BuildCfg{Repo: r})
	if log.If(err) {
		return err
	}
	defer func() {
		log.If(nd.Close())
	}()

	if err := nd.SetupOfflineRouting(); err != nil {
		log.Println(err)
		return err
	}

	return namesys.InitializeKeyspace(ctx, nd.DAG, nd.Namesys, nd.Pinning, nd.PrivateKey)
}