Skip to content
This repository was archived by the owner on May 13, 2022. It is now read-only.

Commit 56cf347

Browse files
author
Casey Kuhlman
authored
Merge pull request #1491 from hyperledger/solts
Fix collisions in ABI output, submit contract metadata on deploy, remove GRPC dependencies from codegen interface.gd.ts
2 parents 89c3124 + e87138a commit 56cf347

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1058
-1132
lines changed

.github/Dockerfile

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
FROM golang:1.15-alpine3.13
1+
FROM golang:1.16-alpine3.13
22
MAINTAINER Monax <[email protected]>
33

4-
ENV DOCKER_VERSION "17.12.1-ce"
5-
ENV GORELEASER_VERSION "v0.104.1"
4+
ENV DOCKER_VERSION "20.10.6"
5+
ENV GORELEASER_VERSION "v0.166.1"
66
# This is the image used by the Circle CI config
77
# Update remote with 'make push_ci_image'
88
RUN apk add --update --no-cache \
@@ -22,8 +22,8 @@ RUN apk add --update --no-cache \
2222
libffi-dev \
2323
openssl-dev \
2424
python3-dev \
25-
py-pip
26-
RUN pip3 install docker-compose
25+
py-pip \
26+
docker-compose
2727
# get docker client
2828
WORKDIR /usr/bin
2929
RUN curl -sS -L https://download.docker.com/linux/static/stable/x86_64/docker-$DOCKER_VERSION.tgz | tar xz --strip-components 1 docker/docker

.github/workflows/main.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
steps:
1212
- uses: actions/setup-go@v1
1313
with:
14-
go-version: 1.15
14+
go-version: 1.16
1515
id: go
1616
- uses: actions/checkout@v2
1717
- run: make test

.github/workflows/release.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
- run: git fetch --prune --unshallow
1414
- uses: actions/setup-go@v1
1515
with:
16-
go-version: 1.15
16+
go-version: 1.16
1717
- uses: goreleaser/goreleaser-action@v1
1818
with:
1919
version: latest

.github/workflows/test.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
steps:
1212
- uses: actions/setup-go@v1
1313
with:
14-
go-version: 1.15
14+
go-version: 1.16
1515
id: go
1616
- uses: actions/checkout@v2
1717
- run: git fetch --unshallow --prune
@@ -27,7 +27,7 @@ jobs:
2727
steps:
2828
- uses: actions/setup-go@v1
2929
with:
30-
go-version: 1.15
30+
go-version: 1.16
3131
id: go
3232
- uses: actions/checkout@v1
3333
- run: make test_integration

CHANGELOG.md

+15
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,18 @@
11
# [Hyperledger Burrow](https://github.com/hyperledger/burrow) Changelog
2+
## [0.34.0] - 2021-05-28
3+
### Changed
4+
- [JS] Provider interface no longer depends on GRPC types to improve compatibility between versions of Burrow.js and ease of extension
5+
- [JS] Use non-unique marker interface to indicate stream cancellation in event reducer (again for compatibility between versions and extensibility)
6+
- [Go] Upgrade to Go 1.16
7+
8+
### Fixed
9+
- [JS] Fix codegen silently swallowing collisions of abi files (renamed from .bin to .abi) and use hierarchical directory structure to further reduce chance of collision
10+
- [JS] Just depende on @ethersproject/abi rather than entire umbrella project
11+
12+
### Added
13+
- [JS] Include deployedBycode and optionally submit ABI's to Burrow's contract metadata store on deploy
14+
15+
216
## [0.33.1] - 2021-05-24
317
### Fixed
418
- [JS] Return bytesNN as Buffer to agree with typings
@@ -775,6 +789,7 @@ This release marks the start of Eris-DB as the full permissioned blockchain node
775789
- [Blockchain] Fix getBlocks to respect block height cap.
776790

777791

792+
[0.34.0]: https://github.com/hyperledger/burrow/compare/v0.33.1...v0.34.0
778793
[0.33.1]: https://github.com/hyperledger/burrow/compare/v0.33.0...v0.33.1
779794
[0.33.0]: https://github.com/hyperledger/burrow/compare/v0.32.1...v0.33.0
780795
[0.32.1]: https://github.com/hyperledger/burrow/compare/v0.32.0...v0.32.1

