<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: criss.dev</title>
    <description>The latest articles on DEV Community by criss.dev (@cerbivore).</description>
    <link>https://dev.to/cerbivore</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F252484%2Fdcb38fdb-20fb-47ae-b263-ae6b0a90222e.jpg</url>
      <title>DEV Community: criss.dev</title>
      <link>https://dev.to/cerbivore</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cerbivore"/>
    <language>en</language>
    <item>
      <title>Build your first blockchain from scratch (#3 Finding the longest chain)</title>
      <dc:creator>criss.dev</dc:creator>
      <pubDate>Thu, 31 Oct 2019 09:46:11 +0000</pubDate>
      <link>https://dev.to/cerbivore/building-your-first-blockchain-from-scratch-3-finding-the-longest-branch-glp</link>
      <guid>https://dev.to/cerbivore/building-your-first-blockchain-from-scratch-3-finding-the-longest-branch-glp</guid>
      <description>&lt;p&gt;In the previous articles (&lt;a href="https://dev.to/cerbivore/build-your-first-blockchain-from-scratch-463p"&gt;Probabilistic Finality&lt;/a&gt;, &lt;a href="https://dev.to/cerbivore/build-your-first-blockchain-from-scratch-2-dag-4f8k"&gt;DAG&lt;/a&gt;) we looked into how Probabilistic Finality works and how DAGs can help to find the longest chain.&lt;/p&gt;

&lt;p&gt;Today we are going have a look at implementing a basic DAG in &lt;a href="https://crystal-lang.org"&gt;Crystal&lt;/a&gt;. We will focus on implementing a &lt;code&gt;DAG::Vertex&lt;/code&gt; class and finding the &lt;em&gt;vertex&lt;/em&gt; with the longest distance from a given starting vertex.&lt;br&gt;
Each vertex will have a unique name and a &lt;a href="https://crystal-lang.org/api/0.31.1/Hash.html"&gt;Hash&lt;/a&gt; to represent its edges pointing to its children. &lt;/p&gt;

&lt;p&gt;Here is the complete finished implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;DAG&lt;/span&gt;
  &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="no"&gt;Tip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;vertex&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;distance&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Int32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;branch_root&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Vertex&lt;/span&gt;
    &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;Name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;

    &lt;span class="n"&gt;getter&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Name&lt;/span&gt;
    &lt;span class="n"&gt;getter&lt;/span&gt; &lt;span class="n"&gt;edges&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@edges&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="no"&gt;Name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;edge_to&lt;/span&gt; &lt;span class="n"&gt;vertex&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Nil&lt;/span&gt;
      &lt;span class="vi"&gt;@edges&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vertex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vertex&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;children&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@edges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="kp"&gt;extend&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;tips&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;vertex&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;visited&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;distance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Int32&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;tips&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Tip&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;current_branch_root&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Tip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# remember the starting vertex&lt;/span&gt;
    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vertex&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;distance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;empty?&lt;/span&gt;

    &lt;span class="c1"&gt;# mark current vertex as visited&lt;/span&gt;
    &lt;span class="n"&gt;visited&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vertex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;

    &lt;span class="c1"&gt;# sort children just to make it easier to test&lt;/span&gt;
    &lt;span class="n"&gt;sorted_children&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vertex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;children&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort_by&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;# if it has no children it's the tip of a branch&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;sorted_children&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]?&lt;/span&gt;
      &lt;span class="n"&gt;tips&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Tip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="ss"&gt;vertex: &lt;/span&gt;&lt;span class="n"&gt;vertex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;distance: &lt;/span&gt;&lt;span class="n"&gt;distance&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vertex&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="ss"&gt;branch_root: &lt;/span&gt;&lt;span class="n"&gt;current_branch_root&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="c1"&gt;# it has children so let's continue the traverse&lt;/span&gt;
      &lt;span class="n"&gt;sorted_children&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;visited&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
          &lt;span class="c1"&gt;# we mark the child of the starting vertex as the current root&lt;/span&gt;
          &lt;span class="c1"&gt;# of the branch we are exploring&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;vertex&lt;/span&gt;
            &lt;span class="n"&gt;current_branch_root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;child&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;
          &lt;span class="c1"&gt;# we calculate the distance of the child&lt;/span&gt;
          &lt;span class="n"&gt;distance&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;distance&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vertex&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

          &lt;span class="n"&gt;tips&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="ss"&gt;from: &lt;/span&gt;&lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="ss"&gt;visited: &lt;/span&gt;&lt;span class="n"&gt;visited&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="ss"&gt;distance: &lt;/span&gt;&lt;span class="n"&gt;distance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="ss"&gt;tips: &lt;/span&gt;&lt;span class="n"&gt;tips&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="ss"&gt;start: &lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="ss"&gt;current_branch_root: &lt;/span&gt;&lt;span class="n"&gt;current_branch_root&lt;/span&gt;
          &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;tips&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;tip_of_longest_branch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;vertex&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Tip&lt;/span&gt;
    &lt;span class="n"&gt;tips&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tips&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;from: &lt;/span&gt;&lt;span class="n"&gt;vertex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;tip_of_longest_branch&lt;/span&gt; &lt;span class="ss"&gt;from: &lt;/span&gt;&lt;span class="n"&gt;tips&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;tip_of_longest_branch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;tips&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Tip&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Tip&lt;/span&gt;
    &lt;span class="c1"&gt;# Tip of longest branch (chain)&lt;/span&gt;
    &lt;span class="n"&gt;tips&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max_by&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;distance&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's break the code apart to understand how it works.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. DAG::Vertex Class&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;DAG&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Vertex&lt;/span&gt;
    &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="no"&gt;Name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;

    &lt;span class="n"&gt;getter&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Name&lt;/span&gt;
    &lt;span class="n"&gt;getter&lt;/span&gt; &lt;span class="n"&gt;edges&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@edges&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="no"&gt;Name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;edge_to&lt;/span&gt; &lt;span class="n"&gt;vertex&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Void&lt;/span&gt;
      &lt;span class="vi"&gt;@edges&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vertex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vertex&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;children&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@edges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should be straight forward. We build a class &lt;code&gt;Vertex&lt;/code&gt; and pass along the &lt;code&gt;Name&lt;/code&gt; when we initialize it. Afterwards we create its edges:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;v1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;v2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"B"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt; &lt;span class="ss"&gt;edge_to: &lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;

&lt;span class="n"&gt;pp&lt;/span&gt; &lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt; &lt;span class="c1"&gt;#=&amp;gt; "A"&lt;/span&gt;
&lt;span class="n"&gt;pp&lt;/span&gt; &lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;children&lt;/span&gt; &lt;span class="c1"&gt;#=&amp;gt; [#&amp;lt;DAG::Vertex:0x7f0f4866ee60 @edges={}, @name="B"&amp;gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# same as&lt;/span&gt;
&lt;span class="n"&gt;pp&lt;/span&gt; &lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt; &lt;span class="c1"&gt;#=&amp;gt; [#&amp;lt;DAG::Vertex:0x7f0f4866ee60 @edges={}, @name="B"&amp;gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can play with the code &lt;a href="https://play.crystal-lang.org/#/r/7wq4/edit"&gt;here&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Distances and the Tips of branches&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;DAG&lt;/span&gt;

  &lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="kp"&gt;extend&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;tips&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;vertex&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;visited&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;distance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Int32&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;tips&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Tip&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;current_branch_root&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Tip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# remember the starting vertex&lt;/span&gt;
    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vertex&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;distance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;empty?&lt;/span&gt;

    &lt;span class="c1"&gt;# mark current vertex as visited&lt;/span&gt;
    &lt;span class="n"&gt;visited&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vertex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;

    &lt;span class="c1"&gt;# sort children just to make it easier to test&lt;/span&gt;
    &lt;span class="n"&gt;sorted_children&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vertex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;children&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort_by&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;# if it has no children it's the tip of a branch&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;sorted_children&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]?&lt;/span&gt;
      &lt;span class="n"&gt;tips&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Tip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="ss"&gt;vertex: &lt;/span&gt;&lt;span class="n"&gt;vertex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;distance: &lt;/span&gt;&lt;span class="n"&gt;distance&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vertex&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="ss"&gt;branch_root: &lt;/span&gt;&lt;span class="n"&gt;current_branch_root&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="c1"&gt;# it has children so let's continue the traverse&lt;/span&gt;
      &lt;span class="n"&gt;sorted_children&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;visited&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
          &lt;span class="c1"&gt;# we mark the child of the starting vertex as the current root&lt;/span&gt;
          &lt;span class="c1"&gt;# of the branch we are exploring&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;vertex&lt;/span&gt;
            &lt;span class="n"&gt;current_branch_root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;child&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;
          &lt;span class="c1"&gt;# we calculate the distance of the child&lt;/span&gt;
          &lt;span class="n"&gt;distance&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;distance&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vertex&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

          &lt;span class="n"&gt;tips&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="ss"&gt;from: &lt;/span&gt;&lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="ss"&gt;visited: &lt;/span&gt;&lt;span class="n"&gt;visited&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="ss"&gt;distance: &lt;/span&gt;&lt;span class="n"&gt;distance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="ss"&gt;tips: &lt;/span&gt;&lt;span class="n"&gt;tips&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="ss"&gt;start: &lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="ss"&gt;current_branch_root: &lt;/span&gt;&lt;span class="n"&gt;current_branch_root&lt;/span&gt;
          &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;tips&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To find out the distances starting from say block &lt;code&gt;B1&lt;/code&gt; to &lt;code&gt;Bn&lt;/code&gt; we use depth first search (DFS), that explores each branch to the end and than moves on to the next one. If you think you need to better understand DFS you should watch &lt;a href="https://www.youtube.com/watch?v=7fujbpJ0LB4"&gt;this video&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;tips&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;vertex&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;visited&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Bool&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;distance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Int32&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;tips&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Tip&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;current_branch_root&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Tip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;tips&lt;/code&gt; method is a recursive method that initially only needs the &lt;code&gt;from vertex&lt;/code&gt; parameter and all other parameters are passed along with each step.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;visited&lt;/code&gt; is an empty hash, which has been initialized with a default value of &lt;code&gt;false&lt;/code&gt; for each key that is unknown.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;distance&lt;/code&gt; contains a &lt;code&gt;Hash&lt;/code&gt; of &lt;code&gt;DAG::Vertex&lt;/code&gt; with its value being the distance from the first block passed as &lt;code&gt;from vertex&lt;/code&gt; parameter&lt;/p&gt;

&lt;p&gt;&lt;code&gt;tips&lt;/code&gt; contains an &lt;code&gt;Array&lt;/code&gt; of &lt;code&gt;DAG::Tip&lt;/code&gt; which is a &lt;a href="https://crystal-lang.org/api/0.31.1/Struct.html"&gt;Struct&lt;/a&gt; defined using the &lt;a href="https://crystal-lang.org/api/0.31.1/toplevel.html#record(name,*properties)-macro"&gt;record&lt;/a&gt; macro&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;DAG&lt;/span&gt;
  &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="no"&gt;Tip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;vertex&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;distance&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Int32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;branch_root&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;Nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will examine the missing &lt;code&gt;start&lt;/code&gt; and &lt;code&gt;current_branch_root&lt;/code&gt; parameters later. First let's refresh our memory with an example of a DAG:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ue8tLnTY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/t7978sl3fhuv71otn4w0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ue8tLnTY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/t7978sl3fhuv71otn4w0.png" alt="Alt Text" width="819" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we pass block &lt;code&gt;3000.1&lt;/code&gt; as &lt;code&gt;from vertex&lt;/code&gt; we should receive an Array of &lt;code&gt;[ 3001.2, 3004.2, 3005.1 ]&lt;/code&gt; as the &lt;code&gt;tips&lt;/code&gt; of this DAG.&lt;/p&gt;

&lt;p&gt;Let's step into the method now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;    &lt;span class="o"&gt;...&lt;/span&gt;

    &lt;span class="c1"&gt;# remember the starting vertex&lt;/span&gt;
    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vertex&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;distance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;empty?&lt;/span&gt;

    &lt;span class="c1"&gt;# mark current vertex as visited&lt;/span&gt;
    &lt;span class="n"&gt;visited&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vertex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;

    &lt;span class="c1"&gt;# sort children just to make it easier to test&lt;/span&gt;
    &lt;span class="n"&gt;sorted_children&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vertex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;children&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort_by&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;start&lt;/code&gt; is set to the first vertex that we actually passed to the method and it's not altered afterwards as &lt;code&gt;distance&lt;/code&gt; will never be empty once we move on to the next step of the traverse.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;visited&lt;/code&gt; is marking the vertex as visited and this is repeated each step&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sorted_children&lt;/code&gt; is only set for convenience&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;    &lt;span class="c1"&gt;# if it has no children it's the tip of a branch&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;sorted_children&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;empty?&lt;/span&gt;
      &lt;span class="n"&gt;tips&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Tip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="ss"&gt;vertex: &lt;/span&gt;&lt;span class="n"&gt;vertex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;distance: &lt;/span&gt;&lt;span class="n"&gt;distance&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vertex&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="ss"&gt;branch_root: &lt;/span&gt;&lt;span class="n"&gt;current_branch_root&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="c1"&gt;# it has children so let's continue the traverse&lt;/span&gt;
      &lt;span class="n"&gt;sorted_children&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;visited&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
          &lt;span class="c1"&gt;# we mark the child of the starting vertex as the current root&lt;/span&gt;
          &lt;span class="c1"&gt;# of the branch we are exploring&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;vertex&lt;/span&gt;
            &lt;span class="n"&gt;current_branch_root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;child&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;
          &lt;span class="c1"&gt;# we calculate the distance of the child&lt;/span&gt;
          &lt;span class="n"&gt;distance&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;distance&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vertex&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

          &lt;span class="n"&gt;tips&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="ss"&gt;from: &lt;/span&gt;&lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="ss"&gt;visited: &lt;/span&gt;&lt;span class="n"&gt;visited&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="ss"&gt;distance: &lt;/span&gt;&lt;span class="n"&gt;distance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="ss"&gt;tips: &lt;/span&gt;&lt;span class="n"&gt;tips&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="ss"&gt;start: &lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="ss"&gt;current_branch_root: &lt;/span&gt;&lt;span class="n"&gt;current_branch_root&lt;/span&gt;
          &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;sorted_children.empty?&lt;/code&gt; if this returns true it means we are at the end of a branch. So it's a &lt;code&gt;DAG::Tip&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;if !visited[child.name]&lt;/code&gt; otherwise we continue traversing unvisited children.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;vertex&lt;/span&gt;
  &lt;span class="n"&gt;current_branch_root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;child&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember the DAG example above? You have to imagine that once the traverse reaches a tip it steps back until the the branch splits off again and starts traversing unvisited vertices. If we start from &lt;code&gt;3000.1&lt;/code&gt; all possible &lt;code&gt;current_branch_roots&lt;/code&gt; are &lt;code&gt;3001.1&lt;/code&gt; and &lt;code&gt;3001.2&lt;/code&gt;. We will need this later on to determine which is the branch root of the longest chain.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;distance[child] = distance[vertex] + 1&lt;/code&gt; now we calculate the distance and in the next step call &lt;code&gt;tips&lt;/code&gt; again to make another step.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;tip_of_longest_branch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;vertex&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Tip&lt;/span&gt;
    &lt;span class="n"&gt;tips&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tips&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;from: &lt;/span&gt;&lt;span class="n"&gt;vertex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;tip_of_longest_branch&lt;/span&gt; &lt;span class="ss"&gt;from: &lt;/span&gt;&lt;span class="n"&gt;tips&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;tip_of_longest_branch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;tips&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Tip&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Tip&lt;/span&gt;
    &lt;span class="c1"&gt;# Tip of longest branch (chain)&lt;/span&gt;
    &lt;span class="n"&gt;tips&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max_by&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;distance&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;tips.max_by { |t| t.distance }&lt;/code&gt; to find the tip of the longest branch and its branch root we filter for the one with the highest distance value.&lt;br&gt;
If there are multiple vertices with the same distance we don't really care which one we pick. Why this is not important will become apparent later in the series.&lt;/p&gt;

&lt;p&gt;Now let's give it a try:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;v1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;v2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"B"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;v3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"C"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;v4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Vertex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"D"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt; &lt;span class="ss"&gt;edge_to: &lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;
&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt; &lt;span class="ss"&gt;edge_to: &lt;/span&gt;&lt;span class="n"&gt;v3&lt;/span&gt;
&lt;span class="n"&gt;v3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt; &lt;span class="ss"&gt;edge_to: &lt;/span&gt;&lt;span class="n"&gt;v4&lt;/span&gt;

&lt;span class="n"&gt;pp&lt;/span&gt; &lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tips&lt;/span&gt; &lt;span class="ss"&gt;from: &lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;
&lt;span class="c1"&gt;#[DAG::Tip(&lt;/span&gt;
&lt;span class="c1"&gt;#  @branch_root=&lt;/span&gt;
&lt;span class="c1"&gt;#   #&amp;lt;DAG::Vertex:0x7fce8d002e60&lt;/span&gt;
&lt;span class="c1"&gt;#    @edges=&lt;/span&gt;
&lt;span class="c1"&gt;#     {"C" =&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;#       #&amp;lt;DAG::Vertex:0x7fce8d002e40&lt;/span&gt;
&lt;span class="c1"&gt;#        @edges={"D" =&amp;gt; #&amp;lt;DAG::Vertex:0x7fce8d002e20 @edges={}, #@name="D"&amp;gt;},&lt;/span&gt;
&lt;span class="c1"&gt;#        @name="C"&amp;gt;},&lt;/span&gt;
&lt;span class="c1"&gt;#    @name="B"&amp;gt;,&lt;/span&gt;
&lt;span class="c1"&gt;#  @distance=3,&lt;/span&gt;
&lt;span class="c1"&gt;#  @vertex=#&amp;lt;DAG::Vertex:0x7fce8d002e20 @edges={}, @name="D"&amp;gt;)]&lt;/span&gt;


&lt;span class="n"&gt;pp&lt;/span&gt; &lt;span class="no"&gt;DAG&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tip_of_longest_branch&lt;/span&gt; &lt;span class="ss"&gt;from: &lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;
&lt;span class="c1"&gt;# @vertex=#&amp;lt;DAG::Vertex:0x7f3acc219e20 @edges={}, @name="D"&amp;gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can try it out yourself &lt;a href="https://play.crystal-lang.org/#/r/810j/edit"&gt;here&lt;/a&gt; and create more complex structures resembling real life scenarios. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Conclusion&lt;/strong&gt;&lt;br&gt;
We found an easy way to create a DAG and using a simple depth first search we were able to find the tip of the longest chain.&lt;/p&gt;

&lt;p&gt;Integrating the code into a working blockchain will require some more work, but we'll get to that later on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Cocol Project&lt;/strong&gt;&lt;br&gt;
The &lt;a href="https://github.com/cocol-project"&gt;Cocol Project&lt;/a&gt; is an effort to implement a basic, but fully working, blockchain in Crystal — a "Minimum Viable Blockchain"&lt;/p&gt;

&lt;p&gt;The code we talked about in this article is part of the &lt;a href="https://gitbub.com/cocol-project/probfin"&gt;ProbFin&lt;/a&gt; shard. Here is the &lt;a href="https://github.com/cocol-project/probfin/blob/master/src/dag.cr"&gt;DAG implementation&lt;/a&gt; and the &lt;a href="https://github.com/cocol-project/probfin/blob/master/spec/dag_spec.cr"&gt;tests&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>crystal</category>
      <category>cocol</category>
      <category>finality</category>
    </item>
    <item>
      <title>Build your first blockchain from scratch (#2 DAG) </title>
      <dc:creator>criss.dev</dc:creator>
      <pubDate>Tue, 22 Oct 2019 14:52:19 +0000</pubDate>
      <link>https://dev.to/cerbivore/build-your-first-blockchain-from-scratch-2-dag-4f8k</link>
      <guid>https://dev.to/cerbivore/build-your-first-blockchain-from-scratch-2-dag-4f8k</guid>
      <description>&lt;h2&gt;
  
  
  How to use a DAG to find the longest chain
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://dev.to/cerbivore/build-your-first-blockchain-from-scratch-463p"&gt;first part #1&lt;/a&gt; we talked about how probabilistic finality works and why it's needed. Also we saw an example of how blocks might be structured and linked to each other:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GUpNnNOW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/bfimp8gtxgbiyc5pb480.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GUpNnNOW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/bfimp8gtxgbiyc5pb480.png" alt="Alt Text" width="779" height="167"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The data structure above resembles a Directed Acyclic Graph (DAG) and fortunately DAGs allow for an easy way to find the longest chain. This is an important part of achieving probabilistic finality.&lt;/p&gt;

&lt;p&gt;A DAG is made up of nodes (also called vertices) and edges. An edge represents a link between 2 vertices (e.g. &lt;code&gt;3000.1-&amp;gt;3001.1&lt;/code&gt;). We can and should traverse a DAG to find out more about its structure, like how far away is vertex &lt;code&gt;3005.1&lt;/code&gt; from vertex &lt;code&gt;3000.1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Additionally a DAG has some unique properties. Find out more about it &lt;a href="https://www.youtube.com/watch?v=TXkDpqjDMHA"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. How to find the longest chain&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If we look again at the example above, it becomes apparent that &lt;code&gt;3005.1&lt;/code&gt; is the tip of the longest chain. But how can we find it out programmatically?&lt;/p&gt;

&lt;p&gt;We are going to use &lt;a href="https://www.youtube.com/watch?v=7fujbpJ0LB4"&gt;Depth First Search&lt;/a&gt; to traverse the graph and mark every vertex with its distance from the starting vertex.&lt;br&gt;
We start at &lt;code&gt;3000.1&lt;/code&gt; and give it a distance of &lt;code&gt;0&lt;/code&gt;. Now we traverse through all vertices and give each a distance of &lt;code&gt;parent distance + 1&lt;/code&gt;. So &lt;code&gt;3001.1&lt;/code&gt; has a &lt;code&gt;parent distance&lt;/code&gt; of &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;+1&lt;/code&gt; gives a distance of &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hhYx2tpy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/qexgjvm9yv8ko8cwv6y2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hhYx2tpy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/qexgjvm9yv8ko8cwv6y2.png" alt="Alt Text" width="819" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If we store blocks as a DAG, we can use Depth First Search to find the longest chain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Next Up&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We will finally make our hands dirty and implement a DAG in &lt;a href="https://crystal-lang.org"&gt;Crystal&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;UPDATE: &lt;a href="https://dev.to/cerbivore/building-your-first-blockchain-from-scratch-3-finding-the-longest-branch-glp"&gt;#3 Finding the longest chain&lt;/a&gt; implementation&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>dag</category>
      <category>crystal</category>
      <category>cocol</category>
    </item>
    <item>
      <title>Build your first blockchain from scratch (#1 Probabilistic Finality)</title>
      <dc:creator>criss.dev</dc:creator>
      <pubDate>Fri, 18 Oct 2019 10:01:01 +0000</pubDate>
      <link>https://dev.to/cerbivore/build-your-first-blockchain-from-scratch-463p</link>
      <guid>https://dev.to/cerbivore/build-your-first-blockchain-from-scratch-463p</guid>
      <description>&lt;h3&gt;
  
  
  This is the first part in a series that will teach you how to build a full featured blockchain from scratch.
&lt;/h3&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I won't be able to cover all aspects in detail, neither is it intended. You should rather make yourself familiar with the high level concept of how a blockchain works. As kind of a reference point you should be familiar with Andreas Antonopoulos' book &lt;a href="https://github.com/bitcoinbook/bitcoinbook"&gt;Mastering Bitcoin&lt;/a&gt;, which if needed covers quite some detail.&lt;/p&gt;

&lt;p&gt;Understanding how e.g. Bitcoin works doesn't necessarily give you the insight on how to actually build your own blockchain. So I will try to focus during the series solely on the aspects of engineering and will reference to videos, blog articles or to &lt;code&gt;Mastering Bitcoin&lt;/code&gt; when it might be of help.&lt;/p&gt;

&lt;p&gt;Think of the series as a walkthrough. You can follow along and end up with your own blockchain, but you need to do your homework to fully grasp the non-technical side of blockchain.&lt;/p&gt;

&lt;p&gt;Let's start with one of the hardest parts of blockchain: Probabilistic Finality. It's at the core of the consensus mechanism and depends on multiple concepts that come together to achieve probabilistic finality.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Probabilistic Finality
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Finality&lt;/em&gt; is the agreement that a valid transaction between &lt;em&gt;A&lt;/em&gt; and &lt;em&gt;B&lt;/em&gt; has been executed and can't be reverted. If &lt;em&gt;A&lt;/em&gt; uses a Visa card to buy coffee from &lt;em&gt;B&lt;/em&gt;, &lt;em&gt;B&lt;/em&gt; trusts its bank that the agreement the bank made with Visa will ensure a finalized transaction.&lt;/p&gt;

&lt;p&gt;In a decentralized network the trust is given to the majority of the participants (nodes in our case) and we find out what is considered finalized by looking at how the majority sees the state of the transaction.&lt;/p&gt;

&lt;p&gt;Learn more about it here: &lt;a href="https://blog.ethereum.org/2016/05/09/on-settlement-finality/"&gt;On Settlement Finality&lt;/a&gt;, &lt;a href="https://www.youtube.com/watch?v=efyiPhZvqOA"&gt;Finality in Blockchain Consensus [video]&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So how do we "implement finality" in our blockchain?&lt;/p&gt;

&lt;p&gt;Imagine you are a &lt;em&gt;node&lt;/em&gt; within our blockchain network. Your node is maintaining a copy of the blockchain data and at the moment it's waiting for the next block to be propagated. Current block is &lt;code&gt;#3000&lt;/code&gt; and &lt;code&gt;#3001&lt;/code&gt; should arrive soon. But because there are multiple miners there is a chance you will receive 2 versions of &lt;code&gt;#3001&lt;/code&gt;. Which one to choose?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--s54IEC4B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/0hobbj89lkrwdy7gaeua.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--s54IEC4B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/0hobbj89lkrwdy7gaeua.png" alt="Alt Text" width="683" height="167"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The example above shows how the current tip of the blockchain could look like after we received 2 versions of block &lt;code&gt;#3001&lt;/code&gt;. In the end we don't choose any of the propagated &lt;code&gt;#3001&lt;/code&gt; blocks, but wait for several more consecutive blocks to make a decision.&lt;/p&gt;

&lt;p&gt;To understand why waiting makes sense we also need to understand &lt;em&gt;Proof of Work&lt;/em&gt; (PoW).&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Proof of Work (PoW)
&lt;/h2&gt;

&lt;p&gt;PoW is the algorithm that makes mining possible. It is usually explained by what&lt;br&gt;
 it does:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In the simplest terms, mining is the process of hashing the block header repeatedly, changing one parameter, until the resulting hash matches a specific target. The hash function’s result cannot be determined in advance, nor can a pattern be created that will produce a specific hash value.&lt;br&gt;
(from Mastering Bitcoin)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But more than by what it does, we need to understand what it's used for. The game theoretic aspect is one of its use cases, that we will cover later. It is important for finality, but not so much for the engineering part.&lt;/p&gt;

&lt;p&gt;PoW is also used for &lt;em&gt;randomness&lt;/em&gt; and we are very much interested in that part, so that we can implement finality.&lt;/p&gt;

&lt;p&gt;Imagine 3 miners embark on the mission to mine the next block. All 3 look for a different solution, since the block header they constructed is unique and because of that the time it takes to mine is more or less random.&lt;/p&gt;

&lt;p&gt;Another way to think about mining is by imagining a race, where each participant has a different predetermined, but unknown, finish line. Thus the time it takes to reach the finish line is unpredictable and random.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.1 Randomness
&lt;/h3&gt;

&lt;p&gt;Let's find out what would happen if we build a blockchain without PoW. If every node in the network would have the ability to create a block instantly, it would look like in the example below&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ru1tIBGH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2f330n5qeruall6jk3d6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ru1tIBGH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/2f330n5qeruall6jk3d6.png" alt="Alt Text" width="716" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Multiple miners will create a block at the same time and broadcast it to the network. It would be impossible to reach consensus, if for each round &lt;code&gt;T&lt;/code&gt; all blocks of &lt;code&gt;Tn&lt;/code&gt; would be propagated at the same time.&lt;/p&gt;

&lt;p&gt;It can still happen that different miners find the next block at the same time (see example below), but at some point the chances that &lt;em&gt;only one&lt;/em&gt; miner will find the next block are very high (because of the randomness in PoW) and as a consequence we can consider the chain of &lt;code&gt;B1.1-&amp;gt; B2.1-&amp;gt;B3.1-&amp;gt;B4.1-&amp;gt;B5.1&lt;/code&gt; as the longest one. Also we can decide to finalize block &lt;code&gt;B2.1&lt;/code&gt; if we want.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZLI1qzyn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/macwc1kyewgfb5cl5n05.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZLI1qzyn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/macwc1kyewgfb5cl5n05.png" alt="Alt Text" width="768" height="222"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: Block 4.2 has been abandoned mid-mining because it just wasn't fast enough. So there is no reason to waste more energy on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Conclusion
&lt;/h2&gt;

&lt;p&gt;In order to reach probabilistic finality we need to make our nodes agree on the longest chain and the mechanism that enables this is PoW. There is much more to PoW, but for now we don't need to cover that.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Next Up
&lt;/h2&gt;

&lt;p&gt;In the next article will find out how a Directed Acyclic Graph works and why we need it to find the longest chain.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>cocol</category>
      <category>crystal</category>
      <category>finality</category>
    </item>
  </channel>
</rss>
