From 68dd751dd129d9358654a9c181913b315508a128 Mon Sep 17 00:00:00 2001
From: Sean Young <sean.young@monax.io>
Date: Wed, 22 Aug 2018 15:34:51 +0100
Subject: [PATCH] Fix issue when many relocations are present

This issue was exposed by compiling all the solidity first. Since the
solidity compiler does not do any linking in this case, we are presented
with more linking work to do when we deploy bin files.

Signed-off-by: Sean Young <sean.young@monax.io>
---
 deploy/compile/perform_compilation.go | 28 ++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/deploy/compile/perform_compilation.go b/deploy/compile/perform_compilation.go
index c072513b..8f14d4f4 100644
--- a/deploy/compile/perform_compilation.go
+++ b/deploy/compile/perform_compilation.go
@@ -102,29 +102,31 @@ func RequestBinaryLinkage(file string, libraries map[string]string) (*BinaryResp
 			Error:  "",
 		}, nil
 	}
-	var links map[string]map[string]struct{ Start, Length int }
+	var links map[string]map[string][]struct{ Start, Length int }
 	err = json.Unmarshal(contract.Evm.Bytecode.LinkReferences, &links)
 	if err != nil {
 		return &BinaryResponse{}, err
 	}
 	for _, f := range links {
-		for name, relo := range f {
+		for name, relos := range f {
 			addr, ok := libraries[name]
 			if !ok {
 				return &BinaryResponse{}, fmt.Errorf("library %s is not defined", name)
 			}
-			if relo.Length != RelocationLength {
-				return &BinaryResponse{}, fmt.Errorf("linkReference should be %d bytes long, not %d", RelocationLength, relo.Length)
+			for _, relo := range relos {
+				if relo.Length != RelocationLength {
+					return &BinaryResponse{}, fmt.Errorf("linkReference should be %d bytes long, not %d", RelocationLength, relo.Length)
+				}
+				if len(addr) != AddressLength {
+					return &BinaryResponse{}, fmt.Errorf("address %s should be %d character long, not %d", addr, AddressLength, len(addr))
+				}
+				start := relo.Start * 2
+				end := relo.Start*2 + AddressLength
+				if bin[start+1] != '_' || bin[end-1] != '_' {
+					return &BinaryResponse{}, fmt.Errorf("relocation dummy not found at %d in %s ", relo.Start, bin)
+				}
+				bin = bin[:start] + addr + bin[end:]
 			}
-			if len(addr) != AddressLength {
-				return &BinaryResponse{}, fmt.Errorf("address %s should be %d character long, not %d", addr, AddressLength, len(addr))
-			}
-			start := relo.Start * 2
-			end := relo.Start*2 + AddressLength
-			if bin[start+1] != '_' || bin[end-1] != '_' {
-				return &BinaryResponse{}, fmt.Errorf("relocation dummy not found at %d in %s ", relo.Start, bin)
-			}
-			bin = bin[:start] + addr + bin[end:]
 		}
 	}
 
-- 
GitLab