Dockerfile

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# For solc binary
2-
FROM ethereum/solc:0.5.12 as solc-builder
2+
FROM ethereum/solc:0.5.15 as solc-builder
33
# We use a multistage build to avoid bloating our deployment image with build dependencies
4-
FROM golang:1.15-alpine3.12 as builder
4+
FROM golang:1.16-alpine3.13 as builder
55

66
RUN apk add --no-cache --update git bash make musl-dev gcc libc6-compat
77

@@ -13,7 +13,7 @@ WORKDIR $REPO
1313
RUN make build
1414

1515
# This will be our base container image
16-
FROM alpine:3.11
16+
FROM alpine:3.13
1717

1818
# Variable arguments to populate labels
1919
ARG USER=burrow

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ REPO := $(shell pwd)
1515

1616
# Our own Go files containing the compiled bytecode of solidity files as a constant
1717

18-
export CI_IMAGE=hyperledger/burrow:ci-2
18+
export CI_IMAGE=hyperledger/burrow:ci-3
1919

2020
VERSION := $(shell scripts/version.sh)
2121
# Gets implicit default GOPATH if not set

NOTES.md

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1+
### Changed
2+
- [JS] Provider interface no longer depends on GRPC types to improve compatibility between versions of Burrow.js and ease of extension
3+
- [JS] Use non-unique marker interface to indicate stream cancellation in event reducer (again for compatibility between versions and extensibility)
4+
- [Go] Upgrade to Go 1.16
5+
16
### Fixed
2-
- [JS] Return bytesNN as Buffer to agree with typings
7+
- [JS] Fix codegen silently swallowing collisions of abi files (renamed from .bin to .abi) and use hierarchical directory structure to further reduce chance of collision
8+
- [JS] Just depende on @ethersproject/abi rather than entire umbrella project
39

410
### Added
5-
- [JS] Inline sources and source maps
11+
- [JS] Include deployedBycode and optionally submit ABI's to Burrow's contract metadata store on deploy
612

