Skip to content

Commit ba1dc38

Browse files
authored
Merge pull request #141 from ShyftNetwork/db-upstream
Will merge this and then move to staging where @GregTheGreek can approve and create the next release.
2 parents 10b60d2 + 5c4b26b commit ba1dc38

File tree

204 files changed

+8361
-7143
lines changed

Some content is hidden

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

204 files changed

+8361
-7143
lines changed

.gitignore

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ ethash/
2727
/build/bin/
2828
/geth*.zip
2929

30-
3130
# travis
3231
profile.tmp
3332
profile.cov
@@ -49,8 +48,6 @@ profile.cov
4948
/dashboard/assets/package-lock.json
5049

5150
**/yarn-error.log
52-
$HOME
53-
5451
# Remove Shyft Data
5552
shyftData/*
5653
shyft-cli/web3/token_test/node_modules

.gitmodules

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +0,0 @@
1-
[submodule "tests"]
2-
path = tests/testdata
3-
url = https://github.com/ShyftNetwork/shyft_tests

.travis.yml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,4 @@ before_script:
6666

6767
script:
6868
- go run build/ci.go install
69-
- go run build/ci.go test -coverage $TEST_PACKAGES
70-
71-
72-
69+
- go run build/ci.go test -coverage $TEST_PACKAGES

README.md

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ To stop Geth, **`crtl+C`** in the terminal window, if you proceed with the start
7171
``./shyft-geth.sh --start`` Starts GETH
7272

7373
To see transactions being submitted on the network see the sendTransactions command in the CLI section of this readme.
74+
7475
#### Docker Images
7576

7677
Two sets of Docker Images are available for ShyftGeth, the Postgresql Database, and the Shyft Blockchain Explorer, which can be used for local development and testnet connection. The development settings are included in docker-compose.yml, the testnet settings are included in docker-compose.production.yml. To launch these containers you will need to have docker-compose installed on your computer. Installation instructions for docker-compose are available [here](https://docs.docker.com/install/).
@@ -94,6 +95,7 @@ To stop/pause mining - enter:
9495
**`docker-compose stop`**
9596

9697
And then just issue `docker-compose up` to continue mining.
98+
9799
#### Docker Postgresql - DB Connection
98100
From your local machine you can view the database by connecting to the database in the container at
99101
**``127.0.0.1:8001``**
@@ -225,7 +227,7 @@ For prerequisites and detailed build instructions please read the
225227
[Installation Instructions](https://github.com/empyrean/go-ethereum/wiki/Building-Ethereum)
226228
on the wiki.
227229

228-
Building geth requires both a Go (version 1.7 or later) and a C compiler.
230+
Building geth requires both a Go (version 1.9 or later) and a C compiler.
229231
You can install them using your favourite package manager.
230232
Once the dependencies are installed, run
231233

@@ -375,7 +377,7 @@ HTTP based JSON-RPC API options:
375377
- `--ipcpath` Filename for IPC socket/pipe within the datadir (explicit paths escape it)
376378

377379
You'll need to use your own programming environments' capabilities (libraries, tools, etc) to connect
378-
via HTTP, WS or IPC to a Geth node configured with the above flags and you'll need to speak [JSON-RPC](http://www.jsonrpc.org/specification)
380+
via HTTP, WS or IPC to a Geth node configured with the above flags and you'll need to speak [JSON-RPC](https://www.jsonrpc.org/specification)
379381
on all transports. You can reuse the same connection for multiple requests!
380382

381383
**Note: Please understand the security implications of opening up an HTTP/WS based transport before
@@ -487,6 +489,77 @@ Which will start mining blocks and transactions on a single CPU thread, creditin
487489
the account specified by `--etherbase`. You can further tune the mining by changing the default gas
488490
limit blocks converge to (`--targetgaslimit`) and the price transactions are accepted at (`--gasprice`).
489491

492+
## SHYFT NOTES
493+
494+
#### CLI
495+
496+
Run `./shyft-geth.sh` with one of the following flags:
497+
498+
- `--setup` - Setups postgres and the shyft chain db.
499+
- `--start` - Starts geth.
500+
- `--reset` - Drops postgress and chain db, and reinstantiates both.
501+
- `--js [web3 filename]` - Executes web3 calls with a passed file name. If the file name is `sendTransactions.js`, `./shyft-geth.sh --js sendTransactions`.
502+
503+
#### Docker Images
504+
505+
Docker Images are available for ShyftGeth and the Postgresql Database which can be used for development and testing. To launch these containers you will need to have docker-compose installed on your computer. Installation instructions for docker-compose are available [here](https://docs.docker.com/install/).
506+
507+
To launch ShyftGeth, PG, the ShyftBlock Explorer Api and UI - issue the following command from the root of the project directory:
508+
509+
`docker-compose up`
510+
511+
If you would like to reinitialize/rebuild the docker images you can issue the following command:
512+
513+
`docker-compose up --build`
514+
515+
To rebuild any one of the services - issue the following commands:
516+
517+
```
518+
docker-compose up -d --no-deps --build <docker compose file service name>
519+
520+
# ie. for shyftBlockExplorerApi:
521+
# docker-compose up -d --no-deps --build shyft_block_api
522+
```
523+
__The Postgresql Database Container will persist the database data to a folder in the root of the project directory - pg-data" __. So if you do want to reinitialize the database you should delete this docker container prior to launching the docker containers. To delete this docker volume and have it recreated you should input the following command:
524+
525+
```docker volume rm go-empyrean_pg-data```
526+
527+
From your local machine you can view the database by connecting to the database in the container at 127.0.0.1:8001. To access the shyftBlockExplorer open a browser and visit http://localhost:3000
528+
529+
__Blockchain data is persisted to ./ethash/.ethash__ and ./shyftData. If you would like to reset the test blockchain you will need to delete the ./ethash and ./shyftData directories.
530+
531+
The docker container for the ShyftBlockExplorerApi utilizes govendor to minimize its image size. __If you would like the docker image for this container to reflect any uncommitted changes which may have occurred in the go-empyrean repository, ie. changes with respect to go-empyrean core (ie. cryptographic functions and database). Prior to launching the docker containers you should rebuild the vendor directory for the shyftBlockExplorerApi - by executing the following steps:__
532+
533+
```
534+
# remove existing shyftBlockExplorerApi vendor.json and vendored components:
535+
536+
rm -rf shyftBlockExplorerApi/vendor
537+
538+
# reinitialize vendor.json
539+
540+
cd shyftBlockExplorerApi && govendor init
541+
542+
# rebuild vendor.json using latest uncommitted changes
543+
544+
govendor add -tree -uncommitted +external
545+
546+
# due to a bug in govendor and it not being able to pull in some dependencies that are c-header files
547+
# you should execute the following commands - see these issues - which whilst closed
548+
# appears to have not been fixed: https://github.com/kardianos/govendor/issues/124 && https://github.com/kardianos/govendor/issues/61
549+
550+
govendor remove github.com/ShyftNetwork/go-empyrean/crypto/secp256k1/^
551+
govendor fetch github.com/ShyftNetwork/go-empyrean/crypto/secp256k1/^
552+
553+
```
554+
555+
NB: The Shyft Geth docker image size is 1+ GB so make sure you have adequate space on your disk drive/
556+
557+
_TODO_
558+
559+
- Find better dependency management solution that pulls in c header files without manual intervention
560+
- Reduce size of the ShytfGeth docker container which is responsible for mining and running the blockchain
561+
- Adjust docker scripts and ports to facilitate sending of test transactions
562+
- Modify Docker scripts to facilitate hot reloading during development
490563

491564
## Contribution
492565

accounts/abi/argument.go

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -243,11 +243,7 @@ func (arguments Arguments) Pack(args ...interface{}) ([]byte, error) {
243243
// input offset is the bytes offset for packed output
244244
inputOffset := 0
245245
for _, abiArg := range abiArgs {
246-
if abiArg.Type.T == ArrayTy {
247-
inputOffset += 32 * abiArg.Type.Size
248-
} else {
249-
inputOffset += 32
250-
}
246+
inputOffset += getDynamicTypeOffset(abiArg.Type)
251247
}
252248
var ret []byte
253249
for i, a := range args {
@@ -257,14 +253,13 @@ func (arguments Arguments) Pack(args ...interface{}) ([]byte, error) {
257253
if err != nil {
258254
return nil, err
259255
}
260-
// check for a slice type (string, bytes, slice)
261-
if input.Type.requiresLengthPrefix() {
262-
// calculate the offset
263-
offset := inputOffset + len(variableInput)
256+
// check for dynamic types
257+
if isDynamicType(input.Type) {
264258
// set the offset
265-
ret = append(ret, packNum(reflect.ValueOf(offset))...)
266-
// Append the packed output to the variable input. The variable input
267-
// will be appended at the end of the input.
259+
ret = append(ret, packNum(reflect.ValueOf(inputOffset))...)
260+
// calculate next offset
261+
inputOffset += len(packed)
262+
// append to variable input
268263
variableInput = append(variableInput, packed...)
269264
} else {
270265
// append the packed value to the input

accounts/abi/pack_test.go

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,66 @@ func TestPack(t *testing.T) {
324324
"foobar",
325325
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000006666f6f6261720000000000000000000000000000000000000000000000000000"),
326326
},
327+
{
328+
"string[]",
329+
[]string{"hello", "foobar"},
330+
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002" + // len(array) = 2
331+
"0000000000000000000000000000000000000000000000000000000000000040" + // offset 64 to i = 0
332+
"0000000000000000000000000000000000000000000000000000000000000080" + // offset 128 to i = 1
333+
"0000000000000000000000000000000000000000000000000000000000000005" + // len(str[0]) = 5
334+
"68656c6c6f000000000000000000000000000000000000000000000000000000" + // str[0]
335+
"0000000000000000000000000000000000000000000000000000000000000006" + // len(str[1]) = 6
336+
"666f6f6261720000000000000000000000000000000000000000000000000000"), // str[1]
337+
},
338+
{
339+
"string[2]",
340+
[]string{"hello", "foobar"},
341+
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040" + // offset to i = 0
342+
"0000000000000000000000000000000000000000000000000000000000000080" + // offset to i = 1
343+
"0000000000000000000000000000000000000000000000000000000000000005" + // len(str[0]) = 5
344+
"68656c6c6f000000000000000000000000000000000000000000000000000000" + // str[0]
345+
"0000000000000000000000000000000000000000000000000000000000000006" + // len(str[1]) = 6
346+
"666f6f6261720000000000000000000000000000000000000000000000000000"), // str[1]
347+
},
348+
{
349+
"bytes32[][]",
350+
[][]common.Hash{{{1}, {2}}, {{3}, {4}, {5}}},
351+
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000002" + // len(array) = 2
352+
"0000000000000000000000000000000000000000000000000000000000000040" + // offset 64 to i = 0
353+
"00000000000000000000000000000000000000000000000000000000000000a0" + // offset 160 to i = 1
354+
"0000000000000000000000000000000000000000000000000000000000000002" + // len(array[0]) = 2
355+
"0100000000000000000000000000000000000000000000000000000000000000" + // array[0][0]
356+
"0200000000000000000000000000000000000000000000000000000000000000" + // array[0][1]
357+
"0000000000000000000000000000000000000000000000000000000000000003" + // len(array[1]) = 3
358+
"0300000000000000000000000000000000000000000000000000000000000000" + // array[1][0]
359+
"0400000000000000000000000000000000000000000000000000000000000000" + // array[1][1]
360+
"0500000000000000000000000000000000000000000000000000000000000000"), // array[1][2]
361+
},
362+
363+
{
364+
"bytes32[][2]",
365+
[][]common.Hash{{{1}, {2}}, {{3}, {4}, {5}}},
366+
common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000040" + // offset 64 to i = 0
367+
"00000000000000000000000000000000000000000000000000000000000000a0" + // offset 160 to i = 1
368+
"0000000000000000000000000000000000000000000000000000000000000002" + // len(array[0]) = 2
369+
"0100000000000000000000000000000000000000000000000000000000000000" + // array[0][0]
370+
"0200000000000000000000000000000000000000000000000000000000000000" + // array[0][1]
371+
"0000000000000000000000000000000000000000000000000000000000000003" + // len(array[1]) = 3
372+
"0300000000000000000000000000000000000000000000000000000000000000" + // array[1][0]
373+
"0400000000000000000000000000000000000000000000000000000000000000" + // array[1][1]
374+
"0500000000000000000000000000000000000000000000000000000000000000"), // array[1][2]
375+
},
376+
377+
{
378+
"bytes32[3][2]",
379+
[][]common.Hash{{{1}, {2}, {3}}, {{3}, {4}, {5}}},
380+
common.Hex2Bytes("0100000000000000000000000000000000000000000000000000000000000000" + // array[0][0]
381+
"0200000000000000000000000000000000000000000000000000000000000000" + // array[0][1]
382+
"0300000000000000000000000000000000000000000000000000000000000000" + // array[0][2]
383+
"0300000000000000000000000000000000000000000000000000000000000000" + // array[1][0]
384+
"0400000000000000000000000000000000000000000000000000000000000000" + // array[1][1]
385+
"0500000000000000000000000000000000000000000000000000000000000000"), // array[1][2]
386+
},
327387
} {
328388
typ, err := NewType(test.typ)
329389
if err != nil {
@@ -336,7 +396,7 @@ func TestPack(t *testing.T) {
336396
}
337397

338398
if !bytes.Equal(output, test.output) {
339-
t.Errorf("%d failed. Expected bytes: '%x' Got: '%x'", i, test.output, output)
399+
t.Errorf("input %d for typ: %v failed. Expected bytes: '%x' Got: '%x'", i, typ.String(), test.output, output)
340400
}
341401
}
342402
}

accounts/abi/type.go

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -183,27 +183,67 @@ func (t Type) pack(v reflect.Value) ([]byte, error) {
183183
return nil, err
184184
}
185185

186-
if t.T == SliceTy || t.T == ArrayTy {
187-
var packed []byte
186+
switch t.T {
187+
case SliceTy, ArrayTy:
188+
var ret []byte
188189

190+
if t.requiresLengthPrefix() {
191+
// append length
192+
ret = append(ret, packNum(reflect.ValueOf(v.Len()))...)
193+
}
194+
195+
// calculate offset if any
196+
offset := 0
197+
offsetReq := isDynamicType(*t.Elem)
198+
if offsetReq {
199+
offset = getDynamicTypeOffset(*t.Elem) * v.Len()
200+
}
201+
var tail []byte
189202
for i := 0; i < v.Len(); i++ {
190203
val, err := t.Elem.pack(v.Index(i))
191204
if err != nil {
192205
return nil, err
193206
}
194-
packed = append(packed, val...)
195-
}
196-
if t.T == SliceTy {
197-
return packBytesSlice(packed, v.Len()), nil
198-
} else if t.T == ArrayTy {
199-
return packed, nil
207+
if !offsetReq {
208+
ret = append(ret, val...)
209+
continue
210+
}
211+
ret = append(ret, packNum(reflect.ValueOf(offset))...)
212+
offset += len(val)
213+
tail = append(tail, val...)
200214
}
215+
return append(ret, tail...), nil
216+
default:
217+
return packElement(t, v), nil
201218
}
202-
return packElement(t, v), nil
203219
}
204220

205221
// requireLengthPrefix returns whether the type requires any sort of length
206222
// prefixing.
207223
func (t Type) requiresLengthPrefix() bool {
208224
return t.T == StringTy || t.T == BytesTy || t.T == SliceTy
209225
}
226+
227+
// isDynamicType returns true if the type is dynamic.
228+
// StringTy, BytesTy, and SliceTy(irrespective of slice element type) are dynamic types
229+
// ArrayTy is considered dynamic if and only if the Array element is a dynamic type.
230+
// This function recursively checks the type for slice and array elements.
231+
func isDynamicType(t Type) bool {
232+
// dynamic types
233+
// array is also a dynamic type if the array type is dynamic
234+
return t.T == StringTy || t.T == BytesTy || t.T == SliceTy || (t.T == ArrayTy && isDynamicType(*t.Elem))
235+
}
236+
237+
// getDynamicTypeOffset returns the offset for the type.
238+
// See `isDynamicType` to know which types are considered dynamic.
239+
// If the type t is an array and element type is not a dynamic type, then we consider it a static type and
240+
// return 32 * size of array since length prefix is not required.
241+
// If t is a dynamic type or element type(for slices and arrays) is dynamic, then we simply return 32 as offset.
242+
func getDynamicTypeOffset(t Type) int {
243+
// if it is an array and there are no dynamic types
244+
// then the array is static type
245+
if t.T == ArrayTy && !isDynamicType(*t.Elem) {
246+
return 32 * t.Size
247+
}
248+
return 32
249+
}

accounts/keystore/account_cache.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,10 @@ func (ac *accountCache) scanAccounts() error {
266266
case (addr == common.Address{}):
267267
log.Debug("Failed to decode keystore key", "path", path, "err", "missing or zero address")
268268
default:
269-
return &accounts.Account{Address: addr, URL: accounts.URL{Scheme: KeyStoreScheme, Path: path}}
269+
return &accounts.Account{
270+
Address: addr,
271+
URL: accounts.URL{Scheme: KeyStoreScheme, Path: path},
272+
}
270273
}
271274
return nil
272275
}

accounts/keystore/key.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,10 @@ func storeNewKey(ks keyStore, rand io.Reader, auth string) (*Key, accounts.Accou
171171
if err != nil {
172172
return nil, accounts.Account{}, err
173173
}
174-
a := accounts.Account{Address: key.Address, URL: accounts.URL{Scheme: KeyStoreScheme, Path: ks.JoinPath(keyFileName(key.Address))}}
174+
a := accounts.Account{
175+
Address: key.Address,
176+
URL: accounts.URL{Scheme: KeyStoreScheme, Path: ks.JoinPath(keyFileName(key.Address))},
177+
}
175178
if err := ks.StoreKey(a.URL.Path, key, auth); err != nil {
176179
zeroKey(key.PrivateKey)
177180
return nil, a, err
@@ -224,5 +227,6 @@ func toISO8601(t time.Time) string {
224227
} else {
225228
tz = fmt.Sprintf("%03d00", offset/3600)
226229
}
227-
return fmt.Sprintf("%04d-%02d-%02dT%02d-%02d-%02d.%09d%s", t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), tz)
230+
return fmt.Sprintf("%04d-%02d-%02dT%02d-%02d-%02d.%09d%s",
231+
t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), tz)
228232
}

accounts/keystore/keystore_passphrase.go renamed to accounts/keystore/passphrase.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ func DecryptKey(keyjson []byte, auth string) (*Key, error) {
233233
PrivateKey: key,
234234
}, nil
235235
}
236+
236237
func DecryptDataV3(cryptoJson CryptoJSON, auth string) ([]byte, error) {
237238
if cryptoJson.Cipher != "aes-128-ctr" {
238239
return nil, fmt.Errorf("Cipher not supported: %v", cryptoJson.Cipher)

0 commit comments

Comments
 (0)