在有 coordinator 的 Tangle 上的實驗
===
接續[前文](https://hackmd.io/s/SJ7i1QnIX) , 來說說 mainnet 的實驗要驗證什麼與如何實作
# 帳本篡改
交易是不是確認就看有沒有被 milestone 指向
milestone 有簽章
所以篡改或總 token 數目不對是簽章能不能偽造
這不是 FPGA accelerator 能做的 , 所以不考慮這實驗
# DoS 攻擊
DoS(阻絕服務攻擊) , 目前才是 mainnet 會遇到的
在討論可能的 DoS 攻擊前 , 先介紹 MCMC tip selection 的特點
## MCMC tip selection
回顧 [1.5.0 tip selection](https://hackmd.io/s/HyddgJGGX)
可以知道幾件事:
:::info
* random walk 的起點一定是 milestone
* 最終一定是選到當下 Tangle 的 tip
* random walk 每一步以 IRI 預設 , 都會受累積權重的影響
:::
這邊累積權重指的是一筆交易後面有多少交易直接或間接指向 , 所以 PoW 目前不影響 MCMC tip selection
有了上面的特性 , 可以繼續討論
根據 IF 成員的說法
milestone 也是用 MCMC 選出 trunk 與 branch
依據上面列舉的三個特性 , 那就有三種攻擊的方式
# MCMC 起點
由於 random walk 一定要從某個 milestone 當起點開始行走
所以可以在起點就用大的機率 , 讓 random walk 走到不該選的 tip
示意圖如下:
```graphviz
digraph init{
                rankdir=RL;
			 
				 a[ label="c" color=blue, fontcolor=blue, fontsize=24, shape=box];
				
				b[label="b" color=blue, fontcolor=blue, fontsize=24, shape=box];
				
				c[label="a" color=blue, fontcolor=blue, fontsize=24, shape=box]	
				           
                 e[label="e" color=orange, fontcolor=orange, fontsize=24, shape=box]	
				           
                  d[label="d" color=blue, fontcolor=blue, fontsize=24, shape=box]	 
			
            41[label="41" color=blue, fontcolor=blue, fontsize=24, shape=box]	 
          
          31[label="31" color=blue, fontcolor=blue, fontsize=24, shape=box]	
          
           42[label="42" color=orange, fontcolor=orange, fontsize=24, shape=box]	
 
          21[label="21" color=blue, fontcolor=blue, fontsize=24, shape=box]	
 
          32[label="32" color=blue, fontcolor=blue, fontsize=24, shape=box]	
 
    43[label="43" color=blue, fontcolor=blue, fontsize=24, shape=box]	
       
 33[label="33" color=blue, fontcolor=blue, fontsize=24, shape=box]	
          
 22[label="22" color=blue, fontcolor=blue, fontsize=24, shape=box]	
11[label="11" color=blue, fontcolor=blue, fontsize=24, shape=box]	
 
				a -> c;
                b -> c;  
				a -> c;
                b -> c;
                e -> a;
                e -> b;
                d -> a;
                d -> b;
                41->e;
                41->d;
                31->d;
                31->d;
              42->41;
              42->31;
              21->e;
              21->d;
              32->21;
              32->31;
              43->42;
              43->32;
              11->e;
              11->e;
              22->21;
              22->31;
              33->22;
              33->42;
              
              
              
              A1->e;
              A1->nonExist;
              A2->A1;
              A2->e;
              A3->A2;
              A3->A1;
              A4->A1;
              A4->A2;
              A5->A3;
              A5->A4;
              A6->42;
              A6->A5;
              A7->A5;
              A7->A4;
              A8->A3;
              A8->A6;
              A9->42;
              A9->A7;
              A10->A9;
              A10->A8;
              
          }
```
$A1$ 到 $A10$ , 都是 FPGA accelerator 造出來的
$\color{orange}{e}$ 和 $\color{orange}{42}$ 是 milestone
### non solid
上面示意圖就是 non solid 的例子
non solid 會讓 getTransactionsToApprove 失敗
現在來談攻擊實作上要考慮的問題
## tipset
包含到第15深的 milestone , 以及攻擊產生的 tip (上圖 $A1$ ~ $A10$)
這些 tips 是給 FPGA accelerator 使用
可能分兩組 , 一組是驗證 milestone 與攻擊的subTangle
另一組就只驗證攻擊的subTangle
特別注意 , 目前交易的累積權重是有上限的(IRI 預設 5000)
## 如何維護 milestone
由於 milestone 會不斷更新 , 所以針對某組的 milestone 會隨著時間變得攻擊沒有意義(超過第15深的milestone)
如果要做多次實驗 , 需要有個 process 不斷更新 milestone
## 在攻擊期間維護 subTangle 的 tip
跟上面維護 milestone 類似 , 不同的是維護攻擊 subTangle 的 tip
所以這 process 只會在攻擊期間運作
## 流程
1. 維護 milestone 的 process 常駐
2. 開啟 tipset 提到的兩組程式
3. 用 tangle-analytics 觀察
4. 測試攻擊期間gTTA的狀況與交易確認的情況
## 架構
架構流程圖:
```graphviz
digraph Attack_Architecture{
     
   
   attack_init->IOTA_Reference_Implementation [label = "  attack_start"];
   
     
     milestone_attacker->IOTA_Reference_Implementation [label = "  tip_request"];
     
     
     milestone_attacker->IOTA_Reference_Implementation [label = "  milestone_request"];
     
     subTangle_attacker->IOTA_Reference_Implementation [label = "   tip_request"];
     
     
     
    
     
     
     
     
     milestone_attacker->IOTA_Reference_Implementation[label=" broadcastTransaction"];
     
     subTangle_attacker->IOTA_Reference_Implementation[label="  broadcastTransaction"];
     
   
     
     
     
  
     
   
     IOTA_Reference_Implementation->subTangle_attacker[label="give_tip"];
     
     IOTA_Reference_Implementation->milestone_attacker[label="give_milestone"];
IOTA_Reference_Implementation->milestone_attacker[label="give_tip"];
    gTTA_tester->IOTA_Reference_Implementation[label="getTransactionsToApprove"];
    
    IOTA_Reference_Implementation->gTTA_tester[label="result"];
    
    
    transaction_issuer->IOTA_Reference_Implementation[label="broadcastTransaction"];
    
    confirmed_transaction_tester->IOTA_Reference_Implementation[label="Is confirmed?"];
    
    IOTA_Reference_Implementation->confirmed_transaction_tester[label="result"];
    
    
     attack_end->IOTA_Reference_Implementation [label = "  attack_end"];
    
     
  }
```
### attack_init
發一筆交易到 Mainnet , 這交易帶有攻擊開始的 message
另外這交易的 trunk 或 branch 是指向衝突交易或不存在的交易
```=java
from config import *
from tool import *
api = Iota(Node1, seed=SEED)
# nonSolid DOS attack
if attackType == "nonSolid":
    nodeInfo = api.get_node_info()
    cMilestone = nodeInfo['latestSolidSubtangleMilestone']
    rTips = {'trunkTransaction':cMilestone,'branchTransaction':nonSolidTransaction} 
    send_transfer(startMessage,"",ADDRESS,0,rTips,0)
    print("milestone:"+ str(cMilestone))
    print("startMessage:"+ str(startMessage))
    
# conflictTransaction DOS attack 
```
[執行結果](https://thetangle.org/tag/TESTDOSATTACKSTART)
### attack_end
發一筆交易到 Mainnet , 這交易帶有攻擊結束的 message
### subTangle_attacker
開始執行後 , 先不斷查詢 , 有無攻擊開始 message 的交易 
如果有攻擊開始 message 的交易 , 進入一個 while loop
while loop 依序做三件事:
1. 找出 tips , 這些 tips 直接或間接指向攻擊開始 message 的交易
2. 發交易 , 把 tips 內的 tip 都指向一次
3. 如果發現有攻擊結束 message 的交易 , 程式結束執行
#### 找 subTangle 的 tip
[getReferenceTips](https://github.com/DLTcollab/DOS-attack-with-FPGA-accelerator/blob/master/tool.py#L178)
code:
```=java
def getReferenceTips(node,currentList):
    """
    """
    tipSet = []
    while currentList != []:
        print("currentList:")
        print(currentList)
        for transactionHash in currentList:
            print("transactionHash:")
            print(transactionHash)
            checkResult = node.find_transactions(approvees=[transactionHash])
            print("checkResult:")
            print(checkResult)
            if checkResult['hashes'] == []:
                tipSet.append(transactionHash)
        currentList = node.find_transactions(approvees=currentList)['hashes']
    return tipSet
```
測試例子的[起點](https://thetangle.org/transaction/YJQZCSYJMMZXOFORITQTLHYLTJAKOWOMXOWMQULUVJ9PWBJNRIZTXNVABUTSUWNUHDTRGEGJMVRYA9999)
直接執行的結果
```
tips:
['YJQZCSYJMMZXOFORITQTLHYLTJAKOWOMXOWMQULUVJ9PWBJNRIZTXNVABUTSUWNUHDTRGEGJMVRYA9999']
```
嘗試發一筆交易 , 接到起點後再來查詢
示意圖:
```graphviz
digraph init{
                rankdir=RL;
			 
				 a[ label="a" color=blue, fontcolor=blue, fontsize=24, shape=box];
				
			
				c[label="c" color=blue, fontcolor=blue, fontsize=24, shape=box]	
				           
         
				c -> a;
                c -> a;
                
              
          }
```
查詢的結果
```
tips:
[TransactionHash(b'GTBFDPNJDAKBDKWV9XVWCW9TDELFYZCXW9ONIGGAYBWSNRPWQJJZAHNVMQIFFOHOYKDXSBMIKPFL99999')]
```
再發一筆 , 如下圖
```graphviz
digraph init{
                rankdir=RL;
			 
				 a[ label="a" color=blue, fontcolor=blue, fontsize=24, shape=box];
				
			
				c[label="c" color=blue, fontcolor=blue, fontsize=24, shape=box]	
				 
                 d[label="d" color=blue, fontcolor=blue, fontsize=24, shape=box]
         
				c -> a;
                c -> a;
                d -> a;
                d -> a;
              
          }
```
結果:
```
tips:
[TransactionHash(b'GTBFDPNJDAKBDKWV9XVWCW9TDELFYZCXW9ONIGGAYBWSNRPWQJJZAHNVMQIFFOHOYKDXSBMIKPFL99999'), TransactionHash(b'JFXCK9YJOWFETUEOGNULAVSMMQWFBIVZFW9BXZMJZC9ADIQNSODHMLMOUEBSNWWBGCXNBBCQSQLX99999')]
```
測一筆交易驗證上面的結果 , 如下圖
```graphviz
digraph init{
                rankdir=RL;
			 
				 a[ label="a" color=blue, fontcolor=blue, fontsize=24, shape=box];
				
			
				c[label="c" color=blue, fontcolor=blue, fontsize=24, shape=box]	
				 
                 d[label="d" color=blue, fontcolor=blue, fontsize=24, shape=box]
         
         e[label="e" color=blue, fontcolor=blue, fontsize=24, shape=box]
         
				c -> a;
                c -> a;
                d -> a;
                d -> a;
                 e->d;
                 e->c;
          }
```
查詢結果:
```
tips:
[TransactionHash(b'MQQXPGHUQXHITYHTMYWPYXGKNAEUGZP9BFISJSF9UESABUYTIWUJQXWZYHPLSBKDEWIUVTA9XVGC99999')]
```
d 多一個 tip , c 多一個 tip
如下圖:
```graphviz
digraph init{
                rankdir=RL;
			 
				 a[ label="a" color=blue, fontcolor=blue, fontsize=24, shape=box];
				
			
				c[label="c" color=blue, fontcolor=blue, fontsize=24, shape=box]	
				 
                 d[label="d" color=blue, fontcolor=blue, fontsize=24, shape=box]
         
         e[label="e" color=blue, fontcolor=blue, fontsize=24, shape=box]
         
         h[label="h" color=blue, fontcolor=blue, fontsize=24, shape=box]
         
         g[label="g" color=blue, fontcolor=blue, fontsize=24, shape=box]
         
				c -> a;
                c -> a;
                d -> a;
                d -> a;
                 e->d;
                 e->c;
                 g->c;
                 g->c;
                 h->d;
                 h->d;
          }
```
查詢結果:
```
tips:
[TransactionHash(b'LLFTDXIJTTGITPHYZWIIX9EFFUSTTBKNZMQCQYWMZL99IMAAFUBNCPFZHRYHAWKAKHINLXCAT9LCA9999'), TransactionHash(b'MQQXPGHUQXHITYHTMYWPYXGKNAEUGZP9BFISJSF9UESABUYTIWUJQXWZYHPLSBKDEWIUVTA9XVGC99999'), TransactionHash(b'VRZFSLMGHUFOTITL9ZLEKISWJXRBPWKGFXWORLIUULWBTEFXPAW9XDOMKXKLS99Q9NGYJKJTKZARA9999')]
```
再給 a 一個 tip
查詢結果:
```
tips:
[TransactionHash(b'9IAEXXETGFPRSFVHTYKVQRUBKBDOBEVPKVWSAJZDNKBSGAHZNTHATVCWGZAZCCJGQQPZOFYBUTVX99999'), TransactionHash(b'LLFTDXIJTTGITPHYZWIIX9EFFUSTTBKNZMQCQYWMZL99IMAAFUBNCPFZHRYHAWKAKHINLXCAT9LCA9999'), TransactionHash(b'MQQXPGHUQXHITYHTMYWPYXGKNAEUGZP9BFISJSF9UESABUYTIWUJQXWZYHPLSBKDEWIUVTA9XVGC99999'), TransactionHash(b'VRZFSLMGHUFOTITL9ZLEKISWJXRBPWKGFXWORLIUULWBTEFXPAW9XDOMKXKLS99Q9NGYJKJTKZARA9999')]
```
看起來是沒問題
### milestone_attacker
如同 subTangle_attacker 一樣 , 開始執行後不斷查詢有沒有攻擊開始 message 的交易
發現有攻擊開始 message 的交易後 , 進入 while loop
while loop 做以下四件事:
1. 找出 tips , 這些 tips 直接或間接指向攻擊開始 message 的交易
2. 查詢新的 milestone 並刪除超過第 15 個深的 milestone
3. 發交易 , 交易指向 milestone 與 1. 所說的 tip
4. 如果發現有攻擊結束 message 的交易 , 程式結束執行
milestone 會有一個 table 來紀錄 , 內容是 milestone 與 對應的深度
相關的想法如下:
:::info
可以攻擊後 , 取 node 的solid 的 milestone 並放入 table , 這時深度是 0
在 while loop 時 , 每次查詢新的 milestone , 就同時用 command 檢查新的 milestone 指向多少舊的 milestone
如果有舊的被指向 , 對應的深度就加一
如果有 milestone 深度超過 15 , 就從 table 刪除
:::
### getTransationToApprove(gTTA_tester) 
### transaction_issuer / confirmed_transaction_tester
## 預期結果
### non solid
#### 非攻擊期間
gTTA 時間不會太久
#### 攻擊期間
gTTA 沒回應 , 花很長的時間或回傳 error
#### 攻擊後
### 衝突交易
#### 非攻擊期間
確認時間不長 , CTPS 比例高
#### 攻擊期間
確認時間變長 , CTPS 比例下降
#### 攻擊後
# 分支有最大權重
# 沒有 tip 可以選
# 整個攻擊的流程
## 攻擊前準備
先設定 [config.py](https://github.com/DLTcollab/DOS-attack-with-FPGA-accelerator/blob/master/config.py) 內的參數 , 接著把 [DOS-attack-with-FPGA-accelerator](https://github.com/DLTcollab/DOS-attack-with-FPGA-accelerator) 部署到要做攻擊的機器上
特別注意
:::warning
各機器上的 config.py 必須一樣的參數
:::
接下來執行
```=java
python3 subTangle_attacker.py
```
或
```=java
python3 milestone_attacker.py
```
## 攻擊
如果要開始攻擊 , 執行
```=java
python3 attack_init.py
```
想要攻擊結束 , 執行
```=java
python3 attack_end.py
```
# 在 Main net 上測試的問題
整個攻擊要有效果的關鍵是
:::info
洗到 subTangle 有 5k 以上的交易時 , random walk 要可能走到 subTangle
:::
## 要 5k 以上的理由
由於算權重的[上限](https://github.com/iotaledger/iri/blob/937cb4046ad12f813ad1c04a4613f69ca2af8cc6/src/main/java/com/iota/iri/service/tipselection/impl/CumulativeWeightCalculator.java#L31) , 預設是 5k
Mainnet 上的 IRI , 可以自由修改上限
所以 5k 是個建議值
實際上 , 不同的預設值 , 會對走到 subTangle 有不同的機率
假設預設 5k , 目前的 Tangle 示意圖如下:
```graphviz
digraph init{
                rankdir=RL;
			 
				 a[ label="c" color=blue, fontcolor=blue, fontsize=24, shape=box];
				
				b[label="b" color=blue, fontcolor=blue, fontsize=24, shape=box];
				
				c[label="a" color=blue, fontcolor=blue, fontsize=24, shape=box]	
				           
                 e[label="e" color=blue, fontcolor=blue, fontsize=24, shape=box]	
				           
                  d[label="d" color=blue, fontcolor=blue, fontsize=24, shape=box]
                  
g[label="5k" color=red, fontcolor=red, fontsize=24, shape=circle] 			
h[label="7k" color=red, fontcolor=red, fontsize=24, shape=circle] 
          
				a -> c;
                b -> c;  
				a -> c;
                b -> c;
                e -> a;
                e -> b;
                d -> a;
                d -> b;
                
                h->d;
                g->d;
                
                
              
          }
```
在 5k 下 , 從 d 走到 5k 的 subTangle 和走到 7k 的 subTangle 是一樣的機率
可是如果預設是 10000
那走到 7k 的 subTangle 的機率會比較高
由於各 IRI 可能是不同的值 , 所以不會每個 node 都有 DoS 的效果
## random walk 可能走到 subTangle
另一個是洗到特定的數量 , 也要可能走到洗的 subTangle
目前的 gTTA command , 一定有一個是從 milestone 開始 random walk
預設最深是第 15 個深 milestone
所以從 0 洗到 5k 的 subTangle , 這 subTangle 指向 MainTangle 的交易必須在 solid milestone 到 第15個深 milestone 之間
這就要求攻擊的機器 , 發出的 TPS 不能太低
milestone 由[觀察網站](http://coordinator.iotawatch.it/)
目前是 1 分鐘 , 也曾經是 30 秒
以 30 秒來算 , 最短情況下 , 7.5 分鐘會讓一開始的 solid milestone 變成第 16 個深的 milestone
換句話說 , 需要能在 7.5 分鐘內從 0 洗到 5k 的能力
大約是 11 TPS 的能力
如果要洗 5k 以上 , 需要更高的 TPS
###### tags: `IOTA`