execution/evm/abi/abi.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ func LoadPath(abiFileOrDirs ...string) (*Spec, error) {
3030
specs := make([]*Spec, 0)
3131

3232
for _, dir := range abiFileOrDirs {
33-
err := filepath.Walk(dir, func(path string, fi os.FileInfo, err error) error {
33+
err := filepath.WalkDir(dir, func(path string, dir os.DirEntry, err error) error {
3434
if err != nil {
3535
return fmt.Errorf("error returned while walking abiDir '%s': %v", dir, err)
3636
}
3737
ext := filepath.Ext(path)
38-
if fi.IsDir() || !(ext == ".bin" || ext == ".abi" || ext == ".json") {
38+
if dir.IsDir() || !(ext == ".bin" || ext == ".abi" || ext == ".json") {
3939
return nil
4040
}
4141
abiSpc, err := ReadSpecFile(path)

go.mod

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/hyperledger/burrow
22

3-
go 1.15
3+
go 1.16
44

55
require (
66
github.com/BurntSushi/toml v0.3.1
@@ -52,7 +52,7 @@ require (
5252
github.com/xlab/treeprint v1.0.0
5353
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
5454
golang.org/x/net v0.0.0-20210119194325-5f4716e94777
55-
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
55+
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
5656
google.golang.org/grpc v1.35.0
5757
google.golang.org/protobuf v1.25.0
5858
gopkg.in/yaml.v2 v2.4.0

js/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
},
2222
"dependencies": {
2323
"@grpc/grpc-js": "^1.3.0",
24-
"ethers": "^5.1.4",
24+
"@ethersproject/abi": "^5.2.0",
2525
"google-protobuf": "^3.15.8",
2626
"sha3": "^2.1.4",
2727
"solc_v5": "npm:solc@^0.5.17",

js/src/client.ts

+22-15
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1+
import { Interface } from '@ethersproject/abi';
12
import * as grpc from '@grpc/grpc-js';
2-
import { Interface } from 'ethers/lib/utils';
3-
import { Event, TxExecution } from '../proto/exec_pb';
4-
import { CallTx, ContractMeta } from '../proto/payload_pb';
3+
import { TxExecution } from '../proto/exec_pb';
4+
import { CallTx } from '../proto/payload_pb';
55
import { ExecutionEventsClient, IExecutionEventsClient } from '../proto/rpcevents_grpc_pb';
66
import { IQueryClient, QueryClient } from '../proto/rpcquery_grpc_pb';
77
import { GetMetadataParam, StatusParam } from '../proto/rpcquery_pb';
88
import { ITransactClient, TransactClient } from '../proto/rpctransact_grpc_pb';
99
import { ResultStatus } from '../proto/rpc_pb';
1010
import { ContractCodec, getContractCodec } from './codec';
1111
import { Address } from './contracts/abi';
12-
import { makeCallTx } from './contracts/call';
12+
import { getContractMeta, makeCallTx } from './contracts/call';
1313
import { CallOptions, Contract, ContractInstance } from './contracts/contract';
1414
import { toBuffer } from './convert';
1515
import { getException } from './error';
16-
import { Bounds, EventCallback, EventStream, getBlockRange, queryFor, stream } from './events';
16+
import { Bounds, Event, EventCallback, EventStream, getBlockRange, queryFor, stream } from './events';
1717
import { Namereg } from './namereg';
1818
import { Provider } from './solts/interface.gd';
1919

@@ -125,22 +125,33 @@ export class Client implements Provider {
125125
// Methods below implement the generated codegen provider
126126
// TODO: should probably generate canonical version of Provider interface somewhere outside of files
127127

128-
async deploy(msg: CallTx): Promise<Address> {
129-
const txe = await this.callTxSync(msg);
128+
async deploy(
129+
data: string | Uint8Array,
130+
contractMeta: { abi: string; codeHash: Uint8Array }[] = [],
131+
): Promise<Address> {
132+
const tx = makeCallTx(
133+
toBuffer(data),
134+
this.account,
135+
undefined,
136+
contractMeta.map(({ abi, codeHash }) => getContractMeta(abi, codeHash)),
137+
);
138+
const txe = await this.callTxSync(tx);
130139
const contractAddress = txe.getReceipt()?.getContractaddress_asU8();
131140
if (!contractAddress) {
132141
throw new Error(`deploy appears to have succeeded but contract address is missing from result: ${txe}`);
133142
}
134143
return Buffer.from(contractAddress).toString('hex').toUpperCase();
135144
}
136145

137-
async call(msg: CallTx): Promise<Uint8Array | undefined> {
138-
const txe = await this.callTxSync(msg);
146+
async call(data: string | Uint8Array, address: string): Promise<Uint8Array | undefined> {
147+
const tx = makeCallTx(toBuffer(data), this.account, address);
148+
const txe = await this.callTxSync(tx);
139149
return txe.getResult()?.getReturn_asU8();
140150
}
141151

142-
async callSim(msg: CallTx): Promise<Uint8Array | undefined> {
143-
const txe = await this.callTxSim(msg);
152+
async callSim(data: string | Uint8Array, address: string): Promise<Uint8Array | undefined> {
153+
const tx = makeCallTx(toBuffer(data), this.account, address);
154+
const txe = await this.callTxSim(tx);
144155
return txe.getResult()?.getReturn_asU8();
145156
}
146157

@@ -154,10 +165,6 @@ export class Client implements Provider {
154165
return stream(this.executionEvents, getBlockRange(start, end), queryFor({ address, signatures }), callback);
155166
}
156167

157-
payload(data: string | Uint8Array, address?: string, contractMeta: ContractMeta[] = []): CallTx {
158-
return makeCallTx(typeof data === 'string' ? toBuffer(data) : data, this.account, address, contractMeta);
159-
}
160-
161168
contractCodec(contractABI: string): ContractCodec {
162169
const iface = new Interface(contractABI);
163170
return getContractCodec(iface);

js/src/codec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { EventFragment, Fragment, FunctionFragment, Interface } from 'ethers/lib/utils';
1+
import { EventFragment, Fragment, FunctionFragment, Interface } from '@ethersproject/abi';
22
import { postDecodeResult, preEncodeResult, prefixedHexString, toBuffer } from './convert';
33

44
export type ContractCodec = {

js/src/contracts/abi.ts

+31-16
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,37 @@ export type Address = string;
66

77
export type FunctionIO = FunctionInput & FunctionOutput;
88

9-
// TODO: replace with ethers js
9+
export namespace ABI {
10+
export type Func = {
11+
type: 'function' | 'constructor' | 'fallback';
12+
name: string;
13+
inputs?: Array<FunctionInput>;
14+
outputs?: Array<FunctionOutput>;
15+
stateMutability: 'pure' | 'view' | 'nonpayable' | 'payable';
16+
payable?: boolean;
17+
constant?: boolean;
18+
};
19+
20+
export type Event = {
21+
type: 'event';
22+
name: string;
23+
inputs: Array<EventInput>;
24+
anonymous: boolean;
25+
};
26+
27+
export type FunctionInput = {
28+
name: string;
29+
type: string;
30+
components?: FunctionInput[];
31+
internalType?: string;
32+
};
33+
34+
export type FunctionOutput = FunctionInput;
35+
export type EventInput = FunctionInput & { indexed?: boolean };
36+
37+
export type FunctionIO = FunctionInput & FunctionOutput;
38+
export type FunctionOrEvent = Func | Event;
39+
}
1040

1141
export function transformToFullName(abi: SolidityFunction | Event): string {
1242
if (abi.name.indexOf('(') !== -1) {
@@ -15,18 +45,3 @@ export function transformToFullName(abi: SolidityFunction | Event): string {
1545
const typeName = (abi.inputs as Array<EventInput | FunctionIO>).map((i) => i.type).join(',');
1646
return abi.name + '(' + typeName + ')';
1747
}
18-
19-
export function extractDisplayName(name: string): string {
20-
const length = name.indexOf('(');
21-
return length !== -1 ? name.substr(0, length) : name;
22-
}
23-
24-
export function extractTypeName(name: string): string {
25-
/// TODO: make it invulnerable
26-
const length = name.indexOf('(');
27-
return length !== -1 ? name.substr(length + 1, name.length - 1 - (length + 1)).replace(' ', '') : '';
28-
}
29-
30-
export function isFunction(abi: SolidityFunction | Event): abi is SolidityFunction {
31-
return abi.type === 'function' || abi.type === 'constructor';
32-
}

js/src/contracts/call.ts

+19-4
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
1+
import { AbiCoder, FunctionFragment, Interface, Result as DecodedResult } from '@ethersproject/abi';
12
import * as grpc from '@grpc/grpc-js';
23
import { Metadata } from '@grpc/grpc-js';
34
import { callErrorFromStatus } from '@grpc/grpc-js/build/src/call';
4-
import { AbiCoder, FunctionFragment, Interface, Result as DecodedResult } from 'ethers/lib/utils';
5+
import { Keccak } from 'sha3';
56
import { SolidityFunction } from 'solc';
67
import { Result } from '../../proto/exec_pb';
78
import { CallTx, ContractMeta, TxInput } from '../../proto/payload_pb';
89
import { Envelope } from '../../proto/txs_pb';
910
import { Pipe } from '../client';
1011
import { postDecodeResult, preEncodeResult, toBuffer } from '../convert';
11-
import { Address } from './abi';
12+
import { ABI, Address } from './abi';
1213
import { CallOptions } from './contract';
1314

1415
export const DEFAULT_GAS = 1111111111;
1516

16-
export { Result as DecodeResult } from 'ethers/lib/utils';
17-
1817
const WasmMagic = Buffer.from('\0asm');
1918

2019
const coder = new AbiCoder();
@@ -48,6 +47,22 @@ export function makeCallTx(
4847
return payload;
4948
}
5049

50+
export function getContractMetaFromBytecode(abi: ABI, deployedBytecode: string): ContractMeta {
51+
const hasher = new Keccak(256);
52+
const codeHash = hasher.update(deployedBytecode, 'hex').digest();
53+
return getContractMeta(abi, codeHash);
54+
}
55+
56+
export function getContractMeta(abi: ABI | string, codeHash: Uint8Array): ContractMeta {
57+
const meta = new ContractMeta();
58+
if (typeof abi !== 'string') {
59+
abi = JSON.stringify({ Abi: abi });
60+
}
61+
meta.setMeta(abi);
62+
meta.setCodehash(codeHash);
63+
return meta;
64+
}
65+
5166
export type TransactionResult = {
5267
contractAddress: string;
5368
height: number;
File renamed without changes.

0 commit comments

Comments
 (0)