tests working now
This commit is contained in:
parent
5cc853d807
commit
c293caade9
|
@ -7,6 +7,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"golang.org/x/exp/rand"
|
"golang.org/x/exp/rand"
|
||||||
|
"runtime/debug"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -144,6 +145,7 @@ func testLinkCase(t *testing.T, tcInput linkTestCaseInput) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(res.Addrs) != len(tcInput.expectDeployed) {
|
if len(res.Addrs) != len(tcInput.expectDeployed) {
|
||||||
|
debug.PrintStack()
|
||||||
t.Fatalf("got %d deployed contracts. expected %d.\n", len(res.Addrs), len(tcInput.expectDeployed))
|
t.Fatalf("got %d deployed contracts. expected %d.\n", len(res.Addrs), len(tcInput.expectDeployed))
|
||||||
}
|
}
|
||||||
for contract, _ := range tcInput.expectDeployed {
|
for contract, _ := range tcInput.expectDeployed {
|
||||||
|
@ -164,6 +166,7 @@ func TestContractLinking(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
fmt.Println("2")
|
||||||
testLinkCase(t, linkTestCaseInput{
|
testLinkCase(t, linkTestCaseInput{
|
||||||
map[rune][]rune{
|
map[rune][]rune{
|
||||||
'a': {'b', 'c', 'd', 'e'},
|
'a': {'b', 'c', 'd', 'e'},
|
||||||
|
|
|
@ -70,58 +70,66 @@ type depTreeBuilder struct {
|
||||||
// map of pattern to unlinked contract bytecode (for libraries or contracts)
|
// map of pattern to unlinked contract bytecode (for libraries or contracts)
|
||||||
contracts map[string]string
|
contracts map[string]string
|
||||||
// map of pattern to subtree represented by contract
|
// map of pattern to subtree represented by contract
|
||||||
subtrees map[string]*depTreeNode
|
subtrees map[string]any
|
||||||
|
|
||||||
// map of nodes that aren't referenced by other dependencies (these can be libraries too if user is doing lib-only deployment)
|
// map of nodes that aren't referenced by other dependencies (these can be libraries too if user is doing lib-only deployment)
|
||||||
roots map[string]struct{}
|
roots map[string]struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type depTreeNode struct {
|
type depTreeNode struct {
|
||||||
pattern string
|
pattern string
|
||||||
unlinkedCode string
|
unlinkedCode string
|
||||||
nodes []*depTreeNode
|
nodes []any
|
||||||
|
}
|
||||||
|
|
||||||
|
type overrideNode struct {
|
||||||
|
pattern string
|
||||||
|
addr common.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *depTreeBuilder) buildDepTrees(pattern, contract string) {
|
func (d *depTreeBuilder) buildDepTrees(pattern, contract string) {
|
||||||
reMatchSpecificPattern, err := regexp.Compile("__\\$([a-f0-9]+)\\$__")
|
// if the node is in the subtree set already, bail out early
|
||||||
if err != nil {
|
if _, ok := d.subtrees[pattern]; ok {
|
||||||
panic(err)
|
return
|
||||||
}
|
}
|
||||||
|
if addr, ok := d.overrides[pattern]; ok {
|
||||||
|
node := &overrideNode{
|
||||||
|
pattern: pattern,
|
||||||
|
addr: addr,
|
||||||
|
}
|
||||||
|
d.subtrees[pattern] = node
|
||||||
|
} else {
|
||||||
node := &depTreeNode{
|
node := &depTreeNode{
|
||||||
pattern: pattern,
|
pattern: pattern,
|
||||||
unlinkedCode: contract,
|
unlinkedCode: contract,
|
||||||
}
|
}
|
||||||
|
// if the node is an override node: add it to the node map but don't recurse on it.
|
||||||
|
// else if the node is depNode: recurse on it, and add it to the dep map.
|
||||||
|
reMatchSpecificPattern, err := regexp.Compile("__\\$([a-f0-9]+)\\$__")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
for _, match := range reMatchSpecificPattern.FindAllStringSubmatch(contract, -1) {
|
for _, match := range reMatchSpecificPattern.FindAllStringSubmatch(contract, -1) {
|
||||||
depPattern := match[1]
|
depPattern := match[1]
|
||||||
if _, ok := d.subtrees[depPattern]; ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if _, ok := d.overrides[depPattern]; ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// this library was referenced by another contract. it's not a dependency tree root.
|
|
||||||
delete(d.roots, depPattern)
|
|
||||||
|
|
||||||
d.buildDepTrees(depPattern, d.contracts[depPattern])
|
d.buildDepTrees(depPattern, d.contracts[depPattern])
|
||||||
node.nodes = append(node.nodes, d.subtrees[depPattern])
|
node.nodes = append(node.nodes, d.subtrees[depPattern])
|
||||||
|
|
||||||
|
// this dep can't be a root dependency if it is referenced by other contracts.
|
||||||
|
delete(d.roots, depPattern)
|
||||||
}
|
}
|
||||||
d.subtrees[pattern] = node
|
d.subtrees[pattern] = node
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *depTreeBuilder) BuildDepTrees() (roots []*depTreeNode) {
|
func (d *depTreeBuilder) BuildDepTrees() (roots []*depTreeNode) {
|
||||||
for pattern, contract := range d.contracts {
|
for pattern, contract := range d.contracts {
|
||||||
if _, ok := d.subtrees[pattern]; ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if _, ok := d.overrides[pattern]; ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// pattern has not been explored, it's potentially a root
|
|
||||||
d.roots[pattern] = struct{}{}
|
d.roots[pattern] = struct{}{}
|
||||||
d.buildDepTrees(pattern, contract)
|
d.buildDepTrees(pattern, contract)
|
||||||
}
|
}
|
||||||
for pattern, _ := range d.roots {
|
for pattern, _ := range d.roots {
|
||||||
roots = append(roots, d.subtrees[pattern])
|
switch node := d.subtrees[pattern].(type) {
|
||||||
|
case *depTreeNode:
|
||||||
|
roots = append(roots, node)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return roots
|
return roots
|
||||||
}
|
}
|
||||||
|
@ -134,15 +142,28 @@ type treeDeployer struct {
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *treeDeployer) linkAndDeploy(node *depTreeNode) {
|
func (d *treeDeployer) linkAndDeploy(n any) {
|
||||||
|
node, ok := n.(*depTreeNode)
|
||||||
|
if !ok {
|
||||||
|
// this was an override node
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
for _, childNode := range node.nodes {
|
for _, childNode := range node.nodes {
|
||||||
d.linkAndDeploy(childNode)
|
d.linkAndDeploy(childNode)
|
||||||
}
|
}
|
||||||
// link in all node dependencies and produce the deployer bytecode
|
// link in all node dependencies and produce the deployer bytecode
|
||||||
deployerCode := node.unlinkedCode
|
deployerCode := node.unlinkedCode
|
||||||
|
for _, c := range node.nodes {
|
||||||
for _, child := range node.nodes {
|
switch child := c.(type) {
|
||||||
|
case *depTreeNode:
|
||||||
deployerCode = strings.ReplaceAll(deployerCode, "__$"+child.pattern+"$__", strings.ToLower(d.deployedAddrs[child.pattern].String()[2:]))
|
deployerCode = strings.ReplaceAll(deployerCode, "__$"+child.pattern+"$__", strings.ToLower(d.deployedAddrs[child.pattern].String()[2:]))
|
||||||
|
case *overrideNode:
|
||||||
|
deployerCode = strings.ReplaceAll(deployerCode, "__$"+child.pattern+"$__", strings.ToLower(child.addr.String()[2:]))
|
||||||
|
default:
|
||||||
|
panic("invalid node type")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// deploy the contract.
|
// deploy the contract.
|
||||||
|
@ -175,13 +196,13 @@ func LinkAndDeploy(deployParams DeploymentParams, deploy func(input, deployer []
|
||||||
Addrs: make(map[string]common.Address),
|
Addrs: make(map[string]common.Address),
|
||||||
}
|
}
|
||||||
for _, meta := range deployParams.Contracts {
|
for _, meta := range deployParams.Contracts {
|
||||||
unlinkedContracts[meta.Pattern] = meta.Bin
|
unlinkedContracts[meta.Pattern] = meta.Bin[2:]
|
||||||
}
|
}
|
||||||
// TODO: instantiate this using constructor
|
// TODO: instantiate this using constructor
|
||||||
treeBuilder := depTreeBuilder{
|
treeBuilder := depTreeBuilder{
|
||||||
overrides: deployParams.Overrides,
|
overrides: deployParams.Overrides,
|
||||||
contracts: unlinkedContracts,
|
contracts: unlinkedContracts,
|
||||||
subtrees: make(map[string]*depTreeNode),
|
subtrees: make(map[string]any),
|
||||||
roots: make(map[string]struct{}),
|
roots: make(map[string]struct{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue