Example #1
0
func processTree(srv *context.T, h git.Hash, haves []git.Hash) (objs []git.Object, err error) {
	b, err := readObject(srv, h)
	if err != nil {
		return
	}
	tree := git.DecodeObject(b).(*git.Tree)
	objs = append(objs, tree)
	for i := range tree.Entries {
		entry := tree.Entries[i]
		var objects []git.Object
		b, err = readObject(srv, entry.Hash)
		if err != nil {
			return
		}
		obj := git.DecodeObject(b)
		switch obj.Type() {
		case "commit":
			objects, err = processCommit(srv, entry.Hash, haves)
		case "tree":
			objects, err = processTree(srv, entry.Hash, haves)
		case "blob":
			objects = []git.Object{obj}
		case "tag":
			objects = []git.Object{obj}
		}
		if err != nil {
			return
		}
		objs = append(objs, objects...)
	}
	return
}
Example #2
0
func processCommit(srv *context.T, want git.Hash, haves []git.Hash) (objs []git.Object, err error) {
	for i := range haves {
		if bytes.Compare(want, haves[i]) == 0 {
			return
		}
	}
	b, err := readObject(srv, want)
	if err != nil {
		return
	}
	commit := git.DecodeObject(b).(*git.Commit)
	objs = append(objs, commit)
	tree, err := processTree(srv, commit.Tree, haves)
	if err != nil {
		return
	}
	objs = append(objs, tree...)
	for i := range commit.Parents {
		var objects []git.Object
		objects, err = processCommit(srv, commit.Parents[i], haves)
		if err != nil {
			return
		}
		objs = append(objs, objects...)
	}
	return
}
Example #3
0
func (app *GitchainApp) OnDeliver(msg wendy.Message) {
	log := app.log
	var err error
	if msg.Purpose&MSG_BROADCAST != 0 {
		log.Debug("received a broadcast")
		if msg.Sender.ID == app.cluster.ID() {
			log.Error("received own broadcast", "bugtrap", "true")
		}
		var envelope broadcastEnvelope
		dec := gob.NewDecoder(bytes.NewBuffer(msg.Value))
		dec.Decode(&envelope)
		if err != nil {
			log.Error("error while decoding an incoming message", "err", err)
		} else {
			var txe *transaction.Envelope
			if msg.Purpose&MSG_TRANSACTION != 0 {
				if txe, err = transaction.DecodeEnvelope(envelope.Content); err != nil {
					log.Error("error while decoding transaction", "err", err)
				} else {
					app.srv.Router.Pub(txe, "/transaction")
					log.Debug("announced transaction locally", "txn", txe)
				}
			}
			var newLimit wendy.NodeID
			nodes := app.cluster.RoutingTableNodes()
			if len(nodes) > 1 {
				for i := range nodes[0 : len(nodes)-1] {
					var buf bytes.Buffer
					enc := gob.NewEncoder(&buf)
					if nodes[i].ID.Less(envelope.Limit) {
						if nodes[i+1].ID.Less(envelope.Limit) {
							newLimit = nodes[i+1].ID
						} else {
							newLimit = envelope.Limit
						}
						if err = enc.Encode(broadcastEnvelope{Content: envelope.Content, Limit: newLimit}); err != nil {
							return
						}
						wmsg := app.cluster.NewMessage(msg.Purpose, nodes[i].ID, buf.Bytes())
						if err = app.cluster.Send(wmsg); err != nil {
							log.Error("error sending message", "err", err)
						} else {
							log.Debug("forwarded transaction", "txn", txe)
						}
					} else {
						break
					}
				}
			}
			if nodes[len(nodes)-1].ID.Less(envelope.Limit) {
				var buf bytes.Buffer
				enc := gob.NewEncoder(&buf)
				if err = enc.Encode(broadcastEnvelope{Content: envelope.Content, Limit: app.cluster.ID()}); err != nil {
					return
				}
				wmsg := app.cluster.NewMessage(msg.Purpose, nodes[len(nodes)-1].ID, buf.Bytes())
				if err = app.cluster.Send(wmsg); err != nil {
					log.Error("error sending message", "err", err)
				} else {
					log.Debug("forwarded transaction", "txn", txe)
				}
			}

		}
	} else {
		switch {
		case msg.Purpose&MSG_OBJECT != 0:
			obj := git.DecodeObject(msg.Value)
			err = git.WriteObject(obj, path.Join(app.srv.Config.General.DataPath, "objects"))
			if err != nil {
				log.Error("error while writing object", "obj", obj, "err", err)
			}
		}
	}
}