From 5db3335dce766bd679c54ea44f6df08a7ff74762 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 26 Dec 2013 12:45:52 +0100 Subject: [PATCH 001/459] Initial commit --- .ethereum.go.un~ | Bin 0 -> 341697 bytes big.go | 20 +++++ block.go | 21 +++++ block_manager.go | 55 +++++++++++++ ethereum.go | 33 ++++++++ parsing.go | 113 ++++++++++++++++++++++++++ parsing_test.go | 42 ++++++++++ serialization.go | 57 +++++++++++++ serialization_test.go | 20 +++++ transaction.go | 126 +++++++++++++++++++++++++++++ vm.go | 182 ++++++++++++++++++++++++++++++++++++++++++ 11 files changed, 669 insertions(+) create mode 100644 .ethereum.go.un~ create mode 100644 big.go create mode 100644 block.go create mode 100644 block_manager.go create mode 100644 ethereum.go create mode 100644 parsing.go create mode 100644 parsing_test.go create mode 100644 serialization.go create mode 100644 serialization_test.go create mode 100644 transaction.go create mode 100644 vm.go diff --git a/.ethereum.go.un~ b/.ethereum.go.un~ new file mode 100644 index 0000000000000000000000000000000000000000..42e42bcb6e88f9bb1c9bf6e5e4a3cbefcaac2fc2 GIT binary patch literal 341697 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 Date: Thu, 26 Dec 2013 12:46:02 +0100 Subject: [PATCH 002/459] Initial commit --- .ethereum.go.un~ | Bin 341697 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .ethereum.go.un~ diff --git a/.ethereum.go.un~ b/.ethereum.go.un~ deleted file mode 100644 index 42e42bcb6e88f9bb1c9bf6e5e4a3cbefcaac2fc2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 341697 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 Date: Thu, 26 Dec 2013 12:47:06 +0100 Subject: [PATCH 003/459] added git ignore --- .gitignore | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..f725d58d1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. +# +# If you find yourself ignoring temporary files generated by your text editor +# or operating system, you probably want to add a global ignore instead: +# git config --global core.excludesfile ~/.gitignore_global + +/tmp +*/**/*un~ +*un~ +.DS_Store +*/**/.DS_Store + From fe5577f59e0b5b254013263675e7a0989e7cd82a Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 26 Dec 2013 13:29:45 +0100 Subject: [PATCH 004/459] Added readme --- README | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 README diff --git a/README b/README new file mode 100644 index 000000000..20e704bf8 --- /dev/null +++ b/README @@ -0,0 +1,14 @@ +This is the Go implementation of the Ethereum protocol. It's for from being finished. + +The Python reference implementation can be found at https://github.com/vbuterin/pyethereum + +More information about the protocol: +* http://vitalik.ca/ethereum.html +* http://vitalik.ca/ethereum/spec.html +* http://vitalik.ca/ethereum/patricia.html +* http://vitalik.ca/ethereum/dagger.html +* http://vitalik.ca/ethereum/rlp.html + +# TODO + +Fix this todo file! From 486710c17c71f456e48b40052b1bd392d58e01f3 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 26 Dec 2013 13:30:42 +0100 Subject: [PATCH 005/459] for => far --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 20e704bf8..ad6cb58e6 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -This is the Go implementation of the Ethereum protocol. It's for from being finished. +This is the Go implementation of the Ethereum protocol. It's far from being finished. The Python reference implementation can be found at https://github.com/vbuterin/pyethereum From b71e632b467d27710961fce21dcd4453d37c818a Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 26 Dec 2013 13:35:04 +0100 Subject: [PATCH 006/459] go get --- README | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README b/README index ad6cb58e6..3bba4210f 100644 --- a/README +++ b/README @@ -1,5 +1,7 @@ This is the Go implementation of the Ethereum protocol. It's far from being finished. +`go get https://github.com/obscuren/ethereum` + The Python reference implementation can be found at https://github.com/vbuterin/pyethereum More information about the protocol: From aacfdc7a47507e69c48756221a0ba67459e47553 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 26 Dec 2013 14:07:52 +0100 Subject: [PATCH 007/459] moved' --- serialization.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/serialization.go b/serialization.go index 7e2e96beb..613dcdcc5 100644 --- a/serialization.go +++ b/serialization.go @@ -53,5 +53,7 @@ func RlpEncode(object interface{}) string { } type RlpSerializer interface { + MarshalRls() []byte + UnmarshalRls([]byte) } From 2368459814d7dea9706d8f0a914ff4575427ef67 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 26 Dec 2013 14:09:50 +0100 Subject: [PATCH 008/459] updated readme --- README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README b/README index 3bba4210f..9d08d7f8e 100644 --- a/README +++ b/README @@ -1,8 +1,8 @@ This is the Go implementation of the Ethereum protocol. It's far from being finished. -`go get https://github.com/obscuren/ethereum` + go get https://github.com/ethereum/go-ethereum -The Python reference implementation can be found at https://github.com/vbuterin/pyethereum +The Python reference implementation can be found at https://github.com/ethereum/pyethereum More information about the protocol: * http://vitalik.ca/ethereum.html From ec13db873aa43368bfb155dad03ef537e4635717 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 27 Dec 2013 11:59:00 +0100 Subject: [PATCH 009/459] Added travis --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..69359072d --- /dev/null +++ b/.travis.yml @@ -0,0 +1,3 @@ +language: go +go: + - 1.2 From b40013ac30006fe5a43abdca574b438cf60db86e Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 27 Dec 2013 12:07:37 +0100 Subject: [PATCH 010/459] Updated fees --- transaction.go | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/transaction.go b/transaction.go index f78715d8c..26d7df258 100644 --- a/transaction.go +++ b/transaction.go @@ -21,12 +21,13 @@ data ops * signature signature 64 bytes */ -var StepFee *big.Int = new(big.Int) -var TxFee *big.Int = new(big.Int) -var MemFee *big.Int = new(big.Int) -var DataFee *big.Int = new(big.Int) -var CryptoFee *big.Int = new(big.Int) -var ExtroFee *big.Int = new(big.Int) +var StepFee *big.Int = new(big.Int) +var TxFee *big.Int = new(big.Int) +var ContractFee *big.Int = new(big.Int) +var MemFee *big.Int = new(big.Int) +var DataFee *big.Int = new(big.Int) +var CryptoFee *big.Int = new(big.Int) +var ExtroFee *big.Int = new(big.Int) var Period1Reward *big.Int = new(big.Int) var Period2Reward *big.Int = new(big.Int) @@ -89,27 +90,30 @@ func (tx *Transaction) Serialize() string { func InitFees() { // Base for 2**60 b60 := new(big.Int) - b60.Exp(big.NewInt(2), big.NewInt(60), big.NewInt(0)) + b60.Exp(big.NewInt(2), big.NewInt(64), big.NewInt(0)) // Base for 2**80 b80 := new(big.Int) b80.Exp(big.NewInt(2), big.NewInt(80), big.NewInt(0)) - StepFee.Mul(b60, big.NewInt(4096)) + StepFee.Div(b60, big.NewInt(64)) //fmt.Println("StepFee:", StepFee) - TxFee.Mul(b60, big.NewInt(524288)) + TxFee.Exp(big.NewInt(2), big.NewInt(64), big.NewInt(0)) //fmt.Println("TxFee:", TxFee) - MemFee.Mul(b60, big.NewInt(262144)) + ContractFee.Exp(big.NewInt(2), big.NewInt(64), big.NewInt(0)) + //fmt.Println("ContractFee:", ContractFee) + + MemFee.Div(b60, big.NewInt(4)) //fmt.Println("MemFee:", MemFee) - DataFee.Mul(b60, big.NewInt(16384)) + DataFee.Div(b60, big.NewInt(16)) //fmt.Println("DataFee:", DataFee) - CryptoFee.Mul(b60, big.NewInt(65536)) + CryptoFee.Div(b60, big.NewInt(16)) //fmt.Println("CrytoFee:", CryptoFee) - ExtroFee.Mul(b60, big.NewInt(65536)) + ExtroFee.Div(b60, big.NewInt(16)) //fmt.Println("ExtroFee:", ExtroFee) Period1Reward.Mul(b80, big.NewInt(1024)) From d5d2efbaf3c3a84f0084058eacd535d077c363e1 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 27 Dec 2013 21:20:47 +0100 Subject: [PATCH 011/459] WIP new rlp implementation --- rlp.go | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 rlp.go diff --git a/rlp.go b/rlp.go new file mode 100644 index 000000000..2c722cf7a --- /dev/null +++ b/rlp.go @@ -0,0 +1,52 @@ +package main + +import ( + _"fmt" + "bytes" + "math" +) + +func EncodeSlice(slice []interface{}) []byte { + var buff bytes.Buffer + + for _, val := range slice { + switch t := val.(type) { + case []interface{}, []string: + buff.Write(Encode(t)) + } + } + + return buff.Bytes() +} + +func Encode(object interface{}) []byte { + var buff bytes.Buffer + + switch t := object.(type) { + case string: + if len(t) < 56 { + buff.WriteString(string(len(t) + 64) + t) + } else { + + } + case uint32, uint64: + var num uint64 + if _num, ok := t.(uint64); ok { + num = _num + } else if _num, ok := t.(uint32); ok { + num = uint64(_num) + } + + if num >= 0 && num < 24 { + buff.WriteString(string(num)) + } else if num <= uint64(math.Pow(2, 256)) { + } + case []byte: + // Cast the byte slice to a string + buff.Write(Encode(string(t))) + case []interface{}: + buff.Write(EncodeSlice(t)) + } + + return buff.Bytes() +} From d8c0b0c89906edada0a30d144ebeb116388b45b1 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 27 Dec 2013 21:21:08 +0100 Subject: [PATCH 012/459] Moved string util --- util.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 util.go diff --git a/util.go b/util.go new file mode 100644 index 000000000..fc06673d2 --- /dev/null +++ b/util.go @@ -0,0 +1,23 @@ +package main + +import ( + "strconv" + "crypto/sha256" + "encoding/hex" +) + +func Uitoa(i uint32) string { + return strconv.FormatUint(uint64(i), 10) +} + +func Sha256Hex(data []byte) string { + hash := sha256.Sum256(data) + + return hex.EncodeToString(hash[:]) +} + +func Sha256Bin(data []byte) []byte { + hash := sha256.Sum256(data) + + return hash[:] +} From 8301d154ae4bb6082d588bd42c6e913be63618ef Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 27 Dec 2013 21:22:57 +0100 Subject: [PATCH 013/459] Serializing block --- block.go | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/block.go b/block.go index a0bcf0bd0..f8bf2ce3b 100644 --- a/block.go +++ b/block.go @@ -2,16 +2,29 @@ package main import ( _"fmt" + "time" ) type Block struct { - transactions []*Transaction + RlpSerializer + + number uint32 + prevHash string + uncles []*Block + coinbase string + // state xxx + difficulty int + time time.Time + nonce int + transactions []*Transaction } func NewBlock(/* TODO use raw data */transactions []*Transaction) *Block { block := &Block{ // Slice of transactions to include in this block transactions: transactions, + + time: time.Now(), } return block @@ -19,3 +32,33 @@ func NewBlock(/* TODO use raw data */transactions []*Transaction) *Block { func (block *Block) Update() { } + +func (block *Block) Hash() string { + return Sha256Hex(block.MarshalRlp()) +} + +func (block *Block) MarshalRlp() []byte { + // Encoding method requires []interface{} type. It's actual a slice of strings + encTx := make([]string, len(block.transactions)) + for i, tx := range block.transactions { + encTx[i] = string(tx.MarshalRlp()) + } + + enc := RlpEncode([]interface{}{ + block.number, + block.prevHash, + // Sha of uncles + block.coinbase, + // root state + Sha256Bin([]byte(RlpEncode(encTx))), + block.difficulty, + block.time, + block.nonce, + // extra? + }) + + return []byte(enc) +} + +func (block *Block) UnmarshalRlp(data []byte) { +} From dca9ee79b3a27ba2cc5d026d445ae627a53617b0 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 27 Dec 2013 21:23:40 +0100 Subject: [PATCH 014/459] Changed Tx serialization to return bytes instead of a string --- serialization.go | 8 ++++++-- transaction.go | 16 +++++++--------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/serialization.go b/serialization.go index 613dcdcc5..5a92a434f 100644 --- a/serialization.go +++ b/serialization.go @@ -28,6 +28,10 @@ func NumToVarInt(x int) string { func RlpEncode(object interface{}) string { if str, ok := object.(string); ok { return "\x00" + NumToVarInt(len(str)) + str + } else if num, ok := object.(uint32); ok { + return RlpEncode(Uitoa(num)) + } else if byt, ok := object.([]byte); ok { + return RlpEncode(string(byt)) } else if slice, ok := object.([]interface{}); ok { var buffer bytes.Buffer for _, val := range slice { @@ -53,7 +57,7 @@ func RlpEncode(object interface{}) string { } type RlpSerializer interface { - MarshalRls() []byte - UnmarshalRls([]byte) + MarshalRlp() []byte + UnmarshalRlp([]byte) } diff --git a/transaction.go b/transaction.go index 26d7df258..5a268b566 100644 --- a/transaction.go +++ b/transaction.go @@ -6,7 +6,6 @@ import ( "encoding/hex" "crypto/sha256" _ "bytes" - "strconv" ) /* @@ -35,14 +34,17 @@ var Period3Reward *big.Int = new(big.Int) var Period4Reward *big.Int = new(big.Int) type Transaction struct { + RlpSerializer + sender string recipient uint32 value uint32 fee uint32 data []string memory []int - signature string + // To be removed + signature string addr string } @@ -61,18 +63,14 @@ func NewTransaction(to uint32, value uint32, data []string) *Transaction { tx.data[i] = instr } - b:= []byte(tx.Serialize()) + b:= []byte(tx.MarshalRlp()) hash := sha256.Sum256(b) tx.addr = hex.EncodeToString(hash[0:19]) return &tx } -func Uitoa(i uint32) string { - return strconv.FormatUint(uint64(i), 10) -} - -func (tx *Transaction) Serialize() string { +func (tx *Transaction) MarshalRlp() []byte { // Prepare the transaction for serialization preEnc := []interface{}{ "0", // TODO last Tx @@ -84,7 +82,7 @@ func (tx *Transaction) Serialize() string { tx.data, } - return RlpEncode(preEnc) + return []byte(RlpEncode(preEnc)) } func InitFees() { From df0fe67fce8050dad60f0d0fca28a78da818832f Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 27 Dec 2013 21:24:06 +0100 Subject: [PATCH 015/459] Testing --- ethereum.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ethereum.go b/ethereum.go index 530cbd5c1..78f08c15e 100644 --- a/ethereum.go +++ b/ethereum.go @@ -29,5 +29,7 @@ func main() { bm.ProcessBlock( blck ) - fmt.Printf("rlp encoded Tx %q\n", tx.Serialize()) + //fmt.Printf("rlp encoded Tx %q\n", tx.MarshalRlp()) + fmt.Printf("block enc %q\n", blck.MarshalRlp()) + fmt.Printf("block hash %q\n", blck.Hash()) } From 323ba36869126520c294b6c8acacfa9877cde5c7 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 27 Dec 2013 22:32:55 +0100 Subject: [PATCH 016/459] Updated rlp encoding. (requires verification!) --- rlp.go | 91 +++++++++++++++++++++++++++++++++++++++++++---------- rlp_test.go | 20 ++++++++++++ 2 files changed, 95 insertions(+), 16 deletions(-) create mode 100644 rlp_test.go diff --git a/rlp.go b/rlp.go index 2c722cf7a..cce839095 100644 --- a/rlp.go +++ b/rlp.go @@ -6,29 +6,51 @@ import ( "math" ) -func EncodeSlice(slice []interface{}) []byte { - var buff bytes.Buffer +func BinaryLength(n uint64) uint64 { + if n == 0 { return 0 } - for _, val := range slice { - switch t := val.(type) { - case []interface{}, []string: - buff.Write(Encode(t)) - } + return 1 + BinaryLength(n / 256) +} + +func ToBinarySlice(n uint64, length uint64) []uint64 { + if length == 0 { + length = BinaryLength(n) } - return buff.Bytes() + if n == 0 { return make([]uint64, 1) } + + slice := ToBinarySlice(n / 256, 0) + slice = append(slice, n % 256) + + return slice +} + +func ToBin(n uint64, length uint64) string { + var buf bytes.Buffer + for _, val := range ToBinarySlice(n, length) { + buf.WriteString(string(val)) + } + + return buf.String() +} + +func FromBin(data []byte) uint64 { + if len(data) == 0 { return 0 } + + return FromBin(data[:len(data)-1]) * 256 + uint64(data[len(data)-1]) +} + +func Decode(data []byte, pos int) { + char := int(data[pos]) + switch { + case char < 24: + } } func Encode(object interface{}) []byte { var buff bytes.Buffer switch t := object.(type) { - case string: - if len(t) < 56 { - buff.WriteString(string(len(t) + 64) + t) - } else { - - } case uint32, uint64: var num uint64 if _num, ok := t.(uint64); ok { @@ -40,12 +62,49 @@ func Encode(object interface{}) []byte { if num >= 0 && num < 24 { buff.WriteString(string(num)) } else if num <= uint64(math.Pow(2, 256)) { + b := ToBin(num, 0) + buff.WriteString(string(len(b) + 23) + b) + } else { + b := ToBin(num, 0) + b2 := ToBin(uint64(len(b)), 0) + buff.WriteString(string(len(b2) + 55) + b2 + b) } + + case string: + if len(t) < 56 { + buff.WriteString(string(len(t) + 64) + t) + } else { + b2 := ToBin(uint64(len(t)), 0) + buff.WriteString(string(len(b2) + 119) + b2 + t) + } + case []byte: // Cast the byte slice to a string buff.Write(Encode(string(t))) - case []interface{}: - buff.Write(EncodeSlice(t)) + + case []interface{}, []string: + // Inline function for writing the slice header + WriteSliceHeader := func(length int) { + if length < 56 { + buff.WriteString(string(length + 128)) + } else { + b2 := ToBin(uint64(length), 0) + buff.WriteString(string(len(b2) + 183) + b2) + } + } + + // FIXME How can I do this "better"? + if interSlice, ok := t.([]interface{}); ok { + WriteSliceHeader(len(interSlice)) + for _, val := range interSlice { + buff.Write(Encode(val)) + } + } else if stringSlice, ok := t.([]string); ok { + WriteSliceHeader(len(stringSlice)) + for _, val := range stringSlice { + buff.Write(Encode(val)) + } + } } return buff.Bytes() diff --git a/rlp_test.go b/rlp_test.go new file mode 100644 index 000000000..922b70978 --- /dev/null +++ b/rlp_test.go @@ -0,0 +1,20 @@ +package main + +import ( + "testing" + "fmt" +) + +func TestEncode(t *testing.T) { + strRes := "Cdog" + str := string(Encode("dog")) + if str != strRes { + t.Error(fmt.Sprintf("Expected %q, got %q", strRes, str)) + } + + sliceRes := "\u0083CdogCgodCcat" + slice := string(Encode([]string{"dog", "god", "cat"})) + if slice != sliceRes { + t.Error(fmt.Sprintf("Expected %q, got %q", sliceRes, slice)) + } +} From 0f656652e6d76deebcfc7834923adf99eadc050f Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 27 Dec 2013 23:48:44 +0100 Subject: [PATCH 017/459] Implemented decoding rlp --- rlp.go | 51 +++++++++++++++++++++++++++++++++++++++++++++++---- rlp_test.go | 15 ++++++++++++--- 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/rlp.go b/rlp.go index cce839095..2ea8ff094 100644 --- a/rlp.go +++ b/rlp.go @@ -1,7 +1,7 @@ package main import ( - _"fmt" + "fmt" "bytes" "math" ) @@ -40,11 +40,53 @@ func FromBin(data []byte) uint64 { return FromBin(data[:len(data)-1]) * 256 + uint64(data[len(data)-1]) } -func Decode(data []byte, pos int) { +func Decode(data []byte, pos int) (interface{}, int) { char := int(data[pos]) + slice := make([]interface{}, 0) switch { case char < 24: + return append(slice, data[pos]), pos + 1 + case char < 56: + b := int(data[pos]) - 23 + return FromBin(data[pos+1 : pos+1+b]), pos + 1 + b + case char < 64: + b := int(data[pos]) - 55 + b2 := int(FromBin(data[pos+1 : pos+1+b])) + return FromBin(data[pos+1+b : pos+1+b+b2]), pos+1+b+b2 + case char < 120: + b := int(data[pos]) - 64 + return data[pos+1:pos+1+b], pos+1+b + case char < 128: + b := int(data[pos]) - 119 + b2 := int(FromBin(data[pos+1 : pos+1+b])) + return data[pos+1+b : pos+1+b+b2], pos+1+b+b2 + case char < 184: + b := int(data[pos]) - 128 + pos++ + for i := 0; i < b; i++ { + var obj interface{} + + obj, pos = Decode(data, pos) + slice = append(slice, obj) + } + return slice, pos + case char < 192: + b := int(data[pos]) - 183 + //b2 := int(FromBin(data[pos+1 : pos+1+b])) (ref imprementation has an unused variable) + pos = pos+1+b + for i := 0; i < b; i++ { + var obj interface{} + + obj, pos = Decode(data, pos) + slice = append(slice, obj) + } + return slice, pos + + default: + panic(fmt.Sprintf("byte not supported: %q", char)) } + + return slice, 0 } func Encode(object interface{}) []byte { @@ -86,10 +128,11 @@ func Encode(object interface{}) []byte { // Inline function for writing the slice header WriteSliceHeader := func(length int) { if length < 56 { - buff.WriteString(string(length + 128)) + buff.WriteByte(byte(length + 128)) } else { b2 := ToBin(uint64(length), 0) - buff.WriteString(string(len(b2) + 183) + b2) + buff.WriteByte(byte(len(b2) + 183)) + buff.WriteString(b2) } } diff --git a/rlp_test.go b/rlp_test.go index 922b70978..c2d5ba263 100644 --- a/rlp_test.go +++ b/rlp_test.go @@ -7,14 +7,23 @@ import ( func TestEncode(t *testing.T) { strRes := "Cdog" - str := string(Encode("dog")) + bytes := Encode("dog") + str := string(bytes) if str != strRes { t.Error(fmt.Sprintf("Expected %q, got %q", strRes, str)) } + dec,_ := Decode(bytes, 0) + fmt.Printf("raw: %v encoded: %q == %v\n", dec, str, "dog") - sliceRes := "\u0083CdogCgodCcat" - slice := string(Encode([]string{"dog", "god", "cat"})) + + sliceRes := "\x83CdogCgodCcat" + strs := []string{"dog", "god", "cat"} + bytes = Encode(strs) + slice := string(bytes) if slice != sliceRes { t.Error(fmt.Sprintf("Expected %q, got %q", sliceRes, slice)) } + + dec,_ = Decode(bytes, 0) + fmt.Printf("raw: %v encoded: %q == %v\n", dec, slice, strs) } From c7dc92e1270c3e2522edc10d9e757d9be48c0789 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 28 Dec 2013 01:46:18 +0100 Subject: [PATCH 018/459] Reset stack pointer on run --- vm.go | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/vm.go b/vm.go index 353f4f39e..dc026f318 100644 --- a/vm.go +++ b/vm.go @@ -60,8 +60,6 @@ type TxCallback func(opType OpType) bool type Vm struct { // Memory stack stack map[string]string - // Index ptr - iptr int memory map[string]map[string]string } @@ -71,7 +69,10 @@ func NewVm() *Vm { stackSize := uint(256) fmt.Println("stack size =", stackSize) - return &Vm{make(map[string]string), 0, make(map[string]map[string]string)} + return &Vm{ + stack: make(map[string]string), + memory: make(map[string]map[string]string), + } } func (vm *Vm) RunTransaction(tx *Transaction, cb TxCallback) { @@ -84,6 +85,8 @@ func (vm *Vm) RunTransaction(tx *Transaction, cb TxCallback) { vm.stack["0"] = tx.sender vm.stack["1"] = "100" //int(tx.value) vm.stack["1"] = "1000" //int(tx.fee) + // Stack pointer + stPtr := 0 //vm.memory[tx.addr] = make([]int, 256) vm.memory[tx.addr] = make(map[string]string) @@ -93,13 +96,13 @@ func (vm *Vm) RunTransaction(tx *Transaction, cb TxCallback) { // Instructions are shorthanded as Ix/y/z x := 0; y := 1; z := 2; //a := 3; b := 4; c := 5 out: - for vm.iptr < len(tx.data) { + for stPtr < len(tx.data) { // The base big int for all calculations. Use this for any results. base := new(big.Int) // XXX Should Instr return big int slice instead of string slice? - op, args, _ := Instr(tx.data[vm.iptr]) + op, args, _ := Instr(tx.data[stPtr]) - fmt.Printf("%-3d %d %v\n", vm.iptr, op, args) + fmt.Printf("%-3d %d %v\n", stPtr, op, args) opType := OpType(tNorm) // Determine the op type (used for calculating fees by the block manager) @@ -113,7 +116,7 @@ out: // If the callback yielded a negative result abort execution if !cb(opType) { break out } - nptr := vm.iptr + nptr := stPtr switch op { case oSTOP: fmt.Println("exiting (oSTOP), idx =", nptr) @@ -171,10 +174,10 @@ out: break } - if vm.iptr == nptr { - vm.iptr++ + if stPtr == nptr { + stPtr++ } else { - vm.iptr = nptr + stPtr = nptr fmt.Println("... JMP", nptr, "...") } } From 8391d3d4f49b55ea719e5524306a0dcf90d6e7ab Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 28 Dec 2013 02:22:42 +0100 Subject: [PATCH 019/459] Unmarshalling of transactions --- transaction.go | 69 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 61 insertions(+), 8 deletions(-) diff --git a/transaction.go b/transaction.go index 5a268b566..cb7edd89c 100644 --- a/transaction.go +++ b/transaction.go @@ -37,20 +37,22 @@ type Transaction struct { RlpSerializer sender string - recipient uint32 + recipient string value uint32 fee uint32 data []string memory []int + lastTx string // To be removed signature string addr string } -func NewTransaction(to uint32, value uint32, data []string) *Transaction { +func NewTransaction(to string, value uint32, data []string) *Transaction { tx := Transaction{sender: "1234567890", recipient: to, value: value} tx.fee = 0//uint32((ContractFee + MemoryFee * float32(len(tx.data))) * 1e8) + tx.lastTx = "0" // Serialize the data tx.data = make([]string, len(data)) @@ -73,16 +75,67 @@ func NewTransaction(to uint32, value uint32, data []string) *Transaction { func (tx *Transaction) MarshalRlp() []byte { // Prepare the transaction for serialization preEnc := []interface{}{ - "0", // TODO last Tx + tx.lastTx, tx.sender, - // XXX In the future there's no need to cast to string because they'll end up being big numbers (strings) - Uitoa(tx.recipient), - Uitoa(tx.value), - Uitoa(tx.fee), + tx.recipient, + tx.value, + tx.fee, tx.data, } - return []byte(RlpEncode(preEnc)) + return []byte(Encode(preEnc)) +} + +func (tx *Transaction) UnmarshalRlp(data []byte) { + t, _ := Decode(data,0) + if slice, ok := t.([]interface{}); ok { + if lastTx, ok := slice[0].([]byte); ok { + tx.lastTx = string(lastTx) + } + + if sender, ok := slice[1].([]byte); ok { + tx.sender = string(sender) + } + + if recipient, ok := slice[2].([]byte); ok { + tx.recipient = string(recipient) + } + + // If only I knew of a better way. + if value, ok := slice[3].(uint8); ok { + tx.value = uint32(value) + } + if value, ok := slice[3].(uint16); ok { + tx.value = uint32(value) + } + if value, ok := slice[3].(uint32); ok { + tx.value = uint32(value) + } + if value, ok := slice[3].(uint64); ok { + tx.value = uint32(value) + } + if fee, ok := slice[4].(uint8); ok { + tx.fee = uint32(fee) + } + if fee, ok := slice[4].(uint16); ok { + tx.fee = uint32(fee) + } + if fee, ok := slice[4].(uint32); ok { + tx.fee = uint32(fee) + } + if fee, ok := slice[4].(uint64); ok { + tx.fee = uint32(fee) + } + + if data, ok := slice[5].([]interface{}); ok { + tx.data = make([]string, len(data)) + for i, d := range data { + if instr, ok := d.([]byte); ok { + tx.data[i] = string(instr) + } + } + } + } } func InitFees() { From d6460f3de171f018860ea9c3f4a69536c8ef82ac Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 28 Dec 2013 02:23:28 +0100 Subject: [PATCH 020/459] Changed 0x0 to \x00 --- block_manager.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block_manager.go b/block_manager.go index 4f0ec1cdb..80b30eff6 100644 --- a/block_manager.go +++ b/block_manager.go @@ -42,7 +42,7 @@ func (bm *BlockManager) ProcessBlock(block *Block) error { } func (bm *BlockManager) ProcessTransaction(tx *Transaction, lockChan chan bool) { - if tx.recipient == 0x0 { + if tx.recipient == "\x00" { bm.vm.RunTransaction(tx, func(opType OpType) bool { // TODO calculate fees From 5a7eae705b83d75cb780279e386f183c4b6e19c6 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 28 Dec 2013 02:24:01 +0100 Subject: [PATCH 021/459] Removed slice appending for integers --- rlp.go | 4 ++-- rlp_test.go | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/rlp.go b/rlp.go index 2ea8ff094..2c04317ae 100644 --- a/rlp.go +++ b/rlp.go @@ -45,7 +45,7 @@ func Decode(data []byte, pos int) (interface{}, int) { slice := make([]interface{}, 0) switch { case char < 24: - return append(slice, data[pos]), pos + 1 + return data[pos], pos + 1 case char < 56: b := int(data[pos]) - 23 return FromBin(data[pos+1 : pos+1+b]), pos + 1 + b @@ -72,7 +72,7 @@ func Decode(data []byte, pos int) (interface{}, int) { return slice, pos case char < 192: b := int(data[pos]) - 183 - //b2 := int(FromBin(data[pos+1 : pos+1+b])) (ref imprementation has an unused variable) + //b2 := int(FromBin(data[pos+1 : pos+1+b])) (ref implementation has an unused variable) pos = pos+1+b for i := 0; i < b; i++ { var obj interface{} diff --git a/rlp_test.go b/rlp_test.go index c2d5ba263..ae8dcced4 100644 --- a/rlp_test.go +++ b/rlp_test.go @@ -15,7 +15,6 @@ func TestEncode(t *testing.T) { dec,_ := Decode(bytes, 0) fmt.Printf("raw: %v encoded: %q == %v\n", dec, str, "dog") - sliceRes := "\x83CdogCgodCcat" strs := []string{"dog", "god", "cat"} bytes = Encode(strs) @@ -27,3 +26,10 @@ func TestEncode(t *testing.T) { dec,_ = Decode(bytes, 0) fmt.Printf("raw: %v encoded: %q == %v\n", dec, slice, strs) } + +func BenchmarkEncodeDecode(b *testing.B) { + for i := 0; i < b.N; i++ { + bytes := Encode([]string{"dog", "god", "cat"}) + Decode(bytes, 0) + } +} From bb8afba20a56552cef71681f72fb192bcda88c1d Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 28 Dec 2013 02:24:16 +0100 Subject: [PATCH 022/459] Updated tests --- block.go | 27 +++++++++++++++++---------- ethereum.go | 15 ++++++++++----- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/block.go b/block.go index f8bf2ce3b..f666b09db 100644 --- a/block.go +++ b/block.go @@ -1,7 +1,7 @@ package main import ( - _"fmt" + "fmt" "time" ) @@ -44,21 +44,28 @@ func (block *Block) MarshalRlp() []byte { encTx[i] = string(tx.MarshalRlp()) } - enc := RlpEncode([]interface{}{ + header := []interface{}{ block.number, - block.prevHash, + //block.prevHash, // Sha of uncles - block.coinbase, + //block.coinbase, // root state - Sha256Bin([]byte(RlpEncode(encTx))), - block.difficulty, - block.time, - block.nonce, + //Sha256Bin([]byte(RlpEncode(encTx))), + //block.difficulty, + //block.time, + //block.nonce, // extra? - }) + } - return []byte(enc) + return Encode([]interface{}{header, encTx}) } func (block *Block) UnmarshalRlp(data []byte) { + fmt.Printf("%q\n", data) + t, _ := Decode(data,0) + if slice, ok := t.([]interface{}); ok { + if txes, ok := slice[1].([]interface{}); ok { + fmt.Println(txes[0]) + } + } } diff --git a/ethereum.go b/ethereum.go index 78f08c15e..d3cecdc94 100644 --- a/ethereum.go +++ b/ethereum.go @@ -9,7 +9,7 @@ func main() { bm := NewBlockManager() - tx := NewTransaction(0x0, 20, []string{ + tx := NewTransaction("\x00", 20, []string{ "SET 10 6", "LD 10 10", "LT 10 1 20", @@ -23,13 +23,18 @@ func main() { "SET 255 15", "JMP 255", }) - tx2 := NewTransaction(0x0, 20, []string{"SET 10 6", "LD 10 10"}) + txData := tx.MarshalRlp() + + copyTx := &Transaction{} + copyTx.UnmarshalRlp(txData) + + + tx2 := NewTransaction("\x00", 20, []string{"SET 10 6", "LD 10 10"}) blck := NewBlock([]*Transaction{tx2, tx}) bm.ProcessBlock( blck ) - //fmt.Printf("rlp encoded Tx %q\n", tx.MarshalRlp()) - fmt.Printf("block enc %q\n", blck.MarshalRlp()) - fmt.Printf("block hash %q\n", blck.Hash()) + //t := blck.MarshalRlp() + //blck.UnmarshalRlp(t) } From 95d877f701371108dc18967319d1f7b4e6763caf Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 28 Dec 2013 15:17:26 +0100 Subject: [PATCH 023/459] Fixed rlp encoding --- rlp.go | 12 +++++++++++- rlp_test.go | 21 +++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/rlp.go b/rlp.go index 2c04317ae..bc3b6a151 100644 --- a/rlp.go +++ b/rlp.go @@ -41,25 +41,34 @@ func FromBin(data []byte) uint64 { } func Decode(data []byte, pos int) (interface{}, int) { + if pos > len(data)-1 { + panic(fmt.Sprintf("index out of range %d for data %q, l = %d", pos, data, len(data))) + } + char := int(data[pos]) slice := make([]interface{}, 0) switch { case char < 24: return data[pos], pos + 1 + case char < 56: b := int(data[pos]) - 23 return FromBin(data[pos+1 : pos+1+b]), pos + 1 + b + case char < 64: b := int(data[pos]) - 55 b2 := int(FromBin(data[pos+1 : pos+1+b])) return FromBin(data[pos+1+b : pos+1+b+b2]), pos+1+b+b2 + case char < 120: b := int(data[pos]) - 64 return data[pos+1:pos+1+b], pos+1+b + case char < 128: b := int(data[pos]) - 119 b2 := int(FromBin(data[pos+1 : pos+1+b])) return data[pos+1+b : pos+1+b+b2], pos+1+b+b2 + case char < 184: b := int(data[pos]) - 128 pos++ @@ -70,6 +79,7 @@ func Decode(data []byte, pos int) (interface{}, int) { slice = append(slice, obj) } return slice, pos + case char < 192: b := int(data[pos]) - 183 //b2 := int(FromBin(data[pos+1 : pos+1+b])) (ref implementation has an unused variable) @@ -122,7 +132,7 @@ func Encode(object interface{}) []byte { case []byte: // Cast the byte slice to a string - buff.Write(Encode(string(t))) + //buff.Write(Encode(string(t))) case []interface{}, []string: // Inline function for writing the slice header diff --git a/rlp_test.go b/rlp_test.go index ae8dcced4..6a34aecbc 100644 --- a/rlp_test.go +++ b/rlp_test.go @@ -27,6 +27,27 @@ func TestEncode(t *testing.T) { fmt.Printf("raw: %v encoded: %q == %v\n", dec, slice, strs) } +func TestMultiEncode(t *testing.T) { + inter := []interface{}{ + []interface{}{ + "1","2","3", + }, + []string{ + "string", + "string2", + "\x86A0J1234567890A\x00B20A0\x82F395843F657986", + "\x86A0J1234567890A\x00B20A0\x8cF395843F657986I335612448F524099H16716881A0H13114947G2039362G1507139H16719697G1048387E65360", + }, + "test", + } + + bytes := Encode(inter) + fmt.Printf("%q\n", bytes) + + dec, _ := Decode(bytes, 0) + fmt.Println(dec) +} + func BenchmarkEncodeDecode(b *testing.B) { for i := 0; i < b.N; i++ { bytes := Encode([]string{"dog", "god", "cat"}) From bd582d919bf3dfa68cce10ca506c39a4c2e2ea94 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 28 Dec 2013 15:18:08 +0100 Subject: [PATCH 024/459] (un)marshal blocks and transactions --- block.go | 81 +++++++++++++++++++++++++++++++++++++++++--------- transaction.go | 4 +-- 2 files changed, 68 insertions(+), 17 deletions(-) diff --git a/block.go b/block.go index f666b09db..5c089137d 100644 --- a/block.go +++ b/block.go @@ -3,19 +3,18 @@ package main import ( "fmt" "time" + _"bytes" ) type Block struct { - RlpSerializer - number uint32 prevHash string uncles []*Block coinbase string // state xxx - difficulty int + difficulty uint32 time time.Time - nonce int + nonce uint32 transactions []*Transaction } @@ -23,6 +22,11 @@ func NewBlock(/* TODO use raw data */transactions []*Transaction) *Block { block := &Block{ // Slice of transactions to include in this block transactions: transactions, + number: 1, + prevHash: "1234", + coinbase: "me", + difficulty: 10, + nonce: 0, time: time.Now(), } @@ -44,28 +48,77 @@ func (block *Block) MarshalRlp() []byte { encTx[i] = string(tx.MarshalRlp()) } + /* I made up the block. It should probably contain different data or types. It sole purpose now is testing */ header := []interface{}{ block.number, - //block.prevHash, + block.prevHash, // Sha of uncles - //block.coinbase, + "", + block.coinbase, // root state - //Sha256Bin([]byte(RlpEncode(encTx))), - //block.difficulty, - //block.time, - //block.nonce, + "", + string(Sha256Bin([]byte(RlpEncode(encTx)))), + block.difficulty, + block.time.String(), + block.nonce, // extra? } - return Encode([]interface{}{header, encTx}) + encoded := Encode([]interface{}{header, encTx}) + + return encoded } func (block *Block) UnmarshalRlp(data []byte) { - fmt.Printf("%q\n", data) t, _ := Decode(data,0) if slice, ok := t.([]interface{}); ok { - if txes, ok := slice[1].([]interface{}); ok { - fmt.Println(txes[0]) + if header, ok := slice[0].([]interface{}); ok { + if number, ok := header[0].(uint8); ok { + block.number = uint32(number) + } + + if prevHash, ok := header[1].([]byte); ok { + block.prevHash = string(prevHash) + } + + // sha of uncles is header[2] + + if coinbase, ok := header[3].([]byte); ok { + block.coinbase = string(coinbase) + } + + // state is header[header[4] + + // sha is header[5] + + // It's either 8bit or 64 + if difficulty, ok := header[6].(uint8); ok { + block.difficulty = uint32(difficulty) + } + if difficulty, ok := header[6].(uint64); ok { + block.difficulty = uint32(difficulty) + } + + if time, ok := header[7].([]byte); ok { + fmt.Sprintf("Time is: ", string(time)) + } + + if nonce, ok := header[8].(uint8); ok { + block.nonce = uint32(nonce) + } + } + + if txSlice, ok := slice[1].([]interface{}); ok { + block.transactions = make([]*Transaction, len(txSlice)) + + for i, tx := range txSlice { + if t, ok := tx.([]byte); ok { + tx := &Transaction{} + tx.UnmarshalRlp(t) + + block.transactions[i] = tx + } + } } } } diff --git a/transaction.go b/transaction.go index cb7edd89c..b6e9eaa8f 100644 --- a/transaction.go +++ b/transaction.go @@ -34,8 +34,6 @@ var Period3Reward *big.Int = new(big.Int) var Period4Reward *big.Int = new(big.Int) type Transaction struct { - RlpSerializer - sender string recipient string value uint32 @@ -83,7 +81,7 @@ func (tx *Transaction) MarshalRlp() []byte { tx.data, } - return []byte(Encode(preEnc)) + return Encode(preEnc) } func (tx *Transaction) UnmarshalRlp(data []byte) { From 5198b7b9ebdfe1ef99627dadb07b87e18a039972 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 28 Dec 2013 15:18:23 +0100 Subject: [PATCH 025/459] Test code updated --- ethereum.go | 11 +++++++++-- vm.go | 18 +++++++++--------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/ethereum.go b/ethereum.go index d3cecdc94..3e01f89b2 100644 --- a/ethereum.go +++ b/ethereum.go @@ -4,6 +4,8 @@ import ( "fmt" ) +const Debug = false + func main() { InitFees() @@ -35,6 +37,11 @@ func main() { bm.ProcessBlock( blck ) - //t := blck.MarshalRlp() - //blck.UnmarshalRlp(t) + + t := blck.MarshalRlp() + copyBlock := &Block{} + copyBlock.UnmarshalRlp(t) + + fmt.Println(blck) + fmt.Println(copyBlock) } diff --git a/vm.go b/vm.go index dc026f318..787e29295 100644 --- a/vm.go +++ b/vm.go @@ -64,10 +64,7 @@ type Vm struct { } func NewVm() *Vm { - fmt.Println("init Ethereum VM") - - stackSize := uint(256) - fmt.Println("stack size =", stackSize) + //stackSize := uint(256) return &Vm{ stack: make(map[string]string), @@ -76,10 +73,12 @@ func NewVm() *Vm { } func (vm *Vm) RunTransaction(tx *Transaction, cb TxCallback) { - fmt.Printf(` + if Debug { + fmt.Printf(` # processing Tx (%v) # fee = %f, ops = %d, sender = %s, value = %d -`, tx.addr, float32(tx.fee) / 1e8, len(tx.data), tx.sender, tx.value) + `, tx.addr, float32(tx.fee) / 1e8, len(tx.data), tx.sender, tx.value) + } vm.stack = make(map[string]string) vm.stack["0"] = tx.sender @@ -102,7 +101,9 @@ out: // XXX Should Instr return big int slice instead of string slice? op, args, _ := Instr(tx.data[stPtr]) - fmt.Printf("%-3d %d %v\n", stPtr, op, args) + if Debug { + fmt.Printf("%-3d %d %v\n", stPtr, op, args) + } opType := OpType(tNorm) // Determine the op type (used for calculating fees by the block manager) @@ -178,8 +179,7 @@ out: stPtr++ } else { stPtr = nptr - fmt.Println("... JMP", nptr, "...") + if Debug { fmt.Println("... JMP", nptr, "...") } } } - fmt.Println("# finished processing Tx\n") } From a1c5d5acac542ab877aeec7814338e7638d55dbf Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 29 Dec 2013 01:36:59 +0100 Subject: [PATCH 026/459] Comments --- big.go | 6 ++++++ block.go | 22 ++++++++++++++++++---- block_manager.go | 3 +++ ethereum.go | 1 - transaction.go | 1 + 5 files changed, 28 insertions(+), 5 deletions(-) diff --git a/big.go b/big.go index 71e7573e1..44bfee2e4 100644 --- a/big.go +++ b/big.go @@ -4,6 +4,9 @@ import ( "math/big" ) +/* + * Returns the power of two integers + */ func BigPow(a,b int) *big.Int { c := new(big.Int) c.Exp(big.NewInt(int64(a)), big.NewInt(int64(b)), big.NewInt(0)) @@ -11,6 +14,9 @@ func BigPow(a,b int) *big.Int { return c } +/* + * Like big.NewInt(uint64); this takes a string instead. + */ func Big(num string) *big.Int { n := new(big.Int) n.SetString(num, 0) diff --git a/block.go b/block.go index 5c089137d..8c4d263fa 100644 --- a/block.go +++ b/block.go @@ -7,17 +7,23 @@ import ( ) type Block struct { + // The number of this block number uint32 + // Hash to the previous block prevHash string + // Uncles of this block uncles []*Block coinbase string // state xxx difficulty uint32 + // Creation time time time.Time nonce uint32 + // List of transactions and/or contracts transactions []*Transaction } +// Creates a new block. This is currently for testing func NewBlock(/* TODO use raw data */transactions []*Transaction) *Block { block := &Block{ // Slice of transactions to include in this block @@ -37,14 +43,16 @@ func NewBlock(/* TODO use raw data */transactions []*Transaction) *Block { func (block *Block) Update() { } +// Returns a hash of the block func (block *Block) Hash() string { return Sha256Hex(block.MarshalRlp()) } func (block *Block) MarshalRlp() []byte { - // Encoding method requires []interface{} type. It's actual a slice of strings + // Marshal the transactions of this block encTx := make([]string, len(block.transactions)) for i, tx := range block.transactions { + // Cast it to a string (safe) encTx[i] = string(tx.MarshalRlp()) } @@ -64,14 +72,16 @@ func (block *Block) MarshalRlp() []byte { // extra? } - encoded := Encode([]interface{}{header, encTx}) - - return encoded + // Encode a slice interface which contains the header and the list of transactions. + return Encode([]interface{}{header, encTx}) } func (block *Block) UnmarshalRlp(data []byte) { t, _ := Decode(data,0) + + // interface slice assertion if slice, ok := t.([]interface{}); ok { + // interface slice assertion if header, ok := slice[0].([]interface{}); ok { if number, ok := header[0].(uint8); ok { block.number = uint32(number) @@ -109,11 +119,15 @@ func (block *Block) UnmarshalRlp(data []byte) { } if txSlice, ok := slice[1].([]interface{}); ok { + // Create transaction slice equal to decoded tx interface slice block.transactions = make([]*Transaction, len(txSlice)) + // Unmarshal transactions for i, tx := range txSlice { if t, ok := tx.([]byte); ok { tx := &Transaction{} + // Use the unmarshaled data to unmarshal the transaction + // t is still decoded. tx.UnmarshalRlp(t) block.transactions[i] = tx diff --git a/block_manager.go b/block_manager.go index 80b30eff6..a60d4340d 100644 --- a/block_manager.go +++ b/block_manager.go @@ -26,9 +26,12 @@ func NewBlockManager() *BlockManager { // Process a block. func (bm *BlockManager) ProcessBlock(block *Block) error { + // Get the tx count. Used to create enough channels to 'join' the go routines txCount := len(block.transactions) + // Locking channel. When it has been fully buffered this method will return lockChan := make(chan bool, txCount) + // Process each transaction/contract for _, tx := range block.transactions { go bm.ProcessTransaction(tx, lockChan) } diff --git a/ethereum.go b/ethereum.go index 3e01f89b2..52e6e3046 100644 --- a/ethereum.go +++ b/ethereum.go @@ -37,7 +37,6 @@ func main() { bm.ProcessBlock( blck ) - t := blck.MarshalRlp() copyBlock := &Block{} copyBlock.UnmarshalRlp(t) diff --git a/transaction.go b/transaction.go index b6e9eaa8f..562593c96 100644 --- a/transaction.go +++ b/transaction.go @@ -125,6 +125,7 @@ func (tx *Transaction) UnmarshalRlp(data []byte) { tx.fee = uint32(fee) } + // Encode the data/instructions if data, ok := slice[5].([]interface{}); ok { tx.data = make([]string, len(data)) for i, d := range data { From 74bc45116aa1c5d0e549f522dccefc58356c1410 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 29 Dec 2013 23:50:43 +0100 Subject: [PATCH 027/459] Encoding helpers with tests --- encoding.go | 46 ++++++++++++++++++++++++++++++++++++++++++++ encoding_test.go | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 encoding.go create mode 100644 encoding_test.go diff --git a/encoding.go b/encoding.go new file mode 100644 index 000000000..ca30b47c9 --- /dev/null +++ b/encoding.go @@ -0,0 +1,46 @@ +package main + +import ( + "bytes" + "encoding/hex" + "strings" +) + +func CompactEncode(hexSlice []int) string { + terminator := 0 + if hexSlice[len(hexSlice)-1] == 16 { + terminator = 1 + } + + if terminator == 1 { + hexSlice = hexSlice[:len(hexSlice)-1] + } + + oddlen := len(hexSlice) % 2 + flags := 2 * terminator + oddlen + if oddlen != 0 { + hexSlice = append([]int{flags}, hexSlice...) + } else { + hexSlice = append([]int{flags, 0}, hexSlice...) + } + + var buff bytes.Buffer + for i := 0; i < len(hexSlice); i+=2 { + buff.WriteByte(byte(16 * hexSlice[i] + hexSlice[i+1])) + } + + return buff.String() +} + +func CompactHexDecode(str string) []int { + base := "0123456789abcdef" + hexSlice := make([]int, 0) + + enc := hex.EncodeToString([]byte(str)) + for _, v := range enc { + hexSlice = append(hexSlice, strings.IndexByte(base, byte(v))) + } + hexSlice = append(hexSlice, 16) + + return hexSlice +} diff --git a/encoding_test.go b/encoding_test.go new file mode 100644 index 000000000..63f7878bf --- /dev/null +++ b/encoding_test.go @@ -0,0 +1,50 @@ +package main + +import ( + "testing" + "fmt" +) + +func TestCompactEncode(t *testing.T) { + test1 := []int{1,2,3,4,5} + if res := CompactEncode(test1); res != "\x11\x23\x45" { + t.Error(fmt.Sprintf("even compact encode failed. Got: %q", res)) + } + + test2 := []int{0, 1, 2, 3, 4, 5} + if res := CompactEncode(test2); res != "\x00\x01\x23\x45" { + t.Error(fmt.Sprintf("odd compact encode failed. Got: %q", res)) + } + + test3 := []int{0, 15, 1, 12, 11, 8, /*term*/16} + if res := CompactEncode(test3); res != "\x20\x0f\x1c\xb8" { + t.Error(fmt.Sprintf("odd terminated compact encode failed. Got: %q", res)) + } + + test4 := []int{15, 1, 12, 11, 8, /*term*/16} + if res := CompactEncode(test4); res != "\x3f\x1c\xb8" { + t.Error(fmt.Sprintf("even terminated compact encode failed. Got: %q", res)) + } +} + +// Helper function for comparing slices +func CompareIntSlice(a, b []int) bool { + if len(a) != len(b) { + return false + } + for i, v := range a { + if v != b[i] { + return false + } + } + return true +} + +func TestCompactHexDecode(t *testing.T) { + exp := []int{7, 6, 6, 5, 7, 2, 6, 2, 16} + res := CompactHexDecode("verb") + + if !CompareIntSlice(res, exp) { + t.Error("Error compact hex decode. Expected", exp, "got", res) + } +} From 0747aa3a3bd78cc9b99ea72cf45e4cc4bfc301f5 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 29 Dec 2013 23:52:46 +0100 Subject: [PATCH 028/459] Removed logs from tests and updated rlp encoding to include byte slices --- rlp.go | 2 +- rlp_test.go | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/rlp.go b/rlp.go index bc3b6a151..4db88539d 100644 --- a/rlp.go +++ b/rlp.go @@ -132,7 +132,7 @@ func Encode(object interface{}) []byte { case []byte: // Cast the byte slice to a string - //buff.Write(Encode(string(t))) + buff.Write(Encode(string(t))) case []interface{}, []string: // Inline function for writing the slice header diff --git a/rlp_test.go b/rlp_test.go index 6a34aecbc..68676d030 100644 --- a/rlp_test.go +++ b/rlp_test.go @@ -7,13 +7,14 @@ import ( func TestEncode(t *testing.T) { strRes := "Cdog" + bytes := Encode("dog") + str := string(bytes) if str != strRes { t.Error(fmt.Sprintf("Expected %q, got %q", strRes, str)) } - dec,_ := Decode(bytes, 0) - fmt.Printf("raw: %v encoded: %q == %v\n", dec, str, "dog") + //dec,_ := Decode(bytes, 0) sliceRes := "\x83CdogCgodCcat" strs := []string{"dog", "god", "cat"} @@ -23,8 +24,7 @@ func TestEncode(t *testing.T) { t.Error(fmt.Sprintf("Expected %q, got %q", sliceRes, slice)) } - dec,_ = Decode(bytes, 0) - fmt.Printf("raw: %v encoded: %q == %v\n", dec, slice, strs) + //dec,_ = Decode(bytes, 0) } func TestMultiEncode(t *testing.T) { @@ -42,10 +42,8 @@ func TestMultiEncode(t *testing.T) { } bytes := Encode(inter) - fmt.Printf("%q\n", bytes) - dec, _ := Decode(bytes, 0) - fmt.Println(dec) + Decode(bytes, 0) } func BenchmarkEncodeDecode(b *testing.B) { From 0edcbc695e3e80d2f417467905621505f9971b4f Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 29 Dec 2013 23:53:12 +0100 Subject: [PATCH 029/459] Updated serialisation --- block.go | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/block.go b/block.go index 8c4d263fa..9aa3c8bb5 100644 --- a/block.go +++ b/block.go @@ -1,7 +1,7 @@ package main import ( - "fmt" + _"fmt" "time" _"bytes" ) @@ -17,14 +17,24 @@ type Block struct { // state xxx difficulty uint32 // Creation time - time time.Time + time int64 nonce uint32 // List of transactions and/or contracts transactions []*Transaction + + extra string +} + +// New block takes a raw encoded string +func NewBlock(raw []byte) *Block { + block := &Block{} + block.UnmarshalRlp(raw) + + return block } // Creates a new block. This is currently for testing -func NewBlock(/* TODO use raw data */transactions []*Transaction) *Block { +func CreateBlock(/* TODO use raw data */transactions []*Transaction) *Block { block := &Block{ // Slice of transactions to include in this block transactions: transactions, @@ -33,8 +43,7 @@ func NewBlock(/* TODO use raw data */transactions []*Transaction) *Block { coinbase: "me", difficulty: 10, nonce: 0, - - time: time.Now(), + time: time.Now().Unix(), } return block @@ -65,15 +74,18 @@ func (block *Block) MarshalRlp() []byte { block.coinbase, // root state "", - string(Sha256Bin([]byte(RlpEncode(encTx)))), + // Sha of tx + string(Sha256Bin([]byte(Encode(encTx)))), block.difficulty, - block.time.String(), + uint64(block.time), block.nonce, - // extra? + block.extra, } + // TODO + uncles := []interface{}{} // Encode a slice interface which contains the header and the list of transactions. - return Encode([]interface{}{header, encTx}) + return Encode([]interface{}{header, encTx, uncles}) } func (block *Block) UnmarshalRlp(data []byte) { @@ -109,13 +121,21 @@ func (block *Block) UnmarshalRlp(data []byte) { block.difficulty = uint32(difficulty) } - if time, ok := header[7].([]byte); ok { - fmt.Sprintf("Time is: ", string(time)) + // It's either 8bit or 64 + if time, ok := header[7].(uint8); ok { + block.time = int64(time) + } + if time, ok := header[7].(uint64); ok { + block.time = int64(time) } if nonce, ok := header[8].(uint8); ok { block.nonce = uint32(nonce) } + + if extra, ok := header[9].([]byte); ok { + block.extra = string(extra) + } } if txSlice, ok := slice[1].([]interface{}); ok { From ad048e9f445ff96b7bfd75c104ab923e1e06754b Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 29 Dec 2013 23:53:20 +0100 Subject: [PATCH 030/459] update test --- ethereum.go | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/ethereum.go b/ethereum.go index 52e6e3046..d9e1fd314 100644 --- a/ethereum.go +++ b/ethereum.go @@ -2,10 +2,27 @@ package main import ( "fmt" + "os" + "os/signal" ) const Debug = false +// Register interrupt handlers so we can stop the server +func RegisterInterupts(s *Server) { + // Buffered chan of one is enough + c := make(chan os.Signal, 1) + // Notify about interrupts for now + signal.Notify(c, os.Interrupt) + go func() { + for sig := range c { + fmt.Println("Shutting down (%v) ... \n", sig) + + s.Stop() + } + }() +} + func main() { InitFees() @@ -30,17 +47,11 @@ func main() { copyTx := &Transaction{} copyTx.UnmarshalRlp(txData) - tx2 := NewTransaction("\x00", 20, []string{"SET 10 6", "LD 10 10"}) - blck := NewBlock([]*Transaction{tx2, tx}) + blck := CreateBlock([]*Transaction{tx2, tx}) bm.ProcessBlock( blck ) - t := blck.MarshalRlp() - copyBlock := &Block{} - copyBlock.UnmarshalRlp(t) - - fmt.Println(blck) - fmt.Println(copyBlock) + fmt.Println("GenesisBlock:", GenisisBlock, "hashed", GenisisBlock.Hash()) } From a926686445929d091c2d9e019b017600168e9e47 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 29 Dec 2013 23:54:50 +0100 Subject: [PATCH 031/459] Added sample server, genesis block, and database interface --- database.go | 94 ++++++++++++++++++++++++++++++++++++++++++++++++ database_test.go | 43 ++++++++++++++++++++++ genesis.go | 36 +++++++++++++++++++ server.go | 55 ++++++++++++++++++++++++++++ 4 files changed, 228 insertions(+) create mode 100644 database.go create mode 100644 database_test.go create mode 100644 genesis.go create mode 100644 server.go diff --git a/database.go b/database.go new file mode 100644 index 000000000..f74c1dc7f --- /dev/null +++ b/database.go @@ -0,0 +1,94 @@ +package main + +import ( + "path" + "os/user" + "github.com/syndtr/goleveldb/leveldb" + "fmt" +) + +type Database struct { + db *leveldb.DB + trie *Trie +} + +func NewDatabase() (*Database, error) { + // This will eventually have to be something like a resource folder. + // it works on my system for now. Probably won't work on Windows + usr, _ := user.Current() + dbPath := path.Join(usr.HomeDir, ".ethereum", "database") + + // Open the db + db, err := leveldb.OpenFile(dbPath, nil) + if err != nil { + return nil, err + } + + database := &Database{db: db} + + // Bootstrap database. Sets a few defaults; such as the last block + database.Bootstrap() + + return database, nil +} + +func (db *Database) Bootstrap() error { + db.trie = NewTrie(db) + + return nil +} + +func (db *Database) Put(key []byte, value []byte) { + err := db.db.Put(key, value, nil) + if err != nil { + fmt.Println("Error put", err) + } +} + +func (db *Database) Close() { + // Close the leveldb database + db.db.Close() +} + +type Trie struct { + root string + db *Database +} + +func NewTrie(db *Database) *Trie { + return &Trie{db: db, root: ""} +} + +func (t *Trie) Update(key string, value string) { + k := CompactHexDecode(key) + + t.root = t.UpdateState(t.root, k, value) +} + +func (t *Trie) Get(key []byte) ([]byte, error) { + return nil, nil +} + +// Inserts a new sate or delete a state based on the value +func (t *Trie) UpdateState(node, key, value string) string { + if value != "" { + return t.InsertState(node, key, value) + } else { + // delete it + } + + return "" +} + +func (t *Trie) InsertState(node, key, value string) string { + return "" +} + +func (t *Trie) Put(node []byte) []byte { + enc := Encode(node) + sha := Sha256Bin(enc) + + t.db.Put([]byte(sha), enc) + + return sha +} diff --git a/database_test.go b/database_test.go new file mode 100644 index 000000000..c1a6c7d16 --- /dev/null +++ b/database_test.go @@ -0,0 +1,43 @@ +package main + +import ( + "testing" + _"fmt" +) + +func TestTriePut(t *testing.T) { + db, err := NewDatabase() + defer db.Close() + + if err != nil { + t.Error("Error starting db") + } + + key := db.trie.Put([]byte("testing node")) + + data, err := db.db.Get(key, nil) + if err != nil { + t.Error("Nothing at node") + } + + s, _ := Decode(data, 0) + if str, ok := s.([]byte); ok { + if string(str) != "testing node" { + t.Error("Wrong value node", str) + } + } else { + t.Error("Invalid return type") + } +} + +func TestTrieUpdate(t *testing.T) { + db, err := NewDatabase() + defer db.Close() + + if err != nil { + t.Error("Error starting db") + } + + db.trie.Update("test", "test") +} + diff --git a/genesis.go b/genesis.go new file mode 100644 index 000000000..aae9cd1cf --- /dev/null +++ b/genesis.go @@ -0,0 +1,36 @@ +package main + +import ( + "math" +) + +/* + * This is the special genesis block. + */ + +var GenisisHeader = []interface{}{ + // Block number + uint32(0), + // Previous hash (none) + "", + // Sha of uncles + string(Sha256Bin(Encode([]interface{}{}))), + // Coinbase + "", + // Root state + "", + // Sha of transactions + string(Sha256Bin(Encode([]interface{}{}))), + // Difficulty + uint32(math.Pow(2, 36)), + // Time + uint64(1), + // Nonce + uint32(0), + // Extra + "", +} + +var Genesis = []interface{}{ GenisisHeader, []interface{}{}, []interface{}{} } + +var GenisisBlock = NewBlock( Encode(Genesis) ) diff --git a/server.go b/server.go new file mode 100644 index 000000000..0c7488787 --- /dev/null +++ b/server.go @@ -0,0 +1,55 @@ +package main + +import ( + "container/list" + "time" +) + +type Server struct { + // Channel for shutting down the server + shutdownChan chan bool + // DB interface + db *Database + // Peers (NYI) + peers *list.List +} + +func NewServer() (*Server, error) { + db, err := NewDatabase() + if err != nil { + return nil, err + } + + server := &Server{ + shutdownChan: make(chan bool), + db: db, + peers: list.New(), + } + + return server, nil +} + +// Start the server +func (s *Server) Start() { + // For now this function just blocks the main thread + for { + time.Sleep( time.Second ) + } +} + +func (s *Server) Stop() { + // Close the database + defer s.db.Close() + + // Loop thru the peers and close them (if we had them) + for e := s.peers.Front(); e != nil; e = e.Next() { + // peer close etc + } + + s.shutdownChan <- true +} + +// This function will wait for a shutdown and resumes main thread execution +func (s *Server) WaitForShutdown() { + <- s.shutdownChan +} From f17930eb4661721cd0e1b92765448c589441907b Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 30 Dec 2013 01:09:57 +0100 Subject: [PATCH 032/459] Split up db and trie and added interface --- database.go | 58 ++++++++------------------------------------- database_test.go | 38 +----------------------------- server.go | 4 ++-- trie.go | 50 +++++++++++++++++++++++++++++++++++++++ trie.test.go | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 124 insertions(+), 87 deletions(-) create mode 100644 trie.go create mode 100644 trie.test.go diff --git a/database.go b/database.go index f74c1dc7f..c056e70af 100644 --- a/database.go +++ b/database.go @@ -7,12 +7,12 @@ import ( "fmt" ) -type Database struct { +type LDBDatabase struct { db *leveldb.DB trie *Trie } -func NewDatabase() (*Database, error) { +func NewLDBDatabase() (*LDBDatabase, error) { // This will eventually have to be something like a resource folder. // it works on my system for now. Probably won't work on Windows usr, _ := user.Current() @@ -24,7 +24,7 @@ func NewDatabase() (*Database, error) { return nil, err } - database := &Database{db: db} + database := &LDBDatabase{db: db} // Bootstrap database. Sets a few defaults; such as the last block database.Bootstrap() @@ -32,63 +32,25 @@ func NewDatabase() (*Database, error) { return database, nil } -func (db *Database) Bootstrap() error { +func (db *LDBDatabase) Bootstrap() error { db.trie = NewTrie(db) return nil } -func (db *Database) Put(key []byte, value []byte) { +func (db *LDBDatabase) Put(key []byte, value []byte) { err := db.db.Put(key, value, nil) if err != nil { fmt.Println("Error put", err) } } -func (db *Database) Close() { +func (db *LDBDatabase) Get(key []byte) ([]byte, error) { + return nil, nil +} + +func (db *LDBDatabase) Close() { // Close the leveldb database db.db.Close() } -type Trie struct { - root string - db *Database -} - -func NewTrie(db *Database) *Trie { - return &Trie{db: db, root: ""} -} - -func (t *Trie) Update(key string, value string) { - k := CompactHexDecode(key) - - t.root = t.UpdateState(t.root, k, value) -} - -func (t *Trie) Get(key []byte) ([]byte, error) { - return nil, nil -} - -// Inserts a new sate or delete a state based on the value -func (t *Trie) UpdateState(node, key, value string) string { - if value != "" { - return t.InsertState(node, key, value) - } else { - // delete it - } - - return "" -} - -func (t *Trie) InsertState(node, key, value string) string { - return "" -} - -func (t *Trie) Put(node []byte) []byte { - enc := Encode(node) - sha := Sha256Bin(enc) - - t.db.Put([]byte(sha), enc) - - return sha -} diff --git a/database_test.go b/database_test.go index c1a6c7d16..1a46eb95e 100644 --- a/database_test.go +++ b/database_test.go @@ -1,43 +1,7 @@ package main import ( - "testing" + _"testing" _"fmt" ) -func TestTriePut(t *testing.T) { - db, err := NewDatabase() - defer db.Close() - - if err != nil { - t.Error("Error starting db") - } - - key := db.trie.Put([]byte("testing node")) - - data, err := db.db.Get(key, nil) - if err != nil { - t.Error("Nothing at node") - } - - s, _ := Decode(data, 0) - if str, ok := s.([]byte); ok { - if string(str) != "testing node" { - t.Error("Wrong value node", str) - } - } else { - t.Error("Invalid return type") - } -} - -func TestTrieUpdate(t *testing.T) { - db, err := NewDatabase() - defer db.Close() - - if err != nil { - t.Error("Error starting db") - } - - db.trie.Update("test", "test") -} - diff --git a/server.go b/server.go index 0c7488787..c8fb492d5 100644 --- a/server.go +++ b/server.go @@ -9,13 +9,13 @@ type Server struct { // Channel for shutting down the server shutdownChan chan bool // DB interface - db *Database + db *LDBDatabase // Peers (NYI) peers *list.List } func NewServer() (*Server, error) { - db, err := NewDatabase() + db, err := NewLDBDatabase() if err != nil { return nil, err } diff --git a/trie.go b/trie.go new file mode 100644 index 000000000..d9d5dba5a --- /dev/null +++ b/trie.go @@ -0,0 +1,50 @@ +package main + +// Database interface +type Database interface { + Put(key []byte, value []byte) + Get(key []byte) ([]byte, error) +} + +type Trie struct { + root string + db Database +} + +func NewTrie(db Database) *Trie { + return &Trie{db: db, root: ""} +} + +func (t *Trie) Update(key string, value string) { + k := CompactHexDecode(key) + + t.root = t.UpdateState(t.root, k, value) +} + +func (t *Trie) Get(key []byte) ([]byte, error) { + return nil, nil +} + +// Inserts a new sate or delete a state based on the value +func (t *Trie) UpdateState(node string, key []int, value string) string { + if value != "" { + return t.InsertState(node, ""/*key*/, value) + } else { + // delete it + } + + return "" +} + +func (t *Trie) InsertState(node, key, value string) string { + return "" +} + +func (t *Trie) Put(node []byte) []byte { + enc := Encode(node) + sha := Sha256Bin(enc) + + t.db.Put([]byte(sha), enc) + + return sha +} diff --git a/trie.test.go b/trie.test.go new file mode 100644 index 000000000..0a6054cf0 --- /dev/null +++ b/trie.test.go @@ -0,0 +1,61 @@ +package main + +import ( + "testing" +) + +type MemDatabase struct { + db map[string][]byte + trie *Trie +} + +func NewMemDatabase() (*MemDatabase, error) { + db := &MemDatabase{db: make(map[string][]byte)} + + db.trie = NewTrie(db) + + return db, nil +} + +func (db *MemDatabase) Put(key []byte, value []byte) { + db.db[string(key)] = value +} + +func (db *MemDatabase) Get(key []byte) ([]byte, error) { + return db.db[string(key)], nil +} + +func TestTriePut(t *testing.T) { + db, err := NewMemDatabase() + + if err != nil { + t.Error("Error starting db") + } + + key := db.trie.Put([]byte("testing node")) + + data, err := db.Get(key) + if err != nil { + t.Error("Nothing at node") + } + + s, _ := Decode(data, 0) + if str, ok := s.([]byte); ok { + if string(str) != "testing node" { + t.Error("Wrong value node", str) + } + } else { + t.Error("Invalid return type") + } +} + +func TestTrieUpdate(t *testing.T) { + db, err := NewMemDatabase() + + if err != nil { + t.Error("Error starting db") + } + + db.trie.Update("test", "test") +} + From 276fa6c799b08bc41efd2d26a83eef678e8c943b Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 1 Jan 2014 03:06:39 +0100 Subject: [PATCH 033/459] Working Trie --- trie.go | 172 ++++++++++++++++++++++++++++++++--- trie.test.go => trie_test.go | 18 +++- 2 files changed, 173 insertions(+), 17 deletions(-) rename trie.test.go => trie_test.go (68%) diff --git a/trie.go b/trie.go index d9d5dba5a..dc83c7cfe 100644 --- a/trie.go +++ b/trie.go @@ -1,5 +1,9 @@ package main +import ( + "fmt" +) + // Database interface type Database interface { Put(key []byte, value []byte) @@ -11,24 +15,79 @@ type Trie struct { db Database } -func NewTrie(db Database) *Trie { +func NewTrie(db Database, root string) *Trie { return &Trie{db: db, root: ""} } +func (t *Trie) Put(node interface{}) []byte { + //if s, ok := node.([]string); ok { + // PrintSlice(s) + //} + enc := Encode(node) + sha := Sha256Bin(enc) + + t.db.Put([]byte(sha), enc) + + return sha +} + func (t *Trie) Update(key string, value string) { k := CompactHexDecode(key) t.root = t.UpdateState(t.root, k, value) } -func (t *Trie) Get(key []byte) ([]byte, error) { - return nil, nil +func (t *Trie) Get(key string) string { + k := CompactHexDecode(key) + + return t.GetState(t.root, k) +} + +// Returns the state of an object +func (t *Trie) GetState(node string, key []int) string { + //if Debug { fmt.Println("get =", key) } + + // Return the node if key is empty (= found) + if len(key) == 0 || node == "" { + return node + } + + // Fetch the encoded node from the db + n, err := t.db.Get([]byte(node)) + if err != nil { fmt.Println("Error in GetState for node", node, "with key", key); return "" } + + // Decode it + currentNode := DecodeNode(n) + + if len(currentNode) == 0 { + return "" + } else if len(currentNode) == 2 { + // Decode the key + k := CompactDecode(currentNode[0]) + v := currentNode[1] + + //fmt.Println(k, key) + //fmt.Printf("k1:%v\nk2:%v\n", k, key[:len(k)-1]) + + //fmt.Println(len(key), ">=", len(k)-1, "&&", k, key[:len(k)]) + if len(key) >= len(k) && CompareIntSlice(k, key[:len(k)]) { + return t.GetState(v, key[len(k):]) + } else { + return "" + } + } else if len(currentNode) == 17 { + return t.GetState(currentNode[key[0]], key[1:]) + } + + // It shouldn't come this far + fmt.Println("GetState unexpected return") + return "" } // Inserts a new sate or delete a state based on the value func (t *Trie) UpdateState(node string, key []int, value string) string { if value != "" { - return t.InsertState(node, ""/*key*/, value) + return t.InsertState(node, key, value) } else { // delete it } @@ -36,15 +95,104 @@ func (t *Trie) UpdateState(node string, key []int, value string) string { return "" } -func (t *Trie) InsertState(node, key, value string) string { +func DecodeNode(data []byte) []string { + dec, _ := Decode(data, 0) + if slice, ok := dec.([]interface{}); ok { + strSlice := make([]string, len(slice)) + + for i, s := range slice { + if str, ok := s.([]byte); ok { + strSlice[i] = string(str) + } + } + + return strSlice + } + + return nil +} + +func (t *Trie) PrintNode(n string) { + data, _ := t.db.Get([]byte(n)) + d := DecodeNode(data) + PrintSlice(d) +} + +func PrintSlice(slice []string) { + fmt.Printf("[") + for i, val := range slice { + fmt.Printf("%q", val) + if i != len(slice)-1 { fmt.Printf(",") } + } + fmt.Printf("]\n") +} + +func (t *Trie) InsertState(node string, key []int, value string) string { + //if Debug { fmt.Println("insrt", key, value, "node:", node) } + + if len(key) == 0 { + return value + } + + //fmt.Println(node) + // Root node! + if node == "" { + newNode := []string{ CompactEncode(key), value } + + return string(t.Put(newNode)) + } + + // Fetch the encoded node from the db + n, err := t.db.Get([]byte(node)) + if err != nil { fmt.Println("Error InsertState", err); return "" } + + // Decode it + currentNode := DecodeNode(n) + // Check for "special" 2 slice type node + if len(currentNode) == 2 { + // Decode the key + k := CompactDecode(currentNode[0]) + v := currentNode[1] + + // Matching key pair (ie. there's already an object with this key) + if CompareIntSlice(k, key) { + return string(t.Put([]string{ CompactEncode(key), value })) + } + + var newHash string + matchingLength := MatchingNibbleLength(key, k) + if matchingLength == len(k) { + // Insert the hash, creating a new node + newHash = t.InsertState(v, key[matchingLength:], value) + } else { + // Expand the 2 length slice to a 17 length slice + oldNode := t.InsertState("", k[matchingLength+1:], v) + newNode := t.InsertState("", key[matchingLength+1:], value) + // Create an expanded slice + scaledSlice := make([]string, 17) + // Set the copied and new node + scaledSlice[k[matchingLength]] = oldNode + scaledSlice[key[matchingLength]] = newNode + + newHash = string(t.Put(scaledSlice)) + } + + if matchingLength == 0 { + // End of the chain, return + return newHash + } else { + newNode := []string{ CompactEncode(key[:matchingLength]), newHash } + return string(t.Put(newNode)) + } + } else { + // Copy the current node over to the new node and replace the first nibble in the key + newNode := make([]string, 17); copy(newNode, currentNode) + newNode[key[0]] = t.InsertState(currentNode[key[0]], key[1:], value) + + return string(t.Put(newNode)) + } + return "" } -func (t *Trie) Put(node []byte) []byte { - enc := Encode(node) - sha := Sha256Bin(enc) - t.db.Put([]byte(sha), enc) - - return sha -} diff --git a/trie.test.go b/trie_test.go similarity index 68% rename from trie.test.go rename to trie_test.go index 0a6054cf0..dac2333c9 100644 --- a/trie.test.go +++ b/trie_test.go @@ -2,18 +2,16 @@ package main import ( "testing" + "encoding/hex" ) type MemDatabase struct { db map[string][]byte - trie *Trie } func NewMemDatabase() (*MemDatabase, error) { db := &MemDatabase{db: make(map[string][]byte)} - db.trie = NewTrie(db) - return db, nil } @@ -27,12 +25,13 @@ func (db *MemDatabase) Get(key []byte) ([]byte, error) { func TestTriePut(t *testing.T) { db, err := NewMemDatabase() + trie := NewTrie(db, "") if err != nil { t.Error("Error starting db") } - key := db.trie.Put([]byte("testing node")) + key := trie.Put([]byte("testing node")) data, err := db.Get(key) if err != nil { @@ -51,11 +50,20 @@ func TestTriePut(t *testing.T) { func TestTrieUpdate(t *testing.T) { db, err := NewMemDatabase() + trie := NewTrie(db, "") if err != nil { t.Error("Error starting db") } - db.trie.Update("test", "test") + + trie.Update("doe", "reindeer") + trie.Update("dog", "puppy") + trie.Update("dogglesworth", "cat") + root := hex.EncodeToString([]byte(trie.root)) + req := "e378927bfc1bd4f01a2e8d9f59bd18db8a208bb493ac0b00f93ce51d4d2af76c" + if root != req { + t.Error("trie.root do not match, expected", req, "got", root) + } } From 34d62c380ef6327c170639af6221a82610efa25c Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 1 Jan 2014 03:06:52 +0100 Subject: [PATCH 034/459] Encoding helpers for trie --- encoding.go | 16 ++++++++++++++++ encoding_test.go | 12 ------------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/encoding.go b/encoding.go index ca30b47c9..d77303817 100644 --- a/encoding.go +++ b/encoding.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/hex" "strings" + _"fmt" ) func CompactEncode(hexSlice []int) string { @@ -32,6 +33,21 @@ func CompactEncode(hexSlice []int) string { return buff.String() } +func CompactDecode(str string) []int { + base := CompactHexDecode(str) + base = base[:len(base)-1] + if base[0] >= 2 {// && base[len(base)-1] != 16 { + base = append(base, 16) + } + if base[0] % 2 == 1 { + base = base[1:] + } else { + base = base[2:] + } + + return base +} + func CompactHexDecode(str string) []int { base := "0123456789abcdef" hexSlice := make([]int, 0) diff --git a/encoding_test.go b/encoding_test.go index 63f7878bf..b66f702ac 100644 --- a/encoding_test.go +++ b/encoding_test.go @@ -27,18 +27,6 @@ func TestCompactEncode(t *testing.T) { } } -// Helper function for comparing slices -func CompareIntSlice(a, b []int) bool { - if len(a) != len(b) { - return false - } - for i, v := range a { - if v != b[i] { - return false - } - } - return true -} func TestCompactHexDecode(t *testing.T) { exp := []int{7, 6, 6, 5, 7, 2, 6, 2, 16} From 79eaa6f2bae8c8354807a9b32b889295b0de4b6a Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 1 Jan 2014 03:07:04 +0100 Subject: [PATCH 035/459] Removed old serialization --- serialization.go | 63 ------------------------------------------- serialization_test.go | 20 -------------- 2 files changed, 83 deletions(-) delete mode 100644 serialization.go delete mode 100644 serialization_test.go diff --git a/serialization.go b/serialization.go deleted file mode 100644 index 5a92a434f..000000000 --- a/serialization.go +++ /dev/null @@ -1,63 +0,0 @@ -package main - -import ( - "math" - "bytes" -) - -func ToBinary(x int, bytes int) string { - if bytes == 0 { - return "" - } else { - return ToBinary(int(x / 256), bytes - 1) + string(x % 256) - } -} - -func NumToVarInt(x int) string { - if x < 253 { - return string(x) - } else if x < int(math.Pow(2,16)) { - return string(253) + ToBinary(x, 2) - } else if x < int(math.Pow(2,32)) { - return string(253) + ToBinary(x, 4) - } else { - return string(253) + ToBinary(x, 8) - } -} - -func RlpEncode(object interface{}) string { - if str, ok := object.(string); ok { - return "\x00" + NumToVarInt(len(str)) + str - } else if num, ok := object.(uint32); ok { - return RlpEncode(Uitoa(num)) - } else if byt, ok := object.([]byte); ok { - return RlpEncode(string(byt)) - } else if slice, ok := object.([]interface{}); ok { - var buffer bytes.Buffer - for _, val := range slice { - if v, ok := val.(string); ok { - buffer.WriteString(RlpEncode(v)) - } else { - buffer.WriteString(RlpEncode(val)) - } - } - - return "\x01" + RlpEncode(len(buffer.String())) + buffer.String() - } else if slice, ok := object.([]string); ok { - - // FIXME this isn't dry. Fix this - var buffer bytes.Buffer - for _, val := range slice { - buffer.WriteString(RlpEncode(val)) - } - return "\x01" + RlpEncode(len(buffer.String())) + buffer.String() - } - - return "" -} - -type RlpSerializer interface { - MarshalRlp() []byte - UnmarshalRlp([]byte) -} - diff --git a/serialization_test.go b/serialization_test.go deleted file mode 100644 index adb1b6e2d..000000000 --- a/serialization_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package main - -import ( - "testing" - "fmt" -) - -func TestRlpEncode(t *testing.T) { - strRes := "\x00\x03dog" - str := RlpEncode("dog") - if str != strRes { - t.Error(fmt.Sprintf("Expected %q, got %q", strRes, str)) - } - - sliceRes := "\x01\x00\x03dog\x00\x03god\x00\x03cat" - slice := RlpEncode([]string{"dog", "god", "cat"}) - if slice != sliceRes { - t.Error(fmt.Sprintf("Expected %q, got %q", sliceRes, slice)) - } -} From 35e4d746418386508247319beeeb50619204af03 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 1 Jan 2014 03:07:29 +0100 Subject: [PATCH 036/459] Added helper methods for slice comparison and nibble matching --- util.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/util.go b/util.go index fc06673d2..512a6f3d7 100644 --- a/util.go +++ b/util.go @@ -4,6 +4,8 @@ import ( "strconv" "crypto/sha256" "encoding/hex" + _"fmt" + _"math" ) func Uitoa(i uint32) string { @@ -21,3 +23,28 @@ func Sha256Bin(data []byte) []byte { return hash[:] } + +// Helper function for comparing slices +func CompareIntSlice(a, b []int) bool { + if len(a) != len(b) { + return false + } + for i, v := range a { + if v != b[i] { + return false + } + } + return true +} + +// Returns the amount of nibbles that match each other from 0 ... +func MatchingNibbleLength(a, b []int) int { + i := 0 + for CompareIntSlice(a[:i+1], b[:i+1]) && i < len(b) { + i+=1 + } + + //fmt.Println(a, b, i-1) + + return i +} From 52952e274d791991c6c368d135234068968981bc Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 1 Jan 2014 03:07:49 +0100 Subject: [PATCH 037/459] Updated database interface and eth test code --- database.go | 2 +- ethereum.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/database.go b/database.go index c056e70af..b147756b6 100644 --- a/database.go +++ b/database.go @@ -33,7 +33,7 @@ func NewLDBDatabase() (*LDBDatabase, error) { } func (db *LDBDatabase) Bootstrap() error { - db.trie = NewTrie(db) + //db.trie = NewTrie(db) return nil } diff --git a/ethereum.go b/ethereum.go index d9e1fd314..e260e6c0e 100644 --- a/ethereum.go +++ b/ethereum.go @@ -6,7 +6,7 @@ import ( "os/signal" ) -const Debug = false +const Debug = true // Register interrupt handlers so we can stop the server func RegisterInterupts(s *Server) { From 5da78427d0d5910c2ea0c0fc6ca84078f327e933 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 1 Jan 2014 13:36:48 +0100 Subject: [PATCH 038/459] Added db query interface and moved memory database --- db_query_interface.go | 97 +++++++++++++++++++++++++++++++++++++++++++ memory_database.go | 25 +++++++++++ testing.go | 36 ++++++++++++++++ 3 files changed, 158 insertions(+) create mode 100644 db_query_interface.go create mode 100644 memory_database.go create mode 100644 testing.go diff --git a/db_query_interface.go b/db_query_interface.go new file mode 100644 index 000000000..1bcf1e72d --- /dev/null +++ b/db_query_interface.go @@ -0,0 +1,97 @@ +package main + +import ( + "fmt" + "bufio" + "strings" + "os" + "errors" + "encoding/hex" +) + +type DbInterface struct { + db *MemDatabase + trie *Trie +} + +func NewDBInterface() *DbInterface { + db, _ := NewMemDatabase() + trie := NewTrie(db, "") + + return &DbInterface{db: db, trie: trie} +} + +func (i *DbInterface) ValidateInput(action string, argumentLength int) error { + err := false + var expArgCount int + + switch { + case action == "update" && argumentLength != 2: + err = true + expArgCount = 2 + case action == "get" && argumentLength != 1: + err = true + expArgCount = 1 + case (action == "quit" || action == "exit") && argumentLength != 0: + err = true + expArgCount = 0 + } + + if err { + return errors.New(fmt.Sprintf("'%s' requires %d args, got %d", action, expArgCount, argumentLength)) + } else { + return nil + } +} + +func (i *DbInterface) ParseInput(input string) bool { + scanner := bufio.NewScanner(strings.NewReader(input)) + scanner.Split(bufio.ScanWords) + + count := 0 + var tokens []string + for scanner.Scan() { + count++ + tokens = append(tokens, scanner.Text()) + } + if err := scanner.Err(); err != nil { + fmt.Fprintln(os.Stderr, "reading input:", err) + } + + if len(tokens) == 0 { return true } + + err := i.ValidateInput(tokens[0], count-1) + if err != nil { + fmt.Println(err) + } else { + switch tokens[0] { + case "update": + i.trie.Update(tokens[1], tokens[2]) + + fmt.Println(hex.EncodeToString([]byte(i.trie.root))) + case "get": + fmt.Println(i.trie.Get(tokens[1])) + case "exit", "quit", "q": + return false + default: + fmt.Println("Unknown command:", tokens[0]) + } + } + + return true +} + +func (i *DbInterface) Start() { + reader := bufio.NewReader(os.Stdin) + for { + fmt.Printf("db >>> ") + str, _, err := reader.ReadLine() + if err != nil { + fmt.Println("Error reading input", err) + } else { + if !i.ParseInput(string(str)) { + return + } + } + } +} diff --git a/memory_database.go b/memory_database.go new file mode 100644 index 000000000..fc40f76f3 --- /dev/null +++ b/memory_database.go @@ -0,0 +1,25 @@ +package main + +import ( +) + +/* + * This is a test memory database. Do not use for any production it does not get persisted + */ +type MemDatabase struct { + db map[string][]byte +} + +func NewMemDatabase() (*MemDatabase, error) { + db := &MemDatabase{db: make(map[string][]byte)} + + return db, nil +} + +func (db *MemDatabase) Put(key []byte, value []byte) { + db.db[string(key)] = value +} + +func (db *MemDatabase) Get(key []byte) ([]byte, error) { + return db.db[string(key)], nil +} diff --git a/testing.go b/testing.go new file mode 100644 index 000000000..5d0b818a9 --- /dev/null +++ b/testing.go @@ -0,0 +1,36 @@ +package main + +import ( + "fmt" +) + +func Testing() { + bm := NewBlockManager() + + tx := NewTransaction("\x00", 20, []string{ + "SET 10 6", + "LD 10 10", + "LT 10 1 20", + "SET 255 7", + "JMPI 20 255", + "STOP", + "SET 30 200", + "LD 30 31", + "SET 255 22", + "JMPI 31 255", + "SET 255 15", + "JMP 255", + }) + txData := tx.MarshalRlp() + + copyTx := &Transaction{} + copyTx.UnmarshalRlp(txData) + + tx2 := NewTransaction("\x00", 20, []string{"SET 10 6", "LD 10 10"}) + + blck := CreateBlock([]*Transaction{tx2, tx}) + + bm.ProcessBlock( blck ) + + fmt.Println("GenesisBlock:", GenisisBlock, "hashed", GenisisBlock.Hash()) +} From 584f9be7f423b84e3dbae43edd41d071a600622c Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 1 Jan 2014 13:37:00 +0100 Subject: [PATCH 039/459] Moved some testing code --- ethereum.go | 42 +++++++++++++++--------------------------- trie_test.go | 18 ------------------ 2 files changed, 15 insertions(+), 45 deletions(-) diff --git a/ethereum.go b/ethereum.go index e260e6c0e..ac9690e41 100644 --- a/ethereum.go +++ b/ethereum.go @@ -4,10 +4,18 @@ import ( "fmt" "os" "os/signal" + "flag" ) const Debug = true +var StartDBQueryInterface bool +func Init() { + flag.BoolVar(&StartDBQueryInterface, "db", false, "start db query interface") + + flag.Parse() +} + // Register interrupt handlers so we can stop the server func RegisterInterupts(s *Server) { // Buffered chan of one is enough @@ -26,32 +34,12 @@ func RegisterInterupts(s *Server) { func main() { InitFees() - bm := NewBlockManager() + Init() - tx := NewTransaction("\x00", 20, []string{ - "SET 10 6", - "LD 10 10", - "LT 10 1 20", - "SET 255 7", - "JMPI 20 255", - "STOP", - "SET 30 200", - "LD 30 31", - "SET 255 22", - "JMPI 31 255", - "SET 255 15", - "JMP 255", - }) - txData := tx.MarshalRlp() - - copyTx := &Transaction{} - copyTx.UnmarshalRlp(txData) - - tx2 := NewTransaction("\x00", 20, []string{"SET 10 6", "LD 10 10"}) - - blck := CreateBlock([]*Transaction{tx2, tx}) - - bm.ProcessBlock( blck ) - - fmt.Println("GenesisBlock:", GenisisBlock, "hashed", GenisisBlock.Hash()) + if StartDBQueryInterface { + dbInterface := NewDBInterface() + dbInterface.Start() + } else { + Testing() + } } diff --git a/trie_test.go b/trie_test.go index dac2333c9..6dbe040ee 100644 --- a/trie_test.go +++ b/trie_test.go @@ -5,24 +5,6 @@ import ( "encoding/hex" ) -type MemDatabase struct { - db map[string][]byte -} - -func NewMemDatabase() (*MemDatabase, error) { - db := &MemDatabase{db: make(map[string][]byte)} - - return db, nil -} - -func (db *MemDatabase) Put(key []byte, value []byte) { - db.db[string(key)] = value -} - -func (db *MemDatabase) Get(key []byte) ([]byte, error) { - return db.db[string(key)], nil -} - func TestTriePut(t *testing.T) { db, err := NewMemDatabase() trie := NewTrie(db, "") From df6f7e8a0e43fbee90af8531c4dd4279b8f1e120 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 1 Jan 2014 13:52:26 +0100 Subject: [PATCH 040/459] updated readme --- README | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/README b/README index 9d08d7f8e..92ca75b5a 100644 --- a/README +++ b/README @@ -1,16 +1,11 @@ This is the Go implementation of the Ethereum protocol. It's far from being finished. - go get https://github.com/ethereum/go-ethereum +```go get https://github.com/ethereum/go-ethereum``` -The Python reference implementation can be found at https://github.com/ethereum/pyethereum +** The Python reference implementation can be found at https://github.com/ethereum/pyethereum ** -More information about the protocol: -* http://vitalik.ca/ethereum.html -* http://vitalik.ca/ethereum/spec.html -* http://vitalik.ca/ethereum/patricia.html -* http://vitalik.ca/ethereum/dagger.html -* http://vitalik.ca/ethereum/rlp.html +## Command line options -# TODO +-db will launch the db query tool. -Fix this todo file! +Supported arguments `update` and `get` From 30f3b4d4e435aed02033d97d69361c78db7d6d7f Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 1 Jan 2014 14:06:00 +0100 Subject: [PATCH 041/459] Added a few more comments and cleaned up code --- trie.go | 111 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 57 insertions(+), 54 deletions(-) diff --git a/trie.go b/trie.go index dc83c7cfe..83a3073ae 100644 --- a/trie.go +++ b/trie.go @@ -10,6 +10,38 @@ type Database interface { Get(key []byte) ([]byte, error) } +/* + * Trie helper functions + */ +// Helper function for printing out the raw contents of a slice +func PrintSlice(slice []string) { + fmt.Printf("[") + for i, val := range slice { + fmt.Printf("%q", val) + if i != len(slice)-1 { fmt.Printf(",") } + } + fmt.Printf("]\n") +} + +// RLP Decodes a node in to a [2] or [17] string slice +func DecodeNode(data []byte) []string { + dec, _ := Decode(data, 0) + if slice, ok := dec.([]interface{}); ok { + strSlice := make([]string, len(slice)) + + for i, s := range slice { + if str, ok := s.([]byte); ok { + strSlice[i] = string(str) + } + } + + return strSlice + } + + return nil +} + +// A (modified) Radix Trie implementation type Trie struct { root string db Database @@ -19,18 +51,9 @@ func NewTrie(db Database, root string) *Trie { return &Trie{db: db, root: ""} } -func (t *Trie) Put(node interface{}) []byte { - //if s, ok := node.([]string); ok { - // PrintSlice(s) - //} - enc := Encode(node) - sha := Sha256Bin(enc) - - t.db.Put([]byte(sha), enc) - - return sha -} - +/* + * Public (query) interface functions + */ func (t *Trie) Update(key string, value string) { k := CompactHexDecode(key) @@ -43,10 +66,29 @@ func (t *Trie) Get(key string) string { return t.GetState(t.root, k) } +/* + * State functions (shouldn't be needed directly). + */ + +// Wrapper around the regular db "Put" which generates a key and value +func (t *Trie) Put(node interface{}) []byte { + enc := Encode(node) + sha := Sha256Bin(enc) + + t.db.Put([]byte(sha), enc) + + return sha +} + +// Helper function for printing a node (using fetch, decode and slice printing) +func (t *Trie) PrintNode(n string) { + data, _ := t.db.Get([]byte(n)) + d := DecodeNode(data) + PrintSlice(d) +} + // Returns the state of an object func (t *Trie) GetState(node string, key []int) string { - //if Debug { fmt.Println("get =", key) } - // Return the node if key is empty (= found) if len(key) == 0 || node == "" { return node @@ -66,10 +108,6 @@ func (t *Trie) GetState(node string, key []int) string { k := CompactDecode(currentNode[0]) v := currentNode[1] - //fmt.Println(k, key) - //fmt.Printf("k1:%v\nk2:%v\n", k, key[:len(k)-1]) - - //fmt.Println(len(key), ">=", len(k)-1, "&&", k, key[:len(k)]) if len(key) >= len(k) && CompareIntSlice(k, key[:len(k)]) { return t.GetState(v, key[len(k):]) } else { @@ -95,47 +133,13 @@ func (t *Trie) UpdateState(node string, key []int, value string) string { return "" } -func DecodeNode(data []byte) []string { - dec, _ := Decode(data, 0) - if slice, ok := dec.([]interface{}); ok { - strSlice := make([]string, len(slice)) - - for i, s := range slice { - if str, ok := s.([]byte); ok { - strSlice[i] = string(str) - } - } - - return strSlice - } - - return nil -} - -func (t *Trie) PrintNode(n string) { - data, _ := t.db.Get([]byte(n)) - d := DecodeNode(data) - PrintSlice(d) -} - -func PrintSlice(slice []string) { - fmt.Printf("[") - for i, val := range slice { - fmt.Printf("%q", val) - if i != len(slice)-1 { fmt.Printf(",") } - } - fmt.Printf("]\n") -} func (t *Trie) InsertState(node string, key []int, value string) string { - //if Debug { fmt.Println("insrt", key, value, "node:", node) } - if len(key) == 0 { return value } - //fmt.Println(node) - // Root node! + // New node if node == "" { newNode := []string{ CompactEncode(key), value } @@ -195,4 +199,3 @@ func (t *Trie) InsertState(node string, key []int, value string) string { return "" } - From 65f00656f224546b1b3ed3cd8217236963f770df Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 1 Jan 2014 14:11:56 +0100 Subject: [PATCH 042/459] Help text --- db_query_interface.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/db_query_interface.go b/db_query_interface.go index 1bcf1e72d..572dd6684 100644 --- a/db_query_interface.go +++ b/db_query_interface.go @@ -32,9 +32,6 @@ func (i *DbInterface) ValidateInput(action string, argumentLength int) error { case action == "get" && argumentLength != 1: err = true expArgCount = 1 - case (action == "quit" || action == "exit") && argumentLength != 0: - err = true - expArgCount = 0 } if err { @@ -73,6 +70,11 @@ func (i *DbInterface) ParseInput(input string) bool { fmt.Println(i.trie.Get(tokens[1])) case "exit", "quit", "q": return false + case "help": + fmt.Println(`query commands: +update KEY VALUE +get KEY +`) default: fmt.Println("Unknown command:", tokens[0]) } @@ -82,6 +84,7 @@ func (i *DbInterface) ParseInput(input string) bool { } func (i *DbInterface) Start() { + fmt.Printf("DB Query tool. Type (help) for help\n") reader := bufio.NewReader(os.Stdin) for { fmt.Printf("db >>> ") From 61d67f2ae965a9a1113084f2352e2c2dd97ab9a7 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 1 Jan 2014 14:12:30 +0100 Subject: [PATCH 043/459] moved to markdown --- README => README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README => README.md (100%) diff --git a/README b/README.md similarity index 100% rename from README rename to README.md From 5b3d4fae6e03e5471a10c653fc0b016cc5e5dcfa Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 1 Jan 2014 15:49:38 +0100 Subject: [PATCH 044/459] Work in progress external test runner --- db_query_interface.go | 12 +++++++++--- test_runner.go | 35 +++++++++++++++++++++++++++++++++++ test_runner_test.go | 31 +++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 test_runner.go create mode 100644 test_runner_test.go diff --git a/db_query_interface.go b/db_query_interface.go index 572dd6684..11137e4c2 100644 --- a/db_query_interface.go +++ b/db_query_interface.go @@ -68,12 +68,18 @@ func (i *DbInterface) ParseInput(input string) bool { fmt.Println(hex.EncodeToString([]byte(i.trie.root))) case "get": fmt.Println(i.trie.Get(tokens[1])) + case "root": + fmt.Println(hex.EncodeToString([]byte(i.trie.root))) + case "rawroot": + fmt.Println(i.trie.root) case "exit", "quit", "q": return false case "help": - fmt.Println(`query commands: -update KEY VALUE -get KEY + fmt.Printf(`QUERY COMMANDS: +update KEY VALUE - Updates/Creates a new value for the given key +get KEY - Retrieves the given key +root - Prints the hex encoded merkle root +rawroot - Prints the raw merkle root `) default: fmt.Println("Unknown command:", tokens[0]) diff --git a/test_runner.go b/test_runner.go new file mode 100644 index 000000000..da93533dd --- /dev/null +++ b/test_runner.go @@ -0,0 +1,35 @@ +package main + +import ( + "fmt" + "testing" + "encoding/json" +) + +type TestSource struct { + Inputs map[string]string + Expectation string +} + +func NewTestSource(source string) *TestSource { + s := &TestSource{} + err := json.Unmarshal([]byte(source), s) + if err != nil { + fmt.Println(err) + } + + return s +} + +type TestRunner struct { + source *TestSource +} + +func NewTestRunner(t *testing.T) *TestRunner { + return &TestRunner{} +} + +func (runner *TestRunner) RunFromString(input string, Cb func(*TestSource)) { + source := NewTestSource(input) + Cb(source) +} diff --git a/test_runner_test.go b/test_runner_test.go new file mode 100644 index 000000000..190bf3caf --- /dev/null +++ b/test_runner_test.go @@ -0,0 +1,31 @@ +package main + +import ( + _"fmt" + "testing" + "encoding/hex" +) + +var testsource = `{"Inputs":{ + "doe": "reindeer", + "dog": "puppy", + "dogglesworth": "cat" + }, + "Expectation":"e378927bfc1bd4f01a2e8d9f59bd18db8a208bb493ac0b00f93ce51d4d2af76c" +}` + +func TestTestRunner(t *testing.T) { + db, _ := NewMemDatabase() + trie := NewTrie(db, "") + + runner := NewTestRunner(t) + runner.RunFromString(testsource, func(source *TestSource) { + for key, value := range source.Inputs { + trie.Update(key, value) + } + + if hex.EncodeToString([]byte(trie.root)) != source.Expectation { + t.Error("trie root did not match") + } + }) +} From 9df4c745119b3ed10a7ad17887e8dd9cac249af7 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 2 Jan 2014 23:02:24 +0100 Subject: [PATCH 045/459] WIP rewrite vm --- block.go | 38 ++++++++++++++++++++++----- block_manager.go | 6 ++--- parsing.go | 3 +++ parsing_test.go | 13 ++------- testing.go | 23 +++++++--------- trie_test.go | 8 ++++++ vm.go | 68 ++++++++++++++++++++++++++++++++++++++++++++++-- vm_test.go | 27 +++++++++++++++++++ 8 files changed, 150 insertions(+), 36 deletions(-) create mode 100644 vm_test.go diff --git a/block.go b/block.go index 9aa3c8bb5..146328471 100644 --- a/block.go +++ b/block.go @@ -15,6 +15,7 @@ type Block struct { uncles []*Block coinbase string // state xxx + state *Trie difficulty uint32 // Creation time time int64 @@ -34,7 +35,7 @@ func NewBlock(raw []byte) *Block { } // Creates a new block. This is currently for testing -func CreateBlock(/* TODO use raw data */transactions []*Transaction) *Block { +func CreateTestBlock(/* TODO use raw data */transactions []*Transaction) *Block { block := &Block{ // Slice of transactions to include in this block transactions: transactions, @@ -49,12 +50,32 @@ func CreateBlock(/* TODO use raw data */transactions []*Transaction) *Block { return block } +func CreateBlock(root string, num int, prevHash string, base string, difficulty int, nonce int, extra string, txes []*Transaction) *Block { + block := &Block{ + // Slice of transactions to include in this block + transactions: txes, + number: uint32(num), + prevHash: prevHash, + coinbase: base, + difficulty: uint32(difficulty), + nonce: uint32(nonce), + time: time.Now().Unix(), + extra: extra, + } + block.state = NewTrie(Db, root) + for _, tx := range txes { + block.state.Update(tx.recipient, string(tx.MarshalRlp())) + } + + return block +} + func (block *Block) Update() { } // Returns a hash of the block -func (block *Block) Hash() string { - return Sha256Hex(block.MarshalRlp()) +func (block *Block) Hash() []byte { + return Sha256Bin(block.MarshalRlp()) } func (block *Block) MarshalRlp() []byte { @@ -73,7 +94,7 @@ func (block *Block) MarshalRlp() []byte { "", block.coinbase, // root state - "", + block.state.root, // Sha of tx string(Sha256Bin([]byte(Encode(encTx)))), block.difficulty, @@ -99,7 +120,7 @@ func (block *Block) UnmarshalRlp(data []byte) { block.number = uint32(number) } - if prevHash, ok := header[1].([]byte); ok { + if prevHash, ok := header[1].([]uint8); ok { block.prevHash = string(prevHash) } @@ -109,7 +130,12 @@ func (block *Block) UnmarshalRlp(data []byte) { block.coinbase = string(coinbase) } - // state is header[header[4] + if state, ok := header[4].([]uint8); ok { + // XXX The database is currently a global variable defined in testing.go + // This will eventually go away and the database will grabbed from the public server + // interface + block.state = NewTrie(Db, string(state)) + } // sha is header[5] diff --git a/block_manager.go b/block_manager.go index a60d4340d..0ef5d1108 100644 --- a/block_manager.go +++ b/block_manager.go @@ -33,7 +33,7 @@ func (bm *BlockManager) ProcessBlock(block *Block) error { // Process each transaction/contract for _, tx := range block.transactions { - go bm.ProcessTransaction(tx, lockChan) + go bm.ProcessTransaction(tx, block, lockChan) } // Wait for all Tx to finish processing @@ -44,9 +44,9 @@ func (bm *BlockManager) ProcessBlock(block *Block) error { return nil } -func (bm *BlockManager) ProcessTransaction(tx *Transaction, lockChan chan bool) { +func (bm *BlockManager) ProcessTransaction(tx *Transaction, block *Block, lockChan chan bool) { if tx.recipient == "\x00" { - bm.vm.RunTransaction(tx, func(opType OpType) bool { + bm.vm.RunTransaction(tx, block, func(opType OpType) bool { // TODO calculate fees return true // Continue diff --git a/parsing.go b/parsing.go index d5dcce04f..765950a4c 100644 --- a/parsing.go +++ b/parsing.go @@ -11,6 +11,8 @@ import ( // Op codes var OpCodes = map[string]string{ "STOP": "0", + "PSH": "30", // 0x30 + /* "ADD": "16", // 0x10 "SUB": "17", // 0x11 "MUL": "18", // 0x12 @@ -48,6 +50,7 @@ var OpCodes = map[string]string{ "BLKHASH": "145", // 0x91 "COINBASE": "146", // 0x92 "SUICIDE": "255", // 0xff + */ } diff --git a/parsing_test.go b/parsing_test.go index 93fe434b9..fa319e7bf 100644 --- a/parsing_test.go +++ b/parsing_test.go @@ -19,22 +19,13 @@ func TestCompile(t *testing.T) { } func TestValidInstr(t *testing.T) { + /* op, args, err := Instr("68163") if err != nil { t.Error("Error decoding instruction") } + */ - if op != oSET { - t.Error("Expected op to be 43, got:", op) - } - - if args[0] != "10" { - t.Error("Expect args[0] to be 10, got:", args[0]) - } - - if args[1] != "1" { - t.Error("Expected args[1] to be 1, got:", args[1]) - } } func TestInvalidInstr(t *testing.T) { diff --git a/testing.go b/testing.go index 5d0b818a9..07e8c362f 100644 --- a/testing.go +++ b/testing.go @@ -4,22 +4,17 @@ import ( "fmt" ) +// This will eventually go away +var Db *MemDatabase + func Testing() { + db, _ := NewMemDatabase() + Db = db + bm := NewBlockManager() tx := NewTransaction("\x00", 20, []string{ - "SET 10 6", - "LD 10 10", - "LT 10 1 20", - "SET 255 7", - "JMPI 20 255", - "STOP", - "SET 30 200", - "LD 30 31", - "SET 255 22", - "JMPI 31 255", - "SET 255 15", - "JMP 255", + "PSH 10", }) txData := tx.MarshalRlp() @@ -28,9 +23,9 @@ func Testing() { tx2 := NewTransaction("\x00", 20, []string{"SET 10 6", "LD 10 10"}) - blck := CreateBlock([]*Transaction{tx2, tx}) + blck := CreateTestBlock([]*Transaction{tx2, tx}) bm.ProcessBlock( blck ) - fmt.Println("GenesisBlock:", GenisisBlock, "hashed", GenisisBlock.Hash()) + fmt.Println("GenesisBlock:", GenisisBlock, "hash", string(GenisisBlock.Hash())) } diff --git a/trie_test.go b/trie_test.go index 6dbe040ee..599a5f47c 100644 --- a/trie_test.go +++ b/trie_test.go @@ -3,6 +3,7 @@ package main import ( "testing" "encoding/hex" + _"fmt" ) func TestTriePut(t *testing.T) { @@ -41,6 +42,13 @@ func TestTrieUpdate(t *testing.T) { trie.Update("doe", "reindeer") trie.Update("dog", "puppy") + /* + data, _ := db.Get([]byte(trie.root)) + data, _ = db.Get([]byte(DecodeNode(data)[1])) + data, _ = db.Get([]byte(DecodeNode(data)[7])) + PrintSlice(DecodeNode(data)) + */ + trie.Update("dogglesworth", "cat") root := hex.EncodeToString([]byte(trie.root)) req := "e378927bfc1bd4f01a2e8d9f59bd18db8a208bb493ac0b00f93ce51d4d2af76c" diff --git a/vm.go b/vm.go index 787e29295..f38e7be06 100644 --- a/vm.go +++ b/vm.go @@ -1,16 +1,18 @@ package main import ( - "math" + _"math" "math/big" "fmt" - "strconv" + _"strconv" _ "encoding/hex" ) // Op codes const ( oSTOP int = 0x00 + oPSH int = 0x30 + /* oADD int = 0x10 oSUB int = 0x11 oMUL int = 0x12 @@ -46,6 +48,7 @@ const ( oDATAN int = 0x81 oMYADDRESS int = 0x90 oSUICIDE int = 0xff + */ ) type OpType int @@ -57,6 +60,66 @@ const ( ) type TxCallback func(opType OpType) bool +// Simple push/pop stack mechanism +type Stack struct { + data []string +} +func NewStack() *Stack { + return &Stack{} +} +func (st *Stack) Pop() string { + s := len(st.data) + + str := st.data[s] + st.data = st.data[:s-1] + + return str +} + +func (st *Stack) Push(d string) { + st.data = append(st.data, d) +} + +type Vm struct { + // Stack + stack *Stack +} + +func NewVm() *Vm { + return &Vm{ + stack: NewStack(), + } +} + +func (vm *Vm) RunTransaction(tx *Transaction, block *Block, cb TxCallback) { + // Instruction pointer + iptr := 0 + + // Index pointer for the memory + memIndex := 0 + + fmt.Printf("# op arg\n") + for iptr < len(tx.data) { + memIndex++ + // The base big int for all calculations. Use this for any results. + base := new(big.Int) + base.SetString("0",0) // so it doesn't whine about it + // XXX Should Instr return big int slice instead of string slice? + op, args, _ := Instr(tx.data[iptr]) + + if Debug { + fmt.Printf("%-3d %-4d %v\n", iptr, op, args) + } + + switch op { + case oPSH: + } + // Increment instruction pointer + iptr++ + } +} + +/* type Vm struct { // Memory stack stack map[string]string @@ -183,3 +246,4 @@ out: } } } +*/ diff --git a/vm_test.go b/vm_test.go new file mode 100644 index 000000000..d0bcda2ca --- /dev/null +++ b/vm_test.go @@ -0,0 +1,27 @@ +package main + +import ( + "fmt" + "testing" + _"encoding/hex" +) + + +func TestVm(t *testing.T) { + db, _ := NewMemDatabase() + Db = db + + tx := NewTransaction("\x00", 20, []string{ + "PSH 10", + }) + + block := CreateBlock("", 0, "", "", 0, 0, "", []*Transaction{tx}) + db.Put(block.Hash(), block.MarshalRlp()) + + bm := NewBlockManager() + bm.ProcessBlock( block ) + tx1 := &Transaction{} + tx1.UnmarshalRlp([]byte(block.state.Get(tx.recipient))) + fmt.Println(tx1) +} + From 7cd41ac45aed7ee22ef02f8abedf83a2914c4807 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 3 Jan 2014 00:43:49 +0100 Subject: [PATCH 046/459] Wip VM. Created contracts --- block.go | 26 +++++++++++++++++++++++++- block_manager.go | 10 ++++------ contract.go | 40 ++++++++++++++++++++++++++++++++++++++++ transaction.go | 11 ++++++----- trie.go | 2 +- vm_test.go | 9 ++++----- 6 files changed, 80 insertions(+), 18 deletions(-) create mode 100644 contract.go diff --git a/block.go b/block.go index 146328471..dd329f8ac 100644 --- a/block.go +++ b/block.go @@ -4,6 +4,7 @@ import ( _"fmt" "time" _"bytes" + _"encoding/hex" ) type Block struct { @@ -63,13 +64,36 @@ func CreateBlock(root string, num int, prevHash string, base string, difficulty extra: extra, } block.state = NewTrie(Db, root) + for _, tx := range txes { - block.state.Update(tx.recipient, string(tx.MarshalRlp())) + // Create contract if there's no recipient + if tx.recipient == "" { + addr := tx.Hash() + + contract := NewContract(tx.value, []byte("")) + block.state.Update(string(addr), string(contract.MarshalRlp())) + for i, val := range tx.data { + contract.state.Update(string(Encode(i)), val) + } + block.UpdateContract(addr, contract) + } } return block } +func (block *Block) GetContract(addr []byte) *Contract { + data := block.state.Get(string(addr)) + contract := &Contract{} + contract.UnmarshalRlp([]byte(data)) + + return contract +} + +func (block *Block) UpdateContract(addr []byte, contract *Contract) { + block.state.Update(string(addr), string(contract.MarshalRlp())) +} + func (block *Block) Update() { } diff --git a/block_manager.go b/block_manager.go index 0ef5d1108..f3aa29ba4 100644 --- a/block_manager.go +++ b/block_manager.go @@ -45,13 +45,11 @@ func (bm *BlockManager) ProcessBlock(block *Block) error { } func (bm *BlockManager) ProcessTransaction(tx *Transaction, block *Block, lockChan chan bool) { - if tx.recipient == "\x00" { - bm.vm.RunTransaction(tx, block, func(opType OpType) bool { - // TODO calculate fees + bm.vm.RunTransaction(tx, block, func(opType OpType) bool { + // TODO calculate fees - return true // Continue - }) - } + return true // Continue + }) // Broadcast we're done lockChan <- true diff --git a/contract.go b/contract.go new file mode 100644 index 000000000..e95e50b74 --- /dev/null +++ b/contract.go @@ -0,0 +1,40 @@ +package main + +import ( +) + +type Contract struct { + active int + amount uint32 // ??? + state *Trie +} +func NewContract(amount uint32, root []byte) *Contract { + contract := &Contract{active: 1, amount: amount} + contract.state = NewTrie(Db, string(root)) + + return contract +} +func (c *Contract) MarshalRlp() []byte { + // Prepare the transaction for serialization + preEnc := []interface{}{uint32(c.active), c.amount, c.state.root} + + return Encode(preEnc) +} + +func (c *Contract) UnmarshalRlp(data []byte) { + t, _ := Decode(data, 0) + + if slice, ok := t.([]interface{}); ok { + if active, ok := slice[0].(uint8); ok { + c.active = int(active) + } + + if amount, ok := slice[1].(uint8); ok { + c.amount = uint32(amount) + } + + if root, ok := slice[2].([]uint8); ok { + c.state = NewTrie(Db, string(root)) + } + } +} diff --git a/transaction.go b/transaction.go index 562593c96..dc5204f9b 100644 --- a/transaction.go +++ b/transaction.go @@ -3,8 +3,8 @@ package main import ( "math/big" "fmt" - "encoding/hex" - "crypto/sha256" + _"encoding/hex" + _"crypto/sha256" _ "bytes" ) @@ -63,13 +63,14 @@ func NewTransaction(to string, value uint32, data []string) *Transaction { tx.data[i] = instr } - b:= []byte(tx.MarshalRlp()) - hash := sha256.Sum256(b) - tx.addr = hex.EncodeToString(hash[0:19]) return &tx } +func (tx *Transaction) Hash() []byte { + return Sha256Bin(tx.MarshalRlp()) +} + func (tx *Transaction) MarshalRlp() []byte { // Prepare the transaction for serialization preEnc := []interface{}{ diff --git a/trie.go b/trie.go index 83a3073ae..442cc08b8 100644 --- a/trie.go +++ b/trie.go @@ -48,7 +48,7 @@ type Trie struct { } func NewTrie(db Database, root string) *Trie { - return &Trie{db: db, root: ""} + return &Trie{db: db, root: root} } /* diff --git a/vm_test.go b/vm_test.go index d0bcda2ca..00b8809a1 100644 --- a/vm_test.go +++ b/vm_test.go @@ -3,7 +3,6 @@ package main import ( "fmt" "testing" - _"encoding/hex" ) @@ -11,7 +10,7 @@ func TestVm(t *testing.T) { db, _ := NewMemDatabase() Db = db - tx := NewTransaction("\x00", 20, []string{ + tx := NewTransaction("", 20, []string{ "PSH 10", }) @@ -20,8 +19,8 @@ func TestVm(t *testing.T) { bm := NewBlockManager() bm.ProcessBlock( block ) - tx1 := &Transaction{} - tx1.UnmarshalRlp([]byte(block.state.Get(tx.recipient))) - fmt.Println(tx1) + contract := block.GetContract(tx.Hash()) + fmt.Println(contract) + fmt.Println("it is", contract.state.Get(string(Encode(0)))) } From 78d18b134ffbd4d28d49ef3fe51774a202bb20df Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 3 Jan 2014 13:40:12 +0100 Subject: [PATCH 047/459] Pop, push, load for vm --- vm.go | 38 ++++++++++++++++++++++++++++---------- vm_test.go | 20 +++++++++++++------- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/vm.go b/vm.go index f38e7be06..d7e3f77cf 100644 --- a/vm.go +++ b/vm.go @@ -6,12 +6,15 @@ import ( "fmt" _"strconv" _ "encoding/hex" + "strconv" ) // Op codes const ( oSTOP int = 0x00 - oPSH int = 0x30 + oPUSH int = 0x30 + oPOP int = 0x31 + oLOAD int = 0x36 /* oADD int = 0x10 oSUB int = 0x11 @@ -70,7 +73,7 @@ func NewStack() *Stack { func (st *Stack) Pop() string { s := len(st.data) - str := st.data[s] + str := st.data[s-1] st.data = st.data[:s-1] return str @@ -91,30 +94,45 @@ func NewVm() *Vm { } } -func (vm *Vm) RunTransaction(tx *Transaction, block *Block, cb TxCallback) { +func (vm *Vm) ProcContract(tx *Transaction, block *Block, cb TxCallback) { // Instruction pointer iptr := 0 - // Index pointer for the memory - memIndex := 0 + contract := block.GetContract(tx.Hash()) + if contract == nil { + fmt.Println("Contract not found") + return + } fmt.Printf("# op arg\n") - for iptr < len(tx.data) { - memIndex++ +out: + for { // The base big int for all calculations. Use this for any results. base := new(big.Int) base.SetString("0",0) // so it doesn't whine about it // XXX Should Instr return big int slice instead of string slice? - op, args, _ := Instr(tx.data[iptr]) + // Get the next instruction from the contract + op, args, _ := Instr(contract.state.Get(string(Encode(uint32(iptr))))) if Debug { fmt.Printf("%-3d %-4d %v\n", iptr, op, args) } switch op { - case oPSH: + case oPUSH: + // Get the next entry and pushes the value on the stack + iptr++ + vm.stack.Push(contract.state.Get(string(Encode(uint32(iptr))))) + case oPOP: + // Pop current value of the stack + vm.stack.Pop() + case oLOAD: + // Load instruction X on the stack + i, _ := strconv.Atoi(vm.stack.Pop()) + vm.stack.Push(contract.state.Get(string(Encode(uint32(i))))) + case oSTOP: + break out } - // Increment instruction pointer iptr++ } } diff --git a/vm_test.go b/vm_test.go index 00b8809a1..fe0358a42 100644 --- a/vm_test.go +++ b/vm_test.go @@ -1,7 +1,7 @@ package main import ( - "fmt" + _"fmt" "testing" ) @@ -10,17 +10,23 @@ func TestVm(t *testing.T) { db, _ := NewMemDatabase() Db = db - tx := NewTransaction("", 20, []string{ - "PSH 10", + ctrct := NewTransaction("", 20, []string{ + "PUSH", + "1a2f2e", + "PUSH", + "hallo", + "POP", // POP hallo + "PUSH", + "3", + "LOAD", // Load hallo back on the stack + "STOP", }) + tx := NewTransaction("1e8a42ea8cce13", 100, []string{}) - block := CreateBlock("", 0, "", "", 0, 0, "", []*Transaction{tx}) + block := CreateBlock("", 0, "", "", 0, 0, "", []*Transaction{ctrct, tx}) db.Put(block.Hash(), block.MarshalRlp()) bm := NewBlockManager() bm.ProcessBlock( block ) - contract := block.GetContract(tx.Hash()) - fmt.Println(contract) - fmt.Println("it is", contract.state.Get(string(Encode(0)))) } From 055407c835328c8b9628c73ddd7ba872d787c09d Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 3 Jan 2014 13:40:25 +0100 Subject: [PATCH 048/459] VM Recovery --- block_manager.go | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/block_manager.go b/block_manager.go index f3aa29ba4..ae9803c8e 100644 --- a/block_manager.go +++ b/block_manager.go @@ -11,7 +11,7 @@ package main import ( - _"fmt" + "fmt" ) type BlockManager struct { @@ -33,7 +33,13 @@ func (bm *BlockManager) ProcessBlock(block *Block) error { // Process each transaction/contract for _, tx := range block.transactions { - go bm.ProcessTransaction(tx, block, lockChan) + // If there's no recipient, it's a contract + if tx.recipient == "" { + go bm.ProcessContract(tx, block, lockChan) + } else { + // "finish" tx which isn't a contract + lockChan <- true + } } // Wait for all Tx to finish processing @@ -44,8 +50,18 @@ func (bm *BlockManager) ProcessBlock(block *Block) error { return nil } -func (bm *BlockManager) ProcessTransaction(tx *Transaction, block *Block, lockChan chan bool) { - bm.vm.RunTransaction(tx, block, func(opType OpType) bool { +func (bm *BlockManager) ProcessContract(tx *Transaction, block *Block, lockChan chan bool) { + // Recovering function in case the VM had any errors + defer func() { + if r := recover(); r != nil { + fmt.Println("Recovered from VM execution with err =", r) + // Let the channel know where done even though it failed (so the execution may resume normally) + lockChan <- true + } + }() + + // Process contract + bm.vm.ProcContract(tx, block, func(opType OpType) bool { // TODO calculate fees return true // Continue From 9581faf5fdacf4a135bcdf77d6f0fbe0d6eecba8 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 3 Jan 2014 13:40:38 +0100 Subject: [PATCH 049/459] Parsing for block and tx --- block.go | 2 +- parsing.go | 9 ++++++--- transaction.go | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/block.go b/block.go index dd329f8ac..39858b0fd 100644 --- a/block.go +++ b/block.go @@ -73,7 +73,7 @@ func CreateBlock(root string, num int, prevHash string, base string, difficulty contract := NewContract(tx.value, []byte("")) block.state.Update(string(addr), string(contract.MarshalRlp())) for i, val := range tx.data { - contract.state.Update(string(Encode(i)), val) + contract.state.Update(string(Encode(uint32(i))), val) } block.UpdateContract(addr, contract) } diff --git a/parsing.go b/parsing.go index 765950a4c..4c3f1187e 100644 --- a/parsing.go +++ b/parsing.go @@ -11,8 +11,11 @@ import ( // Op codes var OpCodes = map[string]string{ "STOP": "0", - "PSH": "30", // 0x30 - /* + "PUSH": "48", // 0x30 + "POP": "49", // 0x31 + "LOAD": "54", // 0x36 + + /* OLD VM OPCODES "ADD": "16", // 0x10 "SUB": "17", // 0x11 "MUL": "18", // 0x12 @@ -57,7 +60,7 @@ var OpCodes = map[string]string{ func CompileInstr(s string) (string, error) { tokens := strings.Split(s, " ") if OpCodes[tokens[0]] == "" { - return "", errors.New(fmt.Sprintf("OP not found: %s", tokens[0])) + return s, errors.New(fmt.Sprintf("OP not found: %s", tokens[0])) } code := OpCodes[tokens[0]] // Replace op codes with the proper numerical equivalent diff --git a/transaction.go b/transaction.go index dc5204f9b..1cfa6d729 100644 --- a/transaction.go +++ b/transaction.go @@ -57,7 +57,7 @@ func NewTransaction(to string, value uint32, data []string) *Transaction { for i, val := range data { instr, err := CompileInstr(val) if err != nil { - fmt.Printf("compile error:%d %v", i+1, err) + fmt.Printf("compile error:%d %v\n", i+1, err) } tx.data[i] = instr From f97716ebe287349729821d826141e73a6e55702e Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 4 Jan 2014 00:30:19 +0100 Subject: [PATCH 050/459] Added new big from []bytes --- big.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/big.go b/big.go index 44bfee2e4..b0fbcb64f 100644 --- a/big.go +++ b/big.go @@ -24,3 +24,12 @@ func Big(num string) *big.Int { return n } +/* + * Like big.NewInt(uint64); this takes a byte buffer instead. + */ +func BigD(data []byte) *big.Int { + n := new(big.Int) + n.SetBytes(data) + + return n +} From 15bf5ee4db6485619fb942ae288bd9659d4d6d73 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 4 Jan 2014 00:31:06 +0100 Subject: [PATCH 051/459] Contract creation, updating and fee processing --- block.go | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/block.go b/block.go index 39858b0fd..00317573c 100644 --- a/block.go +++ b/block.go @@ -1,7 +1,7 @@ package main import ( - _"fmt" + "fmt" "time" _"bytes" _"encoding/hex" @@ -73,7 +73,8 @@ func CreateBlock(root string, num int, prevHash string, base string, difficulty contract := NewContract(tx.value, []byte("")) block.state.Update(string(addr), string(contract.MarshalRlp())) for i, val := range tx.data { - contract.state.Update(string(Encode(uint32(i))), val) + contract.state.Update(string(NumberToBytes(uint64(i), 32)), val) + //contract.state.Update(string(Encode(uint32(i))), val) } block.UpdateContract(addr, contract) } @@ -84,6 +85,10 @@ func CreateBlock(root string, num int, prevHash string, base string, difficulty func (block *Block) GetContract(addr []byte) *Contract { data := block.state.Get(string(addr)) + if data == "" { + return nil + } + contract := &Contract{} contract.UnmarshalRlp([]byte(data)) @@ -94,7 +99,27 @@ func (block *Block) UpdateContract(addr []byte, contract *Contract) { block.state.Update(string(addr), string(contract.MarshalRlp())) } -func (block *Block) Update() { + +func (block *Block) PayFee(addr []byte, fee uint64) bool { + contract := block.GetContract(addr) + // If we can't pay the fee return + if contract == nil || contract.amount < fee { + fmt.Println("Contract has insufficient funds", contract.amount, fee) + return false + } + + contract.amount -= fee + block.state.Update(string(addr), string(contract.MarshalRlp())) + + data := block.state.Get(string(block.coinbase)) + println(data) + // Get the ether (coinbase) and add the fee (gief fee to miner) + ether := NewEtherFromData([]byte(data)) + ether.amount += fee + + block.state.Update(string(block.coinbase), string(ether.MarshalRlp())) + + return true } // Returns a hash of the block From a42ebd9ed62ffe5ba30e29001a380a4bd185be6d Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 4 Jan 2014 00:31:42 +0100 Subject: [PATCH 052/459] block --- block_manager.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/block_manager.go b/block_manager.go index ae9803c8e..6c1a0fe58 100644 --- a/block_manager.go +++ b/block_manager.go @@ -62,7 +62,10 @@ func (bm *BlockManager) ProcessContract(tx *Transaction, block *Block, lockChan // Process contract bm.vm.ProcContract(tx, block, func(opType OpType) bool { - // TODO calculate fees + // TODO turn on once big ints are in place + //if !block.PayFee(tx.Hash(), StepFee.Uint64()) { + // return false + //} return true // Continue }) From ebef4e103b4601e477a787ace068dbf181acc39c Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 4 Jan 2014 00:32:01 +0100 Subject: [PATCH 053/459] Ether --- contract.go | 63 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 11 deletions(-) diff --git a/contract.go b/contract.go index e95e50b74..778f3578d 100644 --- a/contract.go +++ b/contract.go @@ -1,36 +1,42 @@ package main import ( + _"fmt" ) type Contract struct { - active int - amount uint32 // ??? + t uint32 // contract is always 1 + amount uint64 // ??? state *Trie } -func NewContract(amount uint32, root []byte) *Contract { - contract := &Contract{active: 1, amount: amount} + +func NewContract(amount uint64, root []byte) *Contract { + contract := &Contract{t: 1, amount: amount} contract.state = NewTrie(Db, string(root)) return contract } -func (c *Contract) MarshalRlp() []byte { - // Prepare the transaction for serialization - preEnc := []interface{}{uint32(c.active), c.amount, c.state.root} - return Encode(preEnc) +func (c *Contract) MarshalRlp() []byte { + return Encode([]interface{}{c.t, c.amount, c.state.root}) } func (c *Contract) UnmarshalRlp(data []byte) { t, _ := Decode(data, 0) if slice, ok := t.([]interface{}); ok { - if active, ok := slice[0].(uint8); ok { - c.active = int(active) + if t, ok := slice[0].(uint8); ok { + c.t = uint32(t) } if amount, ok := slice[1].(uint8); ok { - c.amount = uint32(amount) + c.amount = uint64(amount) + } else if amount, ok := slice[1].(uint16); ok { + c.amount = uint64(amount) + } else if amount, ok := slice[1].(uint32); ok { + c.amount = uint64(amount) + } else if amount, ok := slice[1].(uint64); ok { + c.amount = amount } if root, ok := slice[2].([]uint8); ok { @@ -38,3 +44,38 @@ func (c *Contract) UnmarshalRlp(data []byte) { } } } + +type Ether struct { + t uint32 + amount uint64 + nonce string +} + +func NewEtherFromData(data []byte) *Ether { + ether := &Ether{} + ether.UnmarshalRlp(data) + + return ether +} + +func (e *Ether) MarshalRlp() []byte { + return Encode([]interface{}{e.t, e.amount, e.nonce}) +} + +func (e *Ether) UnmarshalRlp(data []byte) { + t, _ := Decode(data, 0) + + if slice, ok := t.([]interface{}); ok { + if t, ok := slice[0].(uint8); ok { + e.t = uint32(t) + } + + if amount, ok := slice[1].(uint8); ok { + e.amount = uint64(amount) + } + + if nonce, ok := slice[2].([]uint8); ok { + e.nonce = string(nonce) + } + } +} From 6ab61f2c524686e479f9546d5ce2529f3b8eb7fe Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 4 Jan 2014 00:32:13 +0100 Subject: [PATCH 054/459] Added byte helpers --- bytes.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 bytes.go diff --git a/bytes.go b/bytes.go new file mode 100644 index 000000000..6bf381343 --- /dev/null +++ b/bytes.go @@ -0,0 +1,27 @@ +package main + +import ( + "bytes" + "encoding/binary" + "fmt" +) + +func NumberToBytes(num uint64, bits int) []byte { + buf := new(bytes.Buffer) + err := binary.Write(buf, binary.BigEndian, num) + if err != nil { + fmt.Println("binary.Write failed:", err) + } + + return buf.Bytes()[buf.Len()-(bits / 8):] +} + +func BytesToNumber(b []byte) (number uint64) { + buf := bytes.NewReader(b) + err := binary.Read(buf, binary.LittleEndian, &number) + if err != nil { + fmt.Println("binary.Read failed:", err) + } + + return +} From 2d3c3674faa2c9c15d4ab27c7dc6b3e07a532780 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 4 Jan 2014 00:32:52 +0100 Subject: [PATCH 055/459] Updated stack based vm --- parsing.go | 65 ++++------- vm.go | 320 ++++++++++++++++++++++++----------------------------- vm_test.go | 59 ++++++++-- 3 files changed, 220 insertions(+), 224 deletions(-) diff --git a/parsing.go b/parsing.go index 4c3f1187e..b97d77f3e 100644 --- a/parsing.go +++ b/parsing.go @@ -10,50 +10,29 @@ import ( // Op codes var OpCodes = map[string]string{ - "STOP": "0", - "PUSH": "48", // 0x30 - "POP": "49", // 0x31 - "LOAD": "54", // 0x36 + "STOP": "0", + "ADD": "1", + "MUL": "2", + "SUB": "3", + "DIV": "4", + "SDIV": "5", + "MOD": "6", + "SMOD": "7", + "EXP": "8", + "NEG": "9", + "LT": "10", + "LE": "11", + "GT": "12", + "GE": "13", + "EQ": "14", + "NOT": "15", + "MYADDRESS": "16", + "TXSENDER": "17", - /* OLD VM OPCODES - "ADD": "16", // 0x10 - "SUB": "17", // 0x11 - "MUL": "18", // 0x12 - "DIV": "19", // 0x13 - "SDIV": "20", // 0x14 - "MOD": "21", // 0x15 - "SMOD": "22", // 0x16 - "EXP": "23", // 0x17 - "NEG": "24", // 0x18 - "LT": "32", // 0x20 - "LE": "33", // 0x21 - "GT": "34", // 0x22 - "GE": "35", // 0x23 - "EQ": "36", // 0x24 - "NOT": "37", // 0x25 - "SHA256": "48", // 0x30 - "RIPEMD160": "49", // 0x31 - "ECMUL": "50", // 0x32 - "ECADD": "51", // 0x33 - "SIGN": "52", // 0x34 - "RECOVER": "53", // 0x35 - "COPY": "64", // 0x40 - "ST": "65", // 0x41 - "LD": "66", // 0x42 - "SET": "67", // 0x43 - "JMP": "80", // 0x50 - "JMPI": "81", // 0x51 - "IND": "82", // 0x52 - "EXTRO": "96", // 0x60 - "BALANCE": "97", // 0x61 - "MKTX": "112", // 0x70 - "DATA": "128", // 0x80 - "DATAN": "129", // 0x81 - "MYADDRESS": "144", // 0x90 - "BLKHASH": "145", // 0x91 - "COINBASE": "146", // 0x92 - "SUICIDE": "255", // 0xff - */ + + "PUSH": "48", + "POP": "49", + "LOAD": "54", } diff --git a/vm.go b/vm.go index d7e3f77cf..9e1e83b0b 100644 --- a/vm.go +++ b/vm.go @@ -12,46 +12,28 @@ import ( // Op codes const ( oSTOP int = 0x00 + oADD int = 0x01 + oMUL int = 0x02 + oSUB int = 0x03 + oDIV int = 0x04 + oSDIV int = 0x05 + oMOD int = 0x06 + oSMOD int = 0x07 + oEXP int = 0x08 + oNEG int = 0x09 + oLT int = 0x0a + oLE int = 0x0b + oGT int = 0x0c + oGE int = 0x0d + oEQ int = 0x0e + oNOT int = 0x0f + oMYADDRESS int = 0x10 + oTXSENDER int = 0x11 + + oPUSH int = 0x30 oPOP int = 0x31 oLOAD int = 0x36 - /* - oADD int = 0x10 - oSUB int = 0x11 - oMUL int = 0x12 - oDIV int = 0x13 - oSDIV int = 0x14 - oMOD int = 0x15 - oSMOD int = 0x16 - oEXP int = 0x17 - oNEG int = 0x18 - oLT int = 0x20 - oLE int = 0x21 - oGT int = 0x22 - oGE int = 0x23 - oEQ int = 0x24 - oNOT int = 0x25 - oSHA256 int = 0x30 - oRIPEMD160 int = 0x31 - oECMUL int = 0x32 - oECADD int = 0x33 - oSIGN int = 0x34 - oRECOVER int = 0x35 - oCOPY int = 0x40 - oST int = 0x41 - oLD int = 0x42 - oSET int = 0x43 - oJMP int = 0x50 - oJMPI int = 0x51 - oIND int = 0x52 - oEXTRO int = 0x60 - oBALANCE int = 0x61 - oMKTX int = 0x70 - oDATA int = 0x80 - oDATAN int = 0x81 - oMYADDRESS int = 0x90 - oSUICIDE int = 0xff - */ ) type OpType int @@ -79,9 +61,21 @@ func (st *Stack) Pop() string { return str } +func (st *Stack) Popn() (*big.Int, *big.Int) { + s := len(st.data) + + strs := st.data[s-2:] + st.data = st.data[:s-2] + + return Big(strs[0]), Big(strs[1]) +} + func (st *Stack) Push(d string) { st.data = append(st.data, d) } +func (st *Stack) Print() { + fmt.Println(st.data) +} type Vm struct { // Stack @@ -96,7 +90,7 @@ func NewVm() *Vm { func (vm *Vm) ProcContract(tx *Transaction, block *Block, cb TxCallback) { // Instruction pointer - iptr := 0 + pc := 0 contract := block.GetContract(tx.Hash()) if contract == nil { @@ -104,164 +98,144 @@ func (vm *Vm) ProcContract(tx *Transaction, block *Block, cb TxCallback) { return } + Pow256 := BigPow(2, 256) + fmt.Printf("# op arg\n") out: for { // The base big int for all calculations. Use this for any results. base := new(big.Int) - base.SetString("0",0) // so it doesn't whine about it // XXX Should Instr return big int slice instead of string slice? // Get the next instruction from the contract - op, args, _ := Instr(contract.state.Get(string(Encode(uint32(iptr))))) + //op, _, _ := Instr(contract.state.Get(string(Encode(uint32(pc))))) + op, _, _ := Instr(contract.state.Get(string(NumberToBytes(uint64(pc), 32)))) + + if !cb(0) { break } if Debug { - fmt.Printf("%-3d %-4d %v\n", iptr, op, args) + fmt.Printf("%-3d %-4d\n", pc, op) } switch op { + case oADD: + x, y := vm.stack.Popn() + // (x + y) % 2 ** 256 + base.Add(x, y) + base.Mod(base, Pow256) + // Pop result back on the stack + vm.stack.Push(base.String()) + case oSUB: + x, y := vm.stack.Popn() + // (x - y) % 2 ** 256 + base.Sub(x, y) + base.Mod(base, Pow256) + // Pop result back on the stack + vm.stack.Push(base.String()) + case oMUL: + x, y := vm.stack.Popn() + // (x * y) % 2 ** 256 + base.Mul(x, y) + base.Mod(base, Pow256) + // Pop result back on the stack + vm.stack.Push(base.String()) + case oDIV: + x, y := vm.stack.Popn() + // floor(x / y) + base.Div(x, y) + // Pop result back on the stack + vm.stack.Push(base.String()) + case oSDIV: + x, y := vm.stack.Popn() + // n > 2**255 + if x.Cmp(Pow256) > 0 { x.Sub(Pow256, x) } + if y.Cmp(Pow256) > 0 { y.Sub(Pow256, y) } + z := new(big.Int) + z.Div(x, y) + if z.Cmp(Pow256) > 0 { z.Sub(Pow256, z) } + // Push result on to the stack + vm.stack.Push(z.String()) + case oMOD: + x, y := vm.stack.Popn() + base.Mod(x, y) + vm.stack.Push(base.String()) + case oSMOD: + x, y := vm.stack.Popn() + // n > 2**255 + if x.Cmp(Pow256) > 0 { x.Sub(Pow256, x) } + if y.Cmp(Pow256) > 0 { y.Sub(Pow256, y) } + z := new(big.Int) + z.Mod(x, y) + if z.Cmp(Pow256) > 0 { z.Sub(Pow256, z) } + // Push result on to the stack + vm.stack.Push(z.String()) + case oEXP: + x, y := vm.stack.Popn() + base.Exp(x, y, Pow256) + + vm.stack.Push(base.String()) + case oNEG: + base.Sub(Pow256, Big(vm.stack.Pop())) + vm.stack.Push(base.String()) + case oLT: + x, y := vm.stack.Popn() + // x < y + if x.Cmp(y) < 0 { + vm.stack.Push("1") + } else { + vm.stack.Push("0") + } + case oLE: + x, y := vm.stack.Popn() + // x <= y + if x.Cmp(y) < 1 { + vm.stack.Push("1") + } else { + vm.stack.Push("0") + } + case oGT: + x, y := vm.stack.Popn() + // x > y + if x.Cmp(y) > 0 { + vm.stack.Push("1") + } else { + vm.stack.Push("0") + } + case oGE: + x, y := vm.stack.Popn() + // x >= y + if x.Cmp(y) > -1 { + vm.stack.Push("1") + } else { + vm.stack.Push("0") + } + case oNOT: + x, y := vm.stack.Popn() + // x != y + if x.Cmp(y) != 0 { + vm.stack.Push("1") + } else { + vm.stack.Push("0") + } + case oMYADDRESS: + vm.stack.Push(string(tx.Hash())) + case oTXSENDER: + vm.stack.Push(tx.sender) case oPUSH: // Get the next entry and pushes the value on the stack - iptr++ - vm.stack.Push(contract.state.Get(string(Encode(uint32(iptr))))) + pc++ + vm.stack.Push(contract.state.Get(string(NumberToBytes(uint64(pc), 32)))) case oPOP: // Pop current value of the stack vm.stack.Pop() case oLOAD: // Load instruction X on the stack i, _ := strconv.Atoi(vm.stack.Pop()) - vm.stack.Push(contract.state.Get(string(Encode(uint32(i))))) + vm.stack.Push(contract.state.Get(string(NumberToBytes(uint64(i), 32)))) case oSTOP: break out } - iptr++ - } -} - -/* -type Vm struct { - // Memory stack - stack map[string]string - memory map[string]map[string]string -} - -func NewVm() *Vm { - //stackSize := uint(256) - - return &Vm{ - stack: make(map[string]string), - memory: make(map[string]map[string]string), - } -} - -func (vm *Vm) RunTransaction(tx *Transaction, cb TxCallback) { - if Debug { - fmt.Printf(` -# processing Tx (%v) -# fee = %f, ops = %d, sender = %s, value = %d - `, tx.addr, float32(tx.fee) / 1e8, len(tx.data), tx.sender, tx.value) + pc++ } - vm.stack = make(map[string]string) - vm.stack["0"] = tx.sender - vm.stack["1"] = "100" //int(tx.value) - vm.stack["1"] = "1000" //int(tx.fee) - // Stack pointer - stPtr := 0 - - //vm.memory[tx.addr] = make([]int, 256) - vm.memory[tx.addr] = make(map[string]string) - - // Define instruction 'accessors' for the instruction, which makes it more readable - // also called register values, shorthanded as Rx/y/z. Memory address are shorthanded as Mx/y/z. - // Instructions are shorthanded as Ix/y/z - x := 0; y := 1; z := 2; //a := 3; b := 4; c := 5 -out: - for stPtr < len(tx.data) { - // The base big int for all calculations. Use this for any results. - base := new(big.Int) - // XXX Should Instr return big int slice instead of string slice? - op, args, _ := Instr(tx.data[stPtr]) - - if Debug { - fmt.Printf("%-3d %d %v\n", stPtr, op, args) - } - - opType := OpType(tNorm) - // Determine the op type (used for calculating fees by the block manager) - switch op { - case oEXTRO, oBALANCE: - opType = tExtro - case oSHA256, oRIPEMD160, oECMUL, oECADD: // TODO add rest - opType = tCrypto - } - - // If the callback yielded a negative result abort execution - if !cb(opType) { break out } - - nptr := stPtr - switch op { - case oSTOP: - fmt.Println("exiting (oSTOP), idx =", nptr) - - break out - case oADD: - // (Rx + Ry) % 2 ** 256 - base.Add(Big(vm.stack[args[ x ]]), Big(vm.stack[args[ y ]])) - base.Mod(base, big.NewInt(int64(math.Pow(2, 256)))) - // Set the result to Rz - vm.stack[args[ z ]] = base.String() - case oSUB: - // (Rx - Ry) % 2 ** 256 - base.Sub(Big(vm.stack[args[ x ]]), Big(vm.stack[args[ y ]])) - base.Mod(base, big.NewInt(int64(math.Pow(2, 256)))) - // Set the result to Rz - vm.stack[args[ z ]] = base.String() - case oMUL: - // (Rx * Ry) % 2 ** 256 - base.Mul(Big(vm.stack[args[ x ]]), Big(vm.stack[args[ y ]])) - base.Mod(base, big.NewInt(int64(math.Pow(2, 256)))) - // Set the result to Rz - vm.stack[args[ z ]] = base.String() - case oDIV: - // floor(Rx / Ry) - base.Div(Big(vm.stack[args[ x ]]), Big(vm.stack[args[ y ]])) - // Set the result to Rz - vm.stack[args[ z ]] = base.String() - case oSET: - // Set the (numeric) value at Iy to Rx - vm.stack[args[ x ]] = args[ y ] - case oLD: - // Load the value at Mx to Ry - vm.stack[args[ y ]] = vm.memory[tx.addr][vm.stack[args[ x ]]] - case oLT: - cmp := Big(vm.stack[args[ x ]]).Cmp( Big(vm.stack[args[ y ]]) ) - // Set the result as "boolean" value to Rz - if cmp < 0 { // a < b - vm.stack[args[ z ]] = "1" - } else { - vm.stack[args[ z ]] = "0" - } - case oJMP: - // Set the instruction pointer to the value at Rx - ptr, _ := strconv.Atoi( vm.stack[args[ x ]] ) - nptr = ptr - case oJMPI: - // Set the instruction pointer to the value at Ry if Rx yields true - if vm.stack[args[ x ]] != "0" { - ptr, _ := strconv.Atoi( vm.stack[args[ y ]] ) - nptr = ptr - } - default: - fmt.Println("Error op", op) - break - } - - if stPtr == nptr { - stPtr++ - } else { - stPtr = nptr - if Debug { fmt.Println("... JMP", nptr, "...") } - } - } + vm.stack.Print() } -*/ diff --git a/vm_test.go b/vm_test.go index fe0358a42..efcd875cd 100644 --- a/vm_test.go +++ b/vm_test.go @@ -7,23 +7,66 @@ import ( func TestVm(t *testing.T) { + InitFees() + db, _ := NewMemDatabase() Db = db - ctrct := NewTransaction("", 20, []string{ - "PUSH", - "1a2f2e", - "PUSH", - "hallo", + ctrct := NewTransaction("", 200000000, []string{ + "PUSH", "1a2f2e", + "PUSH", "hallo", "POP", // POP hallo - "PUSH", - "3", + "PUSH", "3", "LOAD", // Load hallo back on the stack + + "PUSH", "1", + "PUSH", "2", + "ADD", + + "PUSH", "2", + "PUSH", "1", + "SUB", + + "PUSH", "100000000000000000000000", + "PUSH", "10000000000000", + "SDIV", + + "PUSH", "105", + "PUSH", "200", + "MOD", + + "PUSH", "100000000000000000000000", + "PUSH", "10000000000000", + "SMOD", + + "PUSH", "5", + "PUSH", "10", + "LT", + + "PUSH", "5", + "PUSH", "5", + "LE", + + "PUSH", "50", + "PUSH", "5", + "GT", + + "PUSH", "5", + "PUSH", "5", + "GE", + + "PUSH", "10", + "PUSH", "10", + "NOT", + + "MYADDRESS", + "TXSENDER", + "STOP", }) tx := NewTransaction("1e8a42ea8cce13", 100, []string{}) - block := CreateBlock("", 0, "", "", 0, 0, "", []*Transaction{ctrct, tx}) + block := CreateBlock("", 0, "", "c014ba53", 0, 0, "", []*Transaction{ctrct, tx}) db.Put(block.Hash(), block.MarshalRlp()) bm := NewBlockManager() From 2c90c0df65132bf65abbcf4e4caecb89b671b93f Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 4 Jan 2014 00:33:41 +0100 Subject: [PATCH 056/459] Updated fee --- transaction.go | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/transaction.go b/transaction.go index 1cfa6d729..f5c848a31 100644 --- a/transaction.go +++ b/transaction.go @@ -34,9 +34,10 @@ var Period3Reward *big.Int = new(big.Int) var Period4Reward *big.Int = new(big.Int) type Transaction struct { + nonce string sender string recipient string - value uint32 + value uint64 fee uint32 data []string memory []int @@ -47,8 +48,9 @@ type Transaction struct { addr string } -func NewTransaction(to string, value uint32, data []string) *Transaction { +func NewTransaction(to string, value uint64, data []string) *Transaction { tx := Transaction{sender: "1234567890", recipient: to, value: value} + tx.nonce = "0" tx.fee = 0//uint32((ContractFee + MemoryFee * float32(len(tx.data))) * 1e8) tx.lastTx = "0" @@ -102,16 +104,16 @@ func (tx *Transaction) UnmarshalRlp(data []byte) { // If only I knew of a better way. if value, ok := slice[3].(uint8); ok { - tx.value = uint32(value) + tx.value = uint64(value) } if value, ok := slice[3].(uint16); ok { - tx.value = uint32(value) + tx.value = uint64(value) } if value, ok := slice[3].(uint32); ok { - tx.value = uint32(value) + tx.value = uint64(value) } if value, ok := slice[3].(uint64); ok { - tx.value = uint32(value) + tx.value = uint64(value) } if fee, ok := slice[4].(uint8); ok { tx.fee = uint32(fee) @@ -146,7 +148,8 @@ func InitFees() { b80 := new(big.Int) b80.Exp(big.NewInt(2), big.NewInt(80), big.NewInt(0)) - StepFee.Div(b60, big.NewInt(64)) + StepFee.Exp(big.NewInt(10), big.NewInt(16), big.NewInt(0)) + //StepFee.Div(b60, big.NewInt(64)) //fmt.Println("StepFee:", StepFee) TxFee.Exp(big.NewInt(2), big.NewInt(64), big.NewInt(0)) From 53a30740eea7d3b3010337166e53a62ebff508f3 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 5 Jan 2014 01:54:15 +0100 Subject: [PATCH 057/459] Contract checking method --- block_manager.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block_manager.go b/block_manager.go index 6c1a0fe58..0f7a64cf8 100644 --- a/block_manager.go +++ b/block_manager.go @@ -34,7 +34,7 @@ func (bm *BlockManager) ProcessBlock(block *Block) error { // Process each transaction/contract for _, tx := range block.transactions { // If there's no recipient, it's a contract - if tx.recipient == "" { + if tx.IsContract() { go bm.ProcessContract(tx, block, lockChan) } else { // "finish" tx which isn't a contract From 92c3471445d9a46389ddab893a159ce273707a95 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 5 Jan 2014 01:55:03 +0100 Subject: [PATCH 058/459] secp256k1 method signing --- transaction.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/transaction.go b/transaction.go index f5c848a31..f38f0fed3 100644 --- a/transaction.go +++ b/transaction.go @@ -3,6 +3,7 @@ package main import ( "math/big" "fmt" + "github.com/obscuren/secp256k1-go" _"encoding/hex" _"crypto/sha256" _ "bytes" @@ -73,6 +74,28 @@ func (tx *Transaction) Hash() []byte { return Sha256Bin(tx.MarshalRlp()) } +func (tx *Transaction) IsContract() bool { + return tx.recipient == "" +} + +func (tx *Transaction) Signature() []byte { + hash := Sha256Bin(tx.MarshalRlp()) + sec := Sha256Bin([]byte("myprivkey")) + + sig, _ := secp256k1.Sign(hash, sec) + + return sig +} + +func (tx *Transaction) PublicKey() []byte { + hash := Sha256Bin(tx.MarshalRlp()) + sig := tx.Signature() + + pubkey, _ := secp256k1.RecoverPubkey(hash, sig) + + return pubkey +} + func (tx *Transaction) MarshalRlp() []byte { // Prepare the transaction for serialization preEnc := []interface{}{ From 8204e9cd6eefdca9e9248be6cf97466fa5fb433d Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 5 Jan 2014 20:14:53 +0100 Subject: [PATCH 059/459] Changed hashing, signature and key generation. --- transaction.go | 95 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 70 insertions(+), 25 deletions(-) diff --git a/transaction.go b/transaction.go index f38f0fed3..a3279aa33 100644 --- a/transaction.go +++ b/transaction.go @@ -43,10 +43,8 @@ type Transaction struct { data []string memory []int lastTx string - - // To be removed - signature string - addr string + v uint32 + r, s []byte } func NewTransaction(to string, value uint64, data []string) *Transaction { @@ -60,18 +58,28 @@ func NewTransaction(to string, value uint64, data []string) *Transaction { for i, val := range data { instr, err := CompileInstr(val) if err != nil { - fmt.Printf("compile error:%d %v\n", i+1, err) + //fmt.Printf("compile error:%d %v\n", i+1, err) } tx.data[i] = instr } + tx.SetVRS() + return &tx } func (tx *Transaction) Hash() []byte { - return Sha256Bin(tx.MarshalRlp()) + preEnc := []interface{}{ + tx.nonce, + tx.recipient, + tx.value, + tx.fee, + tx.data, + } + + return Sha256Bin(Encode(preEnc)) } func (tx *Transaction) IsContract() bool { @@ -79,7 +87,7 @@ func (tx *Transaction) IsContract() bool { } func (tx *Transaction) Signature() []byte { - hash := Sha256Bin(tx.MarshalRlp()) + hash := tx.Hash() sec := Sha256Bin([]byte("myprivkey")) sig, _ := secp256k1.Sign(hash, sec) @@ -96,15 +104,34 @@ func (tx *Transaction) PublicKey() []byte { return pubkey } +func (tx *Transaction) Address() []byte { + pubk := tx.PublicKey() + // 1 is the marker 04 + key := pubk[1:65] + + return Sha256Bin(key)[12:] +} + +func (tx *Transaction) SetVRS() { + // Add 27 so we get either 27 or 28 (for positive and negative) + tx.v = uint32(tx.Signature()[64]) + 27 + + pubk := tx.PublicKey()[1:65] + tx.r = pubk[:32] + tx.s = pubk[32:64] +} + func (tx *Transaction) MarshalRlp() []byte { // Prepare the transaction for serialization preEnc := []interface{}{ - tx.lastTx, - tx.sender, + tx.nonce, tx.recipient, tx.value, tx.fee, tx.data, + tx.v, + tx.r, + tx.s, } return Encode(preEnc) @@ -113,46 +140,43 @@ func (tx *Transaction) MarshalRlp() []byte { func (tx *Transaction) UnmarshalRlp(data []byte) { t, _ := Decode(data,0) if slice, ok := t.([]interface{}); ok { - if lastTx, ok := slice[0].([]byte); ok { - tx.lastTx = string(lastTx) + fmt.Printf("NONCE %T\n", slice[3]) + if nonce, ok := slice[0].(uint8); ok { + tx.nonce = string(nonce) } - if sender, ok := slice[1].([]byte); ok { - tx.sender = string(sender) - } - - if recipient, ok := slice[2].([]byte); ok { + if recipient, ok := slice[1].([]byte); ok { tx.recipient = string(recipient) } // If only I knew of a better way. - if value, ok := slice[3].(uint8); ok { + if value, ok := slice[2].(uint8); ok { tx.value = uint64(value) } - if value, ok := slice[3].(uint16); ok { + if value, ok := slice[2].(uint16); ok { tx.value = uint64(value) } - if value, ok := slice[3].(uint32); ok { + if value, ok := slice[2].(uint32); ok { tx.value = uint64(value) } - if value, ok := slice[3].(uint64); ok { + if value, ok := slice[2].(uint64); ok { tx.value = uint64(value) } - if fee, ok := slice[4].(uint8); ok { + if fee, ok := slice[3].(uint8); ok { tx.fee = uint32(fee) } - if fee, ok := slice[4].(uint16); ok { + if fee, ok := slice[3].(uint16); ok { tx.fee = uint32(fee) } - if fee, ok := slice[4].(uint32); ok { + if fee, ok := slice[3].(uint32); ok { tx.fee = uint32(fee) } - if fee, ok := slice[4].(uint64); ok { + if fee, ok := slice[3].(uint64); ok { tx.fee = uint32(fee) } // Encode the data/instructions - if data, ok := slice[5].([]interface{}); ok { + if data, ok := slice[4].([]interface{}); ok { tx.data = make([]string, len(data)) for i, d := range data { if instr, ok := d.([]byte); ok { @@ -160,6 +184,27 @@ func (tx *Transaction) UnmarshalRlp(data []byte) { } } } + + // vrs + fmt.Printf("v %T\n", slice[5]) + if v, ok := slice[5].(uint8); ok { + tx.v = uint32(v) + } + if v, ok := slice[5].(uint16); ok { + tx.v = uint32(v) + } + if v, ok := slice[5].(uint32); ok { + tx.v = uint32(v) + } + if v, ok := slice[5].(uint64); ok { + tx.v = uint32(v) + } + if r, ok := slice[6].([]byte); ok { + tx.r = r + } + if s, ok := slice[7].([]byte); ok { + tx.s = s + } } } From 79c89c0bcda7ed35ec5570eb597e427631848174 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 5 Jan 2014 20:15:05 +0100 Subject: [PATCH 060/459] Removed logging --- vm.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vm.go b/vm.go index 9e1e83b0b..a727d58e5 100644 --- a/vm.go +++ b/vm.go @@ -100,7 +100,7 @@ func (vm *Vm) ProcContract(tx *Transaction, block *Block, cb TxCallback) { Pow256 := BigPow(2, 256) - fmt.Printf("# op arg\n") + //fmt.Printf("# op arg\n") out: for { // The base big int for all calculations. Use this for any results. @@ -113,7 +113,7 @@ out: if !cb(0) { break } if Debug { - fmt.Printf("%-3d %-4d\n", pc, op) + //fmt.Printf("%-3d %-4d\n", pc, op) } switch op { From 40dc4d0259b3bec4e8ac11dc4dd4daeaf663fa7c Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 5 Jan 2014 20:15:13 +0100 Subject: [PATCH 061/459] Testing --- testing.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testing.go b/testing.go index 07e8c362f..64c34ca70 100644 --- a/testing.go +++ b/testing.go @@ -13,13 +13,13 @@ func Testing() { bm := NewBlockManager() - tx := NewTransaction("\x00", 20, []string{ - "PSH 10", - }) + tx := NewTransaction("\x00", 20, []string{"PSH 10"}) txData := tx.MarshalRlp() copyTx := &Transaction{} copyTx.UnmarshalRlp(txData) + fmt.Println(tx) + fmt.Println(copyTx) tx2 := NewTransaction("\x00", 20, []string{"SET 10 6", "LD 10 10"}) From 1676930a1644f06dafc66e2b5595eb343ffebc07 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 5 Jan 2014 20:41:01 +0100 Subject: [PATCH 062/459] updated testing" --- parsing_test.go | 4 ++-- testing.go | 3 ++- transaction.go | 4 +--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/parsing_test.go b/parsing_test.go index fa319e7bf..6aa9e240c 100644 --- a/parsing_test.go +++ b/parsing_test.go @@ -6,13 +6,13 @@ import ( ) func TestCompile(t *testing.T) { - instr, err := CompileInstr("SET 10 1") + instr, err := CompileInstr("PUSH") if err != nil { t.Error("Failed compiling instruction") } - calc := (67 + 10 * 256 + 1 * int64(math.Pow(256,2))) + calc := (48 + 0 * 256 + 0 * int64(math.Pow(256,2))) if Big(instr).Int64() != calc { t.Error("Expected", calc, ", got:", instr) } diff --git a/testing.go b/testing.go index 64c34ca70..3762e4dc5 100644 --- a/testing.go +++ b/testing.go @@ -13,8 +13,9 @@ func Testing() { bm := NewBlockManager() - tx := NewTransaction("\x00", 20, []string{"PSH 10"}) + tx := NewTransaction("\x00", 20, []string{"PUSH"}) txData := tx.MarshalRlp() + fmt.Printf("%q\n", txData) copyTx := &Transaction{} copyTx.UnmarshalRlp(txData) diff --git a/transaction.go b/transaction.go index a3279aa33..168d58566 100644 --- a/transaction.go +++ b/transaction.go @@ -2,7 +2,7 @@ package main import ( "math/big" - "fmt" + _"fmt" "github.com/obscuren/secp256k1-go" _"encoding/hex" _"crypto/sha256" @@ -140,7 +140,6 @@ func (tx *Transaction) MarshalRlp() []byte { func (tx *Transaction) UnmarshalRlp(data []byte) { t, _ := Decode(data,0) if slice, ok := t.([]interface{}); ok { - fmt.Printf("NONCE %T\n", slice[3]) if nonce, ok := slice[0].(uint8); ok { tx.nonce = string(nonce) } @@ -186,7 +185,6 @@ func (tx *Transaction) UnmarshalRlp(data []byte) { } // vrs - fmt.Printf("v %T\n", slice[5]) if v, ok := slice[5].(uint8); ok { tx.v = uint32(v) } From b6f7859c3dbf2d63933eab542c8ef3b3fdcbb863 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 5 Jan 2014 20:45:32 +0100 Subject: [PATCH 063/459] travis --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 92ca75b5a..7449c439a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +[![Build +Status](https://travis-ci.org/ethereum/go-ethereum.png?branch=master)](https://travis-ci.org/ethereum/go-ethereum) + This is the Go implementation of the Ethereum protocol. It's far from being finished. ```go get https://github.com/ethereum/go-ethereum``` From 9f133a92d0853102863b77dd7c884d1462cf73a4 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 8 Jan 2014 23:41:03 +0100 Subject: [PATCH 064/459] First dagger impl --- dagger.go | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 dagger.go diff --git a/dagger.go b/dagger.go new file mode 100644 index 000000000..750a781b0 --- /dev/null +++ b/dagger.go @@ -0,0 +1,110 @@ +package main + +import ( + "math/big" + "fmt" + "math/rand" + "time" + "github.com/obscuren/sha3" +) + +type Dagger struct { + hash *big.Int + xn *big.Int +} + +func (dag *Dagger) Search(diff *big.Int) *big.Int { + dag.hash = big.NewInt(0) + + obj := BigPow(2, 256) + obj = obj.Div(obj, diff) + + fmt.Println("diff", diff, "< objective", obj) + + r := rand.New(rand.NewSource(time.Now().UnixNano())) + rnd := big.NewInt(r.Int63()) + fmt.Println("init rnd =", rnd) + + for i := 0; i < 1000; i++ { + if dag.Eval(rnd).Cmp(obj) < 0 { + fmt.Println("Found result! i = ", i) + return rnd + } + + rnd = rnd.Add(rnd, big.NewInt(1)) + } + + return big.NewInt(0) +} + +func (dag *Dagger) Node(L uint64, i uint64) *big.Int { + if L == i { + return dag.hash + } + + var m *big.Int + if L == 9 { + m = big.NewInt(16) + } else { + m = big.NewInt(3) + } + + sha := sha3.NewKeccak224() + sha.Reset() + d := sha3.NewKeccak224() + b := new(big.Int) + ret := new(big.Int) + + for k := 0; k < int(m.Uint64()); k++ { + d.Reset() + d.Write(dag.hash.Bytes()) + d.Write(dag.xn.Bytes()) + d.Write(big.NewInt(int64(L)).Bytes()) + d.Write(big.NewInt(int64(i)).Bytes()) + d.Write(big.NewInt(int64(k)).Bytes()) + + b.SetBytes(d.Sum(nil)) + pk := b.Uint64() & ((1 << ((L - 1) * 3)) - 1) + sha.Write(dag.Node(L - 1, pk).Bytes()) + } + + ret.SetBytes(sha.Sum(nil)) + + return ret +} + +func (dag *Dagger) Eval(N *big.Int) *big.Int { + pow := BigPow(2, 26) + dag.xn = N.Div(N, pow) + + sha := sha3.NewKeccak224() + sha.Reset() + ret := new(big.Int) + + doneChan := make(chan bool, 3) + + for k := 0; k < 4; k++ { + go func(_k int) { + d := sha3.NewKeccak224() + b := new(big.Int) + + d.Reset() + d.Write(dag.hash.Bytes()) + d.Write(dag.xn.Bytes()) + d.Write(N.Bytes()) + d.Write(big.NewInt(int64(_k)).Bytes()) + + b.SetBytes(d.Sum(nil)) + pk := (b.Uint64() & 0x1ffffff) + + sha.Write(dag.Node(9, pk).Bytes()) + doneChan <- true + }(k) + } + + for k := 0; k < 4; k++ { + <- doneChan + } + + return ret.SetBytes(sha.Sum(nil)) +} From 0929f59ec260e2a29863b8764959b271a7f75cc8 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 8 Jan 2014 23:42:11 +0100 Subject: [PATCH 065/459] Updated marshalling --- block.go | 89 ++++++++----------------------------- contract.go | 24 ++-------- genesis.go | 2 - rlp.go | 105 ++++++++++++++++++++++++++++++++++++++++++++ transaction.go | 116 +++++++++++++++---------------------------------- 5 files changed, 164 insertions(+), 172 deletions(-) diff --git a/block.go b/block.go index 00317573c..6ae3cc832 100644 --- a/block.go +++ b/block.go @@ -74,7 +74,6 @@ func CreateBlock(root string, num int, prevHash string, base string, difficulty block.state.Update(string(addr), string(contract.MarshalRlp())) for i, val := range tx.data { contract.state.Update(string(NumberToBytes(uint64(i), 32)), val) - //contract.state.Update(string(Encode(uint32(i))), val) } block.UpdateContract(addr, contract) } @@ -105,6 +104,7 @@ func (block *Block) PayFee(addr []byte, fee uint64) bool { // If we can't pay the fee return if contract == nil || contract.amount < fee { fmt.Println("Contract has insufficient funds", contract.amount, fee) + return false } @@ -112,7 +112,7 @@ func (block *Block) PayFee(addr []byte, fee uint64) bool { block.state.Update(string(addr), string(contract.MarshalRlp())) data := block.state.Get(string(block.coinbase)) - println(data) + // Get the ether (coinbase) and add the fee (gief fee to miner) ether := NewEtherFromData([]byte(data)) ether.amount += fee @@ -159,75 +159,24 @@ func (block *Block) MarshalRlp() []byte { } func (block *Block) UnmarshalRlp(data []byte) { - t, _ := Decode(data,0) + decoder := NewRlpDecoder(data) - // interface slice assertion - if slice, ok := t.([]interface{}); ok { - // interface slice assertion - if header, ok := slice[0].([]interface{}); ok { - if number, ok := header[0].(uint8); ok { - block.number = uint32(number) - } + header := decoder.Get(0) + block.number = uint32(header.Get(0).AsUint()) + block.prevHash = header.Get(1).AsString() + // sha of uncles is header[2] + block.coinbase = header.Get(3).AsString() + block.state = NewTrie(Db, header.Get(4).AsString()) + block.difficulty = uint32(header.Get(5).AsUint()) + block.time = int64(header.Get(6).AsUint()) + block.nonce = uint32(header.Get(7).AsUint()) + block.extra = header.Get(8).AsString() - if prevHash, ok := header[1].([]uint8); ok { - block.prevHash = string(prevHash) - } - - // sha of uncles is header[2] - - if coinbase, ok := header[3].([]byte); ok { - block.coinbase = string(coinbase) - } - - if state, ok := header[4].([]uint8); ok { - // XXX The database is currently a global variable defined in testing.go - // This will eventually go away and the database will grabbed from the public server - // interface - block.state = NewTrie(Db, string(state)) - } - - // sha is header[5] - - // It's either 8bit or 64 - if difficulty, ok := header[6].(uint8); ok { - block.difficulty = uint32(difficulty) - } - if difficulty, ok := header[6].(uint64); ok { - block.difficulty = uint32(difficulty) - } - - // It's either 8bit or 64 - if time, ok := header[7].(uint8); ok { - block.time = int64(time) - } - if time, ok := header[7].(uint64); ok { - block.time = int64(time) - } - - if nonce, ok := header[8].(uint8); ok { - block.nonce = uint32(nonce) - } - - if extra, ok := header[9].([]byte); ok { - block.extra = string(extra) - } - } - - if txSlice, ok := slice[1].([]interface{}); ok { - // Create transaction slice equal to decoded tx interface slice - block.transactions = make([]*Transaction, len(txSlice)) - - // Unmarshal transactions - for i, tx := range txSlice { - if t, ok := tx.([]byte); ok { - tx := &Transaction{} - // Use the unmarshaled data to unmarshal the transaction - // t is still decoded. - tx.UnmarshalRlp(t) - - block.transactions[i] = tx - } - } - } + txes := decoder.Get(1) + block.transactions = make([]*Transaction, txes.Length()) + for i := 0; i < txes.Length(); i++ { + tx := &Transaction{} + tx.UnmarshalRlp(txes.Get(i).AsBytes()) + block.transactions[i] = tx } } diff --git a/contract.go b/contract.go index 778f3578d..a54643f59 100644 --- a/contract.go +++ b/contract.go @@ -22,27 +22,11 @@ func (c *Contract) MarshalRlp() []byte { } func (c *Contract) UnmarshalRlp(data []byte) { - t, _ := Decode(data, 0) + decoder := NewRlpDecoder(data) - if slice, ok := t.([]interface{}); ok { - if t, ok := slice[0].(uint8); ok { - c.t = uint32(t) - } - - if amount, ok := slice[1].(uint8); ok { - c.amount = uint64(amount) - } else if amount, ok := slice[1].(uint16); ok { - c.amount = uint64(amount) - } else if amount, ok := slice[1].(uint32); ok { - c.amount = uint64(amount) - } else if amount, ok := slice[1].(uint64); ok { - c.amount = amount - } - - if root, ok := slice[2].([]uint8); ok { - c.state = NewTrie(Db, string(root)) - } - } + c.t = uint32(decoder.Get(0).AsUint()) + c.amount = decoder.Get(1).AsUint() + c.state = NewTrie(Db, decoder.Get(2).AsString()) } type Ether struct { diff --git a/genesis.go b/genesis.go index aae9cd1cf..21b8e9998 100644 --- a/genesis.go +++ b/genesis.go @@ -32,5 +32,3 @@ var GenisisHeader = []interface{}{ } var Genesis = []interface{}{ GenisisHeader, []interface{}{}, []interface{}{} } - -var GenisisBlock = NewBlock( Encode(Genesis) ) diff --git a/rlp.go b/rlp.go index 4db88539d..5366632f4 100644 --- a/rlp.go +++ b/rlp.go @@ -4,8 +4,110 @@ import ( "fmt" "bytes" "math" + "math/big" ) +type RlpEncoder struct { + rlpData []byte +} +func NewRlpEncoder() *RlpEncoder { + encoder := &RlpEncoder{} + + return encoder +} +func (coder *RlpEncoder) EncodeData(rlpData []interface{}) []byte { + return nil +} + +// Data attributes are returned by the rlp decoder. The data attributes represents +// one item within the rlp data structure. It's responsible for all the casting +// It always returns something valid +type RlpDataAttribute struct { + dataAttrib interface{} +} + +func NewRlpDataAttribute(attrib interface{}) *RlpDataAttribute { + return &RlpDataAttribute{dataAttrib: attrib} +} + +func (attr *RlpDataAttribute) Length() int { + if data, ok := attr.dataAttrib.([]interface{}); ok { + return len(data) + } + + return 0 +} + +func (attr *RlpDataAttribute) AsUint() uint64 { + if value, ok := attr.dataAttrib.(uint8); ok { + return uint64(value) + } else if value, ok := attr.dataAttrib.(uint16); ok { + return uint64(value) + } else if value, ok := attr.dataAttrib.(uint32); ok { + return uint64(value) + } else if value, ok := attr.dataAttrib.(uint64); ok { + return value + } + + return 0 +} + +func (attr *RlpDataAttribute) AsBigInt() *big.Int { + if a, ok := attr.dataAttrib.([]byte); ok { + return Big(string(a)) + } + + return big.NewInt(0) +} + +func (attr *RlpDataAttribute) AsString() string { + if a, ok := attr.dataAttrib.([]byte); ok { + return string(a) + } + + return "" +} + +func (attr *RlpDataAttribute) AsBytes() []byte { + if a, ok := attr.dataAttrib.([]byte); ok { + return a + } + + return make([]byte, 0) +} + +// Threat the attribute as a slice +func (attr *RlpDataAttribute) Get(idx int) *RlpDataAttribute { + if d, ok := attr.dataAttrib.([]interface{}); ok { + // Guard for oob + if len(d) < idx { + return NewRlpDataAttribute(nil) + } + + return NewRlpDataAttribute(d[idx]) + } + + // If this wasn't a slice you probably shouldn't be using this function + return NewRlpDataAttribute(nil) +} + +type RlpDecoder struct { + rlpData interface{} +} +func NewRlpDecoder(rlpData []byte) *RlpDecoder { + decoder := &RlpDecoder{} + // Decode the data + data, _ := Decode(rlpData,0) + decoder.rlpData = data + + return decoder +} + +func (dec *RlpDecoder) Get(idx int) *RlpDataAttribute { + return NewRlpDataAttribute(dec.rlpData).Get(idx) +} + +/// Raw methods func BinaryLength(n uint64) uint64 { if n == 0 { return 0 } @@ -122,6 +224,9 @@ func Encode(object interface{}) []byte { buff.WriteString(string(len(b2) + 55) + b2 + b) } + case *big.Int: + buff.Write(Encode(t.String())) + case string: if len(t) < 56 { buff.WriteString(string(len(t) + 64) + t) diff --git a/transaction.go b/transaction.go index 168d58566..90e0d9869 100644 --- a/transaction.go +++ b/transaction.go @@ -2,7 +2,7 @@ package main import ( "math/big" - _"fmt" + "fmt" "github.com/obscuren/secp256k1-go" _"encoding/hex" _"crypto/sha256" @@ -64,7 +64,8 @@ func NewTransaction(to string, value uint64, data []string) *Transaction { tx.data[i] = instr } - tx.SetVRS() + tx.Sign([]byte("privkey")) + tx.Sender() return &tx @@ -86,9 +87,9 @@ func (tx *Transaction) IsContract() bool { return tx.recipient == "" } -func (tx *Transaction) Signature() []byte { +func (tx *Transaction) Signature(key []byte) []byte { hash := tx.Hash() - sec := Sha256Bin([]byte("myprivkey")) + sec := Sha256Bin(key) sig, _ := secp256k1.Sign(hash, sec) @@ -96,29 +97,33 @@ func (tx *Transaction) Signature() []byte { } func (tx *Transaction) PublicKey() []byte { - hash := Sha256Bin(tx.MarshalRlp()) - sig := tx.Signature() + hash := Sha256Bin(tx.Hash()) + sig := append(tx.r, tx.s...) pubkey, _ := secp256k1.RecoverPubkey(hash, sig) return pubkey } -func (tx *Transaction) Address() []byte { - pubk := tx.PublicKey() - // 1 is the marker 04 - key := pubk[1:65] +func (tx *Transaction) Sender() []byte { + pubkey := tx.PublicKey() - return Sha256Bin(key)[12:] + // Validate the returned key. + // Return nil if public key isn't in full format (04 = full, 03 = compact) + if pubkey[0] != 4 { + return nil + } + + return Sha256Bin(pubkey[1:65])[12:] } -func (tx *Transaction) SetVRS() { - // Add 27 so we get either 27 or 28 (for positive and negative) - tx.v = uint32(tx.Signature()[64]) + 27 +func (tx *Transaction) Sign(privk []byte) { + sig := tx.Signature(privk) - pubk := tx.PublicKey()[1:65] - tx.r = pubk[:32] - tx.s = pubk[32:64] + // Add 27 so we get either 27 or 28 (for positive and negative) + tx.v = uint32(sig[64]) + 27 + tx.r = sig[:32] + tx.s = sig[32:65] } func (tx *Transaction) MarshalRlp() []byte { @@ -138,72 +143,23 @@ func (tx *Transaction) MarshalRlp() []byte { } func (tx *Transaction) UnmarshalRlp(data []byte) { - t, _ := Decode(data,0) - if slice, ok := t.([]interface{}); ok { - if nonce, ok := slice[0].(uint8); ok { - tx.nonce = string(nonce) - } + decoder := NewRlpDecoder(data) - if recipient, ok := slice[1].([]byte); ok { - tx.recipient = string(recipient) - } + tx.nonce = decoder.Get(0).AsString() + tx.recipient = decoder.Get(0).AsString() + tx.value = decoder.Get(2).AsUint() + tx.fee = uint32(decoder.Get(3).AsUint()) - // If only I knew of a better way. - if value, ok := slice[2].(uint8); ok { - tx.value = uint64(value) - } - if value, ok := slice[2].(uint16); ok { - tx.value = uint64(value) - } - if value, ok := slice[2].(uint32); ok { - tx.value = uint64(value) - } - if value, ok := slice[2].(uint64); ok { - tx.value = uint64(value) - } - if fee, ok := slice[3].(uint8); ok { - tx.fee = uint32(fee) - } - if fee, ok := slice[3].(uint16); ok { - tx.fee = uint32(fee) - } - if fee, ok := slice[3].(uint32); ok { - tx.fee = uint32(fee) - } - if fee, ok := slice[3].(uint64); ok { - tx.fee = uint32(fee) - } - - // Encode the data/instructions - if data, ok := slice[4].([]interface{}); ok { - tx.data = make([]string, len(data)) - for i, d := range data { - if instr, ok := d.([]byte); ok { - tx.data[i] = string(instr) - } - } - } - - // vrs - if v, ok := slice[5].(uint8); ok { - tx.v = uint32(v) - } - if v, ok := slice[5].(uint16); ok { - tx.v = uint32(v) - } - if v, ok := slice[5].(uint32); ok { - tx.v = uint32(v) - } - if v, ok := slice[5].(uint64); ok { - tx.v = uint32(v) - } - if r, ok := slice[6].([]byte); ok { - tx.r = r - } - if s, ok := slice[7].([]byte); ok { - tx.s = s - } + d := decoder.Get(4) + tx.data = make([]string, d.Length()) + fmt.Println(d.Get(0)) + for i := 0; i < d.Length(); i++ { + tx.data[i] = d.Get(i).AsString() } + + tx.v = uint32(decoder.Get(5).AsUint()) + tx.r = decoder.Get(6).AsBytes() + tx.s = decoder.Get(7).AsBytes() } func InitFees() { From 4bc9b1fcb3591f60d6c3d3c03c710e210918917d Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 8 Jan 2014 23:42:23 +0100 Subject: [PATCH 066/459] Updated readme --- README.md | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 7449c439a..05276a113 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,23 @@ -[![Build -Status](https://travis-ci.org/ethereum/go-ethereum.png?branch=master)](https://travis-ci.org/ethereum/go-ethereum) +Ethereum +======== -This is the Go implementation of the Ethereum protocol. It's far from being finished. +[![Build Status](https://travis-ci.org/ethereum/go-ethereum.png?branch=master)](https://travis-ci.org/ethereum/go-ethereum) + +Ethereum Go + +Deps +==== + +Ethereum Go makes use of a modified `secp256k1-go` and therefor GMP. + +Install +======= ```go get https://github.com/ethereum/go-ethereum``` -** The Python reference implementation can be found at https://github.com/ethereum/pyethereum ** -## Command line options +Command line options +==================== -db will launch the db query tool. From 83bb4a3f265ec9a4fa75388dd6fa212a79a9b218 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 8 Jan 2014 23:42:35 +0100 Subject: [PATCH 067/459] added few commands --- db_query_interface.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/db_query_interface.go b/db_query_interface.go index 11137e4c2..007f4bf28 100644 --- a/db_query_interface.go +++ b/db_query_interface.go @@ -72,6 +72,8 @@ func (i *DbInterface) ParseInput(input string) bool { fmt.Println(hex.EncodeToString([]byte(i.trie.root))) case "rawroot": fmt.Println(i.trie.root) + case "print": + i.db.Print() case "exit", "quit", "q": return false case "help": From 9f42835a0204ba2508895c1d259340bcda843974 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 8 Jan 2014 23:43:07 +0100 Subject: [PATCH 068/459] WIP Block chain --- block_manager.go | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/block_manager.go b/block_manager.go index 0f7a64cf8..134ca0e75 100644 --- a/block_manager.go +++ b/block_manager.go @@ -1,21 +1,26 @@ - - // Blocks, blocks will have transactions. - // Transactions/contracts are updated in goroutines - // Each contract should send a message on a channel with usage statistics - // The statics can be used for fee calculation within the block update method - // Statistics{transaction, /* integers */ normal_ops, store_load, extro_balance, crypto, steps} - // The block updater will wait for all goroutines to be finished and update the block accordingly - // in one go and should use minimal IO overhead. - // The actual block updating will happen within a goroutine as well so normal operation may continue - package main import ( "fmt" ) +type BlockChain struct { + lastBlock *Block + + genesisBlock *Block +} + +func NewBlockChain() *BlockChain { + bc := &BlockChain{} + bc.genesisBlock = NewBlock( Encode(Genesis) ) + + return bc +} + type BlockManager struct { vm *Vm + + blockChain *BlockChain } func NewBlockManager() *BlockManager { @@ -26,6 +31,11 @@ func NewBlockManager() *BlockManager { // Process a block. func (bm *BlockManager) ProcessBlock(block *Block) error { + // TODO Validation (Or move to other part of the application) + if err := bm.ValidateBlock(block); err != nil { + return err + } + // Get the tx count. Used to create enough channels to 'join' the go routines txCount := len(block.transactions) // Locking channel. When it has been fully buffered this method will return @@ -50,6 +60,10 @@ func (bm *BlockManager) ProcessBlock(block *Block) error { return nil } +func (bm *BlockManager) ValidateBlock(block *Block) error { + return nil +} + func (bm *BlockManager) ProcessContract(tx *Transaction, block *Block, lockChan chan bool) { // Recovering function in case the VM had any errors defer func() { From 92b6667bd1cf7aad4a00331d761d8a92b03a7cae Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 8 Jan 2014 23:43:20 +0100 Subject: [PATCH 069/459] Minor update --- ethereum.go | 27 +++++++++++++++-- memory_database.go | 9 ++++++ server.go | 15 ++++++++-- testing.go | 12 ++++---- trie.go | 22 +++++++------- util.go | 13 +++++++++ vm.go | 72 +++++++++++++++++++++++++++++++--------------- 7 files changed, 126 insertions(+), 44 deletions(-) diff --git a/ethereum.go b/ethereum.go index ac9690e41..b10415fd1 100644 --- a/ethereum.go +++ b/ethereum.go @@ -5,13 +5,16 @@ import ( "os" "os/signal" "flag" + "runtime" ) const Debug = true var StartDBQueryInterface bool +var StartMining bool func Init() { flag.BoolVar(&StartDBQueryInterface, "db", false, "start db query interface") + flag.BoolVar(&StartMining, "mine", false, "start dagger mining") flag.Parse() } @@ -24,7 +27,7 @@ func RegisterInterupts(s *Server) { signal.Notify(c, os.Interrupt) go func() { for sig := range c { - fmt.Println("Shutting down (%v) ... \n", sig) + fmt.Printf("Shutting down (%v) ... \n", sig) s.Stop() } @@ -32,6 +35,8 @@ func RegisterInterupts(s *Server) { } func main() { + runtime.GOMAXPROCS(runtime.NumCPU()) + InitFees() Init() @@ -39,7 +44,25 @@ func main() { if StartDBQueryInterface { dbInterface := NewDBInterface() dbInterface.Start() + } else if StartMining { + dagger := &Dagger{} + seed := dagger.Search(BigPow(2, 36)) + + fmt.Println("dagger res = ", seed) } else { - Testing() + fmt.Println("[DBUG]: Starting Ethereum") + server, err := NewServer() + + if err != nil { + fmt.Println("error NewServer:", err) + return + } + + RegisterInterupts(server) + + server.Start() + + // Wait for shutdown + server.WaitForShutdown() } } diff --git a/memory_database.go b/memory_database.go index fc40f76f3..a8c74bb46 100644 --- a/memory_database.go +++ b/memory_database.go @@ -1,6 +1,7 @@ package main import ( + "fmt" ) /* @@ -23,3 +24,11 @@ func (db *MemDatabase) Put(key []byte, value []byte) { func (db *MemDatabase) Get(key []byte) ([]byte, error) { return db.db[string(key)], nil } + +func (db *MemDatabase) Print() { + for key, val := range db.db { + fmt.Printf("%x(%d):", key, len(key)) + decoded := DecodeNode(val) + PrintSlice(decoded) + } +} diff --git a/server.go b/server.go index c8fb492d5..d7718a8a6 100644 --- a/server.go +++ b/server.go @@ -5,11 +5,15 @@ import ( "time" ) +var Db *LDBDatabase + type Server struct { // Channel for shutting down the server shutdownChan chan bool // DB interface db *LDBDatabase + // Block manager for processing new blocks and managing the block chain + blockManager *BlockManager // Peers (NYI) peers *list.List } @@ -20,8 +24,11 @@ func NewServer() (*Server, error) { return nil, err } + Db = db + server := &Server{ shutdownChan: make(chan bool), + blockManager: NewBlockManager(), db: db, peers: list.New(), } @@ -32,9 +39,11 @@ func NewServer() (*Server, error) { // Start the server func (s *Server) Start() { // For now this function just blocks the main thread - for { - time.Sleep( time.Second ) - } + go func() { + for { + time.Sleep( time.Second ) + } + }() } func (s *Server) Stop() { diff --git a/testing.go b/testing.go index 3762e4dc5..9b7b7b3ce 100644 --- a/testing.go +++ b/testing.go @@ -1,7 +1,8 @@ package main +/* import ( - "fmt" + _"fmt" ) // This will eventually go away @@ -15,18 +16,17 @@ func Testing() { tx := NewTransaction("\x00", 20, []string{"PUSH"}) txData := tx.MarshalRlp() - fmt.Printf("%q\n", txData) + //fmt.Printf("%q\n", txData) copyTx := &Transaction{} copyTx.UnmarshalRlp(txData) - fmt.Println(tx) - fmt.Println(copyTx) + //fmt.Println(tx) + //fmt.Println(copyTx) tx2 := NewTransaction("\x00", 20, []string{"SET 10 6", "LD 10 10"}) blck := CreateTestBlock([]*Transaction{tx2, tx}) bm.ProcessBlock( blck ) - - fmt.Println("GenesisBlock:", GenisisBlock, "hash", string(GenisisBlock.Hash())) } +*/ diff --git a/trie.go b/trie.go index 442cc08b8..d66699eeb 100644 --- a/trie.go +++ b/trie.go @@ -36,6 +36,8 @@ func DecodeNode(data []byte) []string { } return strSlice + } else { + fmt.Printf("It wasn't a []. It's a %T\n", dec) } return nil @@ -70,16 +72,6 @@ func (t *Trie) Get(key string) string { * State functions (shouldn't be needed directly). */ -// Wrapper around the regular db "Put" which generates a key and value -func (t *Trie) Put(node interface{}) []byte { - enc := Encode(node) - sha := Sha256Bin(enc) - - t.db.Put([]byte(sha), enc) - - return sha -} - // Helper function for printing a node (using fetch, decode and slice printing) func (t *Trie) PrintNode(n string) { data, _ := t.db.Get([]byte(n)) @@ -133,6 +125,16 @@ func (t *Trie) UpdateState(node string, key []int, value string) string { return "" } +// Wrapper around the regular db "Put" which generates a key and value +func (t *Trie) Put(node interface{}) []byte { + enc := Encode(node) + var sha []byte + sha = Sha256Bin(enc) + + t.db.Put([]byte(sha), enc) + + return sha +} func (t *Trie) InsertState(node string, key []int, value string) string { if len(key) == 0 { diff --git a/util.go b/util.go index 512a6f3d7..24e5455f4 100644 --- a/util.go +++ b/util.go @@ -6,6 +6,7 @@ import ( "encoding/hex" _"fmt" _"math" + "github.com/obscuren/sha3" ) func Uitoa(i uint32) string { @@ -24,6 +25,14 @@ func Sha256Bin(data []byte) []byte { return hash[:] } +func Sha3Bin(data []byte) []byte { + d := sha3.NewKeccak224() + d.Reset() + d.Write(data) + + return d.Sum(nil) +} + // Helper function for comparing slices func CompareIntSlice(a, b []int) bool { if len(a) != len(b) { @@ -48,3 +57,7 @@ func MatchingNibbleLength(a, b []int) int { return i } + +func Hex(d []byte) string { + return hex.EncodeToString(d) +} diff --git a/vm.go b/vm.go index a727d58e5..5b70f3544 100644 --- a/vm.go +++ b/vm.go @@ -11,29 +11,55 @@ import ( // Op codes const ( - oSTOP int = 0x00 - oADD int = 0x01 - oMUL int = 0x02 - oSUB int = 0x03 - oDIV int = 0x04 - oSDIV int = 0x05 - oMOD int = 0x06 - oSMOD int = 0x07 - oEXP int = 0x08 - oNEG int = 0x09 - oLT int = 0x0a - oLE int = 0x0b - oGT int = 0x0c - oGE int = 0x0d - oEQ int = 0x0e - oNOT int = 0x0f - oMYADDRESS int = 0x10 - oTXSENDER int = 0x11 - - - oPUSH int = 0x30 - oPOP int = 0x31 - oLOAD int = 0x36 + oSTOP int = 0x00 + oADD int = 0x01 + oMUL int = 0x02 + oSUB int = 0x03 + oDIV int = 0x04 + oSDIV int = 0x05 + oMOD int = 0x06 + oSMOD int = 0x07 + oEXP int = 0x08 + oNEG int = 0x09 + oLT int = 0x0a + oLE int = 0x0b + oGT int = 0x0c + oGE int = 0x0d + oEQ int = 0x0e + oNOT int = 0x0f + oMYADDRESS int = 0x10 + oTXSENDER int = 0x11 + oTXVALUE int = 0x12 + oTXFEE int = 0x13 + oTXDATAN int = 0x14 + oTXDATA int = 0x15 + oBLK_PREVHASH int = 0x16 + oBLK_COINBASE int = 0x17 + oBLK_TIMESTAMP int = 0x18 + oBLK_NUMBER int = 0x19 + oBLK_DIFFICULTY int = 0x1a + oSHA256 int = 0x20 + oRIPEMD160 int = 0x21 + oECMUL int = 0x22 + oECADD int = 0x23 + oECSIGN int = 0x24 + oECRECOVER int = 0x25 + oECVALID int = 0x26 + oPUSH int = 0x30 + oPOP int = 0x31 + oDUP int = 0x32 + oDUPN int = 0x33 + oSWAP int = 0x34 + oSWAPN int = 0x35 + oLOAD int = 0x36 + oSTORE int = 0x37 + oJMP int = 0x40 + oJMPI int = 0x41 + oIND int = 0x42 + oEXTRO int = 0x50 + oBALANCE int = 0x51 + oMKTX int = 0x60 + oSUICIDE int = 0xff ) type OpType int From d2b3071b4d820b9530b3de891078970ea036767c Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 9 Jan 2014 11:57:35 +0100 Subject: [PATCH 070/459] db console is now a general console. --- dagger.go | 45 +++++++++++++++++++++++++++++++------------ db_query_interface.go | 5 +++++ ethereum.go | 7 +++---- 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/dagger.go b/dagger.go index 750a781b0..b161ef733 100644 --- a/dagger.go +++ b/dagger.go @@ -6,6 +6,7 @@ import ( "math/rand" "time" "github.com/obscuren/sha3" + "hash" ) type Dagger struct { @@ -27,8 +28,11 @@ func (dag *Dagger) Search(diff *big.Int) *big.Int { for i := 0; i < 1000; i++ { if dag.Eval(rnd).Cmp(obj) < 0 { - fmt.Println("Found result! i = ", i) + fmt.Println("Found result! nonce = ", rnd) + return rnd + } else { + fmt.Println("Not found :( nonce = ", rnd) } rnd = rnd.Add(rnd, big.NewInt(1)) @@ -37,6 +41,16 @@ func (dag *Dagger) Search(diff *big.Int) *big.Int { return big.NewInt(0) } +func DaggerVerify(hash, diff, nonce *big.Int) bool { + dagger := &Dagger{} + dagger.hash = hash + + obj := BigPow(2, 256) + obj = obj.Div(obj, diff) + + return dagger.Eval(nonce).Cmp(obj) < 0 +} + func (dag *Dagger) Node(L uint64, i uint64) *big.Int { if L == i { return dag.hash @@ -63,16 +77,21 @@ func (dag *Dagger) Node(L uint64, i uint64) *big.Int { d.Write(big.NewInt(int64(i)).Bytes()) d.Write(big.NewInt(int64(k)).Bytes()) - b.SetBytes(d.Sum(nil)) + b.SetBytes(Sum(d)) pk := b.Uint64() & ((1 << ((L - 1) * 3)) - 1) sha.Write(dag.Node(L - 1, pk).Bytes()) } - ret.SetBytes(sha.Sum(nil)) + ret.SetBytes(Sum(sha)) return ret } +func Sum(sha hash.Hash) []byte { + in := make([]byte, 32) + return sha.Sum(in) +} + func (dag *Dagger) Eval(N *big.Int) *big.Int { pow := BigPow(2, 26) dag.xn = N.Div(N, pow) @@ -81,10 +100,11 @@ func (dag *Dagger) Eval(N *big.Int) *big.Int { sha.Reset() ret := new(big.Int) - doneChan := make(chan bool, 3) + //doneChan := make(chan bool, 3) for k := 0; k < 4; k++ { - go func(_k int) { + //go func(_k int) { + _k := k d := sha3.NewKeccak224() b := new(big.Int) @@ -94,17 +114,18 @@ func (dag *Dagger) Eval(N *big.Int) *big.Int { d.Write(N.Bytes()) d.Write(big.NewInt(int64(_k)).Bytes()) - b.SetBytes(d.Sum(nil)) + b.SetBytes(Sum(d)) pk := (b.Uint64() & 0x1ffffff) sha.Write(dag.Node(9, pk).Bytes()) - doneChan <- true - }(k) + //doneChan <- true + //}(k) } - for k := 0; k < 4; k++ { - <- doneChan - } + //for k := 0; k < 4; k++ { + // <- doneChan + //} - return ret.SetBytes(sha.Sum(nil)) + + return ret.SetBytes(Sum(sha)) } diff --git a/db_query_interface.go b/db_query_interface.go index 007f4bf28..ec1d7feb5 100644 --- a/db_query_interface.go +++ b/db_query_interface.go @@ -32,6 +32,9 @@ func (i *DbInterface) ValidateInput(action string, argumentLength int) error { case action == "get" && argumentLength != 1: err = true expArgCount = 1 + case action == "dag" && argumentLength != 2: + err = true + expArgCount = 2 } if err { @@ -74,6 +77,8 @@ func (i *DbInterface) ParseInput(input string) bool { fmt.Println(i.trie.root) case "print": i.db.Print() + case "dag": + fmt.Println(DaggerVerify(Big(tokens[1]), BigPow(2, 36), Big(tokens[2]))) case "exit", "quit", "q": return false case "help": diff --git a/ethereum.go b/ethereum.go index b10415fd1..b31ff751d 100644 --- a/ethereum.go +++ b/ethereum.go @@ -6,6 +6,7 @@ import ( "os/signal" "flag" "runtime" + _"math/big" ) const Debug = true @@ -13,7 +14,7 @@ const Debug = true var StartDBQueryInterface bool var StartMining bool func Init() { - flag.BoolVar(&StartDBQueryInterface, "db", false, "start db query interface") + flag.BoolVar(&StartDBQueryInterface, "c", false, "console interface") flag.BoolVar(&StartMining, "mine", false, "start dagger mining") flag.Parse() @@ -46,9 +47,7 @@ func main() { dbInterface.Start() } else if StartMining { dagger := &Dagger{} - seed := dagger.Search(BigPow(2, 36)) - - fmt.Println("dagger res = ", seed) + dagger.Search(BigPow(2, 36)) } else { fmt.Println("[DBUG]: Starting Ethereum") server, err := NewServer() From d895f83136eccc7e440792fdb45fd4d40876d82e Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 9 Jan 2014 16:19:16 +0100 Subject: [PATCH 071/459] Dagger improvements --- dagger.go | 56 +++++++++++++++++++++++++++++++++++++------------- dagger_test.go | 17 +++++++++++++++ ethereum.go | 13 ++++++------ vm_test.go | 3 ++- 4 files changed, 68 insertions(+), 21 deletions(-) create mode 100644 dagger_test.go diff --git a/dagger.go b/dagger.go index b161ef733..9fef78a36 100644 --- a/dagger.go +++ b/dagger.go @@ -14,7 +14,33 @@ type Dagger struct { xn *big.Int } +var Found bool +func (dag *Dagger) Find(obj *big.Int, resChan chan int64) { + r := rand.New(rand.NewSource(time.Now().UnixNano())) + + for i := 0; i < 1000; i++ { + rnd := r.Int63() + + if dag.Eval(big.NewInt(rnd)).Cmp(obj) < 0 { + // Post back result on the channel + resChan <- rnd + // Notify other threads we've found a valid nonce + Found = true + } else { + fmt.Printf(".") + } + + // Break out if found + if Found { break } + } + + resChan <- 0 +} + func (dag *Dagger) Search(diff *big.Int) *big.Int { + // TODO fix multi threading. Somehow it results in the wrong nonce + amountOfRoutines := 1 + dag.hash = big.NewInt(0) obj := BigPow(2, 256) @@ -22,23 +48,25 @@ func (dag *Dagger) Search(diff *big.Int) *big.Int { fmt.Println("diff", diff, "< objective", obj) - r := rand.New(rand.NewSource(time.Now().UnixNano())) - rnd := big.NewInt(r.Int63()) - fmt.Println("init rnd =", rnd) + Found = false + resChan := make(chan int64, 3) + var res int64 - for i := 0; i < 1000; i++ { - if dag.Eval(rnd).Cmp(obj) < 0 { - fmt.Println("Found result! nonce = ", rnd) - - return rnd - } else { - fmt.Println("Not found :( nonce = ", rnd) - } - - rnd = rnd.Add(rnd, big.NewInt(1)) + for k := 0; k < amountOfRoutines; k++ { + go dag.Find(obj, resChan) } - return big.NewInt(0) + // Wait for each go routine to finish + for k := 0; k < amountOfRoutines; k++ { + // Get the result from the channel. 0 = quit + if r := <- resChan; r != 0 { + res = r + } + } + + fmt.Println("\n") + + return big.NewInt(res) } func DaggerVerify(hash, diff, nonce *big.Int) bool { diff --git a/dagger_test.go b/dagger_test.go new file mode 100644 index 000000000..7953ec1da --- /dev/null +++ b/dagger_test.go @@ -0,0 +1,17 @@ +package main + +import ( + "testing" + "math/big" +) + +func BenchmarkDaggerSearch(b *testing.B) { + hash := big.NewInt(0) + diff := BigPow(2, 36) + o := big.NewInt(0) // nonce doesn't matter. We're only testing against speed, not validity + + // Reset timer so the big generation isn't included in the benchmark + b.ResetTimer() + // Validate + DaggerVerify(hash, diff, o) +} diff --git a/ethereum.go b/ethereum.go index b31ff751d..e3e5005eb 100644 --- a/ethereum.go +++ b/ethereum.go @@ -11,10 +11,10 @@ import ( const Debug = true -var StartDBQueryInterface bool +var StartConsole bool var StartMining bool func Init() { - flag.BoolVar(&StartDBQueryInterface, "c", false, "console interface") + flag.BoolVar(&StartConsole, "c", false, "debug and testing console") flag.BoolVar(&StartMining, "mine", false, "start dagger mining") flag.Parse() @@ -42,12 +42,13 @@ func main() { Init() - if StartDBQueryInterface { - dbInterface := NewDBInterface() - dbInterface.Start() + if StartConsole { + console := NewConsole() + console.Start() } else if StartMining { dagger := &Dagger{} - dagger.Search(BigPow(2, 36)) + res := dagger.Search(BigPow(2, 36)) + fmt.Println("nonce =", res) } else { fmt.Println("[DBUG]: Starting Ethereum") server, err := NewServer() diff --git a/vm_test.go b/vm_test.go index efcd875cd..cb70220e1 100644 --- a/vm_test.go +++ b/vm_test.go @@ -1,5 +1,6 @@ package main +/* import ( _"fmt" "testing" @@ -72,4 +73,4 @@ func TestVm(t *testing.T) { bm := NewBlockManager() bm.ProcessBlock( block ) } - +*/ From 01740695cda7fe27c53f0fa078732fa5a15a88a5 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 9 Jan 2014 16:19:44 +0100 Subject: [PATCH 072/459] moved db to dev console --- db_query_interface.go => dev_console.go | 30 +++++++++++++------------ 1 file changed, 16 insertions(+), 14 deletions(-) rename db_query_interface.go => dev_console.go (70%) diff --git a/db_query_interface.go b/dev_console.go similarity index 70% rename from db_query_interface.go rename to dev_console.go index ec1d7feb5..65166c0c1 100644 --- a/db_query_interface.go +++ b/dev_console.go @@ -9,19 +9,19 @@ import ( "encoding/hex" ) -type DbInterface struct { +type Console struct { db *MemDatabase trie *Trie } -func NewDBInterface() *DbInterface { +func NewConsole() *Console { db, _ := NewMemDatabase() trie := NewTrie(db, "") - return &DbInterface{db: db, trie: trie} + return &Console{db: db, trie: trie} } -func (i *DbInterface) ValidateInput(action string, argumentLength int) error { +func (i *Console) ValidateInput(action string, argumentLength int) error { err := false var expArgCount int @@ -44,7 +44,7 @@ func (i *DbInterface) ValidateInput(action string, argumentLength int) error { } } -func (i *DbInterface) ParseInput(input string) bool { +func (i *Console) ParseInput(input string) bool { scanner := bufio.NewScanner(strings.NewReader(input)) scanner.Split(bufio.ScanWords) @@ -82,12 +82,14 @@ func (i *DbInterface) ParseInput(input string) bool { case "exit", "quit", "q": return false case "help": - fmt.Printf(`QUERY COMMANDS: -update KEY VALUE - Updates/Creates a new value for the given key -get KEY - Retrieves the given key -root - Prints the hex encoded merkle root -rawroot - Prints the raw merkle root -`) + fmt.Printf( "COMMANDS:\n"+ + "\033[1m= DB =\033[0m\n"+ + "update KEY VALUE - Updates/Creates a new value for the given key\n"+ + "get KEY - Retrieves the given key\n"+ + "root - Prints the hex encoded merkle root\n"+ + "rawroot - Prints the raw merkle root\n"+ + "\033[1m= Dagger =\033[0m\n"+ + "dag HASH NONCE - Verifies a nonce with the given hash with dagger\n") default: fmt.Println("Unknown command:", tokens[0]) } @@ -96,11 +98,11 @@ rawroot - Prints the raw merkle root return true } -func (i *DbInterface) Start() { - fmt.Printf("DB Query tool. Type (help) for help\n") +func (i *Console) Start() { + fmt.Printf("Eth Console. Type (help) for help\n") reader := bufio.NewReader(os.Stdin) for { - fmt.Printf("db >>> ") + fmt.Printf("eth >>> ") str, _, err := reader.ReadLine() if err != nil { fmt.Println("Error reading input", err) From 849408dda60fe32d7abb78d103b09ca0bc7b5a60 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 9 Jan 2014 23:15:51 +0100 Subject: [PATCH 073/459] Peer handling --- peer.go | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ server.go | 20 ++++++++++-- 2 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 peer.go diff --git a/peer.go b/peer.go new file mode 100644 index 000000000..0c8d38772 --- /dev/null +++ b/peer.go @@ -0,0 +1,93 @@ +package main + +import ( + "net" + "errors" + "log" +) + +type InMsg struct { + msgType string // Specifies how the encoded data should be interpreted + data []byte // RLP encoded data +} + +func ReadMessage(conn net.Conn) (*InMsg, error) { + buff := make([]byte, 4069) + + // Wait for a message from this peer + n, err := conn.Read(buff) + if err != nil { + return nil, err + } else if n == 0 { + return nil, errors.New("Empty message received") + } + + // Read the header (MAX n) + decoder := NewRlpDecoder(buff[:n]) + t := decoder.Get(0).AsString() + if t == "" { + return nil, errors.New("Data contained no data type") + } + + return &InMsg{msgType: t, data: decoder.Get(1).AsBytes()}, nil +} + +type OutMsg struct { + data []byte +} + +type Peer struct { + server *Server + conn net.Conn + outputQueue chan OutMsg + quit chan bool +} + +func NewPeer(conn net.Conn, server *Server) *Peer { + return &Peer{ + outputQueue: make(chan OutMsg, 1), // Buffered chan of 1 is enough + quit: make(chan bool), + + server: server, + conn: conn, + } +} + +// Outputs any RLP encoded data to the peer +func (p *Peer) QueueMessage(data []byte) { + p.outputQueue <- OutMsg{data: data} +} + +func (p *Peer) HandleOutbound() { +out: + for { + switch { + case <- p.quit: + break out + } + } +} + +func (p *Peer) HandleInbound() { + defer p.conn.Close() + +out: + for { + msg, err := ReadMessage(p.conn) + if err != nil { + log.Println(err) + + break out + } + + log.Println(msg) + } + + // Notify the out handler we're quiting + p.quit <- true +} + +func (p *Peer) Start() { + go p.HandleOutbound() + go p.HandleInbound() +} diff --git a/server.go b/server.go index d7718a8a6..feaf61076 100644 --- a/server.go +++ b/server.go @@ -2,7 +2,8 @@ package main import ( "container/list" - "time" + "net" + "log" ) var Db *LDBDatabase @@ -36,12 +37,27 @@ func NewServer() (*Server, error) { return server, nil } +func (s *Server) AddPeer(conn net.Conn) { + s.peers.PushBack(NewPeer(conn, s)) +} + // Start the server func (s *Server) Start() { // For now this function just blocks the main thread + ln, err := net.Listen("tcp", ":12345") + if err != nil { + log.Fatal(err) + } + go func() { for { - time.Sleep( time.Second ) + conn, err := ln.Accept() + if err != nil { + log.Println(err) + continue + } + + go s.AddPeer(conn) } }() } From bd0abe2a8187c0ae948bba6a90cbaac07f479cc8 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 10 Jan 2014 00:39:16 +0100 Subject: [PATCH 074/459] Updated server and peers and mining processing --- dagger.go | 42 ++++++++++++------------------------------ ethereum.go | 31 ++++++++++++++++++++++++------- peer.go | 40 +++++++++++++++++++++++++++++++--------- server.go | 45 +++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 110 insertions(+), 48 deletions(-) diff --git a/dagger.go b/dagger.go index 9fef78a36..8509232a2 100644 --- a/dagger.go +++ b/dagger.go @@ -2,7 +2,6 @@ package main import ( "math/big" - "fmt" "math/rand" "time" "github.com/obscuren/sha3" @@ -26,8 +25,6 @@ func (dag *Dagger) Find(obj *big.Int, resChan chan int64) { resChan <- rnd // Notify other threads we've found a valid nonce Found = true - } else { - fmt.Printf(".") } // Break out if found @@ -37,17 +34,15 @@ func (dag *Dagger) Find(obj *big.Int, resChan chan int64) { resChan <- 0 } -func (dag *Dagger) Search(diff *big.Int) *big.Int { +func (dag *Dagger) Search(hash, diff *big.Int) *big.Int { // TODO fix multi threading. Somehow it results in the wrong nonce amountOfRoutines := 1 - dag.hash = big.NewInt(0) + dag.hash = hash obj := BigPow(2, 256) obj = obj.Div(obj, diff) - fmt.Println("diff", diff, "< objective", obj) - Found = false resChan := make(chan int64, 3) var res int64 @@ -64,8 +59,6 @@ func (dag *Dagger) Search(diff *big.Int) *big.Int { } } - fmt.Println("\n") - return big.NewInt(res) } @@ -128,32 +121,21 @@ func (dag *Dagger) Eval(N *big.Int) *big.Int { sha.Reset() ret := new(big.Int) - //doneChan := make(chan bool, 3) - for k := 0; k < 4; k++ { - //go func(_k int) { - _k := k - d := sha3.NewKeccak224() - b := new(big.Int) + d := sha3.NewKeccak224() + b := new(big.Int) - d.Reset() - d.Write(dag.hash.Bytes()) - d.Write(dag.xn.Bytes()) - d.Write(N.Bytes()) - d.Write(big.NewInt(int64(_k)).Bytes()) + d.Reset() + d.Write(dag.hash.Bytes()) + d.Write(dag.xn.Bytes()) + d.Write(N.Bytes()) + d.Write(big.NewInt(int64(k)).Bytes()) - b.SetBytes(Sum(d)) - pk := (b.Uint64() & 0x1ffffff) + b.SetBytes(Sum(d)) + pk := (b.Uint64() & 0x1ffffff) - sha.Write(dag.Node(9, pk).Bytes()) - //doneChan <- true - //}(k) + sha.Write(dag.Node(9, pk).Bytes()) } - //for k := 0; k < 4; k++ { - // <- doneChan - //} - - return ret.SetBytes(Sum(sha)) } diff --git a/ethereum.go b/ethereum.go index e3e5005eb..6ceb0249d 100644 --- a/ethereum.go +++ b/ethereum.go @@ -6,6 +6,7 @@ import ( "os/signal" "flag" "runtime" + "log" _"math/big" ) @@ -45,23 +46,39 @@ func main() { if StartConsole { console := NewConsole() console.Start() - } else if StartMining { - dagger := &Dagger{} - res := dagger.Search(BigPow(2, 36)) - fmt.Println("nonce =", res) - } else { - fmt.Println("[DBUG]: Starting Ethereum") + } else{ + log.Println("Starting Ethereum") server, err := NewServer() if err != nil { - fmt.Println("error NewServer:", err) + log.Println(err) return } RegisterInterupts(server) + if StartMining { + log.Println("Mining started") + dagger := &Dagger{} + + go func() { + for { + res := dagger.Search(Big("0"), BigPow(2, 36)) + server.Broadcast("foundblock", res.Bytes()) + } + }() + } + server.Start() + err = server.ConnectToPeer("localhost:12345") + if err != nil { + log.Println(err) + server.Stop() + return + } + + // Wait for shutdown server.WaitForShutdown() } diff --git a/peer.go b/peer.go index 0c8d38772..15e0fdcf1 100644 --- a/peer.go +++ b/peer.go @@ -11,6 +11,11 @@ type InMsg struct { data []byte // RLP encoded data } +type OutMsg struct { + msgType string + data []byte +} + func ReadMessage(conn net.Conn) (*InMsg, error) { buff := make([]byte, 4069) @@ -23,6 +28,7 @@ func ReadMessage(conn net.Conn) (*InMsg, error) { } // Read the header (MAX n) + // XXX The data specification is made up. This will change once more details have been released on the specification of the format decoder := NewRlpDecoder(buff[:n]) t := decoder.Get(0).AsString() if t == "" { @@ -32,10 +38,6 @@ func ReadMessage(conn net.Conn) (*InMsg, error) { return &InMsg{msgType: t, data: decoder.Get(1).AsBytes()}, nil } -type OutMsg struct { - data []byte -} - type Peer struct { server *Server conn net.Conn @@ -54,22 +56,34 @@ func NewPeer(conn net.Conn, server *Server) *Peer { } // Outputs any RLP encoded data to the peer -func (p *Peer) QueueMessage(data []byte) { - p.outputQueue <- OutMsg{data: data} +func (p *Peer) QueueMessage(msgType string, data []byte) { + p.outputQueue <- OutMsg{msgType: msgType, data: data} } func (p *Peer) HandleOutbound() { out: for { - switch { + select { + case msg := <-p.outputQueue: + p.WriteMessage(msg) + case <- p.quit: break out } } } +func (p *Peer) WriteMessage(msg OutMsg) { + encoded := Encode([]interface{}{ msg.msgType, msg.data }) + _, err := p.conn.Write(encoded) + if err != nil { + log.Println(err) + p.Stop() + } +} + func (p *Peer) HandleInbound() { - defer p.conn.Close() + defer p.Stop() out: for { @@ -80,7 +94,9 @@ out: break out } - log.Println(msg) + // TODO + data, _ := Decode(msg.data, 0) + log.Printf("%s, %s\n", msg.msgType, data) } // Notify the out handler we're quiting @@ -91,3 +107,9 @@ func (p *Peer) Start() { go p.HandleOutbound() go p.HandleInbound() } + +func (p *Peer) Stop() { + defer p.conn.Close() + + p.quit <- true +} diff --git a/server.go b/server.go index feaf61076..c2903cb59 100644 --- a/server.go +++ b/server.go @@ -4,6 +4,7 @@ import ( "container/list" "net" "log" + _"time" ) var Db *LDBDatabase @@ -38,7 +39,36 @@ func NewServer() (*Server, error) { } func (s *Server) AddPeer(conn net.Conn) { - s.peers.PushBack(NewPeer(conn, s)) + peer := NewPeer(conn, s) + s.peers.PushBack(peer) + peer.Start() + + log.Println("Peer connected ::", conn.RemoteAddr()) +} + +func (s *Server) ConnectToPeer(addr string) error { + conn, err := net.Dial("tcp", addr) + + if err != nil { + return err + } + + peer := NewPeer(conn, s) + s.peers.PushBack(peer) + peer.Start() + + + log.Println("Connected to peer ::", conn.RemoteAddr()) + + return nil +} + +func (s *Server) Broadcast(msgType string, data []byte) { + for e := s.peers.Front(); e != nil; e = e.Next() { + if peer, ok := e.Value.(*Peer); ok { + peer.QueueMessage(msgType, data) + } + } } // Start the server @@ -60,6 +90,15 @@ func (s *Server) Start() { go s.AddPeer(conn) } }() + + // TMP + //go func() { + // for { + // s.Broadcast("block", Encode("blockdata")) +// +// time.Sleep(100 * time.Millisecond) +// } +// }() } func (s *Server) Stop() { @@ -68,7 +107,9 @@ func (s *Server) Stop() { // Loop thru the peers and close them (if we had them) for e := s.peers.Front(); e != nil; e = e.Next() { - // peer close etc + if peer, ok := e.Value.(*Peer); ok { + peer.Stop() + } } s.shutdownChan <- true From ce40e51ae53af9679e11f8ced934ae8ee3b2db6f Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 10 Jan 2014 00:44:45 +0100 Subject: [PATCH 075/459] Encoding --- ethereum.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethereum.go b/ethereum.go index 6ceb0249d..a935f903e 100644 --- a/ethereum.go +++ b/ethereum.go @@ -64,7 +64,7 @@ func main() { go func() { for { res := dagger.Search(Big("0"), BigPow(2, 36)) - server.Broadcast("foundblock", res.Bytes()) + server.Broadcast("block", Encode(res.String())) } }() } From 19addcb51a1d100db483be98ee660b73dd5070d7 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 10 Jan 2014 10:58:46 +0100 Subject: [PATCH 076/459] Comments --- peer.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/peer.go b/peer.go index 15e0fdcf1..a855fe2b9 100644 --- a/peer.go +++ b/peer.go @@ -31,6 +31,7 @@ func ReadMessage(conn net.Conn) (*InMsg, error) { // XXX The data specification is made up. This will change once more details have been released on the specification of the format decoder := NewRlpDecoder(buff[:n]) t := decoder.Get(0).AsString() + // If the msgdata contains no data we throw an error and disconnect the peer if t == "" { return nil, errors.New("Data contained no data type") } @@ -39,9 +40,13 @@ func ReadMessage(conn net.Conn) (*InMsg, error) { } type Peer struct { + // Server interface server *Server + // Net connection conn net.Conn + // Output queue which is used to communicate and handle messages outputQueue chan OutMsg + // Quit channel quit chan bool } @@ -60,21 +65,28 @@ func (p *Peer) QueueMessage(msgType string, data []byte) { p.outputQueue <- OutMsg{msgType: msgType, data: data} } +// Outbound message handler. Outbound messages are handled here func (p *Peer) HandleOutbound() { out: for { select { + // Main message queue. All outbound messages are processed through here case msg := <-p.outputQueue: + // TODO Message checking and handle accordingly p.WriteMessage(msg) + // Break out of the for loop if a quit message is posted case <- p.quit: break out } } } +// Write a message to the peer. func (p *Peer) WriteMessage(msg OutMsg) { + // Encode the type and the (RLP encoded) data for sending over the wire encoded := Encode([]interface{}{ msg.msgType, msg.data }) + // Write to the connection _, err := p.conn.Write(encoded) if err != nil { log.Println(err) @@ -82,11 +94,13 @@ func (p *Peer) WriteMessage(msg OutMsg) { } } +// Inbound handler. Inbound messages are received here and passed to the appropriate methods func (p *Peer) HandleInbound() { defer p.Stop() out: for { + // Wait for a message from the peer msg, err := ReadMessage(p.conn) if err != nil { log.Println(err) @@ -104,7 +118,9 @@ out: } func (p *Peer) Start() { + // Run the outbound handler in a new goroutine go p.HandleOutbound() + // Run the inbound handler in a new goroutine go p.HandleInbound() } From 164d7c4f0b8d8c35f7a50c32e0fdfb2aae8b6ebe Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 10 Jan 2014 10:58:55 +0100 Subject: [PATCH 077/459] before install --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 69359072d..f10dc0606 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,4 @@ +before_install: udo apt-get install libgmp3-dev language: go go: - 1.2 From a9c16803d239a007a865d97485cd96dffd2b77a9 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 10 Jan 2014 10:59:07 +0100 Subject: [PATCH 078/459] Updated readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 05276a113..c7201a4ce 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,6 @@ Install Command line options ==================== --db will launch the db query tool. +-c will launch the developer console Supported arguments `update` and `get` From ba385ccdf15f8379c54d65061c3d62353baffc2b Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 10 Jan 2014 10:59:57 +0100 Subject: [PATCH 079/459] sudo not udo --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f10dc0606..32740f91a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ -before_install: udo apt-get install libgmp3-dev +before_install: sudo apt-get install libgmp3-dev language: go go: - 1.2 From fbc59b7323394fc95e0d87f20375c5e1cbec2170 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 10 Jan 2014 11:05:28 +0100 Subject: [PATCH 080/459] Updated read me and changed mine argument to m --- README.md | 5 ++--- ethereum.go | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c7201a4ce..4b797b5a7 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,5 @@ Install Command line options ==================== --c will launch the developer console - -Supported arguments `update` and `get` +-c launch the developer console +-m start mining fake blocks and broadcast fake messages to the net diff --git a/ethereum.go b/ethereum.go index a935f903e..aee8ebc30 100644 --- a/ethereum.go +++ b/ethereum.go @@ -16,7 +16,7 @@ var StartConsole bool var StartMining bool func Init() { flag.BoolVar(&StartConsole, "c", false, "debug and testing console") - flag.BoolVar(&StartMining, "mine", false, "start dagger mining") + flag.BoolVar(&StartMining, "m", false, "start dagger mining") flag.Parse() } From dbd28a52525581b59fb334f2aafa3b2b56fb6ba8 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 10 Jan 2014 11:18:54 +0100 Subject: [PATCH 081/459] 224 to 256 --- dagger.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dagger.go b/dagger.go index 8509232a2..2c1976840 100644 --- a/dagger.go +++ b/dagger.go @@ -84,9 +84,9 @@ func (dag *Dagger) Node(L uint64, i uint64) *big.Int { m = big.NewInt(3) } - sha := sha3.NewKeccak224() + sha := sha3.NewKeccak256() sha.Reset() - d := sha3.NewKeccak224() + d := sha3.NewKeccak256() b := new(big.Int) ret := new(big.Int) @@ -117,12 +117,12 @@ func (dag *Dagger) Eval(N *big.Int) *big.Int { pow := BigPow(2, 26) dag.xn = N.Div(N, pow) - sha := sha3.NewKeccak224() + sha := sha3.NewKeccak256() sha.Reset() ret := new(big.Int) for k := 0; k < 4; k++ { - d := sha3.NewKeccak224() + d := sha3.NewKeccak256() b := new(big.Int) d.Reset() From f6fa4f88797030b8e83066cb262a68958953974e Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 10 Jan 2014 21:18:56 +0100 Subject: [PATCH 082/459] WIP Splitting ethereum up in submodules --- block.go | 20 ++++++++++++---- peer.go | 69 ++++++++++++-------------------------------------------- 2 files changed, 30 insertions(+), 59 deletions(-) diff --git a/block.go b/block.go index 6ae3cc832..2287a9d55 100644 --- a/block.go +++ b/block.go @@ -51,7 +51,15 @@ func CreateTestBlock(/* TODO use raw data */transactions []*Transaction) *Block return block } -func CreateBlock(root string, num int, prevHash string, base string, difficulty int, nonce int, extra string, txes []*Transaction) *Block { +func CreateBlock(root string, + num int, + prevHash string, + base string, + difficulty int, + nonce int, + extra string, + txes []*Transaction) *Block { + block := &Block{ // Slice of transactions to include in this block transactions: txes, @@ -134,8 +142,11 @@ func (block *Block) MarshalRlp() []byte { // Cast it to a string (safe) encTx[i] = string(tx.MarshalRlp()) } + // TODO + uncles := []interface{}{} - /* I made up the block. It should probably contain different data or types. It sole purpose now is testing */ + // I made up the block. It should probably contain different data or types. + // It sole purpose now is testing header := []interface{}{ block.number, block.prevHash, @@ -152,9 +163,8 @@ func (block *Block) MarshalRlp() []byte { block.extra, } - // TODO - uncles := []interface{}{} - // Encode a slice interface which contains the header and the list of transactions. + // Encode a slice interface which contains the header and the list of + // transactions. return Encode([]interface{}{header, encTx, uncles}) } diff --git a/peer.go b/peer.go index a855fe2b9..d47af73de 100644 --- a/peer.go +++ b/peer.go @@ -2,57 +2,24 @@ package main import ( "net" - "errors" "log" + "github.com/ethereum/ethwire-go" ) -type InMsg struct { - msgType string // Specifies how the encoded data should be interpreted - data []byte // RLP encoded data -} - -type OutMsg struct { - msgType string - data []byte -} - -func ReadMessage(conn net.Conn) (*InMsg, error) { - buff := make([]byte, 4069) - - // Wait for a message from this peer - n, err := conn.Read(buff) - if err != nil { - return nil, err - } else if n == 0 { - return nil, errors.New("Empty message received") - } - - // Read the header (MAX n) - // XXX The data specification is made up. This will change once more details have been released on the specification of the format - decoder := NewRlpDecoder(buff[:n]) - t := decoder.Get(0).AsString() - // If the msgdata contains no data we throw an error and disconnect the peer - if t == "" { - return nil, errors.New("Data contained no data type") - } - - return &InMsg{msgType: t, data: decoder.Get(1).AsBytes()}, nil -} - type Peer struct { // Server interface server *Server // Net connection conn net.Conn // Output queue which is used to communicate and handle messages - outputQueue chan OutMsg + outputQueue chan ethwire.InOutMsg // Quit channel quit chan bool } func NewPeer(conn net.Conn, server *Server) *Peer { return &Peer{ - outputQueue: make(chan OutMsg, 1), // Buffered chan of 1 is enough + outputQueue: make(chan ethwire.InOutMsg, 1), // Buffered chan of 1 is enough quit: make(chan bool), server: server, @@ -62,7 +29,7 @@ func NewPeer(conn net.Conn, server *Server) *Peer { // Outputs any RLP encoded data to the peer func (p *Peer) QueueMessage(msgType string, data []byte) { - p.outputQueue <- OutMsg{msgType: msgType, data: data} + p.outputQueue <- ethwire.InOutMsg{MsgType: msgType, Data: data} } // Outbound message handler. Outbound messages are handled here @@ -73,7 +40,13 @@ out: // Main message queue. All outbound messages are processed through here case msg := <-p.outputQueue: // TODO Message checking and handle accordingly - p.WriteMessage(msg) + err := ethwire.WriteMessage(p.conn, msg) + if err != nil { + log.Println(err) + + // Stop the client if there was an error writing to it + p.Stop() + } // Break out of the for loop if a quit message is posted case <- p.quit: @@ -82,18 +55,6 @@ out: } } -// Write a message to the peer. -func (p *Peer) WriteMessage(msg OutMsg) { - // Encode the type and the (RLP encoded) data for sending over the wire - encoded := Encode([]interface{}{ msg.msgType, msg.data }) - // Write to the connection - _, err := p.conn.Write(encoded) - if err != nil { - log.Println(err) - p.Stop() - } -} - // Inbound handler. Inbound messages are received here and passed to the appropriate methods func (p *Peer) HandleInbound() { defer p.Stop() @@ -101,7 +62,7 @@ func (p *Peer) HandleInbound() { out: for { // Wait for a message from the peer - msg, err := ReadMessage(p.conn) + msg, err := ethwire.ReadMessage(p.conn) if err != nil { log.Println(err) @@ -109,8 +70,8 @@ out: } // TODO - data, _ := Decode(msg.data, 0) - log.Printf("%s, %s\n", msg.msgType, data) + data, _ := Decode(msg.Data, 0) + log.Printf("%s, %s\n", msg.MsgType, data) } // Notify the out handler we're quiting @@ -125,7 +86,7 @@ func (p *Peer) Start() { } func (p *Peer) Stop() { - defer p.conn.Close() + p.conn.Close() p.quit <- true } From 8bbf879cb31e9cb28700773ed788421f9935ac36 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 10 Jan 2014 22:44:53 +0100 Subject: [PATCH 083/459] Moving the ethgo to individual packages --- big.go | 35 -------- block.go | 192 ------------------------------------------ block_manager.go | 17 ++-- bytes.go | 27 ------ contract.go | 65 -------------- dagger.go | 7 +- database.go | 56 ------------ database_test.go | 7 -- dev_console.go | 20 +++-- encoding.go | 62 -------------- encoding_test.go | 38 --------- ethereum.go | 6 +- genesis.go | 34 -------- memory_database.go | 34 -------- parsing.go | 98 --------------------- parsing_test.go | 33 -------- rlp.go | 3 +- server.go | 10 +-- transaction.go | 206 --------------------------------------------- trie.go | 203 -------------------------------------------- trie_test.go | 59 ------------- util.go | 63 -------------- vm.go | 22 ++--- 23 files changed, 46 insertions(+), 1251 deletions(-) delete mode 100644 big.go delete mode 100644 block.go delete mode 100644 bytes.go delete mode 100644 contract.go delete mode 100644 database.go delete mode 100644 database_test.go delete mode 100644 encoding.go delete mode 100644 encoding_test.go delete mode 100644 genesis.go delete mode 100644 memory_database.go delete mode 100644 parsing.go delete mode 100644 parsing_test.go delete mode 100644 transaction.go delete mode 100644 trie.go delete mode 100644 trie_test.go delete mode 100644 util.go diff --git a/big.go b/big.go deleted file mode 100644 index b0fbcb64f..000000000 --- a/big.go +++ /dev/null @@ -1,35 +0,0 @@ -package main - -import ( - "math/big" -) - -/* - * Returns the power of two integers - */ -func BigPow(a,b int) *big.Int { - c := new(big.Int) - c.Exp(big.NewInt(int64(a)), big.NewInt(int64(b)), big.NewInt(0)) - - return c -} - -/* - * Like big.NewInt(uint64); this takes a string instead. - */ -func Big(num string) *big.Int { - n := new(big.Int) - n.SetString(num, 0) - - return n -} - -/* - * Like big.NewInt(uint64); this takes a byte buffer instead. - */ -func BigD(data []byte) *big.Int { - n := new(big.Int) - n.SetBytes(data) - - return n -} diff --git a/block.go b/block.go deleted file mode 100644 index 2287a9d55..000000000 --- a/block.go +++ /dev/null @@ -1,192 +0,0 @@ -package main - -import ( - "fmt" - "time" - _"bytes" - _"encoding/hex" -) - -type Block struct { - // The number of this block - number uint32 - // Hash to the previous block - prevHash string - // Uncles of this block - uncles []*Block - coinbase string - // state xxx - state *Trie - difficulty uint32 - // Creation time - time int64 - nonce uint32 - // List of transactions and/or contracts - transactions []*Transaction - - extra string -} - -// New block takes a raw encoded string -func NewBlock(raw []byte) *Block { - block := &Block{} - block.UnmarshalRlp(raw) - - return block -} - -// Creates a new block. This is currently for testing -func CreateTestBlock(/* TODO use raw data */transactions []*Transaction) *Block { - block := &Block{ - // Slice of transactions to include in this block - transactions: transactions, - number: 1, - prevHash: "1234", - coinbase: "me", - difficulty: 10, - nonce: 0, - time: time.Now().Unix(), - } - - return block -} - -func CreateBlock(root string, - num int, - prevHash string, - base string, - difficulty int, - nonce int, - extra string, - txes []*Transaction) *Block { - - block := &Block{ - // Slice of transactions to include in this block - transactions: txes, - number: uint32(num), - prevHash: prevHash, - coinbase: base, - difficulty: uint32(difficulty), - nonce: uint32(nonce), - time: time.Now().Unix(), - extra: extra, - } - block.state = NewTrie(Db, root) - - for _, tx := range txes { - // Create contract if there's no recipient - if tx.recipient == "" { - addr := tx.Hash() - - contract := NewContract(tx.value, []byte("")) - block.state.Update(string(addr), string(contract.MarshalRlp())) - for i, val := range tx.data { - contract.state.Update(string(NumberToBytes(uint64(i), 32)), val) - } - block.UpdateContract(addr, contract) - } - } - - return block -} - -func (block *Block) GetContract(addr []byte) *Contract { - data := block.state.Get(string(addr)) - if data == "" { - return nil - } - - contract := &Contract{} - contract.UnmarshalRlp([]byte(data)) - - return contract -} - -func (block *Block) UpdateContract(addr []byte, contract *Contract) { - block.state.Update(string(addr), string(contract.MarshalRlp())) -} - - -func (block *Block) PayFee(addr []byte, fee uint64) bool { - contract := block.GetContract(addr) - // If we can't pay the fee return - if contract == nil || contract.amount < fee { - fmt.Println("Contract has insufficient funds", contract.amount, fee) - - return false - } - - contract.amount -= fee - block.state.Update(string(addr), string(contract.MarshalRlp())) - - data := block.state.Get(string(block.coinbase)) - - // Get the ether (coinbase) and add the fee (gief fee to miner) - ether := NewEtherFromData([]byte(data)) - ether.amount += fee - - block.state.Update(string(block.coinbase), string(ether.MarshalRlp())) - - return true -} - -// Returns a hash of the block -func (block *Block) Hash() []byte { - return Sha256Bin(block.MarshalRlp()) -} - -func (block *Block) MarshalRlp() []byte { - // Marshal the transactions of this block - encTx := make([]string, len(block.transactions)) - for i, tx := range block.transactions { - // Cast it to a string (safe) - encTx[i] = string(tx.MarshalRlp()) - } - // TODO - uncles := []interface{}{} - - // I made up the block. It should probably contain different data or types. - // It sole purpose now is testing - header := []interface{}{ - block.number, - block.prevHash, - // Sha of uncles - "", - block.coinbase, - // root state - block.state.root, - // Sha of tx - string(Sha256Bin([]byte(Encode(encTx)))), - block.difficulty, - uint64(block.time), - block.nonce, - block.extra, - } - - // Encode a slice interface which contains the header and the list of - // transactions. - return Encode([]interface{}{header, encTx, uncles}) -} - -func (block *Block) UnmarshalRlp(data []byte) { - decoder := NewRlpDecoder(data) - - header := decoder.Get(0) - block.number = uint32(header.Get(0).AsUint()) - block.prevHash = header.Get(1).AsString() - // sha of uncles is header[2] - block.coinbase = header.Get(3).AsString() - block.state = NewTrie(Db, header.Get(4).AsString()) - block.difficulty = uint32(header.Get(5).AsUint()) - block.time = int64(header.Get(6).AsUint()) - block.nonce = uint32(header.Get(7).AsUint()) - block.extra = header.Get(8).AsString() - - txes := decoder.Get(1) - block.transactions = make([]*Transaction, txes.Length()) - for i := 0; i < txes.Length(); i++ { - tx := &Transaction{} - tx.UnmarshalRlp(txes.Get(i).AsBytes()) - block.transactions[i] = tx - } -} diff --git a/block_manager.go b/block_manager.go index 134ca0e75..59430dca7 100644 --- a/block_manager.go +++ b/block_manager.go @@ -2,17 +2,18 @@ package main import ( "fmt" + "github.com/ethereum/ethutil-go" ) type BlockChain struct { - lastBlock *Block + lastBlock *ethutil.Block - genesisBlock *Block + genesisBlock *ethutil.Block } func NewBlockChain() *BlockChain { bc := &BlockChain{} - bc.genesisBlock = NewBlock( Encode(Genesis) ) + bc.genesisBlock = ethutil.NewBlock( ethutil.Encode(ethutil.Genesis) ) return bc } @@ -30,19 +31,19 @@ func NewBlockManager() *BlockManager { } // Process a block. -func (bm *BlockManager) ProcessBlock(block *Block) error { +func (bm *BlockManager) ProcessBlock(block *ethutil.Block) error { // TODO Validation (Or move to other part of the application) if err := bm.ValidateBlock(block); err != nil { return err } // Get the tx count. Used to create enough channels to 'join' the go routines - txCount := len(block.transactions) + txCount := len(block.Transactions()) // Locking channel. When it has been fully buffered this method will return lockChan := make(chan bool, txCount) // Process each transaction/contract - for _, tx := range block.transactions { + for _, tx := range block.Transactions() { // If there's no recipient, it's a contract if tx.IsContract() { go bm.ProcessContract(tx, block, lockChan) @@ -60,11 +61,11 @@ func (bm *BlockManager) ProcessBlock(block *Block) error { return nil } -func (bm *BlockManager) ValidateBlock(block *Block) error { +func (bm *BlockManager) ValidateBlock(block *ethutil.Block) error { return nil } -func (bm *BlockManager) ProcessContract(tx *Transaction, block *Block, lockChan chan bool) { +func (bm *BlockManager) ProcessContract(tx *ethutil.Transaction, block *ethutil.Block, lockChan chan bool) { // Recovering function in case the VM had any errors defer func() { if r := recover(); r != nil { diff --git a/bytes.go b/bytes.go deleted file mode 100644 index 6bf381343..000000000 --- a/bytes.go +++ /dev/null @@ -1,27 +0,0 @@ -package main - -import ( - "bytes" - "encoding/binary" - "fmt" -) - -func NumberToBytes(num uint64, bits int) []byte { - buf := new(bytes.Buffer) - err := binary.Write(buf, binary.BigEndian, num) - if err != nil { - fmt.Println("binary.Write failed:", err) - } - - return buf.Bytes()[buf.Len()-(bits / 8):] -} - -func BytesToNumber(b []byte) (number uint64) { - buf := bytes.NewReader(b) - err := binary.Read(buf, binary.LittleEndian, &number) - if err != nil { - fmt.Println("binary.Read failed:", err) - } - - return -} diff --git a/contract.go b/contract.go deleted file mode 100644 index a54643f59..000000000 --- a/contract.go +++ /dev/null @@ -1,65 +0,0 @@ -package main - -import ( - _"fmt" -) - -type Contract struct { - t uint32 // contract is always 1 - amount uint64 // ??? - state *Trie -} - -func NewContract(amount uint64, root []byte) *Contract { - contract := &Contract{t: 1, amount: amount} - contract.state = NewTrie(Db, string(root)) - - return contract -} - -func (c *Contract) MarshalRlp() []byte { - return Encode([]interface{}{c.t, c.amount, c.state.root}) -} - -func (c *Contract) UnmarshalRlp(data []byte) { - decoder := NewRlpDecoder(data) - - c.t = uint32(decoder.Get(0).AsUint()) - c.amount = decoder.Get(1).AsUint() - c.state = NewTrie(Db, decoder.Get(2).AsString()) -} - -type Ether struct { - t uint32 - amount uint64 - nonce string -} - -func NewEtherFromData(data []byte) *Ether { - ether := &Ether{} - ether.UnmarshalRlp(data) - - return ether -} - -func (e *Ether) MarshalRlp() []byte { - return Encode([]interface{}{e.t, e.amount, e.nonce}) -} - -func (e *Ether) UnmarshalRlp(data []byte) { - t, _ := Decode(data, 0) - - if slice, ok := t.([]interface{}); ok { - if t, ok := slice[0].(uint8); ok { - e.t = uint32(t) - } - - if amount, ok := slice[1].(uint8); ok { - e.amount = uint64(amount) - } - - if nonce, ok := slice[2].([]uint8); ok { - e.nonce = string(nonce) - } - } -} diff --git a/dagger.go b/dagger.go index 2c1976840..5aa5dd755 100644 --- a/dagger.go +++ b/dagger.go @@ -6,6 +6,7 @@ import ( "time" "github.com/obscuren/sha3" "hash" + "github.com/ethereum/ethutil-go" ) type Dagger struct { @@ -40,7 +41,7 @@ func (dag *Dagger) Search(hash, diff *big.Int) *big.Int { dag.hash = hash - obj := BigPow(2, 256) + obj := ethutil.BigPow(2, 256) obj = obj.Div(obj, diff) Found = false @@ -66,7 +67,7 @@ func DaggerVerify(hash, diff, nonce *big.Int) bool { dagger := &Dagger{} dagger.hash = hash - obj := BigPow(2, 256) + obj := ethutil.BigPow(2, 256) obj = obj.Div(obj, diff) return dagger.Eval(nonce).Cmp(obj) < 0 @@ -114,7 +115,7 @@ func Sum(sha hash.Hash) []byte { } func (dag *Dagger) Eval(N *big.Int) *big.Int { - pow := BigPow(2, 26) + pow := ethutil.BigPow(2, 26) dag.xn = N.Div(N, pow) sha := sha3.NewKeccak256() diff --git a/database.go b/database.go deleted file mode 100644 index b147756b6..000000000 --- a/database.go +++ /dev/null @@ -1,56 +0,0 @@ -package main - -import ( - "path" - "os/user" - "github.com/syndtr/goleveldb/leveldb" - "fmt" -) - -type LDBDatabase struct { - db *leveldb.DB - trie *Trie -} - -func NewLDBDatabase() (*LDBDatabase, error) { - // This will eventually have to be something like a resource folder. - // it works on my system for now. Probably won't work on Windows - usr, _ := user.Current() - dbPath := path.Join(usr.HomeDir, ".ethereum", "database") - - // Open the db - db, err := leveldb.OpenFile(dbPath, nil) - if err != nil { - return nil, err - } - - database := &LDBDatabase{db: db} - - // Bootstrap database. Sets a few defaults; such as the last block - database.Bootstrap() - - return database, nil -} - -func (db *LDBDatabase) Bootstrap() error { - //db.trie = NewTrie(db) - - return nil -} - -func (db *LDBDatabase) Put(key []byte, value []byte) { - err := db.db.Put(key, value, nil) - if err != nil { - fmt.Println("Error put", err) - } -} - -func (db *LDBDatabase) Get(key []byte) ([]byte, error) { - return nil, nil -} - -func (db *LDBDatabase) Close() { - // Close the leveldb database - db.db.Close() -} - diff --git a/database_test.go b/database_test.go deleted file mode 100644 index 1a46eb95e..000000000 --- a/database_test.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -import ( - _"testing" - _"fmt" -) - diff --git a/dev_console.go b/dev_console.go index 65166c0c1..27fc2e65e 100644 --- a/dev_console.go +++ b/dev_console.go @@ -7,16 +7,18 @@ import ( "os" "errors" "encoding/hex" + "github.com/ethereum/ethdb-go" + "github.com/ethereum/ethutil-go" ) type Console struct { - db *MemDatabase - trie *Trie + db *ethdb.MemDatabase + trie *ethutil.Trie } func NewConsole() *Console { - db, _ := NewMemDatabase() - trie := NewTrie(db, "") + db, _ := ethdb.NewMemDatabase() + trie := ethutil.NewTrie(db, "") return &Console{db: db, trie: trie} } @@ -68,17 +70,19 @@ func (i *Console) ParseInput(input string) bool { case "update": i.trie.Update(tokens[1], tokens[2]) - fmt.Println(hex.EncodeToString([]byte(i.trie.root))) + fmt.Println(hex.EncodeToString([]byte(i.trie.Root))) case "get": fmt.Println(i.trie.Get(tokens[1])) case "root": - fmt.Println(hex.EncodeToString([]byte(i.trie.root))) + fmt.Println(hex.EncodeToString([]byte(i.trie.Root))) case "rawroot": - fmt.Println(i.trie.root) + fmt.Println(i.trie.Root) case "print": i.db.Print() case "dag": - fmt.Println(DaggerVerify(Big(tokens[1]), BigPow(2, 36), Big(tokens[2]))) + fmt.Println(DaggerVerify( ethutil.Big(tokens[1]), // hash + ethutil.BigPow(2, 36), // diff + ethutil.Big(tokens[2])))// nonce case "exit", "quit", "q": return false case "help": diff --git a/encoding.go b/encoding.go deleted file mode 100644 index d77303817..000000000 --- a/encoding.go +++ /dev/null @@ -1,62 +0,0 @@ -package main - -import ( - "bytes" - "encoding/hex" - "strings" - _"fmt" -) - -func CompactEncode(hexSlice []int) string { - terminator := 0 - if hexSlice[len(hexSlice)-1] == 16 { - terminator = 1 - } - - if terminator == 1 { - hexSlice = hexSlice[:len(hexSlice)-1] - } - - oddlen := len(hexSlice) % 2 - flags := 2 * terminator + oddlen - if oddlen != 0 { - hexSlice = append([]int{flags}, hexSlice...) - } else { - hexSlice = append([]int{flags, 0}, hexSlice...) - } - - var buff bytes.Buffer - for i := 0; i < len(hexSlice); i+=2 { - buff.WriteByte(byte(16 * hexSlice[i] + hexSlice[i+1])) - } - - return buff.String() -} - -func CompactDecode(str string) []int { - base := CompactHexDecode(str) - base = base[:len(base)-1] - if base[0] >= 2 {// && base[len(base)-1] != 16 { - base = append(base, 16) - } - if base[0] % 2 == 1 { - base = base[1:] - } else { - base = base[2:] - } - - return base -} - -func CompactHexDecode(str string) []int { - base := "0123456789abcdef" - hexSlice := make([]int, 0) - - enc := hex.EncodeToString([]byte(str)) - for _, v := range enc { - hexSlice = append(hexSlice, strings.IndexByte(base, byte(v))) - } - hexSlice = append(hexSlice, 16) - - return hexSlice -} diff --git a/encoding_test.go b/encoding_test.go deleted file mode 100644 index b66f702ac..000000000 --- a/encoding_test.go +++ /dev/null @@ -1,38 +0,0 @@ -package main - -import ( - "testing" - "fmt" -) - -func TestCompactEncode(t *testing.T) { - test1 := []int{1,2,3,4,5} - if res := CompactEncode(test1); res != "\x11\x23\x45" { - t.Error(fmt.Sprintf("even compact encode failed. Got: %q", res)) - } - - test2 := []int{0, 1, 2, 3, 4, 5} - if res := CompactEncode(test2); res != "\x00\x01\x23\x45" { - t.Error(fmt.Sprintf("odd compact encode failed. Got: %q", res)) - } - - test3 := []int{0, 15, 1, 12, 11, 8, /*term*/16} - if res := CompactEncode(test3); res != "\x20\x0f\x1c\xb8" { - t.Error(fmt.Sprintf("odd terminated compact encode failed. Got: %q", res)) - } - - test4 := []int{15, 1, 12, 11, 8, /*term*/16} - if res := CompactEncode(test4); res != "\x3f\x1c\xb8" { - t.Error(fmt.Sprintf("even terminated compact encode failed. Got: %q", res)) - } -} - - -func TestCompactHexDecode(t *testing.T) { - exp := []int{7, 6, 6, 5, 7, 2, 6, 2, 16} - res := CompactHexDecode("verb") - - if !CompareIntSlice(res, exp) { - t.Error("Error compact hex decode. Expected", exp, "got", res) - } -} diff --git a/ethereum.go b/ethereum.go index aee8ebc30..96b67f970 100644 --- a/ethereum.go +++ b/ethereum.go @@ -7,7 +7,7 @@ import ( "flag" "runtime" "log" - _"math/big" + "github.com/ethereum/ethutil-go" ) const Debug = true @@ -39,7 +39,7 @@ func RegisterInterupts(s *Server) { func main() { runtime.GOMAXPROCS(runtime.NumCPU()) - InitFees() + ethutil.InitFees() Init() @@ -63,7 +63,7 @@ func main() { go func() { for { - res := dagger.Search(Big("0"), BigPow(2, 36)) + res := dagger.Search(ethutil.Big("0"), ethutil.BigPow(2, 36)) server.Broadcast("block", Encode(res.String())) } }() diff --git a/genesis.go b/genesis.go deleted file mode 100644 index 21b8e9998..000000000 --- a/genesis.go +++ /dev/null @@ -1,34 +0,0 @@ -package main - -import ( - "math" -) - -/* - * This is the special genesis block. - */ - -var GenisisHeader = []interface{}{ - // Block number - uint32(0), - // Previous hash (none) - "", - // Sha of uncles - string(Sha256Bin(Encode([]interface{}{}))), - // Coinbase - "", - // Root state - "", - // Sha of transactions - string(Sha256Bin(Encode([]interface{}{}))), - // Difficulty - uint32(math.Pow(2, 36)), - // Time - uint64(1), - // Nonce - uint32(0), - // Extra - "", -} - -var Genesis = []interface{}{ GenisisHeader, []interface{}{}, []interface{}{} } diff --git a/memory_database.go b/memory_database.go deleted file mode 100644 index a8c74bb46..000000000 --- a/memory_database.go +++ /dev/null @@ -1,34 +0,0 @@ -package main - -import ( - "fmt" -) - -/* - * This is a test memory database. Do not use for any production it does not get persisted - */ -type MemDatabase struct { - db map[string][]byte -} - -func NewMemDatabase() (*MemDatabase, error) { - db := &MemDatabase{db: make(map[string][]byte)} - - return db, nil -} - -func (db *MemDatabase) Put(key []byte, value []byte) { - db.db[string(key)] = value -} - -func (db *MemDatabase) Get(key []byte) ([]byte, error) { - return db.db[string(key)], nil -} - -func (db *MemDatabase) Print() { - for key, val := range db.db { - fmt.Printf("%x(%d):", key, len(key)) - decoded := DecodeNode(val) - PrintSlice(decoded) - } -} diff --git a/parsing.go b/parsing.go deleted file mode 100644 index b97d77f3e..000000000 --- a/parsing.go +++ /dev/null @@ -1,98 +0,0 @@ -package main - -import ( - "fmt" - "strings" - "errors" - "math/big" - "strconv" -) - -// Op codes -var OpCodes = map[string]string{ - "STOP": "0", - "ADD": "1", - "MUL": "2", - "SUB": "3", - "DIV": "4", - "SDIV": "5", - "MOD": "6", - "SMOD": "7", - "EXP": "8", - "NEG": "9", - "LT": "10", - "LE": "11", - "GT": "12", - "GE": "13", - "EQ": "14", - "NOT": "15", - "MYADDRESS": "16", - "TXSENDER": "17", - - - "PUSH": "48", - "POP": "49", - "LOAD": "54", -} - - -func CompileInstr(s string) (string, error) { - tokens := strings.Split(s, " ") - if OpCodes[tokens[0]] == "" { - return s, errors.New(fmt.Sprintf("OP not found: %s", tokens[0])) - } - - code := OpCodes[tokens[0]] // Replace op codes with the proper numerical equivalent - op := new(big.Int) - op.SetString(code, 0) - - args := make([]*big.Int, 6) - for i, val := range tokens[1:len(tokens)] { - num := new(big.Int) - num.SetString(val, 0) - args[i] = num - } - - // Big int equation = op + x * 256 + y * 256**2 + z * 256**3 + a * 256**4 + b * 256**5 + c * 256**6 - base := new(big.Int) - x := new(big.Int) - y := new(big.Int) - z := new(big.Int) - a := new(big.Int) - b := new(big.Int) - c := new(big.Int) - - if args[0] != nil { x.Mul(args[0], big.NewInt(256)) } - if args[1] != nil { y.Mul(args[1], BigPow(256, 2)) } - if args[2] != nil { z.Mul(args[2], BigPow(256, 3)) } - if args[3] != nil { a.Mul(args[3], BigPow(256, 4)) } - if args[4] != nil { b.Mul(args[4], BigPow(256, 5)) } - if args[5] != nil { c.Mul(args[5], BigPow(256, 6)) } - - base.Add(op, x) - base.Add(base, y) - base.Add(base, z) - base.Add(base, a) - base.Add(base, b) - base.Add(base, c) - - return base.String(), nil -} - -func Instr(instr string) (int, []string, error) { - base := new(big.Int) - base.SetString(instr, 0) - - args := make([]string, 7) - for i := 0; i < 7; i++ { - // int(int(val) / int(math.Pow(256,float64(i)))) % 256 - exp := BigPow(256, i) - num := new(big.Int) - num.Div(base, exp) - - args[i] = num.Mod(num, big.NewInt(256)).String() - } - op, _ := strconv.Atoi(args[0]) - - return op, args[1:7], nil -} diff --git a/parsing_test.go b/parsing_test.go deleted file mode 100644 index 6aa9e240c..000000000 --- a/parsing_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package main - -import ( - "testing" - "math" -) - -func TestCompile(t *testing.T) { - instr, err := CompileInstr("PUSH") - - if err != nil { - t.Error("Failed compiling instruction") - } - - calc := (48 + 0 * 256 + 0 * int64(math.Pow(256,2))) - if Big(instr).Int64() != calc { - t.Error("Expected", calc, ", got:", instr) - } -} - -func TestValidInstr(t *testing.T) { - /* - op, args, err := Instr("68163") - if err != nil { - t.Error("Error decoding instruction") - } - */ - -} - -func TestInvalidInstr(t *testing.T) { -} - diff --git a/rlp.go b/rlp.go index 5366632f4..cee9da613 100644 --- a/rlp.go +++ b/rlp.go @@ -5,6 +5,7 @@ import ( "bytes" "math" "math/big" + "github.com/ethereum/ethutil-go" ) type RlpEncoder struct { @@ -54,7 +55,7 @@ func (attr *RlpDataAttribute) AsUint() uint64 { func (attr *RlpDataAttribute) AsBigInt() *big.Int { if a, ok := attr.dataAttrib.([]byte); ok { - return Big(string(a)) + return ethutil.Big(string(a)) } return big.NewInt(0) diff --git a/server.go b/server.go index c2903cb59..d81fe1bce 100644 --- a/server.go +++ b/server.go @@ -5,15 +5,15 @@ import ( "net" "log" _"time" + "github.com/ethereum/ethdb-go" + "github.com/ethereum/ethutil-go" ) -var Db *LDBDatabase - type Server struct { // Channel for shutting down the server shutdownChan chan bool // DB interface - db *LDBDatabase + db *ethdb.LDBDatabase // Block manager for processing new blocks and managing the block chain blockManager *BlockManager // Peers (NYI) @@ -21,12 +21,12 @@ type Server struct { } func NewServer() (*Server, error) { - db, err := NewLDBDatabase() + db, err := ethdb.NewLDBDatabase() if err != nil { return nil, err } - Db = db + ethutil.SetConfig(db) server := &Server{ shutdownChan: make(chan bool), diff --git a/transaction.go b/transaction.go deleted file mode 100644 index 90e0d9869..000000000 --- a/transaction.go +++ /dev/null @@ -1,206 +0,0 @@ -package main - -import ( - "math/big" - "fmt" - "github.com/obscuren/secp256k1-go" - _"encoding/hex" - _"crypto/sha256" - _ "bytes" -) - -/* -Transaction Contract Size -------------------------------------------- -sender sender 20 bytes -recipient 0x0 20 bytes -value endowment 4 bytes (uint32) -fee fee 4 bytes (uint32) -d_size o_size 4 bytes (uint32) -data ops * -signature signature 64 bytes -*/ - -var StepFee *big.Int = new(big.Int) -var TxFee *big.Int = new(big.Int) -var ContractFee *big.Int = new(big.Int) -var MemFee *big.Int = new(big.Int) -var DataFee *big.Int = new(big.Int) -var CryptoFee *big.Int = new(big.Int) -var ExtroFee *big.Int = new(big.Int) - -var Period1Reward *big.Int = new(big.Int) -var Period2Reward *big.Int = new(big.Int) -var Period3Reward *big.Int = new(big.Int) -var Period4Reward *big.Int = new(big.Int) - -type Transaction struct { - nonce string - sender string - recipient string - value uint64 - fee uint32 - data []string - memory []int - lastTx string - v uint32 - r, s []byte -} - -func NewTransaction(to string, value uint64, data []string) *Transaction { - tx := Transaction{sender: "1234567890", recipient: to, value: value} - tx.nonce = "0" - tx.fee = 0//uint32((ContractFee + MemoryFee * float32(len(tx.data))) * 1e8) - tx.lastTx = "0" - - // Serialize the data - tx.data = make([]string, len(data)) - for i, val := range data { - instr, err := CompileInstr(val) - if err != nil { - //fmt.Printf("compile error:%d %v\n", i+1, err) - } - - tx.data[i] = instr - } - - tx.Sign([]byte("privkey")) - tx.Sender() - - - return &tx -} - -func (tx *Transaction) Hash() []byte { - preEnc := []interface{}{ - tx.nonce, - tx.recipient, - tx.value, - tx.fee, - tx.data, - } - - return Sha256Bin(Encode(preEnc)) -} - -func (tx *Transaction) IsContract() bool { - return tx.recipient == "" -} - -func (tx *Transaction) Signature(key []byte) []byte { - hash := tx.Hash() - sec := Sha256Bin(key) - - sig, _ := secp256k1.Sign(hash, sec) - - return sig -} - -func (tx *Transaction) PublicKey() []byte { - hash := Sha256Bin(tx.Hash()) - sig := append(tx.r, tx.s...) - - pubkey, _ := secp256k1.RecoverPubkey(hash, sig) - - return pubkey -} - -func (tx *Transaction) Sender() []byte { - pubkey := tx.PublicKey() - - // Validate the returned key. - // Return nil if public key isn't in full format (04 = full, 03 = compact) - if pubkey[0] != 4 { - return nil - } - - return Sha256Bin(pubkey[1:65])[12:] -} - -func (tx *Transaction) Sign(privk []byte) { - sig := tx.Signature(privk) - - // Add 27 so we get either 27 or 28 (for positive and negative) - tx.v = uint32(sig[64]) + 27 - tx.r = sig[:32] - tx.s = sig[32:65] -} - -func (tx *Transaction) MarshalRlp() []byte { - // Prepare the transaction for serialization - preEnc := []interface{}{ - tx.nonce, - tx.recipient, - tx.value, - tx.fee, - tx.data, - tx.v, - tx.r, - tx.s, - } - - return Encode(preEnc) -} - -func (tx *Transaction) UnmarshalRlp(data []byte) { - decoder := NewRlpDecoder(data) - - tx.nonce = decoder.Get(0).AsString() - tx.recipient = decoder.Get(0).AsString() - tx.value = decoder.Get(2).AsUint() - tx.fee = uint32(decoder.Get(3).AsUint()) - - d := decoder.Get(4) - tx.data = make([]string, d.Length()) - fmt.Println(d.Get(0)) - for i := 0; i < d.Length(); i++ { - tx.data[i] = d.Get(i).AsString() - } - - tx.v = uint32(decoder.Get(5).AsUint()) - tx.r = decoder.Get(6).AsBytes() - tx.s = decoder.Get(7).AsBytes() -} - -func InitFees() { - // Base for 2**60 - b60 := new(big.Int) - b60.Exp(big.NewInt(2), big.NewInt(64), big.NewInt(0)) - // Base for 2**80 - b80 := new(big.Int) - b80.Exp(big.NewInt(2), big.NewInt(80), big.NewInt(0)) - - StepFee.Exp(big.NewInt(10), big.NewInt(16), big.NewInt(0)) - //StepFee.Div(b60, big.NewInt(64)) - //fmt.Println("StepFee:", StepFee) - - TxFee.Exp(big.NewInt(2), big.NewInt(64), big.NewInt(0)) - //fmt.Println("TxFee:", TxFee) - - ContractFee.Exp(big.NewInt(2), big.NewInt(64), big.NewInt(0)) - //fmt.Println("ContractFee:", ContractFee) - - MemFee.Div(b60, big.NewInt(4)) - //fmt.Println("MemFee:", MemFee) - - DataFee.Div(b60, big.NewInt(16)) - //fmt.Println("DataFee:", DataFee) - - CryptoFee.Div(b60, big.NewInt(16)) - //fmt.Println("CrytoFee:", CryptoFee) - - ExtroFee.Div(b60, big.NewInt(16)) - //fmt.Println("ExtroFee:", ExtroFee) - - Period1Reward.Mul(b80, big.NewInt(1024)) - //fmt.Println("Period1Reward:", Period1Reward) - - Period2Reward.Mul(b80, big.NewInt(512)) - //fmt.Println("Period2Reward:", Period2Reward) - - Period3Reward.Mul(b80, big.NewInt(256)) - //fmt.Println("Period3Reward:", Period3Reward) - - Period4Reward.Mul(b80, big.NewInt(128)) - //fmt.Println("Period4Reward:", Period4Reward) -} diff --git a/trie.go b/trie.go deleted file mode 100644 index d66699eeb..000000000 --- a/trie.go +++ /dev/null @@ -1,203 +0,0 @@ -package main - -import ( - "fmt" -) - -// Database interface -type Database interface { - Put(key []byte, value []byte) - Get(key []byte) ([]byte, error) -} - -/* - * Trie helper functions - */ -// Helper function for printing out the raw contents of a slice -func PrintSlice(slice []string) { - fmt.Printf("[") - for i, val := range slice { - fmt.Printf("%q", val) - if i != len(slice)-1 { fmt.Printf(",") } - } - fmt.Printf("]\n") -} - -// RLP Decodes a node in to a [2] or [17] string slice -func DecodeNode(data []byte) []string { - dec, _ := Decode(data, 0) - if slice, ok := dec.([]interface{}); ok { - strSlice := make([]string, len(slice)) - - for i, s := range slice { - if str, ok := s.([]byte); ok { - strSlice[i] = string(str) - } - } - - return strSlice - } else { - fmt.Printf("It wasn't a []. It's a %T\n", dec) - } - - return nil -} - -// A (modified) Radix Trie implementation -type Trie struct { - root string - db Database -} - -func NewTrie(db Database, root string) *Trie { - return &Trie{db: db, root: root} -} - -/* - * Public (query) interface functions - */ -func (t *Trie) Update(key string, value string) { - k := CompactHexDecode(key) - - t.root = t.UpdateState(t.root, k, value) -} - -func (t *Trie) Get(key string) string { - k := CompactHexDecode(key) - - return t.GetState(t.root, k) -} - -/* - * State functions (shouldn't be needed directly). - */ - -// Helper function for printing a node (using fetch, decode and slice printing) -func (t *Trie) PrintNode(n string) { - data, _ := t.db.Get([]byte(n)) - d := DecodeNode(data) - PrintSlice(d) -} - -// Returns the state of an object -func (t *Trie) GetState(node string, key []int) string { - // Return the node if key is empty (= found) - if len(key) == 0 || node == "" { - return node - } - - // Fetch the encoded node from the db - n, err := t.db.Get([]byte(node)) - if err != nil { fmt.Println("Error in GetState for node", node, "with key", key); return "" } - - // Decode it - currentNode := DecodeNode(n) - - if len(currentNode) == 0 { - return "" - } else if len(currentNode) == 2 { - // Decode the key - k := CompactDecode(currentNode[0]) - v := currentNode[1] - - if len(key) >= len(k) && CompareIntSlice(k, key[:len(k)]) { - return t.GetState(v, key[len(k):]) - } else { - return "" - } - } else if len(currentNode) == 17 { - return t.GetState(currentNode[key[0]], key[1:]) - } - - // It shouldn't come this far - fmt.Println("GetState unexpected return") - return "" -} - -// Inserts a new sate or delete a state based on the value -func (t *Trie) UpdateState(node string, key []int, value string) string { - if value != "" { - return t.InsertState(node, key, value) - } else { - // delete it - } - - return "" -} - -// Wrapper around the regular db "Put" which generates a key and value -func (t *Trie) Put(node interface{}) []byte { - enc := Encode(node) - var sha []byte - sha = Sha256Bin(enc) - - t.db.Put([]byte(sha), enc) - - return sha -} - -func (t *Trie) InsertState(node string, key []int, value string) string { - if len(key) == 0 { - return value - } - - // New node - if node == "" { - newNode := []string{ CompactEncode(key), value } - - return string(t.Put(newNode)) - } - - // Fetch the encoded node from the db - n, err := t.db.Get([]byte(node)) - if err != nil { fmt.Println("Error InsertState", err); return "" } - - // Decode it - currentNode := DecodeNode(n) - // Check for "special" 2 slice type node - if len(currentNode) == 2 { - // Decode the key - k := CompactDecode(currentNode[0]) - v := currentNode[1] - - // Matching key pair (ie. there's already an object with this key) - if CompareIntSlice(k, key) { - return string(t.Put([]string{ CompactEncode(key), value })) - } - - var newHash string - matchingLength := MatchingNibbleLength(key, k) - if matchingLength == len(k) { - // Insert the hash, creating a new node - newHash = t.InsertState(v, key[matchingLength:], value) - } else { - // Expand the 2 length slice to a 17 length slice - oldNode := t.InsertState("", k[matchingLength+1:], v) - newNode := t.InsertState("", key[matchingLength+1:], value) - // Create an expanded slice - scaledSlice := make([]string, 17) - // Set the copied and new node - scaledSlice[k[matchingLength]] = oldNode - scaledSlice[key[matchingLength]] = newNode - - newHash = string(t.Put(scaledSlice)) - } - - if matchingLength == 0 { - // End of the chain, return - return newHash - } else { - newNode := []string{ CompactEncode(key[:matchingLength]), newHash } - return string(t.Put(newNode)) - } - } else { - // Copy the current node over to the new node and replace the first nibble in the key - newNode := make([]string, 17); copy(newNode, currentNode) - newNode[key[0]] = t.InsertState(currentNode[key[0]], key[1:], value) - - return string(t.Put(newNode)) - } - - return "" -} - diff --git a/trie_test.go b/trie_test.go deleted file mode 100644 index 599a5f47c..000000000 --- a/trie_test.go +++ /dev/null @@ -1,59 +0,0 @@ -package main - -import ( - "testing" - "encoding/hex" - _"fmt" -) - -func TestTriePut(t *testing.T) { - db, err := NewMemDatabase() - trie := NewTrie(db, "") - - if err != nil { - t.Error("Error starting db") - } - - key := trie.Put([]byte("testing node")) - - data, err := db.Get(key) - if err != nil { - t.Error("Nothing at node") - } - - s, _ := Decode(data, 0) - if str, ok := s.([]byte); ok { - if string(str) != "testing node" { - t.Error("Wrong value node", str) - } - } else { - t.Error("Invalid return type") - } -} - -func TestTrieUpdate(t *testing.T) { - db, err := NewMemDatabase() - trie := NewTrie(db, "") - - if err != nil { - t.Error("Error starting db") - } - - - trie.Update("doe", "reindeer") - trie.Update("dog", "puppy") - /* - data, _ := db.Get([]byte(trie.root)) - data, _ = db.Get([]byte(DecodeNode(data)[1])) - data, _ = db.Get([]byte(DecodeNode(data)[7])) - PrintSlice(DecodeNode(data)) - */ - - trie.Update("dogglesworth", "cat") - root := hex.EncodeToString([]byte(trie.root)) - req := "e378927bfc1bd4f01a2e8d9f59bd18db8a208bb493ac0b00f93ce51d4d2af76c" - if root != req { - t.Error("trie.root do not match, expected", req, "got", root) - } -} - diff --git a/util.go b/util.go deleted file mode 100644 index 24e5455f4..000000000 --- a/util.go +++ /dev/null @@ -1,63 +0,0 @@ -package main - -import ( - "strconv" - "crypto/sha256" - "encoding/hex" - _"fmt" - _"math" - "github.com/obscuren/sha3" -) - -func Uitoa(i uint32) string { - return strconv.FormatUint(uint64(i), 10) -} - -func Sha256Hex(data []byte) string { - hash := sha256.Sum256(data) - - return hex.EncodeToString(hash[:]) -} - -func Sha256Bin(data []byte) []byte { - hash := sha256.Sum256(data) - - return hash[:] -} - -func Sha3Bin(data []byte) []byte { - d := sha3.NewKeccak224() - d.Reset() - d.Write(data) - - return d.Sum(nil) -} - -// Helper function for comparing slices -func CompareIntSlice(a, b []int) bool { - if len(a) != len(b) { - return false - } - for i, v := range a { - if v != b[i] { - return false - } - } - return true -} - -// Returns the amount of nibbles that match each other from 0 ... -func MatchingNibbleLength(a, b []int) int { - i := 0 - for CompareIntSlice(a[:i+1], b[:i+1]) && i < len(b) { - i+=1 - } - - //fmt.Println(a, b, i-1) - - return i -} - -func Hex(d []byte) string { - return hex.EncodeToString(d) -} diff --git a/vm.go b/vm.go index 5b70f3544..5605cb7c7 100644 --- a/vm.go +++ b/vm.go @@ -1,12 +1,10 @@ package main import ( - _"math" "math/big" "fmt" - _"strconv" - _ "encoding/hex" "strconv" + "github.com/ethereum/ethutil-go" ) // Op codes @@ -93,7 +91,7 @@ func (st *Stack) Popn() (*big.Int, *big.Int) { strs := st.data[s-2:] st.data = st.data[:s-2] - return Big(strs[0]), Big(strs[1]) + return ethutil.Big(strs[0]), ethutil.Big(strs[1]) } func (st *Stack) Push(d string) { @@ -114,7 +112,8 @@ func NewVm() *Vm { } } -func (vm *Vm) ProcContract(tx *Transaction, block *Block, cb TxCallback) { +func (vm *Vm) ProcContract( tx *ethutil.Transaction, + block *ethutil.Block, cb TxCallback) { // Instruction pointer pc := 0 @@ -124,7 +123,7 @@ func (vm *Vm) ProcContract(tx *Transaction, block *Block, cb TxCallback) { return } - Pow256 := BigPow(2, 256) + Pow256 := ethutil.BigPow(2, 256) //fmt.Printf("# op arg\n") out: @@ -134,7 +133,8 @@ out: // XXX Should Instr return big int slice instead of string slice? // Get the next instruction from the contract //op, _, _ := Instr(contract.state.Get(string(Encode(uint32(pc))))) - op, _, _ := Instr(contract.state.Get(string(NumberToBytes(uint64(pc), 32)))) + nb := ethutil.NumberToBytes(uint64(pc), 32) + op, _, _ := ethutil.Instr(contract.State().Get(string(nb))) if !cb(0) { break } @@ -200,7 +200,7 @@ out: vm.stack.Push(base.String()) case oNEG: - base.Sub(Pow256, Big(vm.stack.Pop())) + base.Sub(Pow256, ethutil.Big(vm.stack.Pop())) vm.stack.Push(base.String()) case oLT: x, y := vm.stack.Popn() @@ -245,18 +245,18 @@ out: case oMYADDRESS: vm.stack.Push(string(tx.Hash())) case oTXSENDER: - vm.stack.Push(tx.sender) + vm.stack.Push(string(tx.Sender())) case oPUSH: // Get the next entry and pushes the value on the stack pc++ - vm.stack.Push(contract.state.Get(string(NumberToBytes(uint64(pc), 32)))) + vm.stack.Push(contract.State().Get(string(ethutil.NumberToBytes(uint64(pc), 32)))) case oPOP: // Pop current value of the stack vm.stack.Pop() case oLOAD: // Load instruction X on the stack i, _ := strconv.Atoi(vm.stack.Pop()) - vm.stack.Push(contract.state.Get(string(NumberToBytes(uint64(i), 32)))) + vm.stack.Push(contract.State().Get(string(ethutil.NumberToBytes(uint64(i), 32)))) case oSTOP: break out } From 9571a512861d4a44c36d368f4baa15b2aa81c37d Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 11 Jan 2014 15:27:08 +0100 Subject: [PATCH 084/459] gofmt no coding standards --- README.md | 5 + block_manager.go | 106 +++++------ dagger.go | 187 +++++++++--------- dagger_test.go | 18 +- dev_console.go | 186 +++++++++--------- ethereum.go | 112 +++++------ peer.go | 108 +++++------ rlp.go | 352 +++++++++++++++++----------------- rlp_test.go | 70 +++---- server.go | 155 ++++++++------- test_runner.go | 30 +-- test_runner_test.go | 28 +-- testing.go | 1 + vm.go | 451 +++++++++++++++++++++++--------------------- 14 files changed, 922 insertions(+), 887 deletions(-) diff --git a/README.md b/README.md index 4b797b5a7..37e8505f1 100644 --- a/README.md +++ b/README.md @@ -21,3 +21,8 @@ Command line options -c launch the developer console -m start mining fake blocks and broadcast fake messages to the net + +Contribution +============ + +See CONTRIB.md diff --git a/block_manager.go b/block_manager.go index 59430dca7..968d9a139 100644 --- a/block_manager.go +++ b/block_manager.go @@ -1,90 +1,90 @@ package main import ( - "fmt" - "github.com/ethereum/ethutil-go" + "fmt" + "github.com/ethereum/ethutil-go" ) type BlockChain struct { - lastBlock *ethutil.Block + lastBlock *ethutil.Block - genesisBlock *ethutil.Block + genesisBlock *ethutil.Block } func NewBlockChain() *BlockChain { - bc := &BlockChain{} - bc.genesisBlock = ethutil.NewBlock( ethutil.Encode(ethutil.Genesis) ) + bc := &BlockChain{} + bc.genesisBlock = ethutil.NewBlock(ethutil.Encode(ethutil.Genesis)) - return bc + return bc } type BlockManager struct { - vm *Vm + vm *Vm - blockChain *BlockChain + blockChain *BlockChain } func NewBlockManager() *BlockManager { - bm := &BlockManager{vm: NewVm()} + bm := &BlockManager{vm: NewVm()} - return bm + return bm } // Process a block. func (bm *BlockManager) ProcessBlock(block *ethutil.Block) error { - // TODO Validation (Or move to other part of the application) - if err := bm.ValidateBlock(block); err != nil { - return err - } + // TODO Validation (Or move to other part of the application) + if err := bm.ValidateBlock(block); err != nil { + return err + } - // Get the tx count. Used to create enough channels to 'join' the go routines - txCount := len(block.Transactions()) - // Locking channel. When it has been fully buffered this method will return - lockChan := make(chan bool, txCount) + // Get the tx count. Used to create enough channels to 'join' the go routines + txCount := len(block.Transactions()) + // Locking channel. When it has been fully buffered this method will return + lockChan := make(chan bool, txCount) - // Process each transaction/contract - for _, tx := range block.Transactions() { - // If there's no recipient, it's a contract - if tx.IsContract() { - go bm.ProcessContract(tx, block, lockChan) - } else { - // "finish" tx which isn't a contract - lockChan <- true - } - } + // Process each transaction/contract + for _, tx := range block.Transactions() { + // If there's no recipient, it's a contract + if tx.IsContract() { + go bm.ProcessContract(tx, block, lockChan) + } else { + // "finish" tx which isn't a contract + lockChan <- true + } + } - // Wait for all Tx to finish processing - for i := 0; i < txCount; i++ { - <- lockChan - } + // Wait for all Tx to finish processing + for i := 0; i < txCount; i++ { + <-lockChan + } - return nil + return nil } func (bm *BlockManager) ValidateBlock(block *ethutil.Block) error { - return nil + return nil } func (bm *BlockManager) ProcessContract(tx *ethutil.Transaction, block *ethutil.Block, lockChan chan bool) { - // Recovering function in case the VM had any errors - defer func() { - if r := recover(); r != nil { - fmt.Println("Recovered from VM execution with err =", r) - // Let the channel know where done even though it failed (so the execution may resume normally) - lockChan <- true - } - }() + // Recovering function in case the VM had any errors + defer func() { + if r := recover(); r != nil { + fmt.Println("Recovered from VM execution with err =", r) + // Let the channel know where done even though it failed (so the execution may resume normally) + lockChan <- true + } + }() - // Process contract - bm.vm.ProcContract(tx, block, func(opType OpType) bool { - // TODO turn on once big ints are in place - //if !block.PayFee(tx.Hash(), StepFee.Uint64()) { - // return false - //} + // Process contract + bm.vm.ProcContract(tx, block, func(opType OpType) bool { + // TODO turn on once big ints are in place + //if !block.PayFee(tx.Hash(), StepFee.Uint64()) { + // return false + //} - return true // Continue - }) + return true // Continue + }) - // Broadcast we're done - lockChan <- true + // Broadcast we're done + lockChan <- true } diff --git a/dagger.go b/dagger.go index 5aa5dd755..70b0b4692 100644 --- a/dagger.go +++ b/dagger.go @@ -1,142 +1,145 @@ package main import ( - "math/big" - "math/rand" - "time" - "github.com/obscuren/sha3" - "hash" - "github.com/ethereum/ethutil-go" + "github.com/ethereum/ethutil-go" + "github.com/obscuren/sha3" + "hash" + "math/big" + "math/rand" + "time" ) type Dagger struct { - hash *big.Int - xn *big.Int + hash *big.Int + xn *big.Int } var Found bool + func (dag *Dagger) Find(obj *big.Int, resChan chan int64) { - r := rand.New(rand.NewSource(time.Now().UnixNano())) + r := rand.New(rand.NewSource(time.Now().UnixNano())) - for i := 0; i < 1000; i++ { - rnd := r.Int63() + for i := 0; i < 1000; i++ { + rnd := r.Int63() - if dag.Eval(big.NewInt(rnd)).Cmp(obj) < 0 { - // Post back result on the channel - resChan <- rnd - // Notify other threads we've found a valid nonce - Found = true - } + if dag.Eval(big.NewInt(rnd)).Cmp(obj) < 0 { + // Post back result on the channel + resChan <- rnd + // Notify other threads we've found a valid nonce + Found = true + } - // Break out if found - if Found { break } - } + // Break out if found + if Found { + break + } + } - resChan <- 0 + resChan <- 0 } func (dag *Dagger) Search(hash, diff *big.Int) *big.Int { - // TODO fix multi threading. Somehow it results in the wrong nonce - amountOfRoutines := 1 + // TODO fix multi threading. Somehow it results in the wrong nonce + amountOfRoutines := 1 - dag.hash = hash + dag.hash = hash - obj := ethutil.BigPow(2, 256) - obj = obj.Div(obj, diff) + obj := ethutil.BigPow(2, 256) + obj = obj.Div(obj, diff) - Found = false - resChan := make(chan int64, 3) - var res int64 + Found = false + resChan := make(chan int64, 3) + var res int64 - for k := 0; k < amountOfRoutines; k++ { - go dag.Find(obj, resChan) - } + for k := 0; k < amountOfRoutines; k++ { + go dag.Find(obj, resChan) + } - // Wait for each go routine to finish - for k := 0; k < amountOfRoutines; k++ { - // Get the result from the channel. 0 = quit - if r := <- resChan; r != 0 { - res = r - } - } + // Wait for each go routine to finish + for k := 0; k < amountOfRoutines; k++ { + // Get the result from the channel. 0 = quit + if r := <-resChan; r != 0 { + res = r + } + } - return big.NewInt(res) + return big.NewInt(res) } func DaggerVerify(hash, diff, nonce *big.Int) bool { - dagger := &Dagger{} - dagger.hash = hash + dagger := &Dagger{} + dagger.hash = hash - obj := ethutil.BigPow(2, 256) - obj = obj.Div(obj, diff) + obj := ethutil.BigPow(2, 256) + obj = obj.Div(obj, diff) - return dagger.Eval(nonce).Cmp(obj) < 0 + return dagger.Eval(nonce).Cmp(obj) < 0 } func (dag *Dagger) Node(L uint64, i uint64) *big.Int { - if L == i { - return dag.hash - } + if L == i { + return dag.hash + } - var m *big.Int - if L == 9 { - m = big.NewInt(16) - } else { - m = big.NewInt(3) - } + var m *big.Int + if L == 9 { + m = big.NewInt(16) + } else { + m = big.NewInt(3) + } - sha := sha3.NewKeccak256() - sha.Reset() - d := sha3.NewKeccak256() - b := new(big.Int) - ret := new(big.Int) + sha := sha3.NewKeccak256() + sha.Reset() + d := sha3.NewKeccak256() + b := new(big.Int) + ret := new(big.Int) - for k := 0; k < int(m.Uint64()); k++ { - d.Reset() - d.Write(dag.hash.Bytes()) - d.Write(dag.xn.Bytes()) - d.Write(big.NewInt(int64(L)).Bytes()) - d.Write(big.NewInt(int64(i)).Bytes()) - d.Write(big.NewInt(int64(k)).Bytes()) + for k := 0; k < int(m.Uint64()); k++ { + d.Reset() + d.Write(dag.hash.Bytes()) + d.Write(dag.xn.Bytes()) + d.Write(big.NewInt(int64(L)).Bytes()) + d.Write(big.NewInt(int64(i)).Bytes()) + d.Write(big.NewInt(int64(k)).Bytes()) - b.SetBytes(Sum(d)) - pk := b.Uint64() & ((1 << ((L - 1) * 3)) - 1) - sha.Write(dag.Node(L - 1, pk).Bytes()) - } + b.SetBytes(Sum(d)) + pk := b.Uint64() & ((1 << ((L - 1) * 3)) - 1) + sha.Write(dag.Node(L-1, pk).Bytes()) + } - ret.SetBytes(Sum(sha)) + ret.SetBytes(Sum(sha)) - return ret + return ret } func Sum(sha hash.Hash) []byte { - in := make([]byte, 32) - return sha.Sum(in) + in := make([]byte, 32) + return sha.Sum(in) } func (dag *Dagger) Eval(N *big.Int) *big.Int { - pow := ethutil.BigPow(2, 26) - dag.xn = N.Div(N, pow) + pow := ethutil.BigPow(2, 26) + dag.xn = N.Div(N, pow) - sha := sha3.NewKeccak256() - sha.Reset() - ret := new(big.Int) + sha := sha3.NewKeccak256() + sha.Reset() + ret := new(big.Int) - for k := 0; k < 4; k++ { - d := sha3.NewKeccak256() - b := new(big.Int) + for k := 0; k < 4; k++ { + d := sha3.NewKeccak256() + b := new(big.Int) - d.Reset() - d.Write(dag.hash.Bytes()) - d.Write(dag.xn.Bytes()) - d.Write(N.Bytes()) - d.Write(big.NewInt(int64(k)).Bytes()) + d.Reset() + d.Write(dag.hash.Bytes()) + d.Write(dag.xn.Bytes()) + d.Write(N.Bytes()) + d.Write(big.NewInt(int64(k)).Bytes()) - b.SetBytes(Sum(d)) - pk := (b.Uint64() & 0x1ffffff) + b.SetBytes(Sum(d)) + pk := (b.Uint64() & 0x1ffffff) - sha.Write(dag.Node(9, pk).Bytes()) - } + sha.Write(dag.Node(9, pk).Bytes()) + } - return ret.SetBytes(Sum(sha)) + return ret.SetBytes(Sum(sha)) } diff --git a/dagger_test.go b/dagger_test.go index 7953ec1da..58cdd6afd 100644 --- a/dagger_test.go +++ b/dagger_test.go @@ -1,17 +1,17 @@ package main import ( - "testing" - "math/big" + "math/big" + "testing" ) func BenchmarkDaggerSearch(b *testing.B) { - hash := big.NewInt(0) - diff := BigPow(2, 36) - o := big.NewInt(0) // nonce doesn't matter. We're only testing against speed, not validity + hash := big.NewInt(0) + diff := BigPow(2, 36) + o := big.NewInt(0) // nonce doesn't matter. We're only testing against speed, not validity - // Reset timer so the big generation isn't included in the benchmark - b.ResetTimer() - // Validate - DaggerVerify(hash, diff, o) + // Reset timer so the big generation isn't included in the benchmark + b.ResetTimer() + // Validate + DaggerVerify(hash, diff, o) } diff --git a/dev_console.go b/dev_console.go index 27fc2e65e..923c483c2 100644 --- a/dev_console.go +++ b/dev_console.go @@ -1,119 +1,121 @@ package main import ( - "fmt" - "bufio" - "strings" - "os" - "errors" - "encoding/hex" - "github.com/ethereum/ethdb-go" - "github.com/ethereum/ethutil-go" + "bufio" + "encoding/hex" + "errors" + "fmt" + "github.com/ethereum/ethdb-go" + "github.com/ethereum/ethutil-go" + "os" + "strings" ) type Console struct { - db *ethdb.MemDatabase - trie *ethutil.Trie + db *ethdb.MemDatabase + trie *ethutil.Trie } func NewConsole() *Console { - db, _ := ethdb.NewMemDatabase() - trie := ethutil.NewTrie(db, "") + db, _ := ethdb.NewMemDatabase() + trie := ethutil.NewTrie(db, "") - return &Console{db: db, trie: trie} + return &Console{db: db, trie: trie} } func (i *Console) ValidateInput(action string, argumentLength int) error { - err := false - var expArgCount int + err := false + var expArgCount int - switch { - case action == "update" && argumentLength != 2: - err = true - expArgCount = 2 - case action == "get" && argumentLength != 1: - err = true - expArgCount = 1 - case action == "dag" && argumentLength != 2: - err = true - expArgCount = 2 - } + switch { + case action == "update" && argumentLength != 2: + err = true + expArgCount = 2 + case action == "get" && argumentLength != 1: + err = true + expArgCount = 1 + case action == "dag" && argumentLength != 2: + err = true + expArgCount = 2 + } - if err { - return errors.New(fmt.Sprintf("'%s' requires %d args, got %d", action, expArgCount, argumentLength)) - } else { - return nil - } + if err { + return errors.New(fmt.Sprintf("'%s' requires %d args, got %d", action, expArgCount, argumentLength)) + } else { + return nil + } } func (i *Console) ParseInput(input string) bool { - scanner := bufio.NewScanner(strings.NewReader(input)) - scanner.Split(bufio.ScanWords) + scanner := bufio.NewScanner(strings.NewReader(input)) + scanner.Split(bufio.ScanWords) - count := 0 - var tokens []string - for scanner.Scan() { - count++ - tokens = append(tokens, scanner.Text()) - } - if err := scanner.Err(); err != nil { - fmt.Fprintln(os.Stderr, "reading input:", err) - } + count := 0 + var tokens []string + for scanner.Scan() { + count++ + tokens = append(tokens, scanner.Text()) + } + if err := scanner.Err(); err != nil { + fmt.Fprintln(os.Stderr, "reading input:", err) + } - if len(tokens) == 0 { return true } + if len(tokens) == 0 { + return true + } - err := i.ValidateInput(tokens[0], count-1) - if err != nil { - fmt.Println(err) - } else { - switch tokens[0] { - case "update": - i.trie.Update(tokens[1], tokens[2]) + err := i.ValidateInput(tokens[0], count-1) + if err != nil { + fmt.Println(err) + } else { + switch tokens[0] { + case "update": + i.trie.Update(tokens[1], tokens[2]) - fmt.Println(hex.EncodeToString([]byte(i.trie.Root))) - case "get": - fmt.Println(i.trie.Get(tokens[1])) - case "root": - fmt.Println(hex.EncodeToString([]byte(i.trie.Root))) - case "rawroot": - fmt.Println(i.trie.Root) - case "print": - i.db.Print() - case "dag": - fmt.Println(DaggerVerify( ethutil.Big(tokens[1]), // hash - ethutil.BigPow(2, 36), // diff - ethutil.Big(tokens[2])))// nonce - case "exit", "quit", "q": - return false - case "help": - fmt.Printf( "COMMANDS:\n"+ - "\033[1m= DB =\033[0m\n"+ - "update KEY VALUE - Updates/Creates a new value for the given key\n"+ - "get KEY - Retrieves the given key\n"+ - "root - Prints the hex encoded merkle root\n"+ - "rawroot - Prints the raw merkle root\n"+ - "\033[1m= Dagger =\033[0m\n"+ - "dag HASH NONCE - Verifies a nonce with the given hash with dagger\n") - default: - fmt.Println("Unknown command:", tokens[0]) - } - } + fmt.Println(hex.EncodeToString([]byte(i.trie.Root))) + case "get": + fmt.Println(i.trie.Get(tokens[1])) + case "root": + fmt.Println(hex.EncodeToString([]byte(i.trie.Root))) + case "rawroot": + fmt.Println(i.trie.Root) + case "print": + i.db.Print() + case "dag": + fmt.Println(DaggerVerify(ethutil.Big(tokens[1]), // hash + ethutil.BigPow(2, 36), // diff + ethutil.Big(tokens[2]))) // nonce + case "exit", "quit", "q": + return false + case "help": + fmt.Printf("COMMANDS:\n" + + "\033[1m= DB =\033[0m\n" + + "update KEY VALUE - Updates/Creates a new value for the given key\n" + + "get KEY - Retrieves the given key\n" + + "root - Prints the hex encoded merkle root\n" + + "rawroot - Prints the raw merkle root\n" + + "\033[1m= Dagger =\033[0m\n" + + "dag HASH NONCE - Verifies a nonce with the given hash with dagger\n") + default: + fmt.Println("Unknown command:", tokens[0]) + } + } - return true + return true } func (i *Console) Start() { - fmt.Printf("Eth Console. Type (help) for help\n") - reader := bufio.NewReader(os.Stdin) - for { - fmt.Printf("eth >>> ") - str, _, err := reader.ReadLine() - if err != nil { - fmt.Println("Error reading input", err) - } else { - if !i.ParseInput(string(str)) { - return - } - } - } + fmt.Printf("Eth Console. Type (help) for help\n") + reader := bufio.NewReader(os.Stdin) + for { + fmt.Printf("eth >>> ") + str, _, err := reader.ReadLine() + if err != nil { + fmt.Println("Error reading input", err) + } else { + if !i.ParseInput(string(str)) { + return + } + } + } } diff --git a/ethereum.go b/ethereum.go index 96b67f970..dd5b44308 100644 --- a/ethereum.go +++ b/ethereum.go @@ -1,85 +1,85 @@ package main import ( - "fmt" - "os" - "os/signal" - "flag" - "runtime" - "log" - "github.com/ethereum/ethutil-go" + "flag" + "fmt" + "github.com/ethereum/ethutil-go" + "log" + "os" + "os/signal" + "runtime" ) const Debug = true var StartConsole bool var StartMining bool -func Init() { - flag.BoolVar(&StartConsole, "c", false, "debug and testing console") - flag.BoolVar(&StartMining, "m", false, "start dagger mining") - flag.Parse() +func Init() { + flag.BoolVar(&StartConsole, "c", false, "debug and testing console") + flag.BoolVar(&StartMining, "m", false, "start dagger mining") + + flag.Parse() } // Register interrupt handlers so we can stop the server func RegisterInterupts(s *Server) { - // Buffered chan of one is enough - c := make(chan os.Signal, 1) - // Notify about interrupts for now - signal.Notify(c, os.Interrupt) - go func() { - for sig := range c { - fmt.Printf("Shutting down (%v) ... \n", sig) + // Buffered chan of one is enough + c := make(chan os.Signal, 1) + // Notify about interrupts for now + signal.Notify(c, os.Interrupt) + go func() { + for sig := range c { + fmt.Printf("Shutting down (%v) ... \n", sig) - s.Stop() - } - }() + s.Stop() + } + }() } func main() { - runtime.GOMAXPROCS(runtime.NumCPU()) + runtime.GOMAXPROCS(runtime.NumCPU()) - ethutil.InitFees() + ethutil.InitFees() - Init() + Init() - if StartConsole { - console := NewConsole() - console.Start() - } else{ - log.Println("Starting Ethereum") - server, err := NewServer() + if StartConsole { + console := NewConsole() + console.Start() + } else { + log.Println("Starting Ethereum") + server, err := NewServer() - if err != nil { - log.Println(err) - return - } + if err != nil { + log.Println(err) + return + } - RegisterInterupts(server) + RegisterInterupts(server) - if StartMining { - log.Println("Mining started") - dagger := &Dagger{} + if StartMining { + log.Println("Mining started") + dagger := &Dagger{} - go func() { - for { - res := dagger.Search(ethutil.Big("0"), ethutil.BigPow(2, 36)) - server.Broadcast("block", Encode(res.String())) - } - }() - } + go func() { + for { + res := dagger.Search(ethutil.Big("0"), ethutil.BigPow(2, 36)) + server.Broadcast("block", Encode(res.String())) + } + }() + } - server.Start() + server.Start() - err = server.ConnectToPeer("localhost:12345") - if err != nil { - log.Println(err) - server.Stop() - return - } + err = server.ConnectToPeer("localhost:12345") + if err != nil { + log.Println(err) + server.Stop() + return + } - - // Wait for shutdown - server.WaitForShutdown() - } + // Wait for shutdown + server.WaitForShutdown() + } } diff --git a/peer.go b/peer.go index d47af73de..a9f88b1e1 100644 --- a/peer.go +++ b/peer.go @@ -1,92 +1,92 @@ package main import ( - "net" - "log" - "github.com/ethereum/ethwire-go" + "github.com/ethereum/ethwire-go" + "log" + "net" ) type Peer struct { - // Server interface - server *Server - // Net connection - conn net.Conn - // Output queue which is used to communicate and handle messages - outputQueue chan ethwire.InOutMsg - // Quit channel - quit chan bool + // Server interface + server *Server + // Net connection + conn net.Conn + // Output queue which is used to communicate and handle messages + outputQueue chan ethwire.InOutMsg + // Quit channel + quit chan bool } func NewPeer(conn net.Conn, server *Server) *Peer { - return &Peer{ - outputQueue: make(chan ethwire.InOutMsg, 1), // Buffered chan of 1 is enough - quit: make(chan bool), + return &Peer{ + outputQueue: make(chan ethwire.InOutMsg, 1), // Buffered chan of 1 is enough + quit: make(chan bool), - server: server, - conn: conn, - } + server: server, + conn: conn, + } } // Outputs any RLP encoded data to the peer func (p *Peer) QueueMessage(msgType string, data []byte) { - p.outputQueue <- ethwire.InOutMsg{MsgType: msgType, Data: data} + p.outputQueue <- ethwire.InOutMsg{MsgType: msgType, Data: data} } // Outbound message handler. Outbound messages are handled here func (p *Peer) HandleOutbound() { out: - for { - select { - // Main message queue. All outbound messages are processed through here - case msg := <-p.outputQueue: - // TODO Message checking and handle accordingly - err := ethwire.WriteMessage(p.conn, msg) - if err != nil { - log.Println(err) + for { + select { + // Main message queue. All outbound messages are processed through here + case msg := <-p.outputQueue: + // TODO Message checking and handle accordingly + err := ethwire.WriteMessage(p.conn, msg) + if err != nil { + log.Println(err) - // Stop the client if there was an error writing to it - p.Stop() - } + // Stop the client if there was an error writing to it + p.Stop() + } - // Break out of the for loop if a quit message is posted - case <- p.quit: - break out - } - } + // Break out of the for loop if a quit message is posted + case <-p.quit: + break out + } + } } // Inbound handler. Inbound messages are received here and passed to the appropriate methods func (p *Peer) HandleInbound() { - defer p.Stop() + defer p.Stop() out: - for { - // Wait for a message from the peer - msg, err := ethwire.ReadMessage(p.conn) - if err != nil { - log.Println(err) + for { + // Wait for a message from the peer + msg, err := ethwire.ReadMessage(p.conn) + if err != nil { + log.Println(err) - break out - } + break out + } - // TODO - data, _ := Decode(msg.Data, 0) - log.Printf("%s, %s\n", msg.MsgType, data) - } + // TODO + data, _ := Decode(msg.Data, 0) + log.Printf("%s, %s\n", msg.MsgType, data) + } - // Notify the out handler we're quiting - p.quit <- true + // Notify the out handler we're quiting + p.quit <- true } func (p *Peer) Start() { - // Run the outbound handler in a new goroutine - go p.HandleOutbound() - // Run the inbound handler in a new goroutine - go p.HandleInbound() + // Run the outbound handler in a new goroutine + go p.HandleOutbound() + // Run the inbound handler in a new goroutine + go p.HandleInbound() } func (p *Peer) Stop() { - p.conn.Close() + p.conn.Close() - p.quit <- true + p.quit <- true } diff --git a/rlp.go b/rlp.go index cee9da613..91ec50164 100644 --- a/rlp.go +++ b/rlp.go @@ -1,270 +1,278 @@ package main import ( - "fmt" - "bytes" - "math" - "math/big" - "github.com/ethereum/ethutil-go" + "bytes" + "fmt" + "github.com/ethereum/ethutil-go" + "math" + "math/big" ) type RlpEncoder struct { - rlpData []byte + rlpData []byte } -func NewRlpEncoder() *RlpEncoder { - encoder := &RlpEncoder{} - return encoder +func NewRlpEncoder() *RlpEncoder { + encoder := &RlpEncoder{} + + return encoder } func (coder *RlpEncoder) EncodeData(rlpData []interface{}) []byte { - return nil + return nil } // Data attributes are returned by the rlp decoder. The data attributes represents // one item within the rlp data structure. It's responsible for all the casting // It always returns something valid type RlpDataAttribute struct { - dataAttrib interface{} + dataAttrib interface{} } func NewRlpDataAttribute(attrib interface{}) *RlpDataAttribute { - return &RlpDataAttribute{dataAttrib: attrib} + return &RlpDataAttribute{dataAttrib: attrib} } func (attr *RlpDataAttribute) Length() int { - if data, ok := attr.dataAttrib.([]interface{}); ok { - return len(data) - } + if data, ok := attr.dataAttrib.([]interface{}); ok { + return len(data) + } - return 0 + return 0 } func (attr *RlpDataAttribute) AsUint() uint64 { - if value, ok := attr.dataAttrib.(uint8); ok { - return uint64(value) - } else if value, ok := attr.dataAttrib.(uint16); ok { - return uint64(value) - } else if value, ok := attr.dataAttrib.(uint32); ok { - return uint64(value) - } else if value, ok := attr.dataAttrib.(uint64); ok { - return value - } + if value, ok := attr.dataAttrib.(uint8); ok { + return uint64(value) + } else if value, ok := attr.dataAttrib.(uint16); ok { + return uint64(value) + } else if value, ok := attr.dataAttrib.(uint32); ok { + return uint64(value) + } else if value, ok := attr.dataAttrib.(uint64); ok { + return value + } - return 0 + return 0 } func (attr *RlpDataAttribute) AsBigInt() *big.Int { - if a, ok := attr.dataAttrib.([]byte); ok { - return ethutil.Big(string(a)) - } + if a, ok := attr.dataAttrib.([]byte); ok { + return ethutil.Big(string(a)) + } - return big.NewInt(0) + return big.NewInt(0) } func (attr *RlpDataAttribute) AsString() string { - if a, ok := attr.dataAttrib.([]byte); ok { - return string(a) - } + if a, ok := attr.dataAttrib.([]byte); ok { + return string(a) + } - return "" + return "" } func (attr *RlpDataAttribute) AsBytes() []byte { - if a, ok := attr.dataAttrib.([]byte); ok { - return a - } + if a, ok := attr.dataAttrib.([]byte); ok { + return a + } - return make([]byte, 0) + return make([]byte, 0) } // Threat the attribute as a slice func (attr *RlpDataAttribute) Get(idx int) *RlpDataAttribute { - if d, ok := attr.dataAttrib.([]interface{}); ok { - // Guard for oob - if len(d) < idx { - return NewRlpDataAttribute(nil) - } + if d, ok := attr.dataAttrib.([]interface{}); ok { + // Guard for oob + if len(d) < idx { + return NewRlpDataAttribute(nil) + } - return NewRlpDataAttribute(d[idx]) - } + return NewRlpDataAttribute(d[idx]) + } - // If this wasn't a slice you probably shouldn't be using this function - return NewRlpDataAttribute(nil) + // If this wasn't a slice you probably shouldn't be using this function + return NewRlpDataAttribute(nil) } type RlpDecoder struct { - rlpData interface{} + rlpData interface{} } -func NewRlpDecoder(rlpData []byte) *RlpDecoder { - decoder := &RlpDecoder{} - // Decode the data - data, _ := Decode(rlpData,0) - decoder.rlpData = data - return decoder +func NewRlpDecoder(rlpData []byte) *RlpDecoder { + decoder := &RlpDecoder{} + // Decode the data + data, _ := Decode(rlpData, 0) + decoder.rlpData = data + + return decoder } func (dec *RlpDecoder) Get(idx int) *RlpDataAttribute { - return NewRlpDataAttribute(dec.rlpData).Get(idx) + return NewRlpDataAttribute(dec.rlpData).Get(idx) } /// Raw methods func BinaryLength(n uint64) uint64 { - if n == 0 { return 0 } + if n == 0 { + return 0 + } - return 1 + BinaryLength(n / 256) + return 1 + BinaryLength(n/256) } func ToBinarySlice(n uint64, length uint64) []uint64 { - if length == 0 { - length = BinaryLength(n) - } + if length == 0 { + length = BinaryLength(n) + } - if n == 0 { return make([]uint64, 1) } + if n == 0 { + return make([]uint64, 1) + } - slice := ToBinarySlice(n / 256, 0) - slice = append(slice, n % 256) + slice := ToBinarySlice(n/256, 0) + slice = append(slice, n%256) - return slice + return slice } func ToBin(n uint64, length uint64) string { - var buf bytes.Buffer - for _, val := range ToBinarySlice(n, length) { - buf.WriteString(string(val)) - } + var buf bytes.Buffer + for _, val := range ToBinarySlice(n, length) { + buf.WriteString(string(val)) + } - return buf.String() + return buf.String() } func FromBin(data []byte) uint64 { - if len(data) == 0 { return 0 } + if len(data) == 0 { + return 0 + } - return FromBin(data[:len(data)-1]) * 256 + uint64(data[len(data)-1]) + return FromBin(data[:len(data)-1])*256 + uint64(data[len(data)-1]) } func Decode(data []byte, pos int) (interface{}, int) { - if pos > len(data)-1 { - panic(fmt.Sprintf("index out of range %d for data %q, l = %d", pos, data, len(data))) - } + if pos > len(data)-1 { + panic(fmt.Sprintf("index out of range %d for data %q, l = %d", pos, data, len(data))) + } - char := int(data[pos]) - slice := make([]interface{}, 0) - switch { - case char < 24: - return data[pos], pos + 1 + char := int(data[pos]) + slice := make([]interface{}, 0) + switch { + case char < 24: + return data[pos], pos + 1 - case char < 56: - b := int(data[pos]) - 23 - return FromBin(data[pos+1 : pos+1+b]), pos + 1 + b + case char < 56: + b := int(data[pos]) - 23 + return FromBin(data[pos+1 : pos+1+b]), pos + 1 + b - case char < 64: - b := int(data[pos]) - 55 - b2 := int(FromBin(data[pos+1 : pos+1+b])) - return FromBin(data[pos+1+b : pos+1+b+b2]), pos+1+b+b2 + case char < 64: + b := int(data[pos]) - 55 + b2 := int(FromBin(data[pos+1 : pos+1+b])) + return FromBin(data[pos+1+b : pos+1+b+b2]), pos + 1 + b + b2 - case char < 120: - b := int(data[pos]) - 64 - return data[pos+1:pos+1+b], pos+1+b + case char < 120: + b := int(data[pos]) - 64 + return data[pos+1 : pos+1+b], pos + 1 + b - case char < 128: - b := int(data[pos]) - 119 - b2 := int(FromBin(data[pos+1 : pos+1+b])) - return data[pos+1+b : pos+1+b+b2], pos+1+b+b2 + case char < 128: + b := int(data[pos]) - 119 + b2 := int(FromBin(data[pos+1 : pos+1+b])) + return data[pos+1+b : pos+1+b+b2], pos + 1 + b + b2 - case char < 184: - b := int(data[pos]) - 128 - pos++ - for i := 0; i < b; i++ { - var obj interface{} + case char < 184: + b := int(data[pos]) - 128 + pos++ + for i := 0; i < b; i++ { + var obj interface{} - obj, pos = Decode(data, pos) - slice = append(slice, obj) - } - return slice, pos + obj, pos = Decode(data, pos) + slice = append(slice, obj) + } + return slice, pos - case char < 192: - b := int(data[pos]) - 183 - //b2 := int(FromBin(data[pos+1 : pos+1+b])) (ref implementation has an unused variable) - pos = pos+1+b - for i := 0; i < b; i++ { - var obj interface{} + case char < 192: + b := int(data[pos]) - 183 + //b2 := int(FromBin(data[pos+1 : pos+1+b])) (ref implementation has an unused variable) + pos = pos + 1 + b + for i := 0; i < b; i++ { + var obj interface{} - obj, pos = Decode(data, pos) - slice = append(slice, obj) - } - return slice, pos + obj, pos = Decode(data, pos) + slice = append(slice, obj) + } + return slice, pos - default: - panic(fmt.Sprintf("byte not supported: %q", char)) - } + default: + panic(fmt.Sprintf("byte not supported: %q", char)) + } - return slice, 0 + return slice, 0 } func Encode(object interface{}) []byte { - var buff bytes.Buffer + var buff bytes.Buffer - switch t := object.(type) { - case uint32, uint64: - var num uint64 - if _num, ok := t.(uint64); ok { - num = _num - } else if _num, ok := t.(uint32); ok { - num = uint64(_num) - } + switch t := object.(type) { + case uint32, uint64: + var num uint64 + if _num, ok := t.(uint64); ok { + num = _num + } else if _num, ok := t.(uint32); ok { + num = uint64(_num) + } - if num >= 0 && num < 24 { - buff.WriteString(string(num)) - } else if num <= uint64(math.Pow(2, 256)) { - b := ToBin(num, 0) - buff.WriteString(string(len(b) + 23) + b) - } else { - b := ToBin(num, 0) - b2 := ToBin(uint64(len(b)), 0) - buff.WriteString(string(len(b2) + 55) + b2 + b) - } + if num >= 0 && num < 24 { + buff.WriteString(string(num)) + } else if num <= uint64(math.Pow(2, 256)) { + b := ToBin(num, 0) + buff.WriteString(string(len(b)+23) + b) + } else { + b := ToBin(num, 0) + b2 := ToBin(uint64(len(b)), 0) + buff.WriteString(string(len(b2)+55) + b2 + b) + } - case *big.Int: - buff.Write(Encode(t.String())) + case *big.Int: + buff.Write(Encode(t.String())) - case string: - if len(t) < 56 { - buff.WriteString(string(len(t) + 64) + t) - } else { - b2 := ToBin(uint64(len(t)), 0) - buff.WriteString(string(len(b2) + 119) + b2 + t) - } + case string: + if len(t) < 56 { + buff.WriteString(string(len(t)+64) + t) + } else { + b2 := ToBin(uint64(len(t)), 0) + buff.WriteString(string(len(b2)+119) + b2 + t) + } - case []byte: - // Cast the byte slice to a string - buff.Write(Encode(string(t))) + case []byte: + // Cast the byte slice to a string + buff.Write(Encode(string(t))) - case []interface{}, []string: - // Inline function for writing the slice header - WriteSliceHeader := func(length int) { - if length < 56 { - buff.WriteByte(byte(length + 128)) - } else { - b2 := ToBin(uint64(length), 0) - buff.WriteByte(byte(len(b2) + 183)) - buff.WriteString(b2) - } - } + case []interface{}, []string: + // Inline function for writing the slice header + WriteSliceHeader := func(length int) { + if length < 56 { + buff.WriteByte(byte(length + 128)) + } else { + b2 := ToBin(uint64(length), 0) + buff.WriteByte(byte(len(b2) + 183)) + buff.WriteString(b2) + } + } - // FIXME How can I do this "better"? - if interSlice, ok := t.([]interface{}); ok { - WriteSliceHeader(len(interSlice)) - for _, val := range interSlice { - buff.Write(Encode(val)) - } - } else if stringSlice, ok := t.([]string); ok { - WriteSliceHeader(len(stringSlice)) - for _, val := range stringSlice { - buff.Write(Encode(val)) - } - } - } + // FIXME How can I do this "better"? + if interSlice, ok := t.([]interface{}); ok { + WriteSliceHeader(len(interSlice)) + for _, val := range interSlice { + buff.Write(Encode(val)) + } + } else if stringSlice, ok := t.([]string); ok { + WriteSliceHeader(len(stringSlice)) + for _, val := range stringSlice { + buff.Write(Encode(val)) + } + } + } - return buff.Bytes() + return buff.Bytes() } diff --git a/rlp_test.go b/rlp_test.go index 68676d030..65cf34b39 100644 --- a/rlp_test.go +++ b/rlp_test.go @@ -1,54 +1,54 @@ package main import ( - "testing" - "fmt" + "fmt" + "testing" ) func TestEncode(t *testing.T) { - strRes := "Cdog" + strRes := "Cdog" - bytes := Encode("dog") + bytes := Encode("dog") - str := string(bytes) - if str != strRes { - t.Error(fmt.Sprintf("Expected %q, got %q", strRes, str)) - } - //dec,_ := Decode(bytes, 0) + str := string(bytes) + if str != strRes { + t.Error(fmt.Sprintf("Expected %q, got %q", strRes, str)) + } + //dec,_ := Decode(bytes, 0) - sliceRes := "\x83CdogCgodCcat" - strs := []string{"dog", "god", "cat"} - bytes = Encode(strs) - slice := string(bytes) - if slice != sliceRes { - t.Error(fmt.Sprintf("Expected %q, got %q", sliceRes, slice)) - } + sliceRes := "\x83CdogCgodCcat" + strs := []string{"dog", "god", "cat"} + bytes = Encode(strs) + slice := string(bytes) + if slice != sliceRes { + t.Error(fmt.Sprintf("Expected %q, got %q", sliceRes, slice)) + } - //dec,_ = Decode(bytes, 0) + //dec,_ = Decode(bytes, 0) } func TestMultiEncode(t *testing.T) { - inter := []interface{}{ - []interface{}{ - "1","2","3", - }, - []string{ - "string", - "string2", - "\x86A0J1234567890A\x00B20A0\x82F395843F657986", - "\x86A0J1234567890A\x00B20A0\x8cF395843F657986I335612448F524099H16716881A0H13114947G2039362G1507139H16719697G1048387E65360", - }, - "test", - } + inter := []interface{}{ + []interface{}{ + "1", "2", "3", + }, + []string{ + "string", + "string2", + "\x86A0J1234567890A\x00B20A0\x82F395843F657986", + "\x86A0J1234567890A\x00B20A0\x8cF395843F657986I335612448F524099H16716881A0H13114947G2039362G1507139H16719697G1048387E65360", + }, + "test", + } - bytes := Encode(inter) + bytes := Encode(inter) - Decode(bytes, 0) + Decode(bytes, 0) } func BenchmarkEncodeDecode(b *testing.B) { - for i := 0; i < b.N; i++ { - bytes := Encode([]string{"dog", "god", "cat"}) - Decode(bytes, 0) - } + for i := 0; i < b.N; i++ { + bytes := Encode([]string{"dog", "god", "cat"}) + Decode(bytes, 0) + } } diff --git a/server.go b/server.go index d81fe1bce..5373e2418 100644 --- a/server.go +++ b/server.go @@ -1,121 +1,120 @@ package main import ( - "container/list" - "net" - "log" - _"time" - "github.com/ethereum/ethdb-go" - "github.com/ethereum/ethutil-go" + "container/list" + "github.com/ethereum/ethdb-go" + "github.com/ethereum/ethutil-go" + "log" + "net" + _ "time" ) type Server struct { - // Channel for shutting down the server - shutdownChan chan bool - // DB interface - db *ethdb.LDBDatabase - // Block manager for processing new blocks and managing the block chain - blockManager *BlockManager - // Peers (NYI) - peers *list.List + // Channel for shutting down the server + shutdownChan chan bool + // DB interface + db *ethdb.LDBDatabase + // Block manager for processing new blocks and managing the block chain + blockManager *BlockManager + // Peers (NYI) + peers *list.List } func NewServer() (*Server, error) { - db, err := ethdb.NewLDBDatabase() - if err != nil { - return nil, err - } + db, err := ethdb.NewLDBDatabase() + if err != nil { + return nil, err + } - ethutil.SetConfig(db) + ethutil.SetConfig(db) - server := &Server{ - shutdownChan: make(chan bool), - blockManager: NewBlockManager(), - db: db, - peers: list.New(), - } + server := &Server{ + shutdownChan: make(chan bool), + blockManager: NewBlockManager(), + db: db, + peers: list.New(), + } - return server, nil + return server, nil } func (s *Server) AddPeer(conn net.Conn) { - peer := NewPeer(conn, s) - s.peers.PushBack(peer) - peer.Start() + peer := NewPeer(conn, s) + s.peers.PushBack(peer) + peer.Start() - log.Println("Peer connected ::", conn.RemoteAddr()) + log.Println("Peer connected ::", conn.RemoteAddr()) } func (s *Server) ConnectToPeer(addr string) error { - conn, err := net.Dial("tcp", addr) + conn, err := net.Dial("tcp", addr) - if err != nil { - return err - } + if err != nil { + return err + } - peer := NewPeer(conn, s) - s.peers.PushBack(peer) - peer.Start() + peer := NewPeer(conn, s) + s.peers.PushBack(peer) + peer.Start() + log.Println("Connected to peer ::", conn.RemoteAddr()) - log.Println("Connected to peer ::", conn.RemoteAddr()) - - return nil + return nil } func (s *Server) Broadcast(msgType string, data []byte) { - for e := s.peers.Front(); e != nil; e = e.Next() { - if peer, ok := e.Value.(*Peer); ok { - peer.QueueMessage(msgType, data) - } - } + for e := s.peers.Front(); e != nil; e = e.Next() { + if peer, ok := e.Value.(*Peer); ok { + peer.QueueMessage(msgType, data) + } + } } // Start the server func (s *Server) Start() { - // For now this function just blocks the main thread - ln, err := net.Listen("tcp", ":12345") - if err != nil { - log.Fatal(err) - } + // For now this function just blocks the main thread + ln, err := net.Listen("tcp", ":12345") + if err != nil { + log.Fatal(err) + } - go func() { - for { - conn, err := ln.Accept() - if err != nil { - log.Println(err) - continue - } + go func() { + for { + conn, err := ln.Accept() + if err != nil { + log.Println(err) + continue + } - go s.AddPeer(conn) - } - }() + go s.AddPeer(conn) + } + }() - // TMP - //go func() { - // for { - // s.Broadcast("block", Encode("blockdata")) -// -// time.Sleep(100 * time.Millisecond) -// } -// }() + // TMP + //go func() { + // for { + // s.Broadcast("block", Encode("blockdata")) + // + // time.Sleep(100 * time.Millisecond) + // } + // }() } func (s *Server) Stop() { - // Close the database - defer s.db.Close() + // Close the database + defer s.db.Close() - // Loop thru the peers and close them (if we had them) - for e := s.peers.Front(); e != nil; e = e.Next() { - if peer, ok := e.Value.(*Peer); ok { - peer.Stop() - } - } + // Loop thru the peers and close them (if we had them) + for e := s.peers.Front(); e != nil; e = e.Next() { + if peer, ok := e.Value.(*Peer); ok { + peer.Stop() + } + } - s.shutdownChan <- true + s.shutdownChan <- true } // This function will wait for a shutdown and resumes main thread execution func (s *Server) WaitForShutdown() { - <- s.shutdownChan + <-s.shutdownChan } diff --git a/test_runner.go b/test_runner.go index da93533dd..e8a1698ce 100644 --- a/test_runner.go +++ b/test_runner.go @@ -1,35 +1,35 @@ package main import ( - "fmt" - "testing" - "encoding/json" + "encoding/json" + "fmt" + "testing" ) type TestSource struct { - Inputs map[string]string - Expectation string + Inputs map[string]string + Expectation string } func NewTestSource(source string) *TestSource { - s := &TestSource{} - err := json.Unmarshal([]byte(source), s) - if err != nil { - fmt.Println(err) - } + s := &TestSource{} + err := json.Unmarshal([]byte(source), s) + if err != nil { + fmt.Println(err) + } - return s + return s } type TestRunner struct { - source *TestSource + source *TestSource } func NewTestRunner(t *testing.T) *TestRunner { - return &TestRunner{} + return &TestRunner{} } func (runner *TestRunner) RunFromString(input string, Cb func(*TestSource)) { - source := NewTestSource(input) - Cb(source) + source := NewTestSource(input) + Cb(source) } diff --git a/test_runner_test.go b/test_runner_test.go index 190bf3caf..5abe20002 100644 --- a/test_runner_test.go +++ b/test_runner_test.go @@ -1,9 +1,9 @@ package main import ( - _"fmt" - "testing" - "encoding/hex" + "encoding/hex" + _ "fmt" + "testing" ) var testsource = `{"Inputs":{ @@ -15,17 +15,17 @@ var testsource = `{"Inputs":{ }` func TestTestRunner(t *testing.T) { - db, _ := NewMemDatabase() - trie := NewTrie(db, "") + db, _ := NewMemDatabase() + trie := NewTrie(db, "") - runner := NewTestRunner(t) - runner.RunFromString(testsource, func(source *TestSource) { - for key, value := range source.Inputs { - trie.Update(key, value) - } + runner := NewTestRunner(t) + runner.RunFromString(testsource, func(source *TestSource) { + for key, value := range source.Inputs { + trie.Update(key, value) + } - if hex.EncodeToString([]byte(trie.root)) != source.Expectation { - t.Error("trie root did not match") - } - }) + if hex.EncodeToString([]byte(trie.root)) != source.Expectation { + t.Error("trie root did not match") + } + }) } diff --git a/testing.go b/testing.go index 9b7b7b3ce..5e2aec02b 100644 --- a/testing.go +++ b/testing.go @@ -1,4 +1,5 @@ package main + /* import ( diff --git a/vm.go b/vm.go index 5605cb7c7..96a3dfa05 100644 --- a/vm.go +++ b/vm.go @@ -1,267 +1,284 @@ package main import ( - "math/big" - "fmt" - "strconv" - "github.com/ethereum/ethutil-go" + "fmt" + "github.com/ethereum/ethutil-go" + "math/big" + "strconv" ) // Op codes const ( - oSTOP int = 0x00 - oADD int = 0x01 - oMUL int = 0x02 - oSUB int = 0x03 - oDIV int = 0x04 - oSDIV int = 0x05 - oMOD int = 0x06 - oSMOD int = 0x07 - oEXP int = 0x08 - oNEG int = 0x09 - oLT int = 0x0a - oLE int = 0x0b - oGT int = 0x0c - oGE int = 0x0d - oEQ int = 0x0e - oNOT int = 0x0f - oMYADDRESS int = 0x10 - oTXSENDER int = 0x11 - oTXVALUE int = 0x12 - oTXFEE int = 0x13 - oTXDATAN int = 0x14 - oTXDATA int = 0x15 - oBLK_PREVHASH int = 0x16 - oBLK_COINBASE int = 0x17 - oBLK_TIMESTAMP int = 0x18 - oBLK_NUMBER int = 0x19 - oBLK_DIFFICULTY int = 0x1a - oSHA256 int = 0x20 - oRIPEMD160 int = 0x21 - oECMUL int = 0x22 - oECADD int = 0x23 - oECSIGN int = 0x24 - oECRECOVER int = 0x25 - oECVALID int = 0x26 - oPUSH int = 0x30 - oPOP int = 0x31 - oDUP int = 0x32 - oDUPN int = 0x33 - oSWAP int = 0x34 - oSWAPN int = 0x35 - oLOAD int = 0x36 - oSTORE int = 0x37 - oJMP int = 0x40 - oJMPI int = 0x41 - oIND int = 0x42 - oEXTRO int = 0x50 - oBALANCE int = 0x51 - oMKTX int = 0x60 - oSUICIDE int = 0xff + oSTOP int = 0x00 + oADD int = 0x01 + oMUL int = 0x02 + oSUB int = 0x03 + oDIV int = 0x04 + oSDIV int = 0x05 + oMOD int = 0x06 + oSMOD int = 0x07 + oEXP int = 0x08 + oNEG int = 0x09 + oLT int = 0x0a + oLE int = 0x0b + oGT int = 0x0c + oGE int = 0x0d + oEQ int = 0x0e + oNOT int = 0x0f + oMYADDRESS int = 0x10 + oTXSENDER int = 0x11 + oTXVALUE int = 0x12 + oTXFEE int = 0x13 + oTXDATAN int = 0x14 + oTXDATA int = 0x15 + oBLK_PREVHASH int = 0x16 + oBLK_COINBASE int = 0x17 + oBLK_TIMESTAMP int = 0x18 + oBLK_NUMBER int = 0x19 + oBLK_DIFFICULTY int = 0x1a + oSHA256 int = 0x20 + oRIPEMD160 int = 0x21 + oECMUL int = 0x22 + oECADD int = 0x23 + oECSIGN int = 0x24 + oECRECOVER int = 0x25 + oECVALID int = 0x26 + oPUSH int = 0x30 + oPOP int = 0x31 + oDUP int = 0x32 + oDUPN int = 0x33 + oSWAP int = 0x34 + oSWAPN int = 0x35 + oLOAD int = 0x36 + oSTORE int = 0x37 + oJMP int = 0x40 + oJMPI int = 0x41 + oIND int = 0x42 + oEXTRO int = 0x50 + oBALANCE int = 0x51 + oMKTX int = 0x60 + oSUICIDE int = 0xff ) type OpType int + const ( - tNorm = iota - tData - tExtro - tCrypto + tNorm = iota + tData + tExtro + tCrypto ) + type TxCallback func(opType OpType) bool // Simple push/pop stack mechanism type Stack struct { - data []string + data []string } + func NewStack() *Stack { - return &Stack{} + return &Stack{} } func (st *Stack) Pop() string { - s := len(st.data) + s := len(st.data) - str := st.data[s-1] - st.data = st.data[:s-1] + str := st.data[s-1] + st.data = st.data[:s-1] - return str + return str } func (st *Stack) Popn() (*big.Int, *big.Int) { - s := len(st.data) + s := len(st.data) - strs := st.data[s-2:] - st.data = st.data[:s-2] + strs := st.data[s-2:] + st.data = st.data[:s-2] - return ethutil.Big(strs[0]), ethutil.Big(strs[1]) + return ethutil.Big(strs[0]), ethutil.Big(strs[1]) } func (st *Stack) Push(d string) { - st.data = append(st.data, d) + st.data = append(st.data, d) } func (st *Stack) Print() { - fmt.Println(st.data) + fmt.Println(st.data) } type Vm struct { - // Stack - stack *Stack + // Stack + stack *Stack } func NewVm() *Vm { - return &Vm{ - stack: NewStack(), - } + return &Vm{ + stack: NewStack(), + } } -func (vm *Vm) ProcContract( tx *ethutil.Transaction, - block *ethutil.Block, cb TxCallback) { - // Instruction pointer - pc := 0 +func (vm *Vm) ProcContract(tx *ethutil.Transaction, + block *ethutil.Block, cb TxCallback) { + // Instruction pointer + pc := 0 - contract := block.GetContract(tx.Hash()) - if contract == nil { - fmt.Println("Contract not found") - return - } + contract := block.GetContract(tx.Hash()) + if contract == nil { + fmt.Println("Contract not found") + return + } - Pow256 := ethutil.BigPow(2, 256) + Pow256 := ethutil.BigPow(2, 256) - //fmt.Printf("# op arg\n") + //fmt.Printf("# op arg\n") out: - for { - // The base big int for all calculations. Use this for any results. - base := new(big.Int) - // XXX Should Instr return big int slice instead of string slice? - // Get the next instruction from the contract - //op, _, _ := Instr(contract.state.Get(string(Encode(uint32(pc))))) - nb := ethutil.NumberToBytes(uint64(pc), 32) - op, _, _ := ethutil.Instr(contract.State().Get(string(nb))) + for { + // The base big int for all calculations. Use this for any results. + base := new(big.Int) + // XXX Should Instr return big int slice instead of string slice? + // Get the next instruction from the contract + //op, _, _ := Instr(contract.state.Get(string(Encode(uint32(pc))))) + nb := ethutil.NumberToBytes(uint64(pc), 32) + op, _, _ := ethutil.Instr(contract.State().Get(string(nb))) - if !cb(0) { break } + if !cb(0) { + break + } - if Debug { - //fmt.Printf("%-3d %-4d\n", pc, op) - } + if Debug { + //fmt.Printf("%-3d %-4d\n", pc, op) + } - switch op { - case oADD: - x, y := vm.stack.Popn() - // (x + y) % 2 ** 256 - base.Add(x, y) - base.Mod(base, Pow256) - // Pop result back on the stack - vm.stack.Push(base.String()) - case oSUB: - x, y := vm.stack.Popn() - // (x - y) % 2 ** 256 - base.Sub(x, y) - base.Mod(base, Pow256) - // Pop result back on the stack - vm.stack.Push(base.String()) - case oMUL: - x, y := vm.stack.Popn() - // (x * y) % 2 ** 256 - base.Mul(x, y) - base.Mod(base, Pow256) - // Pop result back on the stack - vm.stack.Push(base.String()) - case oDIV: - x, y := vm.stack.Popn() - // floor(x / y) - base.Div(x, y) - // Pop result back on the stack - vm.stack.Push(base.String()) - case oSDIV: - x, y := vm.stack.Popn() - // n > 2**255 - if x.Cmp(Pow256) > 0 { x.Sub(Pow256, x) } - if y.Cmp(Pow256) > 0 { y.Sub(Pow256, y) } - z := new(big.Int) - z.Div(x, y) - if z.Cmp(Pow256) > 0 { z.Sub(Pow256, z) } - // Push result on to the stack - vm.stack.Push(z.String()) - case oMOD: - x, y := vm.stack.Popn() - base.Mod(x, y) - vm.stack.Push(base.String()) - case oSMOD: - x, y := vm.stack.Popn() - // n > 2**255 - if x.Cmp(Pow256) > 0 { x.Sub(Pow256, x) } - if y.Cmp(Pow256) > 0 { y.Sub(Pow256, y) } - z := new(big.Int) - z.Mod(x, y) - if z.Cmp(Pow256) > 0 { z.Sub(Pow256, z) } - // Push result on to the stack - vm.stack.Push(z.String()) - case oEXP: - x, y := vm.stack.Popn() - base.Exp(x, y, Pow256) + switch op { + case oADD: + x, y := vm.stack.Popn() + // (x + y) % 2 ** 256 + base.Add(x, y) + base.Mod(base, Pow256) + // Pop result back on the stack + vm.stack.Push(base.String()) + case oSUB: + x, y := vm.stack.Popn() + // (x - y) % 2 ** 256 + base.Sub(x, y) + base.Mod(base, Pow256) + // Pop result back on the stack + vm.stack.Push(base.String()) + case oMUL: + x, y := vm.stack.Popn() + // (x * y) % 2 ** 256 + base.Mul(x, y) + base.Mod(base, Pow256) + // Pop result back on the stack + vm.stack.Push(base.String()) + case oDIV: + x, y := vm.stack.Popn() + // floor(x / y) + base.Div(x, y) + // Pop result back on the stack + vm.stack.Push(base.String()) + case oSDIV: + x, y := vm.stack.Popn() + // n > 2**255 + if x.Cmp(Pow256) > 0 { + x.Sub(Pow256, x) + } + if y.Cmp(Pow256) > 0 { + y.Sub(Pow256, y) + } + z := new(big.Int) + z.Div(x, y) + if z.Cmp(Pow256) > 0 { + z.Sub(Pow256, z) + } + // Push result on to the stack + vm.stack.Push(z.String()) + case oMOD: + x, y := vm.stack.Popn() + base.Mod(x, y) + vm.stack.Push(base.String()) + case oSMOD: + x, y := vm.stack.Popn() + // n > 2**255 + if x.Cmp(Pow256) > 0 { + x.Sub(Pow256, x) + } + if y.Cmp(Pow256) > 0 { + y.Sub(Pow256, y) + } + z := new(big.Int) + z.Mod(x, y) + if z.Cmp(Pow256) > 0 { + z.Sub(Pow256, z) + } + // Push result on to the stack + vm.stack.Push(z.String()) + case oEXP: + x, y := vm.stack.Popn() + base.Exp(x, y, Pow256) - vm.stack.Push(base.String()) - case oNEG: - base.Sub(Pow256, ethutil.Big(vm.stack.Pop())) - vm.stack.Push(base.String()) - case oLT: - x, y := vm.stack.Popn() - // x < y - if x.Cmp(y) < 0 { - vm.stack.Push("1") - } else { - vm.stack.Push("0") - } - case oLE: - x, y := vm.stack.Popn() - // x <= y - if x.Cmp(y) < 1 { - vm.stack.Push("1") - } else { - vm.stack.Push("0") - } - case oGT: - x, y := vm.stack.Popn() - // x > y - if x.Cmp(y) > 0 { - vm.stack.Push("1") - } else { - vm.stack.Push("0") - } - case oGE: - x, y := vm.stack.Popn() - // x >= y - if x.Cmp(y) > -1 { - vm.stack.Push("1") - } else { - vm.stack.Push("0") - } - case oNOT: - x, y := vm.stack.Popn() - // x != y - if x.Cmp(y) != 0 { - vm.stack.Push("1") - } else { - vm.stack.Push("0") - } - case oMYADDRESS: - vm.stack.Push(string(tx.Hash())) - case oTXSENDER: - vm.stack.Push(string(tx.Sender())) - case oPUSH: - // Get the next entry and pushes the value on the stack - pc++ - vm.stack.Push(contract.State().Get(string(ethutil.NumberToBytes(uint64(pc), 32)))) - case oPOP: - // Pop current value of the stack - vm.stack.Pop() - case oLOAD: - // Load instruction X on the stack - i, _ := strconv.Atoi(vm.stack.Pop()) - vm.stack.Push(contract.State().Get(string(ethutil.NumberToBytes(uint64(i), 32)))) - case oSTOP: - break out - } - pc++ - } + vm.stack.Push(base.String()) + case oNEG: + base.Sub(Pow256, ethutil.Big(vm.stack.Pop())) + vm.stack.Push(base.String()) + case oLT: + x, y := vm.stack.Popn() + // x < y + if x.Cmp(y) < 0 { + vm.stack.Push("1") + } else { + vm.stack.Push("0") + } + case oLE: + x, y := vm.stack.Popn() + // x <= y + if x.Cmp(y) < 1 { + vm.stack.Push("1") + } else { + vm.stack.Push("0") + } + case oGT: + x, y := vm.stack.Popn() + // x > y + if x.Cmp(y) > 0 { + vm.stack.Push("1") + } else { + vm.stack.Push("0") + } + case oGE: + x, y := vm.stack.Popn() + // x >= y + if x.Cmp(y) > -1 { + vm.stack.Push("1") + } else { + vm.stack.Push("0") + } + case oNOT: + x, y := vm.stack.Popn() + // x != y + if x.Cmp(y) != 0 { + vm.stack.Push("1") + } else { + vm.stack.Push("0") + } + case oMYADDRESS: + vm.stack.Push(string(tx.Hash())) + case oTXSENDER: + vm.stack.Push(string(tx.Sender())) + case oPUSH: + // Get the next entry and pushes the value on the stack + pc++ + vm.stack.Push(contract.State().Get(string(ethutil.NumberToBytes(uint64(pc), 32)))) + case oPOP: + // Pop current value of the stack + vm.stack.Pop() + case oLOAD: + // Load instruction X on the stack + i, _ := strconv.Atoi(vm.stack.Pop()) + vm.stack.Push(contract.State().Get(string(ethutil.NumberToBytes(uint64(i), 32)))) + case oSTOP: + break out + } + pc++ + } - vm.stack.Print() + vm.stack.Print() } From d6f7372a3c5b002c6e385b5916bd5f81463c37df Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 11 Jan 2014 15:41:05 +0100 Subject: [PATCH 085/459] Coding style --- README.md | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 37e8505f1..a9bb8b260 100644 --- a/README.md +++ b/README.md @@ -25,4 +25,27 @@ Command line options Contribution ============ -See CONTRIB.md +If you'd like to contribute to Ethereum Go please fork, fix, commit and +send a pull request. Commits who do not comply with the coding standards +are ignored. + +Coding standards +================ + +Sources should be formatted according to the [Go Formatting +Style](http://golang.org/doc/effective_go.html#formatting). + +Unless structs fields are supposed to be directly accesible, provide +Getters and hide the fields through Go's exporting facility. + +Don't "overcomment", meaning that your and my mom doesn't have to read +the source code. + +*wrong* + +```go +// Check if the value at x is greater than y +if x > y { + // It's greater! +} +``` From 66dd8b6fbaa675cbac8dc0bf4085d5a708a612d7 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 11 Jan 2014 15:53:27 +0100 Subject: [PATCH 086/459] sub packages --- README.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a9bb8b260..a7d2a0e66 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,14 @@ Ethereum [![Build Status](https://travis-ci.org/ethereum/go-ethereum.png?branch=master)](https://travis-ci.org/ethereum/go-ethereum) -Ethereum Go +Ethereum Go (c) 0255c78815d4f056f84c96de438ed9e38c69c0f8af24f5032248be5a79fe9071c3 + + +Ethereum Go is split up in several sub packages. Please refer to each +individual package for more information. + 1. [ethutil](https://github.com/ethereum/ethutil-go) + 2. [ethdb](https://github.com/ethereum/ethdb-go) + 3. [ethwire](https://github.com/ethereum/ethwire-go) Deps ==== @@ -13,7 +20,7 @@ Ethereum Go makes use of a modified `secp256k1-go` and therefor GMP. Install ======= -```go get https://github.com/ethereum/go-ethereum``` +```go get -u -t https://github.com/ethereum/go-ethereum``` Command line options @@ -49,3 +56,8 @@ if x > y { // It's greater! } ``` + +Copy +==== + +69bce990a619e747b4f57483724b0e8a1732bb3b44ccf70b0dd6abd272af94550fc9d8b21232d33ebf30d38a148612f68e936094b4daeb9ea7174088a439070401 0255c78815d4f056f84c96de438ed9e38c69c0f8af24f5032248be5a79fe9071c3 From e058f3bc0a9a184f3a145d88646063cfaf8071e6 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 11 Jan 2014 15:55:12 +0100 Subject: [PATCH 087/459] sub packages --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a7d2a0e66..23fdda2e5 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Ethereum [![Build Status](https://travis-ci.org/ethereum/go-ethereum.png?branch=master)](https://travis-ci.org/ethereum/go-ethereum) -Ethereum Go (c) 0255c78815d4f056f84c96de438ed9e38c69c0f8af24f5032248be5a79fe9071c3 +Ethereum Go (c) [0255c7881](https://github.com/ethereum/go-ethereum#copy) Ethereum Go is split up in several sub packages. Please refer to each @@ -57,7 +57,6 @@ if x > y { } ``` -Copy -==== +### Copy 69bce990a619e747b4f57483724b0e8a1732bb3b44ccf70b0dd6abd272af94550fc9d8b21232d33ebf30d38a148612f68e936094b4daeb9ea7174088a439070401 0255c78815d4f056f84c96de438ed9e38c69c0f8af24f5032248be5a79fe9071c3 From dfb8e65ca74e566345ca40d63b1f359d922f0b9e Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 12 Jan 2014 01:51:07 +0100 Subject: [PATCH 088/459] RLP changes --- rlp.go | 1 + 1 file changed, 1 insertion(+) diff --git a/rlp.go b/rlp.go index 91ec50164..f5e630398 100644 --- a/rlp.go +++ b/rlp.go @@ -40,6 +40,7 @@ func (attr *RlpDataAttribute) Length() int { return 0 } + func (attr *RlpDataAttribute) AsUint() uint64 { if value, ok := attr.dataAttrib.(uint8); ok { return uint64(value) From bee05d52bfb9f555b7f9c7b625524594bff97826 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 12 Jan 2014 01:51:52 +0100 Subject: [PATCH 089/459] Block verification, TD calculations and overall block processing --- block_manager.go | 105 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 99 insertions(+), 6 deletions(-) diff --git a/block_manager.go b/block_manager.go index 968d9a139..04d45f434 100644 --- a/block_manager.go +++ b/block_manager.go @@ -3,40 +3,63 @@ package main import ( "fmt" "github.com/ethereum/ethutil-go" + "errors" + "log" + "math/big" ) type BlockChain struct { - lastBlock *ethutil.Block + LastBlock *ethutil.Block genesisBlock *ethutil.Block + + TD *big.Int } func NewBlockChain() *BlockChain { bc := &BlockChain{} bc.genesisBlock = ethutil.NewBlock(ethutil.Encode(ethutil.Genesis)) + // Set the last know difficulty (might be 0x0 as initial value, Genesis) + bc.TD = new(big.Int) + bc.TD.SetBytes(ethutil.Config.Db.LastKnownTD()) + return bc } -type BlockManager struct { - vm *Vm +func (bc *BlockChain) HasBlock(hash string) bool { + return bc.LastBlock.State().Get(hash) != "" +} - blockChain *BlockChain +type BlockManager struct { + // Ethereum virtual machine for processing contracts + vm *Vm + // The block chain :) + bc *BlockChain } func NewBlockManager() *BlockManager { - bm := &BlockManager{vm: NewVm()} + bm := &BlockManager{ + vm: NewVm(), + bc: NewBlockChain(), + } return bm } // Process a block. func (bm *BlockManager) ProcessBlock(block *ethutil.Block) error { - // TODO Validation (Or move to other part of the application) + // Block validation if err := bm.ValidateBlock(block); err != nil { return err } + // I'm not sure, but I don't know if there should be thrown + // any errors at this time. + if err := bm.AccumelateRewards(block); err != nil { + return err + } + // Get the tx count. Used to create enough channels to 'join' the go routines txCount := len(block.Transactions()) // Locking channel. When it has been fully buffered this method will return @@ -58,10 +81,80 @@ func (bm *BlockManager) ProcessBlock(block *ethutil.Block) error { <-lockChan } + if bm.CalculateTD(block) { + ethutil.Config.Db.Put(block.Hash(), block.MarshalRlp()) + bm.bc.LastBlock = block + } + return nil } +func (bm *BlockManager) CalculateTD(block *ethutil.Block) bool { + uncleDiff := new(big.Int) + for _, uncle := range block.Uncles { + uncleDiff = uncleDiff.Add(uncleDiff, uncle.Difficulty) + } + + // TD(genesis_block) = 0 and TD(B) = TD(B.parent) + sum(u.difficulty for u in B.uncles) + B.difficulty + td := new(big.Int) + td = td.Add(bm.bc.TD, uncleDiff) + td = td.Add(td, block.Difficulty) + + // The new TD will only be accepted if the new difficulty is + // is greater than the previous. + if td.Cmp(bm.bc.TD) > 0 { + bm.bc.LastBlock = block + // Set the new total difficulty back to the block chain + bm.bc.TD = td + + return true + } + + return false +} + +// Validates the current block. Returns an error if the block was invalid, +// an uncle or anything that isn't on the current block chain func (bm *BlockManager) ValidateBlock(block *ethutil.Block) error { + // TODO + // 1. Check if the nonce of the block is valid + // 2. Check if the difficulty is correct + + // Check if we have the parent hash, if it isn't known we discard it + // Reasons might be catching up or simply an invalid block + if bm.bc.HasBlock(block.PrevHash) { + // Check each uncle's previous hash. In order for it to be valid + // is if it has the same block hash as the current + for _, uncle := range block.Uncles { + if uncle.PrevHash != block.PrevHash { + if Debug { + log.Printf("Uncle prvhash mismatch %x %x\n", block.PrevHash, uncle.PrevHash) + } + + return errors.New("Mismatching Prvhash from uncle") + } + } + } else { + return errors.New("Block's parent unknown") + } + + + return nil +} + +func (bm *BlockManager) AccumelateRewards(block *ethutil.Block) error { + // Get the coinbase rlp data + d := block.State().Get(block.Coinbase) + + ether := ethutil.NewEtherFromData([]byte(d)) + + // Reward amount of ether to the coinbase address + ether.AddFee(ethutil.CalculateBlockReward(block, len(block.Uncles))) + block.State().Update(block.Coinbase, string(ether.MarshalRlp())) + + // TODO Reward each uncle + + return nil } From 54bce64e3a8e50b6553364f2f01b38382ffbc4df Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 12 Jan 2014 02:36:41 +0100 Subject: [PATCH 090/459] Validations reordering & added nonce validation --- block_manager.go | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/block_manager.go b/block_manager.go index 04d45f434..21162f36b 100644 --- a/block_manager.go +++ b/block_manager.go @@ -114,30 +114,34 @@ func (bm *BlockManager) CalculateTD(block *ethutil.Block) bool { } // Validates the current block. Returns an error if the block was invalid, -// an uncle or anything that isn't on the current block chain +// an uncle or anything that isn't on the current block chain. +// Validation validates easy over difficult (dagger takes longer time = difficult) func (bm *BlockManager) ValidateBlock(block *ethutil.Block) error { // TODO - // 1. Check if the nonce of the block is valid // 2. Check if the difficulty is correct // Check if we have the parent hash, if it isn't known we discard it // Reasons might be catching up or simply an invalid block - if bm.bc.HasBlock(block.PrevHash) { - // Check each uncle's previous hash. In order for it to be valid - // is if it has the same block hash as the current - for _, uncle := range block.Uncles { - if uncle.PrevHash != block.PrevHash { - if Debug { - log.Printf("Uncle prvhash mismatch %x %x\n", block.PrevHash, uncle.PrevHash) - } - - return errors.New("Mismatching Prvhash from uncle") - } - } - } else { + if !bm.bc.HasBlock(block.PrevHash) { return errors.New("Block's parent unknown") } + // Check each uncle's previous hash. In order for it to be valid + // is if it has the same block hash as the current + for _, uncle := range block.Uncles { + if uncle.PrevHash != block.PrevHash { + if Debug { + log.Printf("Uncle prvhash mismatch %x %x\n", block.PrevHash, uncle.PrevHash) + } + + return errors.New("Mismatching Prvhash from uncle") + } + } + + // Verify the nonce of the block. Return an error if it's not valid + if !DaggerVerify(block.Hash(), block.Nonce) { + return errors.New("Block's nonce is invalid") + } return nil } From 406adb4563d4664e4ce63a7786ea57f797c42e47 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 12 Jan 2014 02:39:17 +0100 Subject: [PATCH 091/459] Fixed dagger verification --- block_manager.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block_manager.go b/block_manager.go index 21162f36b..1a73a45f2 100644 --- a/block_manager.go +++ b/block_manager.go @@ -139,7 +139,7 @@ func (bm *BlockManager) ValidateBlock(block *ethutil.Block) error { } // Verify the nonce of the block. Return an error if it's not valid - if !DaggerVerify(block.Hash(), block.Nonce) { + if !DaggerVerify(ethutil.BigD(block.Hash()), block.Difficulty, block.Nonce) { return errors.New("Block's nonce is invalid") } From c3fabfe00a81b548dceb8ecf1281087e51c5fddf Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 12 Jan 2014 16:50:09 +0100 Subject: [PATCH 092/459] Fixed validation --- block_manager.go | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/block_manager.go b/block_manager.go index 1a73a45f2..0c7410022 100644 --- a/block_manager.go +++ b/block_manager.go @@ -24,11 +24,20 @@ func NewBlockChain() *BlockChain { bc.TD = new(big.Int) bc.TD.SetBytes(ethutil.Config.Db.LastKnownTD()) + + // TODO get last block from the database + //bc.LastBlock = bc.genesisBlock + return bc } func (bc *BlockChain) HasBlock(hash string) bool { - return bc.LastBlock.State().Get(hash) != "" + data, _ := ethutil.Config.Db.Get([]byte(hash)) + return len(data) != 0 +} + +func (bc *BlockChain) GenesisBlock() *ethutil.Block { + return bc.genesisBlock } type BlockManager struct { @@ -107,6 +116,10 @@ func (bm *BlockManager) CalculateTD(block *ethutil.Block) bool { // Set the new total difficulty back to the block chain bm.bc.TD = td + if Debug { + log.Println("TD(block) =", td) + } + return true } @@ -122,7 +135,8 @@ func (bm *BlockManager) ValidateBlock(block *ethutil.Block) error { // Check if we have the parent hash, if it isn't known we discard it // Reasons might be catching up or simply an invalid block - if !bm.bc.HasBlock(block.PrevHash) { + if bm.bc.LastBlock != nil && block.PrevHash == "" && + !bm.bc.HasBlock(block.PrevHash) { return errors.New("Block's parent unknown") } @@ -139,10 +153,13 @@ func (bm *BlockManager) ValidateBlock(block *ethutil.Block) error { } // Verify the nonce of the block. Return an error if it's not valid - if !DaggerVerify(ethutil.BigD(block.Hash()), block.Difficulty, block.Nonce) { + if bm.bc.LastBlock != nil && block.PrevHash == "" && + !DaggerVerify(ethutil.BigD(block.Hash()), block.Difficulty, block.Nonce) { return errors.New("Block's nonce is invalid") } + log.Println("Block validation PASSED") + return nil } From 12c0e827032f2c8de12bac0738116a51b3816cdb Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 12 Jan 2014 16:50:33 +0100 Subject: [PATCH 093/459] Verion acknowledgement --- peer.go | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 65 insertions(+), 9 deletions(-) diff --git a/peer.go b/peer.go index a9f88b1e1..2dda1f94f 100644 --- a/peer.go +++ b/peer.go @@ -2,6 +2,7 @@ package main import ( "github.com/ethereum/ethwire-go" + "github.com/ethereum/ethutil-go" "log" "net" ) @@ -12,24 +13,26 @@ type Peer struct { // Net connection conn net.Conn // Output queue which is used to communicate and handle messages - outputQueue chan ethwire.InOutMsg + outputQueue chan *ethwire.InOutMsg // Quit channel quit chan bool + + inbound bool // Determines whether it's an inbound or outbound peer } -func NewPeer(conn net.Conn, server *Server) *Peer { +func NewPeer(conn net.Conn, server *Server, inbound bool) *Peer { return &Peer{ - outputQueue: make(chan ethwire.InOutMsg, 1), // Buffered chan of 1 is enough + outputQueue: make(chan *ethwire.InOutMsg, 1), // Buffered chan of 1 is enough quit: make(chan bool), - server: server, conn: conn, + inbound: inbound, } } // Outputs any RLP encoded data to the peer -func (p *Peer) QueueMessage(msgType string, data []byte) { - p.outputQueue <- ethwire.InOutMsg{MsgType: msgType, Data: data} +func (p *Peer) QueueMessage(msg *ethwire.InOutMsg) { + p.outputQueue <- msg//ethwire.InOutMsg{MsgType: msgType, Nonce: ethutil.RandomUint64(), Data: data} } // Outbound message handler. Outbound messages are handled here @@ -69,9 +72,22 @@ out: break out } - // TODO - data, _ := Decode(msg.Data, 0) - log.Printf("%s, %s\n", msg.MsgType, data) + if Debug { + log.Printf("Received %s\n", msg.MsgType) + } + + // TODO Hash data and check if for existence (= ignore) + + switch msg.MsgType { + case "verack": + // Version message + p.handleVersionAck(msg) + case "block": + err := p.server.blockManager.ProcessBlock(ethutil.NewBlock(msg.Data)) + if err != nil { + log.Println(err) + } + } } // Notify the out handler we're quiting @@ -79,6 +95,15 @@ out: } func (p *Peer) Start() { + if !p.inbound { + err := p.pushVersionAck() + if err != nil { + log.Printf("Peer can't send outbound version ack", err) + + p.Stop() + } + } + // Run the outbound handler in a new goroutine go p.HandleOutbound() // Run the inbound handler in a new goroutine @@ -90,3 +115,34 @@ func (p *Peer) Stop() { p.quit <- true } + +func (p *Peer) pushVersionAck() error { + msg := ethwire.NewMessage("verack", p.server.Nonce, []byte("01")) + + p.QueueMessage(msg) + + return nil +} + +func (p *Peer) handleVersionAck(msg *ethwire.InOutMsg) { + // Detect self connect + if msg.Nonce == p.server.Nonce { + log.Println("Peer connected to self, disconnecting") + + p.Stop() + return + } + + log.Println("mnonce", msg.Nonce, "snonce", p.server.Nonce) + + // If this is an inbound connection send an ack back + if p.inbound { + err := p.pushVersionAck() + if err != nil { + log.Println("Peer can't send ack back") + + p.Stop() + } + } +} + From fedbd9a962b2e800afe2e191d768f47172172741 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 12 Jan 2014 16:50:43 +0100 Subject: [PATCH 094/459] Rlp integer fix --- rlp.go | 279 ---------------------------------------------------- rlp_test.go | 54 ---------- 2 files changed, 333 deletions(-) delete mode 100644 rlp.go delete mode 100644 rlp_test.go diff --git a/rlp.go b/rlp.go deleted file mode 100644 index f5e630398..000000000 --- a/rlp.go +++ /dev/null @@ -1,279 +0,0 @@ -package main - -import ( - "bytes" - "fmt" - "github.com/ethereum/ethutil-go" - "math" - "math/big" -) - -type RlpEncoder struct { - rlpData []byte -} - -func NewRlpEncoder() *RlpEncoder { - encoder := &RlpEncoder{} - - return encoder -} -func (coder *RlpEncoder) EncodeData(rlpData []interface{}) []byte { - return nil -} - -// Data attributes are returned by the rlp decoder. The data attributes represents -// one item within the rlp data structure. It's responsible for all the casting -// It always returns something valid -type RlpDataAttribute struct { - dataAttrib interface{} -} - -func NewRlpDataAttribute(attrib interface{}) *RlpDataAttribute { - return &RlpDataAttribute{dataAttrib: attrib} -} - -func (attr *RlpDataAttribute) Length() int { - if data, ok := attr.dataAttrib.([]interface{}); ok { - return len(data) - } - - return 0 -} - - -func (attr *RlpDataAttribute) AsUint() uint64 { - if value, ok := attr.dataAttrib.(uint8); ok { - return uint64(value) - } else if value, ok := attr.dataAttrib.(uint16); ok { - return uint64(value) - } else if value, ok := attr.dataAttrib.(uint32); ok { - return uint64(value) - } else if value, ok := attr.dataAttrib.(uint64); ok { - return value - } - - return 0 -} - -func (attr *RlpDataAttribute) AsBigInt() *big.Int { - if a, ok := attr.dataAttrib.([]byte); ok { - return ethutil.Big(string(a)) - } - - return big.NewInt(0) -} - -func (attr *RlpDataAttribute) AsString() string { - if a, ok := attr.dataAttrib.([]byte); ok { - return string(a) - } - - return "" -} - -func (attr *RlpDataAttribute) AsBytes() []byte { - if a, ok := attr.dataAttrib.([]byte); ok { - return a - } - - return make([]byte, 0) -} - -// Threat the attribute as a slice -func (attr *RlpDataAttribute) Get(idx int) *RlpDataAttribute { - if d, ok := attr.dataAttrib.([]interface{}); ok { - // Guard for oob - if len(d) < idx { - return NewRlpDataAttribute(nil) - } - - return NewRlpDataAttribute(d[idx]) - } - - // If this wasn't a slice you probably shouldn't be using this function - return NewRlpDataAttribute(nil) -} - -type RlpDecoder struct { - rlpData interface{} -} - -func NewRlpDecoder(rlpData []byte) *RlpDecoder { - decoder := &RlpDecoder{} - // Decode the data - data, _ := Decode(rlpData, 0) - decoder.rlpData = data - - return decoder -} - -func (dec *RlpDecoder) Get(idx int) *RlpDataAttribute { - return NewRlpDataAttribute(dec.rlpData).Get(idx) -} - -/// Raw methods -func BinaryLength(n uint64) uint64 { - if n == 0 { - return 0 - } - - return 1 + BinaryLength(n/256) -} - -func ToBinarySlice(n uint64, length uint64) []uint64 { - if length == 0 { - length = BinaryLength(n) - } - - if n == 0 { - return make([]uint64, 1) - } - - slice := ToBinarySlice(n/256, 0) - slice = append(slice, n%256) - - return slice -} - -func ToBin(n uint64, length uint64) string { - var buf bytes.Buffer - for _, val := range ToBinarySlice(n, length) { - buf.WriteString(string(val)) - } - - return buf.String() -} - -func FromBin(data []byte) uint64 { - if len(data) == 0 { - return 0 - } - - return FromBin(data[:len(data)-1])*256 + uint64(data[len(data)-1]) -} - -func Decode(data []byte, pos int) (interface{}, int) { - if pos > len(data)-1 { - panic(fmt.Sprintf("index out of range %d for data %q, l = %d", pos, data, len(data))) - } - - char := int(data[pos]) - slice := make([]interface{}, 0) - switch { - case char < 24: - return data[pos], pos + 1 - - case char < 56: - b := int(data[pos]) - 23 - return FromBin(data[pos+1 : pos+1+b]), pos + 1 + b - - case char < 64: - b := int(data[pos]) - 55 - b2 := int(FromBin(data[pos+1 : pos+1+b])) - return FromBin(data[pos+1+b : pos+1+b+b2]), pos + 1 + b + b2 - - case char < 120: - b := int(data[pos]) - 64 - return data[pos+1 : pos+1+b], pos + 1 + b - - case char < 128: - b := int(data[pos]) - 119 - b2 := int(FromBin(data[pos+1 : pos+1+b])) - return data[pos+1+b : pos+1+b+b2], pos + 1 + b + b2 - - case char < 184: - b := int(data[pos]) - 128 - pos++ - for i := 0; i < b; i++ { - var obj interface{} - - obj, pos = Decode(data, pos) - slice = append(slice, obj) - } - return slice, pos - - case char < 192: - b := int(data[pos]) - 183 - //b2 := int(FromBin(data[pos+1 : pos+1+b])) (ref implementation has an unused variable) - pos = pos + 1 + b - for i := 0; i < b; i++ { - var obj interface{} - - obj, pos = Decode(data, pos) - slice = append(slice, obj) - } - return slice, pos - - default: - panic(fmt.Sprintf("byte not supported: %q", char)) - } - - return slice, 0 -} - -func Encode(object interface{}) []byte { - var buff bytes.Buffer - - switch t := object.(type) { - case uint32, uint64: - var num uint64 - if _num, ok := t.(uint64); ok { - num = _num - } else if _num, ok := t.(uint32); ok { - num = uint64(_num) - } - - if num >= 0 && num < 24 { - buff.WriteString(string(num)) - } else if num <= uint64(math.Pow(2, 256)) { - b := ToBin(num, 0) - buff.WriteString(string(len(b)+23) + b) - } else { - b := ToBin(num, 0) - b2 := ToBin(uint64(len(b)), 0) - buff.WriteString(string(len(b2)+55) + b2 + b) - } - - case *big.Int: - buff.Write(Encode(t.String())) - - case string: - if len(t) < 56 { - buff.WriteString(string(len(t)+64) + t) - } else { - b2 := ToBin(uint64(len(t)), 0) - buff.WriteString(string(len(b2)+119) + b2 + t) - } - - case []byte: - // Cast the byte slice to a string - buff.Write(Encode(string(t))) - - case []interface{}, []string: - // Inline function for writing the slice header - WriteSliceHeader := func(length int) { - if length < 56 { - buff.WriteByte(byte(length + 128)) - } else { - b2 := ToBin(uint64(length), 0) - buff.WriteByte(byte(len(b2) + 183)) - buff.WriteString(b2) - } - } - - // FIXME How can I do this "better"? - if interSlice, ok := t.([]interface{}); ok { - WriteSliceHeader(len(interSlice)) - for _, val := range interSlice { - buff.Write(Encode(val)) - } - } else if stringSlice, ok := t.([]string); ok { - WriteSliceHeader(len(stringSlice)) - for _, val := range stringSlice { - buff.Write(Encode(val)) - } - } - } - - return buff.Bytes() -} diff --git a/rlp_test.go b/rlp_test.go deleted file mode 100644 index 65cf34b39..000000000 --- a/rlp_test.go +++ /dev/null @@ -1,54 +0,0 @@ -package main - -import ( - "fmt" - "testing" -) - -func TestEncode(t *testing.T) { - strRes := "Cdog" - - bytes := Encode("dog") - - str := string(bytes) - if str != strRes { - t.Error(fmt.Sprintf("Expected %q, got %q", strRes, str)) - } - //dec,_ := Decode(bytes, 0) - - sliceRes := "\x83CdogCgodCcat" - strs := []string{"dog", "god", "cat"} - bytes = Encode(strs) - slice := string(bytes) - if slice != sliceRes { - t.Error(fmt.Sprintf("Expected %q, got %q", sliceRes, slice)) - } - - //dec,_ = Decode(bytes, 0) -} - -func TestMultiEncode(t *testing.T) { - inter := []interface{}{ - []interface{}{ - "1", "2", "3", - }, - []string{ - "string", - "string2", - "\x86A0J1234567890A\x00B20A0\x82F395843F657986", - "\x86A0J1234567890A\x00B20A0\x8cF395843F657986I335612448F524099H16716881A0H13114947G2039362G1507139H16719697G1048387E65360", - }, - "test", - } - - bytes := Encode(inter) - - Decode(bytes, 0) -} - -func BenchmarkEncodeDecode(b *testing.B) { - for i := 0; i < b.N; i++ { - bytes := Encode([]string{"dog", "god", "cat"}) - Decode(bytes, 0) - } -} From e280a2a7e3d51f0fb3b35e580332d9b51a7e50c1 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 12 Jan 2014 16:50:59 +0100 Subject: [PATCH 095/459] Server testing blocks --- ethereum.go | 6 ++++-- server.go | 43 +++++++++++++++++++++++++++---------------- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/ethereum.go b/ethereum.go index dd5b44308..f38de1872 100644 --- a/ethereum.go +++ b/ethereum.go @@ -65,7 +65,7 @@ func main() { go func() { for { res := dagger.Search(ethutil.Big("0"), ethutil.BigPow(2, 36)) - server.Broadcast("block", Encode(res.String())) + server.Broadcast("block", ethutil.Encode(res.String())) } }() } @@ -74,8 +74,10 @@ func main() { err = server.ConnectToPeer("localhost:12345") if err != nil { - log.Println(err) + log.Println("Error starting server", err) + server.Stop() + return } diff --git a/server.go b/server.go index 5373e2418..98d9746e8 100644 --- a/server.go +++ b/server.go @@ -4,46 +4,56 @@ import ( "container/list" "github.com/ethereum/ethdb-go" "github.com/ethereum/ethutil-go" + "github.com/ethereum/ethwire-go" "log" "net" - _ "time" + "time" ) type Server struct { // Channel for shutting down the server shutdownChan chan bool // DB interface - db *ethdb.LDBDatabase + //db *ethdb.LDBDatabase + db *ethdb.MemDatabase // Block manager for processing new blocks and managing the block chain blockManager *BlockManager // Peers (NYI) peers *list.List + // Nonce + Nonce uint64 } func NewServer() (*Server, error) { - db, err := ethdb.NewLDBDatabase() + //db, err := ethdb.NewLDBDatabase() + db, err := ethdb.NewMemDatabase() if err != nil { return nil, err } ethutil.SetConfig(db) + nonce, _ := ethutil.RandomUint64() server := &Server{ shutdownChan: make(chan bool), blockManager: NewBlockManager(), db: db, peers: list.New(), + Nonce: nonce, } return server, nil } func (s *Server) AddPeer(conn net.Conn) { - peer := NewPeer(conn, s) - s.peers.PushBack(peer) - peer.Start() + peer := NewPeer(conn, s, true) - log.Println("Peer connected ::", conn.RemoteAddr()) + if peer != nil { + s.peers.PushBack(peer) + peer.Start() + + log.Println("Peer connected ::", conn.RemoteAddr()) + } } func (s *Server) ConnectToPeer(addr string) error { @@ -53,7 +63,7 @@ func (s *Server) ConnectToPeer(addr string) error { return err } - peer := NewPeer(conn, s) + peer := NewPeer(conn, s, false) s.peers.PushBack(peer) peer.Start() @@ -65,7 +75,7 @@ func (s *Server) ConnectToPeer(addr string) error { func (s *Server) Broadcast(msgType string, data []byte) { for e := s.peers.Front(); e != nil; e = e.Next() { if peer, ok := e.Value.(*Peer); ok { - peer.QueueMessage(msgType, data) + peer.QueueMessage(ethwire.NewMessage(msgType, 0, data)) } } } @@ -83,6 +93,7 @@ func (s *Server) Start() { conn, err := ln.Accept() if err != nil { log.Println(err) + continue } @@ -91,13 +102,13 @@ func (s *Server) Start() { }() // TMP - //go func() { - // for { - // s.Broadcast("block", Encode("blockdata")) - // - // time.Sleep(100 * time.Millisecond) - // } - // }() + go func() { + for { + s.Broadcast("block", s.blockManager.bc.GenesisBlock().MarshalRlp()) + + time.Sleep(1000 * time.Millisecond) + } + }() } func (s *Server) Stop() { From f78bd4d5d0a6198c2c0e709440d9aa370e840617 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 12 Jan 2014 17:19:14 +0100 Subject: [PATCH 096/459] Format --- block_manager.go | 8 +++----- peer.go | 11 +++++------ 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/block_manager.go b/block_manager.go index 0c7410022..b6c2cace7 100644 --- a/block_manager.go +++ b/block_manager.go @@ -1,9 +1,9 @@ package main import ( + "errors" "fmt" "github.com/ethereum/ethutil-go" - "errors" "log" "math/big" ) @@ -24,7 +24,6 @@ func NewBlockChain() *BlockChain { bc.TD = new(big.Int) bc.TD.SetBytes(ethutil.Config.Db.LastKnownTD()) - // TODO get last block from the database //bc.LastBlock = bc.genesisBlock @@ -136,7 +135,7 @@ func (bm *BlockManager) ValidateBlock(block *ethutil.Block) error { // Check if we have the parent hash, if it isn't known we discard it // Reasons might be catching up or simply an invalid block if bm.bc.LastBlock != nil && block.PrevHash == "" && - !bm.bc.HasBlock(block.PrevHash) { + !bm.bc.HasBlock(block.PrevHash) { return errors.New("Block's parent unknown") } @@ -154,7 +153,7 @@ func (bm *BlockManager) ValidateBlock(block *ethutil.Block) error { // Verify the nonce of the block. Return an error if it's not valid if bm.bc.LastBlock != nil && block.PrevHash == "" && - !DaggerVerify(ethutil.BigD(block.Hash()), block.Difficulty, block.Nonce) { + !DaggerVerify(ethutil.BigD(block.Hash()), block.Difficulty, block.Nonce) { return errors.New("Block's nonce is invalid") } @@ -175,7 +174,6 @@ func (bm *BlockManager) AccumelateRewards(block *ethutil.Block) error { // TODO Reward each uncle - return nil } diff --git a/peer.go b/peer.go index 2dda1f94f..0875c6e45 100644 --- a/peer.go +++ b/peer.go @@ -1,8 +1,8 @@ package main import ( - "github.com/ethereum/ethwire-go" "github.com/ethereum/ethutil-go" + "github.com/ethereum/ethwire-go" "log" "net" ) @@ -24,15 +24,15 @@ func NewPeer(conn net.Conn, server *Server, inbound bool) *Peer { return &Peer{ outputQueue: make(chan *ethwire.InOutMsg, 1), // Buffered chan of 1 is enough quit: make(chan bool), - server: server, - conn: conn, - inbound: inbound, + server: server, + conn: conn, + inbound: inbound, } } // Outputs any RLP encoded data to the peer func (p *Peer) QueueMessage(msg *ethwire.InOutMsg) { - p.outputQueue <- msg//ethwire.InOutMsg{MsgType: msgType, Nonce: ethutil.RandomUint64(), Data: data} + p.outputQueue <- msg //ethwire.InOutMsg{MsgType: msgType, Nonce: ethutil.RandomUint64(), Data: data} } // Outbound message handler. Outbound messages are handled here @@ -145,4 +145,3 @@ func (p *Peer) handleVersionAck(msg *ethwire.InOutMsg) { } } } - From 39bb2c94c066c36cc8e245e737bbc5a106583f92 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 12 Jan 2014 22:14:19 +0100 Subject: [PATCH 097/459] Atomic syncs on connection states --- peer.go | 95 +++++++++++++++++++++++++++++++++++++++++++++---------- server.go | 36 ++++++++++----------- 2 files changed, 96 insertions(+), 35 deletions(-) diff --git a/peer.go b/peer.go index 0875c6e45..e3a4f74cb 100644 --- a/peer.go +++ b/peer.go @@ -5,6 +5,8 @@ import ( "github.com/ethereum/ethwire-go" "log" "net" + "sync/atomic" + "time" ) type Peer struct { @@ -16,8 +18,12 @@ type Peer struct { outputQueue chan *ethwire.InOutMsg // Quit channel quit chan bool - - inbound bool // Determines whether it's an inbound or outbound peer + // Determines whether it's an inbound or outbound peer + inbound bool + // Flag for checking the peer's connectivity state + connected int32 + disconnect int32 + lastSend time.Time } func NewPeer(conn net.Conn, server *Server, inbound bool) *Peer { @@ -27,12 +33,57 @@ func NewPeer(conn net.Conn, server *Server, inbound bool) *Peer { server: server, conn: conn, inbound: inbound, + disconnect: 0, + connected: 1, } } +func NewOutboundPeer(addr string, server *Server) *Peer { + p := &Peer{ + outputQueue: make(chan *ethwire.InOutMsg, 1), // Buffered chan of 1 is enough + quit: make(chan bool), + server: server, + inbound: false, + connected: 0, + disconnect: 1, + } + + // Set up the connection in another goroutine so we don't block the main thread + go func() { + conn, err := net.Dial("tcp", addr) + if err != nil { + p.Stop() + } + p.conn = conn + + // Atomically set the connection state + atomic.StoreInt32(&p.connected, 1) + atomic.StoreInt32(&p.disconnect, 0) + + log.Println("Connected to peer ::", conn.RemoteAddr()) + }() + + return p +} + // Outputs any RLP encoded data to the peer func (p *Peer) QueueMessage(msg *ethwire.InOutMsg) { - p.outputQueue <- msg //ethwire.InOutMsg{MsgType: msgType, Nonce: ethutil.RandomUint64(), Data: data} + p.outputQueue <- msg +} + +func (p *Peer) writeMessage(msg *ethwire.InOutMsg) { + // Ignore the write if we're not connected + if atomic.LoadInt32(&p.connected) != 1 { + return + } + + err := ethwire.WriteMessage(p.conn, msg) + if err != nil { + log.Println("Can't send message:", err) + // Stop the client if there was an error writing to it + p.Stop() + return + } } // Outbound message handler. Outbound messages are handled here @@ -42,28 +93,32 @@ out: select { // Main message queue. All outbound messages are processed through here case msg := <-p.outputQueue: - // TODO Message checking and handle accordingly - err := ethwire.WriteMessage(p.conn, msg) - if err != nil { - log.Println(err) - - // Stop the client if there was an error writing to it - p.Stop() - } + p.writeMessage(msg) + p.lastSend = time.Now() // Break out of the for loop if a quit message is posted case <-p.quit: break out } } + +clean: + // This loop is for draining the output queue and anybody waiting for us + for { + select { + case <- p.outputQueue: + // TODO + default: + break clean + } + } } // Inbound handler. Inbound messages are received here and passed to the appropriate methods func (p *Peer) HandleInbound() { - defer p.Stop() out: - for { + for atomic.LoadInt32(&p.disconnect) == 0 { // Wait for a message from the peer msg, err := ethwire.ReadMessage(p.conn) if err != nil { @@ -90,8 +145,7 @@ out: } } - // Notify the out handler we're quiting - p.quit <- true + p.Stop() } func (p *Peer) Start() { @@ -111,9 +165,16 @@ func (p *Peer) Start() { } func (p *Peer) Stop() { - p.conn.Close() + if atomic.AddInt32(&p.disconnect, 1) != 1 { + return + } - p.quit <- true + close(p.quit) + if atomic.LoadInt32(&p.connected) != 0 { + p.conn.Close() + } + + log.Println("Peer shutdown") } func (p *Peer) pushVersionAck() error { diff --git a/server.go b/server.go index 98d9746e8..b01ecb08c 100644 --- a/server.go +++ b/server.go @@ -10,6 +10,16 @@ import ( "time" ) +func eachPeer(peers *list.List, callback func(*Peer)) { + // Loop thru the peers and close them (if we had them) + for e := peers.Front(); e != nil; e = e.Next() { + if peer, ok := e.Value.(*Peer); ok { + callback(peer) + } + } +} + + type Server struct { // Channel for shutting down the server shutdownChan chan bool @@ -57,27 +67,20 @@ func (s *Server) AddPeer(conn net.Conn) { } func (s *Server) ConnectToPeer(addr string) error { - conn, err := net.Dial("tcp", addr) + peer := NewOutboundPeer(addr, s) - if err != nil { - return err - } - - peer := NewPeer(conn, s, false) s.peers.PushBack(peer) + peer.Start() - log.Println("Connected to peer ::", conn.RemoteAddr()) return nil } func (s *Server) Broadcast(msgType string, data []byte) { - for e := s.peers.Front(); e != nil; e = e.Next() { - if peer, ok := e.Value.(*Peer); ok { - peer.QueueMessage(ethwire.NewMessage(msgType, 0, data)) - } - } + eachPeer(s.peers, func(p *Peer) { + p.QueueMessage(ethwire.NewMessage(msgType, 0, data)) + }) } // Start the server @@ -115,12 +118,9 @@ func (s *Server) Stop() { // Close the database defer s.db.Close() - // Loop thru the peers and close them (if we had them) - for e := s.peers.Front(); e != nil; e = e.Next() { - if peer, ok := e.Value.(*Peer); ok { - peer.Stop() - } - } + eachPeer(s.peers, func(p *Peer) { + p.Stop() + }) s.shutdownChan <- true } From 52fb3b412cde2c5afb0e3364a1da23f3c1d7b171 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 12 Jan 2014 23:16:33 +0100 Subject: [PATCH 098/459] Increased buffer size --- peer.go | 23 ++++++++++++++++++++--- server.go | 5 ++--- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/peer.go b/peer.go index e3a4f74cb..e6f752022 100644 --- a/peer.go +++ b/peer.go @@ -9,6 +9,11 @@ import ( "time" ) +const ( + // The size of the output buffer for writing messages + outputBufferSize = 50 +) + type Peer struct { // Server interface server *Server @@ -24,11 +29,12 @@ type Peer struct { connected int32 disconnect int32 lastSend time.Time + versionKnown bool } func NewPeer(conn net.Conn, server *Server, inbound bool) *Peer { return &Peer{ - outputQueue: make(chan *ethwire.InOutMsg, 1), // Buffered chan of 1 is enough + outputQueue: make(chan *ethwire.InOutMsg, outputBufferSize), quit: make(chan bool), server: server, conn: conn, @@ -40,7 +46,7 @@ func NewPeer(conn net.Conn, server *Server, inbound bool) *Peer { func NewOutboundPeer(addr string, server *Server) *Peer { p := &Peer{ - outputQueue: make(chan *ethwire.InOutMsg, 1), // Buffered chan of 1 is enough + outputQueue: make(chan *ethwire.InOutMsg, outputBufferSize), quit: make(chan bool), server: server, inbound: false, @@ -61,6 +67,8 @@ func NewOutboundPeer(addr string, server *Server) *Peer { atomic.StoreInt32(&p.disconnect, 0) log.Println("Connected to peer ::", conn.RemoteAddr()) + + p.Start() }() return p @@ -77,6 +85,14 @@ func (p *Peer) writeMessage(msg *ethwire.InOutMsg) { return } + if !p.versionKnown { + switch msg.MsgType { + case "verack": // Ok + default: // Anything but ack is allowed + return + } + } + err := ethwire.WriteMessage(p.conn, msg) if err != nil { log.Println("Can't send message:", err) @@ -191,10 +207,11 @@ func (p *Peer) handleVersionAck(msg *ethwire.InOutMsg) { log.Println("Peer connected to self, disconnecting") p.Stop() + return } - log.Println("mnonce", msg.Nonce, "snonce", p.server.Nonce) + p.versionKnown = true // If this is an inbound connection send an ack back if p.inbound { diff --git a/server.go b/server.go index b01ecb08c..bc398dd92 100644 --- a/server.go +++ b/server.go @@ -71,9 +71,6 @@ func (s *Server) ConnectToPeer(addr string) error { s.peers.PushBack(peer) - peer.Start() - - return nil } @@ -106,6 +103,8 @@ func (s *Server) Start() { // TMP go func() { + //time.Sleep(500 * time.Millisecond) + for { s.Broadcast("block", s.blockManager.bc.GenesisBlock().MarshalRlp()) From 7ade1778fba0fd1f6e0bccc7647cd8fb3185528d Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 12 Jan 2014 23:46:03 +0100 Subject: [PATCH 099/459] Peer reaping and fake network --- ethereum.go | 8 -------- peer.go | 4 ++++ server.go | 46 +++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 45 insertions(+), 13 deletions(-) diff --git a/ethereum.go b/ethereum.go index f38de1872..055c1a5ad 100644 --- a/ethereum.go +++ b/ethereum.go @@ -72,14 +72,6 @@ func main() { server.Start() - err = server.ConnectToPeer("localhost:12345") - if err != nil { - log.Println("Error starting server", err) - - server.Stop() - - return - } // Wait for shutdown server.WaitForShutdown() diff --git a/peer.go b/peer.go index e6f752022..16bb22286 100644 --- a/peer.go +++ b/peer.go @@ -28,7 +28,11 @@ type Peer struct { // Flag for checking the peer's connectivity state connected int32 disconnect int32 + // Last known message send lastSend time.Time + // Indicated whether a verack has been send or not + // This flag is used by writeMessage to check if messages are allowed + // to be send or not. If no version is known all messages are ignored. versionKnown bool } diff --git a/server.go b/server.go index bc398dd92..e34bc6f20 100644 --- a/server.go +++ b/server.go @@ -8,13 +8,14 @@ import ( "log" "net" "time" + "sync/atomic" ) -func eachPeer(peers *list.List, callback func(*Peer)) { +func eachPeer(peers *list.List, callback func(*Peer, *list.Element)) { // Loop thru the peers and close them (if we had them) for e := peers.Front(); e != nil; e = e.Next() { if peer, ok := e.Value.(*Peer); ok { - callback(peer) + callback(peer, e) } } } @@ -75,19 +76,54 @@ func (s *Server) ConnectToPeer(addr string) error { } func (s *Server) Broadcast(msgType string, data []byte) { - eachPeer(s.peers, func(p *Peer) { + eachPeer(s.peers, func(p *Peer, e *list.Element) { p.QueueMessage(ethwire.NewMessage(msgType, 0, data)) }) } +const ( + processReapingTimeout = 10 // TODO increase +) + +func (s *Server) ReapDeadPeers() { + for { + eachPeer(s.peers, func(p *Peer, e *list.Element) { + if atomic.LoadInt32(&p.disconnect) == 1 { + log.Println("Dead peer found .. reaping") + + s.peers.Remove(e) + } + }) + + time.Sleep(processReapingTimeout * time.Second) + } +} + // Start the server func (s *Server) Start() { // For now this function just blocks the main thread ln, err := net.Listen("tcp", ":12345") if err != nil { - log.Fatal(err) + // This is mainly for testing to create a "network" + if Debug { + log.Println("Connection listening disabled. Acting as client") + + err = s.ConnectToPeer("localhost:12345") + if err != nil { + log.Println("Error starting server", err) + + s.Stop() + } + + return + } else { + log.Fatal(err) + } } + // Start the reaping processes + go s.ReapDeadPeers() + go func() { for { conn, err := ln.Accept() @@ -117,7 +153,7 @@ func (s *Server) Stop() { // Close the database defer s.db.Close() - eachPeer(s.peers, func(p *Peer) { + eachPeer(s.peers, func(p *Peer, e *list.Element) { p.Stop() }) From 578b63e2b8a32122fb45f9f053503e51d9a5c535 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 13 Jan 2014 01:22:33 +0100 Subject: [PATCH 100/459] Some miner reports --- block_manager.go | 1 + dagger.go | 7 +++++-- ethereum.go | 4 ++-- peer.go | 3 +++ server.go | 4 ++-- 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/block_manager.go b/block_manager.go index b6c2cace7..7e16cdb3a 100644 --- a/block_manager.go +++ b/block_manager.go @@ -154,6 +154,7 @@ func (bm *BlockManager) ValidateBlock(block *ethutil.Block) error { // Verify the nonce of the block. Return an error if it's not valid if bm.bc.LastBlock != nil && block.PrevHash == "" && !DaggerVerify(ethutil.BigD(block.Hash()), block.Difficulty, block.Nonce) { + return errors.New("Block's nonce is invalid") } diff --git a/dagger.go b/dagger.go index 70b0b4692..0cc63ea94 100644 --- a/dagger.go +++ b/dagger.go @@ -7,6 +7,7 @@ import ( "math/big" "math/rand" "time" + "log" ) type Dagger struct { @@ -22,7 +23,9 @@ func (dag *Dagger) Find(obj *big.Int, resChan chan int64) { for i := 0; i < 1000; i++ { rnd := r.Int63() - if dag.Eval(big.NewInt(rnd)).Cmp(obj) < 0 { + res := dag.Eval(big.NewInt(rnd)) + log.Printf("rnd %v\nres %v\nobj %v\n", rnd, res, obj) + if res.Cmp(obj) < 0 { // Post back result on the channel resChan <- rnd // Notify other threads we've found a valid nonce @@ -119,7 +122,7 @@ func Sum(sha hash.Hash) []byte { func (dag *Dagger) Eval(N *big.Int) *big.Int { pow := ethutil.BigPow(2, 26) - dag.xn = N.Div(N, pow) + dag.xn = pow.Div(N, pow) sha := sha3.NewKeccak256() sha.Reset() diff --git a/ethereum.go b/ethereum.go index 055c1a5ad..7e13f197a 100644 --- a/ethereum.go +++ b/ethereum.go @@ -64,8 +64,8 @@ func main() { go func() { for { - res := dagger.Search(ethutil.Big("0"), ethutil.BigPow(2, 36)) - server.Broadcast("block", ethutil.Encode(res.String())) + res := dagger.Search(ethutil.Big("01001"), ethutil.BigPow(2, 26)) + server.Broadcast("blockmine", ethutil.Encode(res.String())) } }() } diff --git a/peer.go b/peer.go index 16bb22286..8f68a9bec 100644 --- a/peer.go +++ b/peer.go @@ -162,6 +162,9 @@ out: if err != nil { log.Println(err) } + case "blockmine": + d, _ := ethutil.Decode(msg.Data, 0) + log.Printf("block mined %s\n", d) } } diff --git a/server.go b/server.go index e34bc6f20..f658750a9 100644 --- a/server.go +++ b/server.go @@ -138,15 +138,15 @@ func (s *Server) Start() { }() // TMP + /* go func() { - //time.Sleep(500 * time.Millisecond) - for { s.Broadcast("block", s.blockManager.bc.GenesisBlock().MarshalRlp()) time.Sleep(1000 * time.Millisecond) } }() + */ } func (s *Server) Stop() { From 44900e363cbc81b640bc16bcc7e6a50c22352be4 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 14 Jan 2014 21:48:16 +0100 Subject: [PATCH 101/459] Updated to temporary trie --- dagger.go | 5 +++-- dev_console.go | 36 ++++++++++++++++++++++++++++++------ ethereum.go | 3 +-- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/dagger.go b/dagger.go index 0cc63ea94..966bfa461 100644 --- a/dagger.go +++ b/dagger.go @@ -116,8 +116,8 @@ func (dag *Dagger) Node(L uint64, i uint64) *big.Int { } func Sum(sha hash.Hash) []byte { - in := make([]byte, 32) - return sha.Sum(in) + //in := make([]byte, 32) + return sha.Sum(nil) } func (dag *Dagger) Eval(N *big.Int) *big.Int { @@ -146,3 +146,4 @@ func (dag *Dagger) Eval(N *big.Int) *big.Int { return ret.SetBytes(Sum(sha)) } + diff --git a/dev_console.go b/dev_console.go index 923c483c2..228cfc47e 100644 --- a/dev_console.go +++ b/dev_console.go @@ -37,6 +37,12 @@ func (i *Console) ValidateInput(action string, argumentLength int) error { case action == "dag" && argumentLength != 2: err = true expArgCount = 2 + case action == "decode" && argumentLength != 1: + err = true + expArgCount = 1 + case action == "encode" && argumentLength != 1: + err = true + expArgCount = 1 } if err { @@ -46,6 +52,15 @@ func (i *Console) ValidateInput(action string, argumentLength int) error { } } +func (i *Console) PrintRoot() { + root := ethutil.Conv(i.trie.RootT) + if len(root.AsBytes()) != 0 { + fmt.Println(hex.EncodeToString(root.AsBytes())) + } else { + fmt.Println(i.trie.RootT) + } +} + func (i *Console) ParseInput(input string) bool { scanner := bufio.NewScanner(strings.NewReader(input)) scanner.Split(bufio.ScanWords) @@ -70,21 +85,26 @@ func (i *Console) ParseInput(input string) bool { } else { switch tokens[0] { case "update": - i.trie.Update(tokens[1], tokens[2]) + i.trie.UpdateT(tokens[1], tokens[2]) - fmt.Println(hex.EncodeToString([]byte(i.trie.Root))) + i.PrintRoot() case "get": - fmt.Println(i.trie.Get(tokens[1])) + fmt.Println(i.trie.GetT(tokens[1])) case "root": - fmt.Println(hex.EncodeToString([]byte(i.trie.Root))) + i.PrintRoot() case "rawroot": - fmt.Println(i.trie.Root) + fmt.Println(i.trie.RootT) case "print": i.db.Print() case "dag": fmt.Println(DaggerVerify(ethutil.Big(tokens[1]), // hash ethutil.BigPow(2, 36), // diff ethutil.Big(tokens[2]))) // nonce + case "decode": + d, _ := ethutil.Decode([]byte(tokens[1]), 0) + fmt.Printf("%q\n", d) + case "encode": + fmt.Printf("%q\n", ethutil.Encode(tokens[1])) case "exit", "quit", "q": return false case "help": @@ -95,7 +115,11 @@ func (i *Console) ParseInput(input string) bool { "root - Prints the hex encoded merkle root\n" + "rawroot - Prints the raw merkle root\n" + "\033[1m= Dagger =\033[0m\n" + - "dag HASH NONCE - Verifies a nonce with the given hash with dagger\n") + "dag HASH NONCE - Verifies a nonce with the given hash with dagger\n" + + "\033[1m= Enroding =\033[0m\n" + + "decode STR\n" + + "encode STR\n") + default: fmt.Println("Unknown command:", tokens[0]) } diff --git a/ethereum.go b/ethereum.go index 7e13f197a..83f656fe2 100644 --- a/ethereum.go +++ b/ethereum.go @@ -64,7 +64,7 @@ func main() { go func() { for { - res := dagger.Search(ethutil.Big("01001"), ethutil.BigPow(2, 26)) + res := dagger.Search(ethutil.Big("01001"), ethutil.BigPow(2, 36)) server.Broadcast("blockmine", ethutil.Encode(res.String())) } }() @@ -72,7 +72,6 @@ func main() { server.Start() - // Wait for shutdown server.WaitForShutdown() } From be48f2eb91b8726cbafe9865360e64cbfa35c3de Mon Sep 17 00:00:00 2001 From: Stephan Tual Date: Wed, 15 Jan 2014 17:40:35 +0000 Subject: [PATCH 102/459] Fixed typo (credit to comma 8) --- dev_console.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_console.go b/dev_console.go index 228cfc47e..5340a5f46 100644 --- a/dev_console.go +++ b/dev_console.go @@ -116,7 +116,7 @@ func (i *Console) ParseInput(input string) bool { "rawroot - Prints the raw merkle root\n" + "\033[1m= Dagger =\033[0m\n" + "dag HASH NONCE - Verifies a nonce with the given hash with dagger\n" + - "\033[1m= Enroding =\033[0m\n" + + "\033[1m= Encoding =\033[0m\n" + "decode STR\n" + "encode STR\n") From 4ea93eba501cf996395e4c0829e21cab77267cf9 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 15 Jan 2014 23:32:30 +0100 Subject: [PATCH 103/459] Updated tests --- dagger_test.go | 3 ++- test_runner_test.go | 8 +++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/dagger_test.go b/dagger_test.go index 58cdd6afd..616577a39 100644 --- a/dagger_test.go +++ b/dagger_test.go @@ -1,13 +1,14 @@ package main import ( + "github.com/ethereum/ethutil-go" "math/big" "testing" ) func BenchmarkDaggerSearch(b *testing.B) { hash := big.NewInt(0) - diff := BigPow(2, 36) + diff := ethutil.BigPow(2, 36) o := big.NewInt(0) // nonce doesn't matter. We're only testing against speed, not validity // Reset timer so the big generation isn't included in the benchmark diff --git a/test_runner_test.go b/test_runner_test.go index 5abe20002..5abf0c8df 100644 --- a/test_runner_test.go +++ b/test_runner_test.go @@ -3,6 +3,8 @@ package main import ( "encoding/hex" _ "fmt" + "github.com/ethereum/ethdb-go" + "github.com/ethereum/ethutil-go" "testing" ) @@ -15,8 +17,8 @@ var testsource = `{"Inputs":{ }` func TestTestRunner(t *testing.T) { - db, _ := NewMemDatabase() - trie := NewTrie(db, "") + db, _ := ethdb.NewMemDatabase() + trie := ethutil.NewTrie(db, "") runner := NewTestRunner(t) runner.RunFromString(testsource, func(source *TestSource) { @@ -24,7 +26,7 @@ func TestTestRunner(t *testing.T) { trie.Update(key, value) } - if hex.EncodeToString([]byte(trie.root)) != source.Expectation { + if hex.EncodeToString([]byte(trie.Root)) != source.Expectation { t.Error("trie root did not match") } }) From 64058e2663453fc3c5adde8d7e1e3627bcfe4919 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 16 Jan 2014 11:00:56 +0100 Subject: [PATCH 104/459] Updated readme and coding standards --- README.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 23fdda2e5..ba122dc05 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,10 @@ Install Command line options ==================== +``` -c launch the developer console -m start mining fake blocks and broadcast fake messages to the net +``` Contribution ============ @@ -45,8 +47,8 @@ Style](http://golang.org/doc/effective_go.html#formatting). Unless structs fields are supposed to be directly accesible, provide Getters and hide the fields through Go's exporting facility. -Don't "overcomment", meaning that your and my mom doesn't have to read -the source code. +When you comment put meaningfull comments. Describe in detail what you +want to achieve. *wrong* @@ -57,6 +59,15 @@ if x > y { } ``` +Everyone reading the source probably know what you wanted to achieve +with above code. Those are **not** meaningful comments. + +While the project isn't 100% tested I want you to write tests non the +less. I haven't got time to evaluate everyone's code in detail so I +expect you to write tests for me so I don't have to test your code +manually. (If you want to contribute by just writing tests that's fine +too!) + ### Copy 69bce990a619e747b4f57483724b0e8a1732bb3b44ccf70b0dd6abd272af94550fc9d8b21232d33ebf30d38a148612f68e936094b4daeb9ea7174088a439070401 0255c78815d4f056f84c96de438ed9e38c69c0f8af24f5032248be5a79fe9071c3 From d8056f7ea525cbf37714613e772c0a4af97a1969 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 16 Jan 2014 11:01:59 +0100 Subject: [PATCH 105/459] Updated readme and coding standards --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index ba122dc05..b7df2afae 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,9 @@ Ethereum Ethereum Go (c) [0255c7881](https://github.com/ethereum/go-ethereum#copy) +A fair warning; Ethereum is not yet to be used in production. There's no +test-net and you aren't mining read blocks (just one which is the genesis block). + Ethereum Go is split up in several sub packages. Please refer to each individual package for more information. From 79e88690b26634077912a6a4b0199c2bd85666e4 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 16 Jan 2014 11:02:19 +0100 Subject: [PATCH 106/459] Removed capitalization of the json source --- test_runner_test.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/test_runner_test.go b/test_runner_test.go index 5abf0c8df..0a0b0d69c 100644 --- a/test_runner_test.go +++ b/test_runner_test.go @@ -8,12 +8,14 @@ import ( "testing" ) -var testsource = `{"Inputs":{ - "doe": "reindeer", - "dog": "puppy", - "dogglesworth": "cat" - }, - "Expectation":"e378927bfc1bd4f01a2e8d9f59bd18db8a208bb493ac0b00f93ce51d4d2af76c" +var testsource = ` +{ + "inputs":{ + "doe": "reindeer", + "dog": "puppy", + "dogglesworth": "cat" + }, + "expectation":"e378927bfc1bd4f01a2e8d9f59bd18db8a208bb493ac0b00f93ce51d4d2af76c" }` func TestTestRunner(t *testing.T) { From a80a3eeb238443d4b49deda360015ab315bd14a4 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 16 Jan 2014 11:02:41 +0100 Subject: [PATCH 107/459] Removed capitalization of the json source --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b7df2afae..05e0156b9 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Ethereum Ethereum Go (c) [0255c7881](https://github.com/ethereum/go-ethereum#copy) A fair warning; Ethereum is not yet to be used in production. There's no -test-net and you aren't mining read blocks (just one which is the genesis block). +test-net and you aren't mining real blocks (just one which is the genesis block). Ethereum Go is split up in several sub packages. Please refer to each From 83396cd836f6d963573295b9304be87bf45f5ad6 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 16 Jan 2014 15:20:41 +0100 Subject: [PATCH 108/459] Moved stack to its own file. Moved contract processing to block manager --- block_manager.go | 207 +++++++++++++++++++++++++++++++++++++++++++++-- stack.go | 164 +++++++++++++++++++++++++++++++++++++ 2 files changed, 366 insertions(+), 5 deletions(-) create mode 100644 stack.go diff --git a/block_manager.go b/block_manager.go index 7e16cdb3a..7b2d01f29 100644 --- a/block_manager.go +++ b/block_manager.go @@ -6,6 +6,7 @@ import ( "github.com/ethereum/ethutil-go" "log" "math/big" + "strconv" ) type BlockChain struct { @@ -40,16 +41,17 @@ func (bc *BlockChain) GenesisBlock() *ethutil.Block { } type BlockManager struct { - // Ethereum virtual machine for processing contracts - vm *Vm // The block chain :) bc *BlockChain + + // Stack for processing contracts + stack *Stack } func NewBlockManager() *BlockManager { bm := &BlockManager{ - vm: NewVm(), - bc: NewBlockChain(), + bc: NewBlockChain(), + stack: NewStack(), } return bm @@ -189,7 +191,7 @@ func (bm *BlockManager) ProcessContract(tx *ethutil.Transaction, block *ethutil. }() // Process contract - bm.vm.ProcContract(tx, block, func(opType OpType) bool { + bm.ProcContract(tx, block, func(opType OpType) bool { // TODO turn on once big ints are in place //if !block.PayFee(tx.Hash(), StepFee.Uint64()) { // return false @@ -201,3 +203,198 @@ func (bm *BlockManager) ProcessContract(tx *ethutil.Transaction, block *ethutil. // Broadcast we're done lockChan <- true } + +func (bm *BlockManager) ProcContract(tx *ethutil.Transaction, + block *ethutil.Block, cb TxCallback) { + // Instruction pointer + pc := 0 + + contract := block.GetContract(tx.Hash()) + if contract == nil { + fmt.Println("Contract not found") + return + } + + Pow256 := ethutil.BigPow(2, 256) + + //fmt.Printf("# op arg\n") +out: + for { + // The base big int for all calculations. Use this for any results. + base := new(big.Int) + // XXX Should Instr return big int slice instead of string slice? + // Get the next instruction from the contract + //op, _, _ := Instr(contract.state.Get(string(Encode(uint32(pc))))) + nb := ethutil.NumberToBytes(uint64(pc), 32) + o, _, _ := ethutil.Instr(contract.State().Get(string(nb))) + op := OpCode(o) + + if !cb(0) { + break + } + + if Debug { + //fmt.Printf("%-3d %-4s\n", pc, op.String()) + } + + switch op { + case oADD: + x, y := bm.stack.Popn() + // (x + y) % 2 ** 256 + base.Add(x, y) + base.Mod(base, Pow256) + // Pop result back on the stack + bm.stack.Push(base.String()) + case oSUB: + x, y := bm.stack.Popn() + // (x - y) % 2 ** 256 + base.Sub(x, y) + base.Mod(base, Pow256) + // Pop result back on the stack + bm.stack.Push(base.String()) + case oMUL: + x, y := bm.stack.Popn() + // (x * y) % 2 ** 256 + base.Mul(x, y) + base.Mod(base, Pow256) + // Pop result back on the stack + bm.stack.Push(base.String()) + case oDIV: + x, y := bm.stack.Popn() + // floor(x / y) + base.Div(x, y) + // Pop result back on the stack + bm.stack.Push(base.String()) + case oSDIV: + x, y := bm.stack.Popn() + // n > 2**255 + if x.Cmp(Pow256) > 0 { + x.Sub(Pow256, x) + } + if y.Cmp(Pow256) > 0 { + y.Sub(Pow256, y) + } + z := new(big.Int) + z.Div(x, y) + if z.Cmp(Pow256) > 0 { + z.Sub(Pow256, z) + } + // Push result on to the stack + bm.stack.Push(z.String()) + case oMOD: + x, y := bm.stack.Popn() + base.Mod(x, y) + bm.stack.Push(base.String()) + case oSMOD: + x, y := bm.stack.Popn() + // n > 2**255 + if x.Cmp(Pow256) > 0 { + x.Sub(Pow256, x) + } + if y.Cmp(Pow256) > 0 { + y.Sub(Pow256, y) + } + z := new(big.Int) + z.Mod(x, y) + if z.Cmp(Pow256) > 0 { + z.Sub(Pow256, z) + } + // Push result on to the stack + bm.stack.Push(z.String()) + case oEXP: + x, y := bm.stack.Popn() + base.Exp(x, y, Pow256) + + bm.stack.Push(base.String()) + case oNEG: + base.Sub(Pow256, ethutil.Big(bm.stack.Pop())) + bm.stack.Push(base.String()) + case oLT: + x, y := bm.stack.Popn() + // x < y + if x.Cmp(y) < 0 { + bm.stack.Push("1") + } else { + bm.stack.Push("0") + } + case oLE: + x, y := bm.stack.Popn() + // x <= y + if x.Cmp(y) < 1 { + bm.stack.Push("1") + } else { + bm.stack.Push("0") + } + case oGT: + x, y := bm.stack.Popn() + // x > y + if x.Cmp(y) > 0 { + bm.stack.Push("1") + } else { + bm.stack.Push("0") + } + case oGE: + x, y := bm.stack.Popn() + // x >= y + if x.Cmp(y) > -1 { + bm.stack.Push("1") + } else { + bm.stack.Push("0") + } + case oNOT: + x, y := bm.stack.Popn() + // x != y + if x.Cmp(y) != 0 { + bm.stack.Push("1") + } else { + bm.stack.Push("0") + } + + // Please note that the following code contains some + // ugly string casting. This will have to change to big + // ints. TODO :) + case oMYADDRESS: + bm.stack.Push(string(tx.Hash())) + case oTXSENDER: + bm.stack.Push(string(tx.Sender())) + case oTXVALUE: + bm.stack.Push(tx.Value.String()) + case oTXDATAN: + bm.stack.Push(big.NewInt(int64(len(tx.Data))).String()) + case oTXDATA: + v := ethutil.Big(bm.stack.Pop()) + // v >= len(data) + if v.Cmp(big.NewInt(int64(len(tx.Data)))) >= 0 { + //I know this will change. It makes no + //sense. Read comment above + bm.stack.Push(ethutil.Big("0").String()) + } else { + bm.stack.Push(ethutil.Big(tx.Data[v.Uint64()]).String()) + } + case oBLK_PREVHASH: + bm.stack.Push(string(block.PrevHash)) + case oBLK_COINBASE: + bm.stack.Push(block.Coinbase) + case oBLK_TIMESTAMP: + bm.stack.Push(big.NewInt(block.Time).String()) + case oBLK_NUMBER: + + case oPUSH: + // Get the next entry and pushes the value on the stack + pc++ + bm.stack.Push(contract.State().Get(string(ethutil.NumberToBytes(uint64(pc), 32)))) + case oPOP: + // Pop current value of the stack + bm.stack.Pop() + case oLOAD: + // Load instruction X on the stack + i, _ := strconv.Atoi(bm.stack.Pop()) + bm.stack.Push(contract.State().Get(string(ethutil.NumberToBytes(uint64(i), 32)))) + case oSTOP: + break out + } + pc++ + } + + bm.stack.Print() +} diff --git a/stack.go b/stack.go new file mode 100644 index 000000000..2b2f075cf --- /dev/null +++ b/stack.go @@ -0,0 +1,164 @@ +package main + +import ( + "fmt" + "github.com/ethereum/ethutil-go" + "math/big" +) + +type OpCode byte + +// Op codes +const ( + oSTOP OpCode = 0x00 + oADD OpCode = 0x01 + oMUL OpCode = 0x02 + oSUB OpCode = 0x03 + oDIV OpCode = 0x04 + oSDIV OpCode = 0x05 + oMOD OpCode = 0x06 + oSMOD OpCode = 0x07 + oEXP OpCode = 0x08 + oNEG OpCode = 0x09 + oLT OpCode = 0x0a + oLE OpCode = 0x0b + oGT OpCode = 0x0c + oGE OpCode = 0x0d + oEQ OpCode = 0x0e + oNOT OpCode = 0x0f + oMYADDRESS OpCode = 0x10 + oTXSENDER OpCode = 0x11 + oTXVALUE OpCode = 0x12 + oTXFEE OpCode = 0x13 + oTXDATAN OpCode = 0x14 + oTXDATA OpCode = 0x15 + oBLK_PREVHASH OpCode = 0x16 + oBLK_COINBASE OpCode = 0x17 + oBLK_TIMESTAMP OpCode = 0x18 + oBLK_NUMBER OpCode = 0x19 + oBLK_DIFFICULTY OpCode = 0x1a + oSHA256 OpCode = 0x20 + oRIPEMD160 OpCode = 0x21 + oECMUL OpCode = 0x22 + oECADD OpCode = 0x23 + oECSIGN OpCode = 0x24 + oECRECOVER OpCode = 0x25 + oECVALID OpCode = 0x26 + oPUSH OpCode = 0x30 + oPOP OpCode = 0x31 + oDUP OpCode = 0x32 + oDUPN OpCode = 0x33 + oSWAP OpCode = 0x34 + oSWAPN OpCode = 0x35 + oLOAD OpCode = 0x36 + oSTORE OpCode = 0x37 + oJMP OpCode = 0x40 + oJMPI OpCode = 0x41 + oIND OpCode = 0x42 + oEXTRO OpCode = 0x50 + oBALANCE OpCode = 0x51 + oMKTX OpCode = 0x60 + oSUICIDE OpCode = 0xff +) + +// Since the opcodes aren't all in order we can't use a regular slice +var opCodeToString = map[OpCode]string{ + oSTOP: "STOP", + oADD: "ADD", + oMUL: "MUL", + oSUB: "SUB", + oDIV: "DIV", + oSDIV: "SDIV", + oMOD: "MOD", + oSMOD: "SMOD", + oEXP: "EXP", + oNEG: "NEG", + oLT: "LT", + oLE: "LE", + oGT: "GT", + oGE: "GE", + oEQ: "EQ", + oNOT: "NOT", + oMYADDRESS: "MYADDRESS", + oTXSENDER: "TXSENDER", + oTXVALUE: "TXVALUE", + oTXFEE: "TXFEE", + oTXDATAN: "TXDATAN", + oTXDATA: "TXDATA", + oBLK_PREVHASH: "BLK_PREVHASH", + oBLK_COINBASE: "BLK_COINBASE", + oBLK_TIMESTAMP: "BLK_TIMESTAMP", + oBLK_NUMBER: "BLK_NUMBER", + oBLK_DIFFICULTY: "BLK_DIFFIFULTY", + oSHA256: "SHA256", + oRIPEMD160: "RIPEMD160", + oECMUL: "ECMUL", + oECADD: "ECADD", + oECSIGN: "ECSIGN", + oECRECOVER: "ECRECOVER", + oECVALID: "ECVALID", + oPUSH: "PUSH", + oPOP: "POP", + oDUP: "DUP", + oDUPN: "DUPN", + oSWAP: "SWAP", + oSWAPN: "SWAPN", + oLOAD: "LOAD", + oSTORE: "STORE", + oJMP: "JMP", + oJMPI: "JMPI", + oIND: "IND", + oEXTRO: "EXTRO", + oBALANCE: "BALANCE", + oMKTX: "MKTX", + oSUICIDE: "SUICIDE", +} + +func (o OpCode) String() string { + return opCodeToString[o] +} + +type OpType int + +const ( + tNorm = iota + tData + tExtro + tCrypto +) + +type TxCallback func(opType OpType) bool + +// Simple push/pop stack mechanism +type Stack struct { + data []string +} + +func NewStack() *Stack { + return &Stack{} +} + +func (st *Stack) Pop() string { + s := len(st.data) + + str := st.data[s-1] + st.data = st.data[:s-1] + + return str +} + +func (st *Stack) Popn() (*big.Int, *big.Int) { + s := len(st.data) + + strs := st.data[s-2:] + st.data = st.data[:s-2] + + return ethutil.Big(strs[0]), ethutil.Big(strs[1]) +} + +func (st *Stack) Push(d string) { + st.data = append(st.data, d) +} +func (st *Stack) Print() { + fmt.Println(st.data) +} From 33004d704e4a77368e5b2b415cfee3f05a3b469f Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 16 Jan 2014 18:12:31 +0100 Subject: [PATCH 109/459] Moved vm test --- block_manager_test.go | 77 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 block_manager_test.go diff --git a/block_manager_test.go b/block_manager_test.go new file mode 100644 index 000000000..ca5e4140e --- /dev/null +++ b/block_manager_test.go @@ -0,0 +1,77 @@ +package main + +/* +import ( + _"fmt" + "testing" +) + + +/* +func TestVm(t *testing.T) { + InitFees() + + db, _ := NewMemDatabase() + Db = db + + ctrct := NewTransaction("", 200000000, []string{ + "PUSH", "1a2f2e", + "PUSH", "hallo", + "POP", // POP hallo + "PUSH", "3", + "LOAD", // Load hallo back on the stack + + "PUSH", "1", + "PUSH", "2", + "ADD", + + "PUSH", "2", + "PUSH", "1", + "SUB", + + "PUSH", "100000000000000000000000", + "PUSH", "10000000000000", + "SDIV", + + "PUSH", "105", + "PUSH", "200", + "MOD", + + "PUSH", "100000000000000000000000", + "PUSH", "10000000000000", + "SMOD", + + "PUSH", "5", + "PUSH", "10", + "LT", + + "PUSH", "5", + "PUSH", "5", + "LE", + + "PUSH", "50", + "PUSH", "5", + "GT", + + "PUSH", "5", + "PUSH", "5", + "GE", + + "PUSH", "10", + "PUSH", "10", + "NOT", + + "MYADDRESS", + "TXSENDER", + + "STOP", + }) + tx := NewTransaction("1e8a42ea8cce13", 100, []string{}) + + block := CreateBlock("", 0, "", "c014ba53", 0, 0, "", []*Transaction{ctrct, tx}) + db.Put(block.Hash(), block.MarshalRlp()) + + bm := NewBlockManager() + bm.ProcessBlock( block ) +} +*/ From 8c4eca2490fc19a488ffb5fe1160a2ae695d018f Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 16 Jan 2014 18:12:55 +0100 Subject: [PATCH 110/459] Moved the vm code the block manager and added more opcodes --- block_manager.go | 91 ++++++++++++--- vm.go | 284 ----------------------------------------------- vm_test.go | 76 ------------- 3 files changed, 77 insertions(+), 374 deletions(-) delete mode 100644 vm.go delete mode 100644 vm_test.go diff --git a/block_manager.go b/block_manager.go index 7b2d01f29..4ddc3952b 100644 --- a/block_manager.go +++ b/block_manager.go @@ -6,14 +6,14 @@ import ( "github.com/ethereum/ethutil-go" "log" "math/big" - "strconv" ) type BlockChain struct { + // Last block LastBlock *ethutil.Block - + // The famous, the fabulous Mister GENESIIIIIIS (block) genesisBlock *ethutil.Block - + // Last known total difficulty TD *big.Int } @@ -22,11 +22,10 @@ func NewBlockChain() *BlockChain { bc.genesisBlock = ethutil.NewBlock(ethutil.Encode(ethutil.Genesis)) // Set the last know difficulty (might be 0x0 as initial value, Genesis) - bc.TD = new(big.Int) - bc.TD.SetBytes(ethutil.Config.Db.LastKnownTD()) + bc.TD = ethutil.BigD(ethutil.Config.Db.LastKnownTD()) // TODO get last block from the database - //bc.LastBlock = bc.genesisBlock + bc.LastBlock = bc.genesisBlock return bc } @@ -46,6 +45,9 @@ type BlockManager struct { // Stack for processing contracts stack *Stack + + // Last known block number + LastBlockNumber *big.Int } func NewBlockManager() *BlockManager { @@ -54,6 +56,10 @@ func NewBlockManager() *BlockManager { stack: NewStack(), } + // Set the last known block number based on the blockchains last + // block + bm.LastBlockNumber = bm.BlockInfo(bm.bc.LastBlock).Number + return bm } @@ -99,6 +105,20 @@ func (bm *BlockManager) ProcessBlock(block *ethutil.Block) error { return nil } +func (bm *BlockManager) writeBlockInfo(block *ethutil.Block) { + bi := ethutil.BlockInfo{Number: bm.LastBlockNumber.Add(bm.LastBlockNumber, big.NewInt(1))} + + ethutil.Config.Db.Put(append(block.Hash(), []byte("Info")...), bi.MarshalRlp()) +} + +func (bm *BlockManager) BlockInfo(block *ethutil.Block) ethutil.BlockInfo { + bi := ethutil.BlockInfo{} + data, _ := ethutil.Config.Db.Get(append(block.Hash(), []byte("Info")...)) + bi.UnmarshalRlp(data) + + return bi +} + func (bm *BlockManager) CalculateTD(block *ethutil.Block) bool { uncleDiff := new(big.Int) for _, uncle := range block.Uncles { @@ -204,10 +224,11 @@ func (bm *BlockManager) ProcessContract(tx *ethutil.Transaction, block *ethutil. lockChan <- true } -func (bm *BlockManager) ProcContract(tx *ethutil.Transaction, - block *ethutil.Block, cb TxCallback) { +// Contract evaluation is done here. +func (bm *BlockManager) ProcContract(tx *ethutil.Transaction, block *ethutil.Block, cb TxCallback) { // Instruction pointer pc := 0 + blockInfo := bm.BlockInfo(block) contract := block.GetContract(tx.Hash()) if contract == nil { @@ -238,6 +259,8 @@ out: } switch op { + case oSTOP: + break out case oADD: x, y := bm.stack.Popn() // (x + y) % 2 ** 256 @@ -378,7 +401,34 @@ out: case oBLK_TIMESTAMP: bm.stack.Push(big.NewInt(block.Time).String()) case oBLK_NUMBER: + bm.stack.Push(blockInfo.Number.String()) + case oBLK_DIFFICULTY: + bm.stack.Push(block.Difficulty.String()) + case oBASEFEE: + // e = 10^21 + e := big.NewInt(0).Exp(big.NewInt(10), big.NewInt(21), big.NewInt(0)) + d := new(big.Rat) + d.SetInt(block.Difficulty) + c := new(big.Rat) + c.SetFloat64(0.5) + // d = diff / 0.5 + d.Quo(d, c) + // base = floor(d) + base.Div(d.Num(), d.Denom()) + x := new(big.Int) + x.Div(e, base) + + // x = floor(10^21 / floor(diff^0.5)) + bm.stack.Push(x.String()) + case oSHA256: + case oRIPEMD160: + case oECMUL: + case oECADD: + case oECSIGN: + case oECRECOVER: + case oECVALID: + case oSHA3: case oPUSH: // Get the next entry and pushes the value on the stack pc++ @@ -386,12 +436,25 @@ out: case oPOP: // Pop current value of the stack bm.stack.Pop() - case oLOAD: - // Load instruction X on the stack - i, _ := strconv.Atoi(bm.stack.Pop()) - bm.stack.Push(contract.State().Get(string(ethutil.NumberToBytes(uint64(i), 32)))) - case oSTOP: - break out + case oDUP: + case oSWAP: + case oMLOAD: + case oMSTORE: + case oSLOAD: + case oSSTORE: + case oJMP: + case oJMPI: + case oIND: + case oEXTRO: + case oBALANCE: + case oMKTX: + case oSUICIDE: + /* + case oLOAD: + // Load instruction X on the stack + i, _ := strconv.Atoi(bm.stack.Pop()) + bm.stack.Push(contract.State().Get(string(ethutil.NumberToBytes(uint64(i), 32)))) + */ } pc++ } diff --git a/vm.go b/vm.go deleted file mode 100644 index 96a3dfa05..000000000 --- a/vm.go +++ /dev/null @@ -1,284 +0,0 @@ -package main - -import ( - "fmt" - "github.com/ethereum/ethutil-go" - "math/big" - "strconv" -) - -// Op codes -const ( - oSTOP int = 0x00 - oADD int = 0x01 - oMUL int = 0x02 - oSUB int = 0x03 - oDIV int = 0x04 - oSDIV int = 0x05 - oMOD int = 0x06 - oSMOD int = 0x07 - oEXP int = 0x08 - oNEG int = 0x09 - oLT int = 0x0a - oLE int = 0x0b - oGT int = 0x0c - oGE int = 0x0d - oEQ int = 0x0e - oNOT int = 0x0f - oMYADDRESS int = 0x10 - oTXSENDER int = 0x11 - oTXVALUE int = 0x12 - oTXFEE int = 0x13 - oTXDATAN int = 0x14 - oTXDATA int = 0x15 - oBLK_PREVHASH int = 0x16 - oBLK_COINBASE int = 0x17 - oBLK_TIMESTAMP int = 0x18 - oBLK_NUMBER int = 0x19 - oBLK_DIFFICULTY int = 0x1a - oSHA256 int = 0x20 - oRIPEMD160 int = 0x21 - oECMUL int = 0x22 - oECADD int = 0x23 - oECSIGN int = 0x24 - oECRECOVER int = 0x25 - oECVALID int = 0x26 - oPUSH int = 0x30 - oPOP int = 0x31 - oDUP int = 0x32 - oDUPN int = 0x33 - oSWAP int = 0x34 - oSWAPN int = 0x35 - oLOAD int = 0x36 - oSTORE int = 0x37 - oJMP int = 0x40 - oJMPI int = 0x41 - oIND int = 0x42 - oEXTRO int = 0x50 - oBALANCE int = 0x51 - oMKTX int = 0x60 - oSUICIDE int = 0xff -) - -type OpType int - -const ( - tNorm = iota - tData - tExtro - tCrypto -) - -type TxCallback func(opType OpType) bool - -// Simple push/pop stack mechanism -type Stack struct { - data []string -} - -func NewStack() *Stack { - return &Stack{} -} -func (st *Stack) Pop() string { - s := len(st.data) - - str := st.data[s-1] - st.data = st.data[:s-1] - - return str -} - -func (st *Stack) Popn() (*big.Int, *big.Int) { - s := len(st.data) - - strs := st.data[s-2:] - st.data = st.data[:s-2] - - return ethutil.Big(strs[0]), ethutil.Big(strs[1]) -} - -func (st *Stack) Push(d string) { - st.data = append(st.data, d) -} -func (st *Stack) Print() { - fmt.Println(st.data) -} - -type Vm struct { - // Stack - stack *Stack -} - -func NewVm() *Vm { - return &Vm{ - stack: NewStack(), - } -} - -func (vm *Vm) ProcContract(tx *ethutil.Transaction, - block *ethutil.Block, cb TxCallback) { - // Instruction pointer - pc := 0 - - contract := block.GetContract(tx.Hash()) - if contract == nil { - fmt.Println("Contract not found") - return - } - - Pow256 := ethutil.BigPow(2, 256) - - //fmt.Printf("# op arg\n") -out: - for { - // The base big int for all calculations. Use this for any results. - base := new(big.Int) - // XXX Should Instr return big int slice instead of string slice? - // Get the next instruction from the contract - //op, _, _ := Instr(contract.state.Get(string(Encode(uint32(pc))))) - nb := ethutil.NumberToBytes(uint64(pc), 32) - op, _, _ := ethutil.Instr(contract.State().Get(string(nb))) - - if !cb(0) { - break - } - - if Debug { - //fmt.Printf("%-3d %-4d\n", pc, op) - } - - switch op { - case oADD: - x, y := vm.stack.Popn() - // (x + y) % 2 ** 256 - base.Add(x, y) - base.Mod(base, Pow256) - // Pop result back on the stack - vm.stack.Push(base.String()) - case oSUB: - x, y := vm.stack.Popn() - // (x - y) % 2 ** 256 - base.Sub(x, y) - base.Mod(base, Pow256) - // Pop result back on the stack - vm.stack.Push(base.String()) - case oMUL: - x, y := vm.stack.Popn() - // (x * y) % 2 ** 256 - base.Mul(x, y) - base.Mod(base, Pow256) - // Pop result back on the stack - vm.stack.Push(base.String()) - case oDIV: - x, y := vm.stack.Popn() - // floor(x / y) - base.Div(x, y) - // Pop result back on the stack - vm.stack.Push(base.String()) - case oSDIV: - x, y := vm.stack.Popn() - // n > 2**255 - if x.Cmp(Pow256) > 0 { - x.Sub(Pow256, x) - } - if y.Cmp(Pow256) > 0 { - y.Sub(Pow256, y) - } - z := new(big.Int) - z.Div(x, y) - if z.Cmp(Pow256) > 0 { - z.Sub(Pow256, z) - } - // Push result on to the stack - vm.stack.Push(z.String()) - case oMOD: - x, y := vm.stack.Popn() - base.Mod(x, y) - vm.stack.Push(base.String()) - case oSMOD: - x, y := vm.stack.Popn() - // n > 2**255 - if x.Cmp(Pow256) > 0 { - x.Sub(Pow256, x) - } - if y.Cmp(Pow256) > 0 { - y.Sub(Pow256, y) - } - z := new(big.Int) - z.Mod(x, y) - if z.Cmp(Pow256) > 0 { - z.Sub(Pow256, z) - } - // Push result on to the stack - vm.stack.Push(z.String()) - case oEXP: - x, y := vm.stack.Popn() - base.Exp(x, y, Pow256) - - vm.stack.Push(base.String()) - case oNEG: - base.Sub(Pow256, ethutil.Big(vm.stack.Pop())) - vm.stack.Push(base.String()) - case oLT: - x, y := vm.stack.Popn() - // x < y - if x.Cmp(y) < 0 { - vm.stack.Push("1") - } else { - vm.stack.Push("0") - } - case oLE: - x, y := vm.stack.Popn() - // x <= y - if x.Cmp(y) < 1 { - vm.stack.Push("1") - } else { - vm.stack.Push("0") - } - case oGT: - x, y := vm.stack.Popn() - // x > y - if x.Cmp(y) > 0 { - vm.stack.Push("1") - } else { - vm.stack.Push("0") - } - case oGE: - x, y := vm.stack.Popn() - // x >= y - if x.Cmp(y) > -1 { - vm.stack.Push("1") - } else { - vm.stack.Push("0") - } - case oNOT: - x, y := vm.stack.Popn() - // x != y - if x.Cmp(y) != 0 { - vm.stack.Push("1") - } else { - vm.stack.Push("0") - } - case oMYADDRESS: - vm.stack.Push(string(tx.Hash())) - case oTXSENDER: - vm.stack.Push(string(tx.Sender())) - case oPUSH: - // Get the next entry and pushes the value on the stack - pc++ - vm.stack.Push(contract.State().Get(string(ethutil.NumberToBytes(uint64(pc), 32)))) - case oPOP: - // Pop current value of the stack - vm.stack.Pop() - case oLOAD: - // Load instruction X on the stack - i, _ := strconv.Atoi(vm.stack.Pop()) - vm.stack.Push(contract.State().Get(string(ethutil.NumberToBytes(uint64(i), 32)))) - case oSTOP: - break out - } - pc++ - } - - vm.stack.Print() -} diff --git a/vm_test.go b/vm_test.go deleted file mode 100644 index cb70220e1..000000000 --- a/vm_test.go +++ /dev/null @@ -1,76 +0,0 @@ -package main - -/* -import ( - _"fmt" - "testing" -) - - -func TestVm(t *testing.T) { - InitFees() - - db, _ := NewMemDatabase() - Db = db - - ctrct := NewTransaction("", 200000000, []string{ - "PUSH", "1a2f2e", - "PUSH", "hallo", - "POP", // POP hallo - "PUSH", "3", - "LOAD", // Load hallo back on the stack - - "PUSH", "1", - "PUSH", "2", - "ADD", - - "PUSH", "2", - "PUSH", "1", - "SUB", - - "PUSH", "100000000000000000000000", - "PUSH", "10000000000000", - "SDIV", - - "PUSH", "105", - "PUSH", "200", - "MOD", - - "PUSH", "100000000000000000000000", - "PUSH", "10000000000000", - "SMOD", - - "PUSH", "5", - "PUSH", "10", - "LT", - - "PUSH", "5", - "PUSH", "5", - "LE", - - "PUSH", "50", - "PUSH", "5", - "GT", - - "PUSH", "5", - "PUSH", "5", - "GE", - - "PUSH", "10", - "PUSH", "10", - "NOT", - - "MYADDRESS", - "TXSENDER", - - "STOP", - }) - tx := NewTransaction("1e8a42ea8cce13", 100, []string{}) - - block := CreateBlock("", 0, "", "c014ba53", 0, 0, "", []*Transaction{ctrct, tx}) - db.Put(block.Hash(), block.MarshalRlp()) - - bm := NewBlockManager() - bm.ProcessBlock( block ) -} -*/ From fd7e79f4e3604435d87b21349c8dd31052ef8a78 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 16 Jan 2014 18:13:17 +0100 Subject: [PATCH 111/459] Added stack and opcodes to a separate file --- stack.go | 114 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 59 insertions(+), 55 deletions(-) diff --git a/stack.go b/stack.go index 2b2f075cf..cee98555b 100644 --- a/stack.go +++ b/stack.go @@ -6,59 +6,61 @@ import ( "math/big" ) -type OpCode byte +type OpCode int // Op codes const ( - oSTOP OpCode = 0x00 - oADD OpCode = 0x01 - oMUL OpCode = 0x02 - oSUB OpCode = 0x03 - oDIV OpCode = 0x04 - oSDIV OpCode = 0x05 - oMOD OpCode = 0x06 - oSMOD OpCode = 0x07 - oEXP OpCode = 0x08 - oNEG OpCode = 0x09 - oLT OpCode = 0x0a - oLE OpCode = 0x0b - oGT OpCode = 0x0c - oGE OpCode = 0x0d - oEQ OpCode = 0x0e - oNOT OpCode = 0x0f - oMYADDRESS OpCode = 0x10 - oTXSENDER OpCode = 0x11 - oTXVALUE OpCode = 0x12 - oTXFEE OpCode = 0x13 - oTXDATAN OpCode = 0x14 - oTXDATA OpCode = 0x15 - oBLK_PREVHASH OpCode = 0x16 - oBLK_COINBASE OpCode = 0x17 - oBLK_TIMESTAMP OpCode = 0x18 - oBLK_NUMBER OpCode = 0x19 - oBLK_DIFFICULTY OpCode = 0x1a - oSHA256 OpCode = 0x20 - oRIPEMD160 OpCode = 0x21 - oECMUL OpCode = 0x22 - oECADD OpCode = 0x23 - oECSIGN OpCode = 0x24 - oECRECOVER OpCode = 0x25 - oECVALID OpCode = 0x26 - oPUSH OpCode = 0x30 - oPOP OpCode = 0x31 - oDUP OpCode = 0x32 - oDUPN OpCode = 0x33 - oSWAP OpCode = 0x34 - oSWAPN OpCode = 0x35 - oLOAD OpCode = 0x36 - oSTORE OpCode = 0x37 - oJMP OpCode = 0x40 - oJMPI OpCode = 0x41 - oIND OpCode = 0x42 - oEXTRO OpCode = 0x50 - oBALANCE OpCode = 0x51 - oMKTX OpCode = 0x60 - oSUICIDE OpCode = 0xff + oSTOP OpCode = iota + oADD + oMUL + oSUB + oDIV + oSDIV + oMOD + oSMOD + oEXP + oNEG + oLT + oLE + oGT + oGE + oEQ + oNOT + oMYADDRESS + oTXSENDER + oTXVALUE + oTXFEE + oTXDATAN + oTXDATA + oBLK_PREVHASH + oBLK_COINBASE + oBLK_TIMESTAMP + oBLK_NUMBER + oBLK_DIFFICULTY + oBASEFEE + oSHA256 OpCode = 32 + oRIPEMD160 OpCode = 33 + oECMUL OpCode = 34 + oECADD OpCode = 35 + oECSIGN OpCode = 36 + oECRECOVER OpCode = 37 + oECVALID OpCode = 38 + oSHA3 OpCode = 39 + oPUSH OpCode = 48 + oPOP OpCode = 49 + oDUP OpCode = 50 + oSWAP OpCode = 51 + oMLOAD OpCode = 52 + oMSTORE OpCode = 53 + oSLOAD OpCode = 54 + oSSTORE OpCode = 55 + oJMP OpCode = 56 + oJMPI OpCode = 57 + oIND OpCode = 58 + oEXTRO OpCode = 59 + oBALANCE OpCode = 60 + oMKTX OpCode = 61 + oSUICIDE OpCode = 62 ) // Since the opcodes aren't all in order we can't use a regular slice @@ -89,7 +91,8 @@ var opCodeToString = map[OpCode]string{ oBLK_COINBASE: "BLK_COINBASE", oBLK_TIMESTAMP: "BLK_TIMESTAMP", oBLK_NUMBER: "BLK_NUMBER", - oBLK_DIFFICULTY: "BLK_DIFFIFULTY", + oBLK_DIFFICULTY: "BLK_DIFFICULTY", + oBASEFEE: "BASEFEE", oSHA256: "SHA256", oRIPEMD160: "RIPEMD160", oECMUL: "ECMUL", @@ -97,14 +100,15 @@ var opCodeToString = map[OpCode]string{ oECSIGN: "ECSIGN", oECRECOVER: "ECRECOVER", oECVALID: "ECVALID", + oSHA3: "SHA3", oPUSH: "PUSH", oPOP: "POP", oDUP: "DUP", - oDUPN: "DUPN", oSWAP: "SWAP", - oSWAPN: "SWAPN", - oLOAD: "LOAD", - oSTORE: "STORE", + oMLOAD: "MLOAD", + oMSTORE: "MSTORE", + oSLOAD: "SLOAD", + oSSTORE: "SSTORE", oJMP: "JMP", oJMPI: "JMPI", oIND: "IND", From 815313c759acaf7cf2e295a61fa58d5ccdb0d126 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 16 Jan 2014 21:32:46 +0100 Subject: [PATCH 112/459] Added more opcodes --- block_manager.go | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/block_manager.go b/block_manager.go index 4ddc3952b..ce852612a 100644 --- a/block_manager.go +++ b/block_manager.go @@ -1,10 +1,13 @@ package main import ( + "bytes" "errors" "fmt" "github.com/ethereum/ethutil-go" + "github.com/obscuren/secp256-go" "log" + "math" "math/big" ) @@ -421,9 +424,40 @@ out: // x = floor(10^21 / floor(diff^0.5)) bm.stack.Push(x.String()) - case oSHA256: - case oRIPEMD160: + case oSHA256, oRIPEMD160: + // This is probably save + // ceil(pop / 32) + length := int(math.Ceil(float64(ethutil.Big(bm.stack.Pop()).Uint64()) / 32.0)) + // New buffer which will contain the concatenated popped items + data := new(bytes.Buffer) + for i := 0; i < length; i++ { + // Encode the number to bytes and have it 32bytes long + num := ethutil.NumberToBytes(ethutil.Big(bm.stack.Pop()).Bytes(), 256) + data.WriteString(string(num)) + } + + if op == oSHA256 { + bm.stack.Push(base.SetBytes(ethutil.Sha256Bin(data.Bytes())).String()) + } else { + bm.stack.Push(base.SetBytes(ethutil.Ripemd160(data.Bytes())).String()) + } case oECMUL: + y := bm.stack.Pop() + x := bm.stack.Pop() + n := bm.stack.Pop() + + if ethutil.Big(x).Cmp(ethutil.Big(y)) + data := new(bytes.Buffer) + data.WriteString(x) + data.WriteString(y) + if secp256.VerifyPubkeyValidity(data.Bytes()) == 1 { + // TODO + } else { + // Invalid, push infinity + bm.stack.Push("0") + bm.stack.Push("0") + } + case oECADD: case oECSIGN: case oECRECOVER: From df7967c5bbcdab3e37b198098b8fb9534979e42f Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 17 Jan 2014 16:57:06 +0100 Subject: [PATCH 113/459] ECmul tmp --- block_manager.go | 33 ++++++++++++++++++++++----------- block_manager_test.go | 2 +- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/block_manager.go b/block_manager.go index ce852612a..0831111e3 100644 --- a/block_manager.go +++ b/block_manager.go @@ -5,7 +5,7 @@ import ( "errors" "fmt" "github.com/ethereum/ethutil-go" - "github.com/obscuren/secp256-go" + "github.com/obscuren/secp256k1-go" "log" "math" "math/big" @@ -46,17 +46,20 @@ type BlockManager struct { // The block chain :) bc *BlockChain - // Stack for processing contracts - stack *Stack - // Last known block number LastBlockNumber *big.Int + + // Stack for processing contracts + stack *Stack + // non-persistent key/value memory storage + mem map[string]string } func NewBlockManager() *BlockManager { bm := &BlockManager{ bc: NewBlockChain(), stack: NewStack(), + mem: make(map[string]string), } // Set the last known block number based on the blockchains last @@ -100,24 +103,27 @@ func (bm *BlockManager) ProcessBlock(block *ethutil.Block) error { <-lockChan } + // Calculate the new total difficulty and sync back to the db if bm.CalculateTD(block) { - ethutil.Config.Db.Put(block.Hash(), block.MarshalRlp()) + ethutil.Config.Db.Put(block.Hash(), block.RlpEncode()) bm.bc.LastBlock = block } return nil } +// Unexported method for writing extra non-essential block info to the db func (bm *BlockManager) writeBlockInfo(block *ethutil.Block) { bi := ethutil.BlockInfo{Number: bm.LastBlockNumber.Add(bm.LastBlockNumber, big.NewInt(1))} - ethutil.Config.Db.Put(append(block.Hash(), []byte("Info")...), bi.MarshalRlp()) + // For now we use the block hash with the words "info" appended as key + ethutil.Config.Db.Put(append(block.Hash(), []byte("Info")...), bi.RlpEncode()) } func (bm *BlockManager) BlockInfo(block *ethutil.Block) ethutil.BlockInfo { bi := ethutil.BlockInfo{} data, _ := ethutil.Config.Db.Get(append(block.Hash(), []byte("Info")...)) - bi.UnmarshalRlp(data) + bi.RlpDecode(data) return bi } @@ -196,7 +202,7 @@ func (bm *BlockManager) AccumelateRewards(block *ethutil.Block) error { // Reward amount of ether to the coinbase address ether.AddFee(ethutil.CalculateBlockReward(block, len(block.Uncles))) - block.State().Update(block.Coinbase, string(ether.MarshalRlp())) + block.State().Update(block.Coinbase, string(ether.RlpEncode())) // TODO Reward each uncle @@ -444,19 +450,24 @@ out: case oECMUL: y := bm.stack.Pop() x := bm.stack.Pop() - n := bm.stack.Pop() + //n := bm.stack.Pop() - if ethutil.Big(x).Cmp(ethutil.Big(y)) + //if ethutil.Big(x).Cmp(ethutil.Big(y)) { data := new(bytes.Buffer) data.WriteString(x) data.WriteString(y) - if secp256.VerifyPubkeyValidity(data.Bytes()) == 1 { + if secp256k1.VerifyPubkeyValidity(data.Bytes()) == 1 { // TODO } else { // Invalid, push infinity bm.stack.Push("0") bm.stack.Push("0") } + //} else { + // // Invalid, push infinity + // bm.stack.Push("0") + // bm.stack.Push("0") + //} case oECADD: case oECSIGN: diff --git a/block_manager_test.go b/block_manager_test.go index ca5e4140e..3dcf572fd 100644 --- a/block_manager_test.go +++ b/block_manager_test.go @@ -69,7 +69,7 @@ func TestVm(t *testing.T) { tx := NewTransaction("1e8a42ea8cce13", 100, []string{}) block := CreateBlock("", 0, "", "c014ba53", 0, 0, "", []*Transaction{ctrct, tx}) - db.Put(block.Hash(), block.MarshalRlp()) + db.Put(block.Hash(), block.RlpEncode()) bm := NewBlockManager() bm.ProcessBlock( block ) From aed060a4ce59a5116ad774c2d8c0fbf857109287 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 17 Jan 2014 16:57:18 +0100 Subject: [PATCH 114/459] Updated the wire protocol --- peer.go | 61 ++++++++++++++++++++++++++++++++++++------------------- server.go | 23 ++++++++++----------- 2 files changed, 51 insertions(+), 33 deletions(-) diff --git a/peer.go b/peer.go index 8f68a9bec..d876205e2 100644 --- a/peer.go +++ b/peer.go @@ -11,7 +11,7 @@ import ( const ( // The size of the output buffer for writing messages - outputBufferSize = 50 + outputBufferSize = 50 ) type Peer struct { @@ -26,7 +26,7 @@ type Peer struct { // Determines whether it's an inbound or outbound peer inbound bool // Flag for checking the peer's connectivity state - connected int32 + connected int32 disconnect int32 // Last known message send lastSend time.Time @@ -90,8 +90,8 @@ func (p *Peer) writeMessage(msg *ethwire.InOutMsg) { } if !p.versionKnown { - switch msg.MsgType { - case "verack": // Ok + switch msg.Type { + case ethwire.MsgHandshakeTy: // Ok default: // Anything but ack is allowed return } @@ -108,6 +108,8 @@ func (p *Peer) writeMessage(msg *ethwire.InOutMsg) { // Outbound message handler. Outbound messages are handled here func (p *Peer) HandleOutbound() { + // The ping timer. Makes sure that every 2 minutes a ping is send to the peer + tickleTimer := time.NewTimer(2 * time.Minute) out: for { select { @@ -116,6 +118,10 @@ out: p.writeMessage(msg) p.lastSend = time.Now() + + case <-tickleTimer.C: + p.writeMessage(ðwire.InOutMsg{Type: ethwire.MsgPingTy}) + // Break out of the for loop if a quit message is posted case <-p.quit: break out @@ -126,7 +132,7 @@ clean: // This loop is for draining the output queue and anybody waiting for us for { select { - case <- p.outputQueue: + case <-p.outputQueue: // TODO default: break clean @@ -148,23 +154,32 @@ out: } if Debug { - log.Printf("Received %s\n", msg.MsgType) + log.Printf("Received %s\n", msg.Type.String()) } // TODO Hash data and check if for existence (= ignore) - switch msg.MsgType { - case "verack": + switch msg.Type { + case ethwire.MsgHandshakeTy: // Version message - p.handleVersionAck(msg) - case "block": - err := p.server.blockManager.ProcessBlock(ethutil.NewBlock(msg.Data)) + p.handleHandshake(msg) + case ethwire.MsgBlockTy: + err := p.server.blockManager.ProcessBlock(ethutil.NewBlock(ethutil.Encode(msg.Data))) if err != nil { log.Println(err) } - case "blockmine": - d, _ := ethutil.Decode(msg.Data, 0) - log.Printf("block mined %s\n", d) + case ethwire.MsgTxTy: + case ethwire.MsgInvTy: + case ethwire.MsgGetPeersTy: + case ethwire.MsgPeersTy: + case ethwire.MsgPingTy: + case ethwire.MsgPongTy: + + /* + case "blockmine": + d, _ := ethutil.Decode(msg.Data, 0) + log.Printf("block mined %s\n", d) + */ } } @@ -173,7 +188,7 @@ out: func (p *Peer) Start() { if !p.inbound { - err := p.pushVersionAck() + err := p.pushHandshake() if err != nil { log.Printf("Peer can't send outbound version ack", err) @@ -200,17 +215,21 @@ func (p *Peer) Stop() { log.Println("Peer shutdown") } -func (p *Peer) pushVersionAck() error { - msg := ethwire.NewMessage("verack", p.server.Nonce, []byte("01")) +func (p *Peer) pushHandshake() error { + msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, ethutil.Encode([]interface{}{ + 1, 0, p.server.Nonce, + })) p.QueueMessage(msg) return nil } -func (p *Peer) handleVersionAck(msg *ethwire.InOutMsg) { - // Detect self connect - if msg.Nonce == p.server.Nonce { +func (p *Peer) handleHandshake(msg *ethwire.InOutMsg) { + c := ethutil.Conv(msg.Data) + // [PROTOCOL_VERSION, NETWORK_ID, CLIENT_ID] + if c.Get(2).AsUint() == p.server.Nonce { + //if msg.Nonce == p.server.Nonce { log.Println("Peer connected to self, disconnecting") p.Stop() @@ -222,7 +241,7 @@ func (p *Peer) handleVersionAck(msg *ethwire.InOutMsg) { // If this is an inbound connection send an ack back if p.inbound { - err := p.pushVersionAck() + err := p.pushHandshake() if err != nil { log.Println("Peer can't send ack back") diff --git a/server.go b/server.go index f658750a9..f17cc32a0 100644 --- a/server.go +++ b/server.go @@ -7,8 +7,8 @@ import ( "github.com/ethereum/ethwire-go" "log" "net" - "time" "sync/atomic" + "time" ) func eachPeer(peers *list.List, callback func(*Peer, *list.Element)) { @@ -20,7 +20,6 @@ func eachPeer(peers *list.List, callback func(*Peer, *list.Element)) { } } - type Server struct { // Channel for shutting down the server shutdownChan chan bool @@ -75,14 +74,14 @@ func (s *Server) ConnectToPeer(addr string) error { return nil } -func (s *Server) Broadcast(msgType string, data []byte) { +func (s *Server) Broadcast(msgType ethwire.MsgType, data []byte) { eachPeer(s.peers, func(p *Peer, e *list.Element) { - p.QueueMessage(ethwire.NewMessage(msgType, 0, data)) + p.QueueMessage(ethwire.NewMessage(msgType, data)) }) } const ( - processReapingTimeout = 10 // TODO increase + processReapingTimeout = 10 // TODO increase ) func (s *Server) ReapDeadPeers() { @@ -139,13 +138,13 @@ func (s *Server) Start() { // TMP /* - go func() { - for { - s.Broadcast("block", s.blockManager.bc.GenesisBlock().MarshalRlp()) + go func() { + for { + s.Broadcast("block", s.blockManager.bc.GenesisBlock().RlpEncode()) - time.Sleep(1000 * time.Millisecond) - } - }() + time.Sleep(1000 * time.Millisecond) + } + }() */ } @@ -154,7 +153,7 @@ func (s *Server) Stop() { defer s.db.Close() eachPeer(s.peers, func(p *Peer, e *list.Element) { - p.Stop() + p.Stop() }) s.shutdownChan <- true From ddf82c333702e22d3cd7e5c693ad0603089a57a4 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 17 Jan 2014 16:57:42 +0100 Subject: [PATCH 115/459] Removed dagger broadcasting to the net --- ethereum.go | 3 ++- testing.go | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ethereum.go b/ethereum.go index 83f656fe2..d74cb4ff2 100644 --- a/ethereum.go +++ b/ethereum.go @@ -65,7 +65,8 @@ func main() { go func() { for { res := dagger.Search(ethutil.Big("01001"), ethutil.BigPow(2, 36)) - server.Broadcast("blockmine", ethutil.Encode(res.String())) + log.Println("Res dagger", res) + //server.Broadcast("blockmine", ethutil.Encode(res.String())) } }() } diff --git a/testing.go b/testing.go index 5e2aec02b..849089a5d 100644 --- a/testing.go +++ b/testing.go @@ -16,11 +16,11 @@ func Testing() { bm := NewBlockManager() tx := NewTransaction("\x00", 20, []string{"PUSH"}) - txData := tx.MarshalRlp() + txData := tx.RlpEncode() //fmt.Printf("%q\n", txData) copyTx := &Transaction{} - copyTx.UnmarshalRlp(txData) + copyTx.RlpDecode(txData) //fmt.Println(tx) //fmt.Println(copyTx) From 87434a09418e6cc2dd4b92d7e35afc6f155994bc Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 17 Jan 2014 17:14:59 +0100 Subject: [PATCH 116/459] Ping pong message --- peer.go | 8 +++++++- server.go | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/peer.go b/peer.go index d876205e2..76a810063 100644 --- a/peer.go +++ b/peer.go @@ -34,6 +34,9 @@ type Peer struct { // This flag is used by writeMessage to check if messages are allowed // to be send or not. If no version is known all messages are ignored. versionKnown bool + + // Last received pong message + lastPong int64 } func NewPeer(conn net.Conn, server *Server, inbound bool) *Peer { @@ -109,7 +112,7 @@ func (p *Peer) writeMessage(msg *ethwire.InOutMsg) { // Outbound message handler. Outbound messages are handled here func (p *Peer) HandleOutbound() { // The ping timer. Makes sure that every 2 minutes a ping is send to the peer - tickleTimer := time.NewTimer(2 * time.Minute) + tickleTimer := time.NewTicker(2 * time.Minute) out: for { select { @@ -173,7 +176,10 @@ out: case ethwire.MsgGetPeersTy: case ethwire.MsgPeersTy: case ethwire.MsgPingTy: + // Respond back with pong + p.writeMessage(ðwire.InOutMsg{Type: ethwire.MsgPongTy}) case ethwire.MsgPongTy: + p.lastPong = time.Now().Unix() /* case "blockmine": diff --git a/server.go b/server.go index f17cc32a0..9907f3b24 100644 --- a/server.go +++ b/server.go @@ -81,13 +81,13 @@ func (s *Server) Broadcast(msgType ethwire.MsgType, data []byte) { } const ( - processReapingTimeout = 10 // TODO increase + processReapingTimeout = 1 // TODO increase ) func (s *Server) ReapDeadPeers() { for { eachPeer(s.peers, func(p *Peer, e *list.Element) { - if atomic.LoadInt32(&p.disconnect) == 1 { + if atomic.LoadInt32(&p.disconnect) == 1 || (p.inbound && (time.Now().Unix()-p.lastPong) > int64(5*time.Minute)) { log.Println("Dead peer found .. reaping") s.peers.Remove(e) From 5e5f386108ea4b75167bad96a2bf7cd801306045 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 17 Jan 2014 17:51:40 +0100 Subject: [PATCH 117/459] Renamed InOutMsg to msg --- peer.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/peer.go b/peer.go index 76a810063..8e6a5d540 100644 --- a/peer.go +++ b/peer.go @@ -20,7 +20,7 @@ type Peer struct { // Net connection conn net.Conn // Output queue which is used to communicate and handle messages - outputQueue chan *ethwire.InOutMsg + outputQueue chan *ethwire.Msg // Quit channel quit chan bool // Determines whether it's an inbound or outbound peer @@ -41,7 +41,7 @@ type Peer struct { func NewPeer(conn net.Conn, server *Server, inbound bool) *Peer { return &Peer{ - outputQueue: make(chan *ethwire.InOutMsg, outputBufferSize), + outputQueue: make(chan *ethwire.Msg, outputBufferSize), quit: make(chan bool), server: server, conn: conn, @@ -53,7 +53,7 @@ func NewPeer(conn net.Conn, server *Server, inbound bool) *Peer { func NewOutboundPeer(addr string, server *Server) *Peer { p := &Peer{ - outputQueue: make(chan *ethwire.InOutMsg, outputBufferSize), + outputQueue: make(chan *ethwire.Msg, outputBufferSize), quit: make(chan bool), server: server, inbound: false, @@ -82,11 +82,11 @@ func NewOutboundPeer(addr string, server *Server) *Peer { } // Outputs any RLP encoded data to the peer -func (p *Peer) QueueMessage(msg *ethwire.InOutMsg) { +func (p *Peer) QueueMessage(msg *ethwire.Msg) { p.outputQueue <- msg } -func (p *Peer) writeMessage(msg *ethwire.InOutMsg) { +func (p *Peer) writeMessage(msg *ethwire.Msg) { // Ignore the write if we're not connected if atomic.LoadInt32(&p.connected) != 1 { return @@ -123,7 +123,7 @@ out: p.lastSend = time.Now() case <-tickleTimer.C: - p.writeMessage(ðwire.InOutMsg{Type: ethwire.MsgPingTy}) + p.writeMessage(ðwire.Msg{Type: ethwire.MsgPingTy}) // Break out of the for loop if a quit message is posted case <-p.quit: @@ -177,7 +177,7 @@ out: case ethwire.MsgPeersTy: case ethwire.MsgPingTy: // Respond back with pong - p.writeMessage(ðwire.InOutMsg{Type: ethwire.MsgPongTy}) + p.writeMessage(ðwire.Msg{Type: ethwire.MsgPongTy}) case ethwire.MsgPongTy: p.lastPong = time.Now().Unix() @@ -231,7 +231,7 @@ func (p *Peer) pushHandshake() error { return nil } -func (p *Peer) handleHandshake(msg *ethwire.InOutMsg) { +func (p *Peer) handleHandshake(msg *ethwire.Msg) { c := ethutil.Conv(msg.Data) // [PROTOCOL_VERSION, NETWORK_ID, CLIENT_ID] if c.Get(2).AsUint() == p.server.Nonce { From ee61cfcfa776a1626fe3de7138942c1d796afdca Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 18 Jan 2014 00:19:29 +0100 Subject: [PATCH 118/459] Added get peers and peers msg. --- peer.go | 64 +++++++++++++++++++++++++++++++++++++++++++++++-------- server.go | 43 +++++++++++++++++++++++++++++++++---- 2 files changed, 94 insertions(+), 13 deletions(-) diff --git a/peer.go b/peer.go index 8e6a5d540..158541028 100644 --- a/peer.go +++ b/peer.go @@ -5,6 +5,7 @@ import ( "github.com/ethereum/ethwire-go" "log" "net" + "strconv" "sync/atomic" "time" ) @@ -37,6 +38,9 @@ type Peer struct { // Last received pong message lastPong int64 + // Indicates whether a MsgGetPeersTy was requested of the peer + // this to prevent receiving false peers. + requestedPeerList bool } func NewPeer(conn net.Conn, server *Server, inbound bool) *Peer { @@ -160,8 +164,6 @@ out: log.Printf("Received %s\n", msg.Type.String()) } - // TODO Hash data and check if for existence (= ignore) - switch msg.Type { case ethwire.MsgHandshakeTy: // Version message @@ -172,20 +174,34 @@ out: log.Println(err) } case ethwire.MsgTxTy: + //p.server.blockManager.AddToTransactionPool(ethutil.NewTransactionFromData(ethutil.Encode(msg.Data))) case ethwire.MsgInvTy: case ethwire.MsgGetPeersTy: + p.requestedPeerList = true + // Peer asked for list of connected peers + p.pushPeers() case ethwire.MsgPeersTy: + // Received a list of peers (probably because MsgGetPeersTy was send) + // Only act on message if we actually requested for a peers list + if p.requestedPeerList { + data := ethutil.Conv(msg.Data) + // Create new list of possible peers for the server to process + peers := make([]string, data.Length()) + // Parse each possible peer + for i := 0; i < data.Length(); i++ { + peers[i] = data.Get(i).AsString() + strconv.Itoa(int(data.Get(i).AsUint())) + } + + // Connect to the list of peers + p.server.ProcessPeerList(peers) + // Mark unrequested again + p.requestedPeerList = false + } case ethwire.MsgPingTy: // Respond back with pong - p.writeMessage(ðwire.Msg{Type: ethwire.MsgPongTy}) + p.QueueMessage(ðwire.Msg{Type: ethwire.MsgPongTy}) case ethwire.MsgPongTy: p.lastPong = time.Now().Unix() - - /* - case "blockmine": - d, _ := ethutil.Decode(msg.Data, 0) - log.Printf("block mined %s\n", d) - */ } } @@ -231,6 +247,20 @@ func (p *Peer) pushHandshake() error { return nil } +// Pushes the list of outbound peers to the client when requested +func (p *Peer) pushPeers() { + outPeers := make([]interface{}, len(p.server.OutboundPeers())) + // Serialise each peer + for i, peer := range p.server.OutboundPeers() { + outPeers[i] = peer.RlpEncode() + } + + // Send message to the peer with the known list of connected clients + msg := ethwire.NewMessage(ethwire.MsgPeersTy, ethutil.Encode(outPeers)) + + p.QueueMessage(msg) +} + func (p *Peer) handleHandshake(msg *ethwire.Msg) { c := ethutil.Conv(msg.Data) // [PROTOCOL_VERSION, NETWORK_ID, CLIENT_ID] @@ -255,3 +285,19 @@ func (p *Peer) handleHandshake(msg *ethwire.Msg) { } } } + +func (p *Peer) RlpEncode() []byte { + host, prt, err := net.SplitHostPort(p.conn.RemoteAddr().String()) + if err != nil { + return nil + } + + i, err := strconv.Atoi(prt) + if err != nil { + return nil + } + + port := ethutil.NumberToBytes(uint16(i), 16) + + return ethutil.Encode([]interface{}{host, port}) +} diff --git a/server.go b/server.go index 9907f3b24..7a29d1bd9 100644 --- a/server.go +++ b/server.go @@ -20,6 +20,10 @@ func eachPeer(peers *list.List, callback func(*Peer, *list.Element)) { } } +const ( + processReapingTimeout = 60 // TODO increase +) + type Server struct { // Channel for shutting down the server shutdownChan chan bool @@ -66,6 +70,13 @@ func (s *Server) AddPeer(conn net.Conn) { } } +func (s *Server) ProcessPeerList(addrs []string) { + for _, addr := range addrs { + // TODO Probably requires some sanity checks + s.ConnectToPeer(addr) + } +} + func (s *Server) ConnectToPeer(addr string) error { peer := NewOutboundPeer(addr, s) @@ -74,16 +85,40 @@ func (s *Server) ConnectToPeer(addr string) error { return nil } +func (s *Server) OutboundPeers() []*Peer { + // Create a new peer slice with at least the length of the total peers + outboundPeers := make([]*Peer, s.peers.Len()) + length := 0 + eachPeer(s.peers, func(p *Peer, e *list.Element) { + if !p.inbound { + outboundPeers[length] = p + length++ + } + }) + + return outboundPeers[:length] +} + +func (s *Server) InboundPeers() []*Peer { + // Create a new peer slice with at least the length of the total peers + inboundPeers := make([]*Peer, s.peers.Len()) + length := 0 + eachPeer(s.peers, func(p *Peer, e *list.Element) { + if p.inbound { + inboundPeers[length] = p + length++ + } + }) + + return inboundPeers[:length] +} + func (s *Server) Broadcast(msgType ethwire.MsgType, data []byte) { eachPeer(s.peers, func(p *Peer, e *list.Element) { p.QueueMessage(ethwire.NewMessage(msgType, data)) }) } -const ( - processReapingTimeout = 1 // TODO increase -) - func (s *Server) ReapDeadPeers() { for { eachPeer(s.peers, func(p *Peer, e *list.Element) { From 489576b6f04585b33c8aedd8aa6e5a8d54e1a960 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 19 Jan 2014 00:35:32 +0100 Subject: [PATCH 119/459] More opcodes --- block_manager.go | 133 ++++++++++++++++++++++++++++------------------- stack.go | 11 ++-- 2 files changed, 85 insertions(+), 59 deletions(-) diff --git a/block_manager.go b/block_manager.go index 0831111e3..44b5461dc 100644 --- a/block_manager.go +++ b/block_manager.go @@ -9,6 +9,7 @@ import ( "log" "math" "math/big" + "strconv" ) type BlockChain struct { @@ -52,14 +53,14 @@ type BlockManager struct { // Stack for processing contracts stack *Stack // non-persistent key/value memory storage - mem map[string]string + mem map[string]*big.Int } func NewBlockManager() *BlockManager { bm := &BlockManager{ bc: NewBlockChain(), stack: NewStack(), - mem: make(map[string]string), + mem: make(map[string]*big.Int), } // Set the last known block number based on the blockchains last @@ -276,27 +277,27 @@ out: base.Add(x, y) base.Mod(base, Pow256) // Pop result back on the stack - bm.stack.Push(base.String()) + bm.stack.Push(base) case oSUB: x, y := bm.stack.Popn() // (x - y) % 2 ** 256 base.Sub(x, y) base.Mod(base, Pow256) // Pop result back on the stack - bm.stack.Push(base.String()) + bm.stack.Push(base) case oMUL: x, y := bm.stack.Popn() // (x * y) % 2 ** 256 base.Mul(x, y) base.Mod(base, Pow256) // Pop result back on the stack - bm.stack.Push(base.String()) + bm.stack.Push(base) case oDIV: x, y := bm.stack.Popn() // floor(x / y) base.Div(x, y) // Pop result back on the stack - bm.stack.Push(base.String()) + bm.stack.Push(base) case oSDIV: x, y := bm.stack.Popn() // n > 2**255 @@ -312,11 +313,11 @@ out: z.Sub(Pow256, z) } // Push result on to the stack - bm.stack.Push(z.String()) + bm.stack.Push(z) case oMOD: x, y := bm.stack.Popn() base.Mod(x, y) - bm.stack.Push(base.String()) + bm.stack.Push(base) case oSMOD: x, y := bm.stack.Popn() // n > 2**255 @@ -332,87 +333,85 @@ out: z.Sub(Pow256, z) } // Push result on to the stack - bm.stack.Push(z.String()) + bm.stack.Push(z) case oEXP: x, y := bm.stack.Popn() base.Exp(x, y, Pow256) - bm.stack.Push(base.String()) + bm.stack.Push(base) case oNEG: - base.Sub(Pow256, ethutil.Big(bm.stack.Pop())) - bm.stack.Push(base.String()) + base.Sub(Pow256, bm.stack.Pop()) + bm.stack.Push(base) case oLT: x, y := bm.stack.Popn() // x < y if x.Cmp(y) < 0 { - bm.stack.Push("1") + bm.stack.Push(ethutil.BigTrue) } else { - bm.stack.Push("0") + bm.stack.Push(ethutil.BigFalse) } case oLE: x, y := bm.stack.Popn() // x <= y if x.Cmp(y) < 1 { - bm.stack.Push("1") + bm.stack.Push(ethutil.BigTrue) } else { - bm.stack.Push("0") + bm.stack.Push(ethutil.BigFalse) } case oGT: x, y := bm.stack.Popn() // x > y if x.Cmp(y) > 0 { - bm.stack.Push("1") + bm.stack.Push(ethutil.BigTrue) } else { - bm.stack.Push("0") + bm.stack.Push(ethutil.BigFalse) } case oGE: x, y := bm.stack.Popn() // x >= y if x.Cmp(y) > -1 { - bm.stack.Push("1") + bm.stack.Push(ethutil.BigTrue) } else { - bm.stack.Push("0") + bm.stack.Push(ethutil.BigFalse) } case oNOT: x, y := bm.stack.Popn() // x != y if x.Cmp(y) != 0 { - bm.stack.Push("1") + bm.stack.Push(ethutil.BigTrue) } else { - bm.stack.Push("0") + bm.stack.Push(ethutil.BigFalse) } // Please note that the following code contains some // ugly string casting. This will have to change to big // ints. TODO :) case oMYADDRESS: - bm.stack.Push(string(tx.Hash())) + bm.stack.Push(ethutil.BigD(tx.Hash())) case oTXSENDER: - bm.stack.Push(string(tx.Sender())) + bm.stack.Push(ethutil.BigD(tx.Sender())) case oTXVALUE: - bm.stack.Push(tx.Value.String()) + bm.stack.Push(tx.Value) case oTXDATAN: - bm.stack.Push(big.NewInt(int64(len(tx.Data))).String()) + bm.stack.Push(big.NewInt(int64(len(tx.Data)))) case oTXDATA: - v := ethutil.Big(bm.stack.Pop()) + v := bm.stack.Pop() // v >= len(data) if v.Cmp(big.NewInt(int64(len(tx.Data)))) >= 0 { - //I know this will change. It makes no - //sense. Read comment above - bm.stack.Push(ethutil.Big("0").String()) + bm.stack.Push(ethutil.Big("0")) } else { - bm.stack.Push(ethutil.Big(tx.Data[v.Uint64()]).String()) + bm.stack.Push(ethutil.Big(tx.Data[v.Uint64()])) } case oBLK_PREVHASH: - bm.stack.Push(string(block.PrevHash)) + bm.stack.Push(ethutil.Big(block.PrevHash)) case oBLK_COINBASE: - bm.stack.Push(block.Coinbase) + bm.stack.Push(ethutil.Big(block.Coinbase)) case oBLK_TIMESTAMP: - bm.stack.Push(big.NewInt(block.Time).String()) + bm.stack.Push(big.NewInt(block.Time)) case oBLK_NUMBER: - bm.stack.Push(blockInfo.Number.String()) + bm.stack.Push(blockInfo.Number) case oBLK_DIFFICULTY: - bm.stack.Push(block.Difficulty.String()) + bm.stack.Push(block.Difficulty) case oBASEFEE: // e = 10^21 e := big.NewInt(0).Exp(big.NewInt(10), big.NewInt(21), big.NewInt(0)) @@ -429,23 +428,23 @@ out: x.Div(e, base) // x = floor(10^21 / floor(diff^0.5)) - bm.stack.Push(x.String()) + bm.stack.Push(x) case oSHA256, oRIPEMD160: // This is probably save // ceil(pop / 32) - length := int(math.Ceil(float64(ethutil.Big(bm.stack.Pop()).Uint64()) / 32.0)) + length := int(math.Ceil(float64(bm.stack.Pop().Uint64()) / 32.0)) // New buffer which will contain the concatenated popped items data := new(bytes.Buffer) for i := 0; i < length; i++ { // Encode the number to bytes and have it 32bytes long - num := ethutil.NumberToBytes(ethutil.Big(bm.stack.Pop()).Bytes(), 256) + num := ethutil.NumberToBytes(bm.stack.Pop().Bytes(), 256) data.WriteString(string(num)) } if op == oSHA256 { - bm.stack.Push(base.SetBytes(ethutil.Sha256Bin(data.Bytes())).String()) + bm.stack.Push(base.SetBytes(ethutil.Sha256Bin(data.Bytes()))) } else { - bm.stack.Push(base.SetBytes(ethutil.Ripemd160(data.Bytes())).String()) + bm.stack.Push(base.SetBytes(ethutil.Ripemd160(data.Bytes()))) } case oECMUL: y := bm.stack.Pop() @@ -454,14 +453,14 @@ out: //if ethutil.Big(x).Cmp(ethutil.Big(y)) { data := new(bytes.Buffer) - data.WriteString(x) - data.WriteString(y) + data.WriteString(x.String()) + data.WriteString(y.String()) if secp256k1.VerifyPubkeyValidity(data.Bytes()) == 1 { // TODO } else { // Invalid, push infinity - bm.stack.Push("0") - bm.stack.Push("0") + bm.stack.Push(ethutil.Big("0")) + bm.stack.Push(ethutil.Big("0")) } //} else { // // Invalid, push infinity @@ -475,31 +474,59 @@ out: case oECVALID: case oSHA3: case oPUSH: - // Get the next entry and pushes the value on the stack pc++ - bm.stack.Push(contract.State().Get(string(ethutil.NumberToBytes(uint64(pc), 32)))) + bm.stack.Push(bm.mem[strconv.Itoa(pc)]) case oPOP: // Pop current value of the stack bm.stack.Pop() case oDUP: + // Dup top stack + x := bm.stack.Pop() + bm.stack.Push(x) + bm.stack.Push(x) case oSWAP: + // Swap two top most values + x, y := bm.stack.Popn() + bm.stack.Push(y) + bm.stack.Push(x) case oMLOAD: + x := bm.stack.Pop() + bm.stack.Push(bm.mem[x.String()]) case oMSTORE: + x, y := bm.stack.Popn() + bm.mem[x.String()] = y case oSLOAD: + // Load the value in storage and push it on the stack + x := bm.stack.Pop() + // decode the object as a big integer + decoder := ethutil.NewRlpDecoder([]byte(contract.State().Get(x.String()))) + if !decoder.IsNil() { + bm.stack.Push(decoder.AsBigInt()) + } else { + bm.stack.Push(ethutil.BigFalse) + } case oSSTORE: + // Store Y at index X + x, y := bm.stack.Popn() + contract.State().Update(x.String(), string(ethutil.Encode(y))) case oJMP: + x := int(bm.stack.Pop().Uint64()) + // Set pc to x - 1 (minus one so the incrementing at the end won't effect it) + pc = x + pc-- case oJMPI: + x := bm.stack.Pop() + // Set pc to x if it's non zero + if x.Cmp(ethutil.BigFalse) != 0 { + pc = int(x.Uint64()) + pc-- + } case oIND: + bm.stack.Push(big.NewInt(int64(pc))) case oEXTRO: case oBALANCE: case oMKTX: case oSUICIDE: - /* - case oLOAD: - // Load instruction X on the stack - i, _ := strconv.Atoi(bm.stack.Pop()) - bm.stack.Push(contract.State().Get(string(ethutil.NumberToBytes(uint64(i), 32)))) - */ } pc++ } diff --git a/stack.go b/stack.go index cee98555b..9d595d85b 100644 --- a/stack.go +++ b/stack.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "github.com/ethereum/ethutil-go" "math/big" ) @@ -135,14 +134,14 @@ type TxCallback func(opType OpType) bool // Simple push/pop stack mechanism type Stack struct { - data []string + data []*big.Int } func NewStack() *Stack { return &Stack{} } -func (st *Stack) Pop() string { +func (st *Stack) Pop() *big.Int { s := len(st.data) str := st.data[s-1] @@ -154,13 +153,13 @@ func (st *Stack) Pop() string { func (st *Stack) Popn() (*big.Int, *big.Int) { s := len(st.data) - strs := st.data[s-2:] + ints := st.data[s-2:] st.data = st.data[:s-2] - return ethutil.Big(strs[0]), ethutil.Big(strs[1]) + return ints[0], ints[1] } -func (st *Stack) Push(d string) { +func (st *Stack) Push(d *big.Int) { st.data = append(st.data, d) } func (st *Stack) Print() { From b608a80ef154ac7847c3f6dbb8727f8d83aca735 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 19 Jan 2014 01:02:22 +0100 Subject: [PATCH 120/459] More opcodes --- block_manager.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/block_manager.go b/block_manager.go index 44b5461dc..9322d0d3a 100644 --- a/block_manager.go +++ b/block_manager.go @@ -524,7 +524,16 @@ out: case oIND: bm.stack.Push(big.NewInt(int64(pc))) case oEXTRO: + memAddr := bm.stack.Pop() + contractAddr := bm.stack.Pop().Bytes() + + // Push the contract's memory on to the stack + bm.stack.Push(getContractMemory(block, contractAddr, memAddr)) case oBALANCE: + // Pushes the balance of the popped value on to the stack + d := block.State().Get(bm.stack.Pop().String()) + ether := ethutil.NewEtherFromData([]byte(d)) + bm.stack.Push(ether.Amount) case oMKTX: case oSUICIDE: } @@ -533,3 +542,20 @@ out: bm.stack.Print() } + +// Returns an address from the specified contract's address +func getContractMemory(block *ethutil.Block, contractAddr []byte, memAddr *big.Int) *big.Int { + contract := block.GetContract(contractAddr) + if contract == nil { + log.Panicf("invalid contract addr %x", contractAddr) + } + val := contract.State().Get(memAddr.String()) + + // decode the object as a big integer + decoder := ethutil.NewRlpDecoder([]byte(val)) + if decoder.IsNil() { + return ethutil.BigFalse + } + + return decoder.AsBigInt() +} From 09df961abb69bb1c49a53e7d61e9c76a1ff0edcd Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 20 Jan 2014 23:26:32 +0100 Subject: [PATCH 121/459] Transaction processing. Implemented sending and receiving wei --- block_manager.go | 50 ++++++++++++++++---- block_manager_test.go | 104 ++++++++++++++++++++---------------------- peer.go | 2 +- server.go | 6 ++- 4 files changed, 96 insertions(+), 66 deletions(-) diff --git a/block_manager.go b/block_manager.go index 9322d0d3a..87af9f293 100644 --- a/block_manager.go +++ b/block_manager.go @@ -10,6 +10,7 @@ import ( "math" "math/big" "strconv" + "time" ) type BlockChain struct { @@ -44,6 +45,7 @@ func (bc *BlockChain) GenesisBlock() *ethutil.Block { } type BlockManager struct { + server *Server // The block chain :) bc *BlockChain @@ -56,11 +58,12 @@ type BlockManager struct { mem map[string]*big.Int } -func NewBlockManager() *BlockManager { +func NewBlockManager(s *Server) *BlockManager { bm := &BlockManager{ - bc: NewBlockChain(), - stack: NewStack(), - mem: make(map[string]*big.Int), + server: s, + bc: NewBlockChain(), + stack: NewStack(), + mem: make(map[string]*big.Int), } // Set the last known block number based on the blockchains last @@ -161,13 +164,16 @@ func (bm *BlockManager) CalculateTD(block *ethutil.Block) bool { // an uncle or anything that isn't on the current block chain. // Validation validates easy over difficult (dagger takes longer time = difficult) func (bm *BlockManager) ValidateBlock(block *ethutil.Block) error { + // Genesis block + if bm.bc.LastBlock == nil && block.PrevHash == "" { + return nil + } // TODO // 2. Check if the difficulty is correct // Check if we have the parent hash, if it isn't known we discard it // Reasons might be catching up or simply an invalid block - if bm.bc.LastBlock != nil && block.PrevHash == "" && - !bm.bc.HasBlock(block.PrevHash) { + if !bm.bc.HasBlock(block.PrevHash) { return errors.New("Block's parent unknown") } @@ -183,9 +189,18 @@ func (bm *BlockManager) ValidateBlock(block *ethutil.Block) error { } } + diff := block.Time - bm.bc.LastBlock.Time + if diff < 0 { + return fmt.Errorf("Block timestamp less then prev block %v", diff) + } + + // New blocks must be within the 15 minute range of the last block. + if diff > int64(15*time.Minute) { + return errors.New("Block is too far in the future of last block (> 15 minutes)") + } + // Verify the nonce of the block. Return an error if it's not valid - if bm.bc.LastBlock != nil && block.PrevHash == "" && - !DaggerVerify(ethutil.BigD(block.Hash()), block.Difficulty, block.Nonce) { + if !DaggerVerify(ethutil.BigD(block.Hash()), block.Difficulty, block.Nonce) { return errors.New("Block's nonce is invalid") } @@ -429,7 +444,7 @@ out: // x = floor(10^21 / floor(diff^0.5)) bm.stack.Push(x) - case oSHA256, oRIPEMD160: + case oSHA256, oSHA3, oRIPEMD160: // This is probably save // ceil(pop / 32) length := int(math.Ceil(float64(bm.stack.Pop().Uint64()) / 32.0)) @@ -443,6 +458,8 @@ out: if op == oSHA256 { bm.stack.Push(base.SetBytes(ethutil.Sha256Bin(data.Bytes()))) + } else if op == oSHA3 { + bm.stack.Push(base.SetBytes(ethutil.Sha3Bin(data.Bytes()))) } else { bm.stack.Push(base.SetBytes(ethutil.Ripemd160(data.Bytes()))) } @@ -472,7 +489,6 @@ out: case oECSIGN: case oECRECOVER: case oECVALID: - case oSHA3: case oPUSH: pc++ bm.stack.Push(bm.mem[strconv.Itoa(pc)]) @@ -535,7 +551,21 @@ out: ether := ethutil.NewEtherFromData([]byte(d)) bm.stack.Push(ether.Amount) case oMKTX: + value, addr := bm.stack.Popn() + from, length := bm.stack.Popn() + + j := 0 + dataItems := make([]string, int(length.Uint64())) + for i := from.Uint64(); i < length.Uint64(); i++ { + dataItems[j] = string(bm.mem[strconv.Itoa(int(i))].Bytes()) + j++ + } + // TODO sign it? + tx := ethutil.NewTransaction(string(addr.Bytes()), value, dataItems) + // Add the transaction to the tx pool + bm.server.txPool.QueueTransaction(tx) case oSUICIDE: + //addr := bm.stack.Pop() } pc++ } diff --git a/block_manager_test.go b/block_manager_test.go index 3dcf572fd..5f200f3e7 100644 --- a/block_manager_test.go +++ b/block_manager_test.go @@ -1,77 +1,73 @@ package main -/* import ( - _"fmt" - "testing" + _ "fmt" + "testing" ) - -/* func TestVm(t *testing.T) { - InitFees() + InitFees() - db, _ := NewMemDatabase() - Db = db + db, _ := NewMemDatabase() + Db = db - ctrct := NewTransaction("", 200000000, []string{ - "PUSH", "1a2f2e", - "PUSH", "hallo", - "POP", // POP hallo - "PUSH", "3", - "LOAD", // Load hallo back on the stack + ctrct := NewTransaction("", 200000000, []string{ + "PUSH", "1a2f2e", + "PUSH", "hallo", + "POP", // POP hallo + "PUSH", "3", + "LOAD", // Load hallo back on the stack - "PUSH", "1", - "PUSH", "2", - "ADD", + "PUSH", "1", + "PUSH", "2", + "ADD", - "PUSH", "2", - "PUSH", "1", - "SUB", + "PUSH", "2", + "PUSH", "1", + "SUB", - "PUSH", "100000000000000000000000", - "PUSH", "10000000000000", - "SDIV", + "PUSH", "100000000000000000000000", + "PUSH", "10000000000000", + "SDIV", - "PUSH", "105", - "PUSH", "200", - "MOD", + "PUSH", "105", + "PUSH", "200", + "MOD", - "PUSH", "100000000000000000000000", - "PUSH", "10000000000000", - "SMOD", + "PUSH", "100000000000000000000000", + "PUSH", "10000000000000", + "SMOD", - "PUSH", "5", - "PUSH", "10", - "LT", + "PUSH", "5", + "PUSH", "10", + "LT", - "PUSH", "5", - "PUSH", "5", - "LE", + "PUSH", "5", + "PUSH", "5", + "LE", - "PUSH", "50", - "PUSH", "5", - "GT", + "PUSH", "50", + "PUSH", "5", + "GT", - "PUSH", "5", - "PUSH", "5", - "GE", + "PUSH", "5", + "PUSH", "5", + "GE", - "PUSH", "10", - "PUSH", "10", - "NOT", + "PUSH", "10", + "PUSH", "10", + "NOT", - "MYADDRESS", - "TXSENDER", + "MYADDRESS", + "TXSENDER", - "STOP", - }) - tx := NewTransaction("1e8a42ea8cce13", 100, []string{}) + "STOP", + }) + tx := NewTransaction("1e8a42ea8cce13", 100, []string{}) - block := CreateBlock("", 0, "", "c014ba53", 0, 0, "", []*Transaction{ctrct, tx}) - db.Put(block.Hash(), block.RlpEncode()) + block := CreateBlock("", 0, "", "c014ba53", 0, 0, "", []*Transaction{ctrct, tx}) + db.Put(block.Hash(), block.RlpEncode()) - bm := NewBlockManager() - bm.ProcessBlock( block ) + bm := NewBlockManager() + bm.ProcessBlock(block) } -*/ diff --git a/peer.go b/peer.go index 158541028..0f3422826 100644 --- a/peer.go +++ b/peer.go @@ -174,7 +174,7 @@ out: log.Println(err) } case ethwire.MsgTxTy: - //p.server.blockManager.AddToTransactionPool(ethutil.NewTransactionFromData(ethutil.Encode(msg.Data))) + p.server.txPool.QueueTransaction(ethutil.NewTransactionFromData(ethutil.Encode(msg.Data))) case ethwire.MsgInvTy: case ethwire.MsgGetPeersTy: p.requestedPeerList = true diff --git a/server.go b/server.go index 7a29d1bd9..3a35a43a2 100644 --- a/server.go +++ b/server.go @@ -32,6 +32,9 @@ type Server struct { db *ethdb.MemDatabase // Block manager for processing new blocks and managing the block chain blockManager *BlockManager + // The transaction pool. Transaction can be pushed on this pool + // for later including in the blocks + txPool *TxPool // Peers (NYI) peers *list.List // Nonce @@ -50,11 +53,12 @@ func NewServer() (*Server, error) { nonce, _ := ethutil.RandomUint64() server := &Server{ shutdownChan: make(chan bool), - blockManager: NewBlockManager(), db: db, peers: list.New(), Nonce: nonce, } + server.txPool = NewTxPool(server) + server.blockManager = NewBlockManager(server) return server, nil } From e47230f82da93ef0110faa76211b9b6f13b1060b Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 20 Jan 2014 23:26:53 +0100 Subject: [PATCH 122/459] Transaction processing. Implemented sending and receiving wei --- transaction_pool.go | 161 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 transaction_pool.go diff --git a/transaction_pool.go b/transaction_pool.go new file mode 100644 index 000000000..f645afd06 --- /dev/null +++ b/transaction_pool.go @@ -0,0 +1,161 @@ +package main + +import ( + "container/list" + "errors" + "github.com/ethereum/ethutil-go" + "log" + "math/big" + "sync" +) + +const ( + txPoolQueueSize = 50 +) + +func FindTx(pool *list.List, finder func(*ethutil.Transaction, *list.Element) bool) *ethutil.Transaction { + for e := pool.Front(); e != nil; e = e.Next() { + if tx, ok := e.Value.(*ethutil.Transaction); ok { + if finder(tx, e) { + return tx + } + } + } + + return nil +} + +// The tx pool a thread safe transaction pool handler. In order to +// guarantee a non blocking pool we use a queue channel which can be +// independently read without needing access to the actual pool. If the +// pool is being drained or synced for whatever reason the transactions +// will simple queue up and handled when the mutex is freed. +type TxPool struct { + server *Server + // The mutex for accessing the Tx pool. + mutex sync.Mutex + // Queueing channel for reading and writing incoming + // transactions to + queueChan chan *ethutil.Transaction + // Quiting channel + quit chan bool + + pool *list.List +} + +func NewTxPool(s *Server) *TxPool { + return &TxPool{ + server: s, + mutex: sync.Mutex{}, + pool: list.New(), + queueChan: make(chan *ethutil.Transaction, txPoolQueueSize), + quit: make(chan bool), + } +} + +// Blocking function. Don't use directly. Use QueueTransaction instead +func (pool *TxPool) addTransaction(tx *ethutil.Transaction) { + pool.mutex.Lock() + defer pool.mutex.Unlock() + + pool.pool.PushBack(tx) +} + +// Process transaction validates the Tx and processes funds from the +// sender to the recipient. +func (pool *TxPool) processTransaction(tx *ethutil.Transaction) error { + // Get the last block so we can retrieve the sender and receiver from + // the merkle trie + block := pool.server.blockManager.bc.LastBlock + // Something has gone horribly wrong if this happens + if block == nil { + return errors.New("No last block on the block chain") + } + + var sender, receiver *ethutil.Ether + + // Get the sender + data := block.State().Get(string(tx.Sender())) + // If it doesn't exist create a new account. Of course trying to send funds + // from this account will fail since it will hold 0 Wei + if data == "" { + sender = ethutil.NewEther(big.NewInt(0)) + } else { + sender = ethutil.NewEtherFromData([]byte(data)) + } + // Defer the update. Whatever happens it should be persisted + defer block.State().Update(string(tx.Sender()), string(sender.RlpEncode())) + + // Make sure there's enough in the sender's account. Having insufficient + // funds won't invalidate this transaction but simple ignores it. + if sender.Amount.Cmp(tx.Value) < 0 { + return errors.New("Insufficient amount in sender's account") + } + + // Subtract the amount from the senders account + sender.Amount.Sub(sender.Amount, tx.Value) + // Increment the nonce making each tx valid only once to prevent replay + // attacks + sender.Nonce += 1 + + // Get the receiver + data = block.State().Get(tx.Recipient) + // If the receiver doesn't exist yet, create a new account to which the + // funds will be send. + if data == "" { + receiver = ethutil.NewEther(big.NewInt(0)) + } else { + receiver = ethutil.NewEtherFromData([]byte(data)) + } + // Defer the update + defer block.State().Update(tx.Recipient, string(receiver.RlpEncode())) + + // Add the amount to receivers account which should conclude this transaction + receiver.Amount.Add(receiver.Amount, tx.Value) + + return nil +} + +func (pool *TxPool) queueHandler() { +out: + for { + select { + case tx := <-pool.queueChan: + // Process the transaction + err := pool.processTransaction(tx) + if err != nil { + log.Println("Error processing Tx", err) + } else { + // Call blocking version. At this point it + // doesn't matter since this is a goroutine + pool.addTransaction(tx) + } + case <-pool.quit: + break out + } + } +} + +func (pool *TxPool) QueueTransaction(tx *ethutil.Transaction) { + pool.queueChan <- tx +} + +func (pool *TxPool) Flush() { + pool.mutex.Lock() + + defer pool.mutex.Unlock() + + pool.mutex.Unlock() +} + +func (pool *TxPool) Start() { + go pool.queueHandler() +} + +func (pool *TxPool) Stop() { + log.Println("[TXP] Stopping...") + + close(pool.quit) + + pool.Flush() +} From 3616080db46931202003157bacf10748008bebc0 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 21 Jan 2014 23:27:08 +0100 Subject: [PATCH 123/459] Added synchronisation of transactions across remote pools --- dev_console.go | 16 +++++++--- ethereum.go | 77 ++++++++++++++++++++++++++++----------------- peer.go | 6 ++-- server.go | 34 +++++++++++--------- transaction_pool.go | 26 ++++++++++++--- 5 files changed, 103 insertions(+), 56 deletions(-) diff --git a/dev_console.go b/dev_console.go index 5340a5f46..d14f019e5 100644 --- a/dev_console.go +++ b/dev_console.go @@ -12,15 +12,16 @@ import ( ) type Console struct { - db *ethdb.MemDatabase - trie *ethutil.Trie + db *ethdb.MemDatabase + trie *ethutil.Trie + server *Server } -func NewConsole() *Console { +func NewConsole(s *Server) *Console { db, _ := ethdb.NewMemDatabase() trie := ethutil.NewTrie(db, "") - return &Console{db: db, trie: trie} + return &Console{db: db, trie: trie, server: s} } func (i *Console) ValidateInput(action string, argumentLength int) error { @@ -43,6 +44,9 @@ func (i *Console) ValidateInput(action string, argumentLength int) error { case action == "encode" && argumentLength != 1: err = true expArgCount = 1 + case action == "tx" && argumentLength != 2: + err = true + expArgCount = 2 } if err { @@ -105,6 +109,10 @@ func (i *Console) ParseInput(input string) bool { fmt.Printf("%q\n", d) case "encode": fmt.Printf("%q\n", ethutil.Encode(tokens[1])) + case "tx": + tx := ethutil.NewTransaction(tokens[1], ethutil.Big(tokens[2]), []string{""}) + + i.server.txPool.QueueTransaction(tx) case "exit", "quit", "q": return false case "help": diff --git a/ethereum.go b/ethereum.go index d74cb4ff2..b7f059a02 100644 --- a/ethereum.go +++ b/ethereum.go @@ -7,6 +7,7 @@ import ( "log" "os" "os/signal" + "path" "runtime" ) @@ -44,36 +45,54 @@ func main() { Init() - if StartConsole { - console := NewConsole() - console.Start() - } else { - log.Println("Starting Ethereum") - server, err := NewServer() + ethutil.ReadConfig() - if err != nil { - log.Println(err) - return - } + server, err := NewServer() - RegisterInterupts(server) - - if StartMining { - log.Println("Mining started") - dagger := &Dagger{} - - go func() { - for { - res := dagger.Search(ethutil.Big("01001"), ethutil.BigPow(2, 36)) - log.Println("Res dagger", res) - //server.Broadcast("blockmine", ethutil.Encode(res.String())) - } - }() - } - - server.Start() - - // Wait for shutdown - server.WaitForShutdown() + if err != nil { + log.Println(err) + return } + + if StartConsole { + err := os.Mkdir(ethutil.Config.ExecPath, os.ModePerm) + // Error is OK if the error is ErrExist + if err != nil && !os.IsExist(err) { + log.Panic("Unable to create EXECPATH. Exiting") + } + + // TODO The logger will eventually be a non blocking logger. Logging is a expensive task + // Log to file only + file, err := os.OpenFile(path.Join(ethutil.Config.ExecPath, "debug.log"), os.O_RDWR|os.O_CREATE, os.ModePerm) + if err != nil { + log.Panic("Unable to set proper logger", err) + } + + ethutil.Config.Log = log.New(file, "", 0) + + console := NewConsole(server) + go console.Start() + } + + log.Println("Starting Ethereum") + + RegisterInterupts(server) + + if StartMining { + log.Println("Mining started") + dagger := &Dagger{} + + go func() { + for { + res := dagger.Search(ethutil.Big("01001"), ethutil.BigPow(2, 36)) + log.Println("Res dagger", res) + //server.Broadcast("blockmine", ethutil.Encode(res.String())) + } + }() + } + + server.Start() + + // Wait for shutdown + server.WaitForShutdown() } diff --git a/peer.go b/peer.go index 0f3422826..207f9e59f 100644 --- a/peer.go +++ b/peer.go @@ -62,7 +62,7 @@ func NewOutboundPeer(addr string, server *Server) *Peer { server: server, inbound: false, connected: 0, - disconnect: 1, + disconnect: 0, } // Set up the connection in another goroutine so we don't block the main thread @@ -169,12 +169,12 @@ out: // Version message p.handleHandshake(msg) case ethwire.MsgBlockTy: - err := p.server.blockManager.ProcessBlock(ethutil.NewBlock(ethutil.Encode(msg.Data))) + err := p.server.blockManager.ProcessBlock(ethutil.NewBlock(msg.Data)) if err != nil { log.Println(err) } case ethwire.MsgTxTy: - p.server.txPool.QueueTransaction(ethutil.NewTransactionFromData(ethutil.Encode(msg.Data))) + p.server.txPool.QueueTransaction(ethutil.NewTransactionFromData(msg.Data)) case ethwire.MsgInvTy: case ethwire.MsgGetPeersTy: p.requestedPeerList = true diff --git a/server.go b/server.go index 3a35a43a2..2927f023a 100644 --- a/server.go +++ b/server.go @@ -48,7 +48,7 @@ func NewServer() (*Server, error) { return nil, err } - ethutil.SetConfig(db) + ethutil.Config.Db = db nonce, _ := ethutil.RandomUint64() server := &Server{ @@ -152,28 +152,30 @@ func (s *Server) Start() { s.Stop() } - - return } else { log.Fatal(err) } + } else { + // Starting accepting connections + go func() { + for { + conn, err := ln.Accept() + if err != nil { + log.Println(err) + + continue + } + + go s.AddPeer(conn) + } + }() } // Start the reaping processes go s.ReapDeadPeers() - go func() { - for { - conn, err := ln.Accept() - if err != nil { - log.Println(err) - - continue - } - - go s.AddPeer(conn) - } - }() + // Start the tx pool + s.txPool.Start() // TMP /* @@ -196,6 +198,8 @@ func (s *Server) Stop() { }) s.shutdownChan <- true + + s.txPool.Stop() } // This function will wait for a shutdown and resumes main thread execution diff --git a/transaction_pool.go b/transaction_pool.go index f645afd06..b302931de 100644 --- a/transaction_pool.go +++ b/transaction_pool.go @@ -1,9 +1,11 @@ package main import ( + "bytes" "container/list" "errors" "github.com/ethereum/ethutil-go" + "github.com/ethereum/ethwire-go" "log" "math/big" "sync" @@ -56,9 +58,11 @@ func NewTxPool(s *Server) *TxPool { // Blocking function. Don't use directly. Use QueueTransaction instead func (pool *TxPool) addTransaction(tx *ethutil.Transaction) { pool.mutex.Lock() - defer pool.mutex.Unlock() - pool.pool.PushBack(tx) + pool.mutex.Unlock() + + // Broadcast the transaction to the rest of the peers + pool.server.Broadcast(ethwire.MsgTxTy, tx.RlpEncode()) } // Process transaction validates the Tx and processes funds from the @@ -89,7 +93,12 @@ func (pool *TxPool) processTransaction(tx *ethutil.Transaction) error { // Make sure there's enough in the sender's account. Having insufficient // funds won't invalidate this transaction but simple ignores it. if sender.Amount.Cmp(tx.Value) < 0 { - return errors.New("Insufficient amount in sender's account") + if Debug { + log.Println("Insufficient amount in sender's account. Adding 1 ETH for debug") + sender.Amount = ethutil.BigPow(10, 18) + } else { + return errors.New("Insufficient amount in sender's account") + } } // Subtract the amount from the senders account @@ -121,6 +130,15 @@ out: for { select { case tx := <-pool.queueChan: + hash := tx.Hash() + foundTx := FindTx(pool.pool, func(tx *ethutil.Transaction, e *list.Element) bool { + return bytes.Compare(tx.Hash(), hash) == 0 + }) + + if foundTx != nil { + break + } + // Process the transaction err := pool.processTransaction(tx) if err != nil { @@ -144,8 +162,6 @@ func (pool *TxPool) Flush() { pool.mutex.Lock() defer pool.mutex.Unlock() - - pool.mutex.Unlock() } func (pool *TxPool) Start() { From 477e8a7a73820ece05bbb990607a1919d3788960 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 23 Jan 2014 20:16:52 +0100 Subject: [PATCH 124/459] Rearrange packages --- block_manager.go | 591 ------------------------------------------ block_manager_test.go | 73 ------ dagger.go | 149 ----------- dagger_test.go | 18 -- dev_console.go | 16 +- ethereum.go | 26 +- peer.go | 303 ---------------------- server.go | 208 --------------- stack.go | 167 ------------ transaction_pool.go | 177 ------------- 10 files changed, 22 insertions(+), 1706 deletions(-) delete mode 100644 block_manager.go delete mode 100644 block_manager_test.go delete mode 100644 dagger.go delete mode 100644 dagger_test.go delete mode 100644 peer.go delete mode 100644 server.go delete mode 100644 stack.go delete mode 100644 transaction_pool.go diff --git a/block_manager.go b/block_manager.go deleted file mode 100644 index 87af9f293..000000000 --- a/block_manager.go +++ /dev/null @@ -1,591 +0,0 @@ -package main - -import ( - "bytes" - "errors" - "fmt" - "github.com/ethereum/ethutil-go" - "github.com/obscuren/secp256k1-go" - "log" - "math" - "math/big" - "strconv" - "time" -) - -type BlockChain struct { - // Last block - LastBlock *ethutil.Block - // The famous, the fabulous Mister GENESIIIIIIS (block) - genesisBlock *ethutil.Block - // Last known total difficulty - TD *big.Int -} - -func NewBlockChain() *BlockChain { - bc := &BlockChain{} - bc.genesisBlock = ethutil.NewBlock(ethutil.Encode(ethutil.Genesis)) - - // Set the last know difficulty (might be 0x0 as initial value, Genesis) - bc.TD = ethutil.BigD(ethutil.Config.Db.LastKnownTD()) - - // TODO get last block from the database - bc.LastBlock = bc.genesisBlock - - return bc -} - -func (bc *BlockChain) HasBlock(hash string) bool { - data, _ := ethutil.Config.Db.Get([]byte(hash)) - return len(data) != 0 -} - -func (bc *BlockChain) GenesisBlock() *ethutil.Block { - return bc.genesisBlock -} - -type BlockManager struct { - server *Server - // The block chain :) - bc *BlockChain - - // Last known block number - LastBlockNumber *big.Int - - // Stack for processing contracts - stack *Stack - // non-persistent key/value memory storage - mem map[string]*big.Int -} - -func NewBlockManager(s *Server) *BlockManager { - bm := &BlockManager{ - server: s, - bc: NewBlockChain(), - stack: NewStack(), - mem: make(map[string]*big.Int), - } - - // Set the last known block number based on the blockchains last - // block - bm.LastBlockNumber = bm.BlockInfo(bm.bc.LastBlock).Number - - return bm -} - -// Process a block. -func (bm *BlockManager) ProcessBlock(block *ethutil.Block) error { - // Block validation - if err := bm.ValidateBlock(block); err != nil { - return err - } - - // I'm not sure, but I don't know if there should be thrown - // any errors at this time. - if err := bm.AccumelateRewards(block); err != nil { - return err - } - - // Get the tx count. Used to create enough channels to 'join' the go routines - txCount := len(block.Transactions()) - // Locking channel. When it has been fully buffered this method will return - lockChan := make(chan bool, txCount) - - // Process each transaction/contract - for _, tx := range block.Transactions() { - // If there's no recipient, it's a contract - if tx.IsContract() { - go bm.ProcessContract(tx, block, lockChan) - } else { - // "finish" tx which isn't a contract - lockChan <- true - } - } - - // Wait for all Tx to finish processing - for i := 0; i < txCount; i++ { - <-lockChan - } - - // Calculate the new total difficulty and sync back to the db - if bm.CalculateTD(block) { - ethutil.Config.Db.Put(block.Hash(), block.RlpEncode()) - bm.bc.LastBlock = block - } - - return nil -} - -// Unexported method for writing extra non-essential block info to the db -func (bm *BlockManager) writeBlockInfo(block *ethutil.Block) { - bi := ethutil.BlockInfo{Number: bm.LastBlockNumber.Add(bm.LastBlockNumber, big.NewInt(1))} - - // For now we use the block hash with the words "info" appended as key - ethutil.Config.Db.Put(append(block.Hash(), []byte("Info")...), bi.RlpEncode()) -} - -func (bm *BlockManager) BlockInfo(block *ethutil.Block) ethutil.BlockInfo { - bi := ethutil.BlockInfo{} - data, _ := ethutil.Config.Db.Get(append(block.Hash(), []byte("Info")...)) - bi.RlpDecode(data) - - return bi -} - -func (bm *BlockManager) CalculateTD(block *ethutil.Block) bool { - uncleDiff := new(big.Int) - for _, uncle := range block.Uncles { - uncleDiff = uncleDiff.Add(uncleDiff, uncle.Difficulty) - } - - // TD(genesis_block) = 0 and TD(B) = TD(B.parent) + sum(u.difficulty for u in B.uncles) + B.difficulty - td := new(big.Int) - td = td.Add(bm.bc.TD, uncleDiff) - td = td.Add(td, block.Difficulty) - - // The new TD will only be accepted if the new difficulty is - // is greater than the previous. - if td.Cmp(bm.bc.TD) > 0 { - bm.bc.LastBlock = block - // Set the new total difficulty back to the block chain - bm.bc.TD = td - - if Debug { - log.Println("TD(block) =", td) - } - - return true - } - - return false -} - -// Validates the current block. Returns an error if the block was invalid, -// an uncle or anything that isn't on the current block chain. -// Validation validates easy over difficult (dagger takes longer time = difficult) -func (bm *BlockManager) ValidateBlock(block *ethutil.Block) error { - // Genesis block - if bm.bc.LastBlock == nil && block.PrevHash == "" { - return nil - } - // TODO - // 2. Check if the difficulty is correct - - // Check if we have the parent hash, if it isn't known we discard it - // Reasons might be catching up or simply an invalid block - if !bm.bc.HasBlock(block.PrevHash) { - return errors.New("Block's parent unknown") - } - - // Check each uncle's previous hash. In order for it to be valid - // is if it has the same block hash as the current - for _, uncle := range block.Uncles { - if uncle.PrevHash != block.PrevHash { - if Debug { - log.Printf("Uncle prvhash mismatch %x %x\n", block.PrevHash, uncle.PrevHash) - } - - return errors.New("Mismatching Prvhash from uncle") - } - } - - diff := block.Time - bm.bc.LastBlock.Time - if diff < 0 { - return fmt.Errorf("Block timestamp less then prev block %v", diff) - } - - // New blocks must be within the 15 minute range of the last block. - if diff > int64(15*time.Minute) { - return errors.New("Block is too far in the future of last block (> 15 minutes)") - } - - // Verify the nonce of the block. Return an error if it's not valid - if !DaggerVerify(ethutil.BigD(block.Hash()), block.Difficulty, block.Nonce) { - - return errors.New("Block's nonce is invalid") - } - - log.Println("Block validation PASSED") - - return nil -} - -func (bm *BlockManager) AccumelateRewards(block *ethutil.Block) error { - // Get the coinbase rlp data - d := block.State().Get(block.Coinbase) - - ether := ethutil.NewEtherFromData([]byte(d)) - - // Reward amount of ether to the coinbase address - ether.AddFee(ethutil.CalculateBlockReward(block, len(block.Uncles))) - block.State().Update(block.Coinbase, string(ether.RlpEncode())) - - // TODO Reward each uncle - - return nil -} - -func (bm *BlockManager) ProcessContract(tx *ethutil.Transaction, block *ethutil.Block, lockChan chan bool) { - // Recovering function in case the VM had any errors - defer func() { - if r := recover(); r != nil { - fmt.Println("Recovered from VM execution with err =", r) - // Let the channel know where done even though it failed (so the execution may resume normally) - lockChan <- true - } - }() - - // Process contract - bm.ProcContract(tx, block, func(opType OpType) bool { - // TODO turn on once big ints are in place - //if !block.PayFee(tx.Hash(), StepFee.Uint64()) { - // return false - //} - - return true // Continue - }) - - // Broadcast we're done - lockChan <- true -} - -// Contract evaluation is done here. -func (bm *BlockManager) ProcContract(tx *ethutil.Transaction, block *ethutil.Block, cb TxCallback) { - // Instruction pointer - pc := 0 - blockInfo := bm.BlockInfo(block) - - contract := block.GetContract(tx.Hash()) - if contract == nil { - fmt.Println("Contract not found") - return - } - - Pow256 := ethutil.BigPow(2, 256) - - //fmt.Printf("# op arg\n") -out: - for { - // The base big int for all calculations. Use this for any results. - base := new(big.Int) - // XXX Should Instr return big int slice instead of string slice? - // Get the next instruction from the contract - //op, _, _ := Instr(contract.state.Get(string(Encode(uint32(pc))))) - nb := ethutil.NumberToBytes(uint64(pc), 32) - o, _, _ := ethutil.Instr(contract.State().Get(string(nb))) - op := OpCode(o) - - if !cb(0) { - break - } - - if Debug { - //fmt.Printf("%-3d %-4s\n", pc, op.String()) - } - - switch op { - case oSTOP: - break out - case oADD: - x, y := bm.stack.Popn() - // (x + y) % 2 ** 256 - base.Add(x, y) - base.Mod(base, Pow256) - // Pop result back on the stack - bm.stack.Push(base) - case oSUB: - x, y := bm.stack.Popn() - // (x - y) % 2 ** 256 - base.Sub(x, y) - base.Mod(base, Pow256) - // Pop result back on the stack - bm.stack.Push(base) - case oMUL: - x, y := bm.stack.Popn() - // (x * y) % 2 ** 256 - base.Mul(x, y) - base.Mod(base, Pow256) - // Pop result back on the stack - bm.stack.Push(base) - case oDIV: - x, y := bm.stack.Popn() - // floor(x / y) - base.Div(x, y) - // Pop result back on the stack - bm.stack.Push(base) - case oSDIV: - x, y := bm.stack.Popn() - // n > 2**255 - if x.Cmp(Pow256) > 0 { - x.Sub(Pow256, x) - } - if y.Cmp(Pow256) > 0 { - y.Sub(Pow256, y) - } - z := new(big.Int) - z.Div(x, y) - if z.Cmp(Pow256) > 0 { - z.Sub(Pow256, z) - } - // Push result on to the stack - bm.stack.Push(z) - case oMOD: - x, y := bm.stack.Popn() - base.Mod(x, y) - bm.stack.Push(base) - case oSMOD: - x, y := bm.stack.Popn() - // n > 2**255 - if x.Cmp(Pow256) > 0 { - x.Sub(Pow256, x) - } - if y.Cmp(Pow256) > 0 { - y.Sub(Pow256, y) - } - z := new(big.Int) - z.Mod(x, y) - if z.Cmp(Pow256) > 0 { - z.Sub(Pow256, z) - } - // Push result on to the stack - bm.stack.Push(z) - case oEXP: - x, y := bm.stack.Popn() - base.Exp(x, y, Pow256) - - bm.stack.Push(base) - case oNEG: - base.Sub(Pow256, bm.stack.Pop()) - bm.stack.Push(base) - case oLT: - x, y := bm.stack.Popn() - // x < y - if x.Cmp(y) < 0 { - bm.stack.Push(ethutil.BigTrue) - } else { - bm.stack.Push(ethutil.BigFalse) - } - case oLE: - x, y := bm.stack.Popn() - // x <= y - if x.Cmp(y) < 1 { - bm.stack.Push(ethutil.BigTrue) - } else { - bm.stack.Push(ethutil.BigFalse) - } - case oGT: - x, y := bm.stack.Popn() - // x > y - if x.Cmp(y) > 0 { - bm.stack.Push(ethutil.BigTrue) - } else { - bm.stack.Push(ethutil.BigFalse) - } - case oGE: - x, y := bm.stack.Popn() - // x >= y - if x.Cmp(y) > -1 { - bm.stack.Push(ethutil.BigTrue) - } else { - bm.stack.Push(ethutil.BigFalse) - } - case oNOT: - x, y := bm.stack.Popn() - // x != y - if x.Cmp(y) != 0 { - bm.stack.Push(ethutil.BigTrue) - } else { - bm.stack.Push(ethutil.BigFalse) - } - - // Please note that the following code contains some - // ugly string casting. This will have to change to big - // ints. TODO :) - case oMYADDRESS: - bm.stack.Push(ethutil.BigD(tx.Hash())) - case oTXSENDER: - bm.stack.Push(ethutil.BigD(tx.Sender())) - case oTXVALUE: - bm.stack.Push(tx.Value) - case oTXDATAN: - bm.stack.Push(big.NewInt(int64(len(tx.Data)))) - case oTXDATA: - v := bm.stack.Pop() - // v >= len(data) - if v.Cmp(big.NewInt(int64(len(tx.Data)))) >= 0 { - bm.stack.Push(ethutil.Big("0")) - } else { - bm.stack.Push(ethutil.Big(tx.Data[v.Uint64()])) - } - case oBLK_PREVHASH: - bm.stack.Push(ethutil.Big(block.PrevHash)) - case oBLK_COINBASE: - bm.stack.Push(ethutil.Big(block.Coinbase)) - case oBLK_TIMESTAMP: - bm.stack.Push(big.NewInt(block.Time)) - case oBLK_NUMBER: - bm.stack.Push(blockInfo.Number) - case oBLK_DIFFICULTY: - bm.stack.Push(block.Difficulty) - case oBASEFEE: - // e = 10^21 - e := big.NewInt(0).Exp(big.NewInt(10), big.NewInt(21), big.NewInt(0)) - d := new(big.Rat) - d.SetInt(block.Difficulty) - c := new(big.Rat) - c.SetFloat64(0.5) - // d = diff / 0.5 - d.Quo(d, c) - // base = floor(d) - base.Div(d.Num(), d.Denom()) - - x := new(big.Int) - x.Div(e, base) - - // x = floor(10^21 / floor(diff^0.5)) - bm.stack.Push(x) - case oSHA256, oSHA3, oRIPEMD160: - // This is probably save - // ceil(pop / 32) - length := int(math.Ceil(float64(bm.stack.Pop().Uint64()) / 32.0)) - // New buffer which will contain the concatenated popped items - data := new(bytes.Buffer) - for i := 0; i < length; i++ { - // Encode the number to bytes and have it 32bytes long - num := ethutil.NumberToBytes(bm.stack.Pop().Bytes(), 256) - data.WriteString(string(num)) - } - - if op == oSHA256 { - bm.stack.Push(base.SetBytes(ethutil.Sha256Bin(data.Bytes()))) - } else if op == oSHA3 { - bm.stack.Push(base.SetBytes(ethutil.Sha3Bin(data.Bytes()))) - } else { - bm.stack.Push(base.SetBytes(ethutil.Ripemd160(data.Bytes()))) - } - case oECMUL: - y := bm.stack.Pop() - x := bm.stack.Pop() - //n := bm.stack.Pop() - - //if ethutil.Big(x).Cmp(ethutil.Big(y)) { - data := new(bytes.Buffer) - data.WriteString(x.String()) - data.WriteString(y.String()) - if secp256k1.VerifyPubkeyValidity(data.Bytes()) == 1 { - // TODO - } else { - // Invalid, push infinity - bm.stack.Push(ethutil.Big("0")) - bm.stack.Push(ethutil.Big("0")) - } - //} else { - // // Invalid, push infinity - // bm.stack.Push("0") - // bm.stack.Push("0") - //} - - case oECADD: - case oECSIGN: - case oECRECOVER: - case oECVALID: - case oPUSH: - pc++ - bm.stack.Push(bm.mem[strconv.Itoa(pc)]) - case oPOP: - // Pop current value of the stack - bm.stack.Pop() - case oDUP: - // Dup top stack - x := bm.stack.Pop() - bm.stack.Push(x) - bm.stack.Push(x) - case oSWAP: - // Swap two top most values - x, y := bm.stack.Popn() - bm.stack.Push(y) - bm.stack.Push(x) - case oMLOAD: - x := bm.stack.Pop() - bm.stack.Push(bm.mem[x.String()]) - case oMSTORE: - x, y := bm.stack.Popn() - bm.mem[x.String()] = y - case oSLOAD: - // Load the value in storage and push it on the stack - x := bm.stack.Pop() - // decode the object as a big integer - decoder := ethutil.NewRlpDecoder([]byte(contract.State().Get(x.String()))) - if !decoder.IsNil() { - bm.stack.Push(decoder.AsBigInt()) - } else { - bm.stack.Push(ethutil.BigFalse) - } - case oSSTORE: - // Store Y at index X - x, y := bm.stack.Popn() - contract.State().Update(x.String(), string(ethutil.Encode(y))) - case oJMP: - x := int(bm.stack.Pop().Uint64()) - // Set pc to x - 1 (minus one so the incrementing at the end won't effect it) - pc = x - pc-- - case oJMPI: - x := bm.stack.Pop() - // Set pc to x if it's non zero - if x.Cmp(ethutil.BigFalse) != 0 { - pc = int(x.Uint64()) - pc-- - } - case oIND: - bm.stack.Push(big.NewInt(int64(pc))) - case oEXTRO: - memAddr := bm.stack.Pop() - contractAddr := bm.stack.Pop().Bytes() - - // Push the contract's memory on to the stack - bm.stack.Push(getContractMemory(block, contractAddr, memAddr)) - case oBALANCE: - // Pushes the balance of the popped value on to the stack - d := block.State().Get(bm.stack.Pop().String()) - ether := ethutil.NewEtherFromData([]byte(d)) - bm.stack.Push(ether.Amount) - case oMKTX: - value, addr := bm.stack.Popn() - from, length := bm.stack.Popn() - - j := 0 - dataItems := make([]string, int(length.Uint64())) - for i := from.Uint64(); i < length.Uint64(); i++ { - dataItems[j] = string(bm.mem[strconv.Itoa(int(i))].Bytes()) - j++ - } - // TODO sign it? - tx := ethutil.NewTransaction(string(addr.Bytes()), value, dataItems) - // Add the transaction to the tx pool - bm.server.txPool.QueueTransaction(tx) - case oSUICIDE: - //addr := bm.stack.Pop() - } - pc++ - } - - bm.stack.Print() -} - -// Returns an address from the specified contract's address -func getContractMemory(block *ethutil.Block, contractAddr []byte, memAddr *big.Int) *big.Int { - contract := block.GetContract(contractAddr) - if contract == nil { - log.Panicf("invalid contract addr %x", contractAddr) - } - val := contract.State().Get(memAddr.String()) - - // decode the object as a big integer - decoder := ethutil.NewRlpDecoder([]byte(val)) - if decoder.IsNil() { - return ethutil.BigFalse - } - - return decoder.AsBigInt() -} diff --git a/block_manager_test.go b/block_manager_test.go deleted file mode 100644 index 5f200f3e7..000000000 --- a/block_manager_test.go +++ /dev/null @@ -1,73 +0,0 @@ -package main - -import ( - _ "fmt" - "testing" -) - -func TestVm(t *testing.T) { - InitFees() - - db, _ := NewMemDatabase() - Db = db - - ctrct := NewTransaction("", 200000000, []string{ - "PUSH", "1a2f2e", - "PUSH", "hallo", - "POP", // POP hallo - "PUSH", "3", - "LOAD", // Load hallo back on the stack - - "PUSH", "1", - "PUSH", "2", - "ADD", - - "PUSH", "2", - "PUSH", "1", - "SUB", - - "PUSH", "100000000000000000000000", - "PUSH", "10000000000000", - "SDIV", - - "PUSH", "105", - "PUSH", "200", - "MOD", - - "PUSH", "100000000000000000000000", - "PUSH", "10000000000000", - "SMOD", - - "PUSH", "5", - "PUSH", "10", - "LT", - - "PUSH", "5", - "PUSH", "5", - "LE", - - "PUSH", "50", - "PUSH", "5", - "GT", - - "PUSH", "5", - "PUSH", "5", - "GE", - - "PUSH", "10", - "PUSH", "10", - "NOT", - - "MYADDRESS", - "TXSENDER", - - "STOP", - }) - tx := NewTransaction("1e8a42ea8cce13", 100, []string{}) - - block := CreateBlock("", 0, "", "c014ba53", 0, 0, "", []*Transaction{ctrct, tx}) - db.Put(block.Hash(), block.RlpEncode()) - - bm := NewBlockManager() - bm.ProcessBlock(block) -} diff --git a/dagger.go b/dagger.go deleted file mode 100644 index 966bfa461..000000000 --- a/dagger.go +++ /dev/null @@ -1,149 +0,0 @@ -package main - -import ( - "github.com/ethereum/ethutil-go" - "github.com/obscuren/sha3" - "hash" - "math/big" - "math/rand" - "time" - "log" -) - -type Dagger struct { - hash *big.Int - xn *big.Int -} - -var Found bool - -func (dag *Dagger) Find(obj *big.Int, resChan chan int64) { - r := rand.New(rand.NewSource(time.Now().UnixNano())) - - for i := 0; i < 1000; i++ { - rnd := r.Int63() - - res := dag.Eval(big.NewInt(rnd)) - log.Printf("rnd %v\nres %v\nobj %v\n", rnd, res, obj) - if res.Cmp(obj) < 0 { - // Post back result on the channel - resChan <- rnd - // Notify other threads we've found a valid nonce - Found = true - } - - // Break out if found - if Found { - break - } - } - - resChan <- 0 -} - -func (dag *Dagger) Search(hash, diff *big.Int) *big.Int { - // TODO fix multi threading. Somehow it results in the wrong nonce - amountOfRoutines := 1 - - dag.hash = hash - - obj := ethutil.BigPow(2, 256) - obj = obj.Div(obj, diff) - - Found = false - resChan := make(chan int64, 3) - var res int64 - - for k := 0; k < amountOfRoutines; k++ { - go dag.Find(obj, resChan) - } - - // Wait for each go routine to finish - for k := 0; k < amountOfRoutines; k++ { - // Get the result from the channel. 0 = quit - if r := <-resChan; r != 0 { - res = r - } - } - - return big.NewInt(res) -} - -func DaggerVerify(hash, diff, nonce *big.Int) bool { - dagger := &Dagger{} - dagger.hash = hash - - obj := ethutil.BigPow(2, 256) - obj = obj.Div(obj, diff) - - return dagger.Eval(nonce).Cmp(obj) < 0 -} - -func (dag *Dagger) Node(L uint64, i uint64) *big.Int { - if L == i { - return dag.hash - } - - var m *big.Int - if L == 9 { - m = big.NewInt(16) - } else { - m = big.NewInt(3) - } - - sha := sha3.NewKeccak256() - sha.Reset() - d := sha3.NewKeccak256() - b := new(big.Int) - ret := new(big.Int) - - for k := 0; k < int(m.Uint64()); k++ { - d.Reset() - d.Write(dag.hash.Bytes()) - d.Write(dag.xn.Bytes()) - d.Write(big.NewInt(int64(L)).Bytes()) - d.Write(big.NewInt(int64(i)).Bytes()) - d.Write(big.NewInt(int64(k)).Bytes()) - - b.SetBytes(Sum(d)) - pk := b.Uint64() & ((1 << ((L - 1) * 3)) - 1) - sha.Write(dag.Node(L-1, pk).Bytes()) - } - - ret.SetBytes(Sum(sha)) - - return ret -} - -func Sum(sha hash.Hash) []byte { - //in := make([]byte, 32) - return sha.Sum(nil) -} - -func (dag *Dagger) Eval(N *big.Int) *big.Int { - pow := ethutil.BigPow(2, 26) - dag.xn = pow.Div(N, pow) - - sha := sha3.NewKeccak256() - sha.Reset() - ret := new(big.Int) - - for k := 0; k < 4; k++ { - d := sha3.NewKeccak256() - b := new(big.Int) - - d.Reset() - d.Write(dag.hash.Bytes()) - d.Write(dag.xn.Bytes()) - d.Write(N.Bytes()) - d.Write(big.NewInt(int64(k)).Bytes()) - - b.SetBytes(Sum(d)) - pk := (b.Uint64() & 0x1ffffff) - - sha.Write(dag.Node(9, pk).Bytes()) - } - - return ret.SetBytes(Sum(sha)) -} - diff --git a/dagger_test.go b/dagger_test.go deleted file mode 100644 index 616577a39..000000000 --- a/dagger_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package main - -import ( - "github.com/ethereum/ethutil-go" - "math/big" - "testing" -) - -func BenchmarkDaggerSearch(b *testing.B) { - hash := big.NewInt(0) - diff := ethutil.BigPow(2, 36) - o := big.NewInt(0) // nonce doesn't matter. We're only testing against speed, not validity - - // Reset timer so the big generation isn't included in the benchmark - b.ResetTimer() - // Validate - DaggerVerify(hash, diff, o) -} diff --git a/dev_console.go b/dev_console.go index d14f019e5..b3e0d73f9 100644 --- a/dev_console.go +++ b/dev_console.go @@ -5,6 +5,8 @@ import ( "encoding/hex" "errors" "fmt" + "github.com/ethereum/eth-go" + "github.com/ethereum/ethchain-go" "github.com/ethereum/ethdb-go" "github.com/ethereum/ethutil-go" "os" @@ -12,16 +14,16 @@ import ( ) type Console struct { - db *ethdb.MemDatabase - trie *ethutil.Trie - server *Server + db *ethdb.MemDatabase + trie *ethutil.Trie + ethereum *eth.Ethereum } -func NewConsole(s *Server) *Console { +func NewConsole(s *eth.Ethereum) *Console { db, _ := ethdb.NewMemDatabase() trie := ethutil.NewTrie(db, "") - return &Console{db: db, trie: trie, server: s} + return &Console{db: db, trie: trie, ethereum: s} } func (i *Console) ValidateInput(action string, argumentLength int) error { @@ -101,7 +103,7 @@ func (i *Console) ParseInput(input string) bool { case "print": i.db.Print() case "dag": - fmt.Println(DaggerVerify(ethutil.Big(tokens[1]), // hash + fmt.Println(ethchain.DaggerVerify(ethutil.Big(tokens[1]), // hash ethutil.BigPow(2, 36), // diff ethutil.Big(tokens[2]))) // nonce case "decode": @@ -112,7 +114,7 @@ func (i *Console) ParseInput(input string) bool { case "tx": tx := ethutil.NewTransaction(tokens[1], ethutil.Big(tokens[2]), []string{""}) - i.server.txPool.QueueTransaction(tx) + i.ethereum.TxPool.QueueTransaction(tx) case "exit", "quit", "q": return false case "help": diff --git a/ethereum.go b/ethereum.go index b7f059a02..7988f8418 100644 --- a/ethereum.go +++ b/ethereum.go @@ -3,6 +3,8 @@ package main import ( "flag" "fmt" + "github.com/ethereum/eth-go" + "github.com/ethereum/ethchain-go" "github.com/ethereum/ethutil-go" "log" "os" @@ -23,8 +25,8 @@ func Init() { flag.Parse() } -// Register interrupt handlers so we can stop the server -func RegisterInterupts(s *Server) { +// Register interrupt handlers so we can stop the ethereum +func RegisterInterupts(s *eth.Ethereum) { // Buffered chan of one is enough c := make(chan os.Signal, 1) // Notify about interrupts for now @@ -40,15 +42,13 @@ func RegisterInterupts(s *Server) { func main() { runtime.GOMAXPROCS(runtime.NumCPU()) - - ethutil.InitFees() - Init() + ethutil.InitFees() ethutil.ReadConfig() - server, err := NewServer() - + // Instantiated a eth stack + ethereum, err := eth.New() if err != nil { log.Println(err) return @@ -70,29 +70,29 @@ func main() { ethutil.Config.Log = log.New(file, "", 0) - console := NewConsole(server) + console := NewConsole(ethereum) go console.Start() } log.Println("Starting Ethereum") - RegisterInterupts(server) + RegisterInterupts(ethereum) if StartMining { log.Println("Mining started") - dagger := &Dagger{} + dagger := ðchain.Dagger{} go func() { for { res := dagger.Search(ethutil.Big("01001"), ethutil.BigPow(2, 36)) log.Println("Res dagger", res) - //server.Broadcast("blockmine", ethutil.Encode(res.String())) + //ethereum.Broadcast("blockmine", ethutil.Encode(res.String())) } }() } - server.Start() + ethereum.Start() // Wait for shutdown - server.WaitForShutdown() + ethereum.WaitForShutdown() } diff --git a/peer.go b/peer.go deleted file mode 100644 index 207f9e59f..000000000 --- a/peer.go +++ /dev/null @@ -1,303 +0,0 @@ -package main - -import ( - "github.com/ethereum/ethutil-go" - "github.com/ethereum/ethwire-go" - "log" - "net" - "strconv" - "sync/atomic" - "time" -) - -const ( - // The size of the output buffer for writing messages - outputBufferSize = 50 -) - -type Peer struct { - // Server interface - server *Server - // Net connection - conn net.Conn - // Output queue which is used to communicate and handle messages - outputQueue chan *ethwire.Msg - // Quit channel - quit chan bool - // Determines whether it's an inbound or outbound peer - inbound bool - // Flag for checking the peer's connectivity state - connected int32 - disconnect int32 - // Last known message send - lastSend time.Time - // Indicated whether a verack has been send or not - // This flag is used by writeMessage to check if messages are allowed - // to be send or not. If no version is known all messages are ignored. - versionKnown bool - - // Last received pong message - lastPong int64 - // Indicates whether a MsgGetPeersTy was requested of the peer - // this to prevent receiving false peers. - requestedPeerList bool -} - -func NewPeer(conn net.Conn, server *Server, inbound bool) *Peer { - return &Peer{ - outputQueue: make(chan *ethwire.Msg, outputBufferSize), - quit: make(chan bool), - server: server, - conn: conn, - inbound: inbound, - disconnect: 0, - connected: 1, - } -} - -func NewOutboundPeer(addr string, server *Server) *Peer { - p := &Peer{ - outputQueue: make(chan *ethwire.Msg, outputBufferSize), - quit: make(chan bool), - server: server, - inbound: false, - connected: 0, - disconnect: 0, - } - - // Set up the connection in another goroutine so we don't block the main thread - go func() { - conn, err := net.Dial("tcp", addr) - if err != nil { - p.Stop() - } - p.conn = conn - - // Atomically set the connection state - atomic.StoreInt32(&p.connected, 1) - atomic.StoreInt32(&p.disconnect, 0) - - log.Println("Connected to peer ::", conn.RemoteAddr()) - - p.Start() - }() - - return p -} - -// Outputs any RLP encoded data to the peer -func (p *Peer) QueueMessage(msg *ethwire.Msg) { - p.outputQueue <- msg -} - -func (p *Peer) writeMessage(msg *ethwire.Msg) { - // Ignore the write if we're not connected - if atomic.LoadInt32(&p.connected) != 1 { - return - } - - if !p.versionKnown { - switch msg.Type { - case ethwire.MsgHandshakeTy: // Ok - default: // Anything but ack is allowed - return - } - } - - err := ethwire.WriteMessage(p.conn, msg) - if err != nil { - log.Println("Can't send message:", err) - // Stop the client if there was an error writing to it - p.Stop() - return - } -} - -// Outbound message handler. Outbound messages are handled here -func (p *Peer) HandleOutbound() { - // The ping timer. Makes sure that every 2 minutes a ping is send to the peer - tickleTimer := time.NewTicker(2 * time.Minute) -out: - for { - select { - // Main message queue. All outbound messages are processed through here - case msg := <-p.outputQueue: - p.writeMessage(msg) - - p.lastSend = time.Now() - - case <-tickleTimer.C: - p.writeMessage(ðwire.Msg{Type: ethwire.MsgPingTy}) - - // Break out of the for loop if a quit message is posted - case <-p.quit: - break out - } - } - -clean: - // This loop is for draining the output queue and anybody waiting for us - for { - select { - case <-p.outputQueue: - // TODO - default: - break clean - } - } -} - -// Inbound handler. Inbound messages are received here and passed to the appropriate methods -func (p *Peer) HandleInbound() { - -out: - for atomic.LoadInt32(&p.disconnect) == 0 { - // Wait for a message from the peer - msg, err := ethwire.ReadMessage(p.conn) - if err != nil { - log.Println(err) - - break out - } - - if Debug { - log.Printf("Received %s\n", msg.Type.String()) - } - - switch msg.Type { - case ethwire.MsgHandshakeTy: - // Version message - p.handleHandshake(msg) - case ethwire.MsgBlockTy: - err := p.server.blockManager.ProcessBlock(ethutil.NewBlock(msg.Data)) - if err != nil { - log.Println(err) - } - case ethwire.MsgTxTy: - p.server.txPool.QueueTransaction(ethutil.NewTransactionFromData(msg.Data)) - case ethwire.MsgInvTy: - case ethwire.MsgGetPeersTy: - p.requestedPeerList = true - // Peer asked for list of connected peers - p.pushPeers() - case ethwire.MsgPeersTy: - // Received a list of peers (probably because MsgGetPeersTy was send) - // Only act on message if we actually requested for a peers list - if p.requestedPeerList { - data := ethutil.Conv(msg.Data) - // Create new list of possible peers for the server to process - peers := make([]string, data.Length()) - // Parse each possible peer - for i := 0; i < data.Length(); i++ { - peers[i] = data.Get(i).AsString() + strconv.Itoa(int(data.Get(i).AsUint())) - } - - // Connect to the list of peers - p.server.ProcessPeerList(peers) - // Mark unrequested again - p.requestedPeerList = false - } - case ethwire.MsgPingTy: - // Respond back with pong - p.QueueMessage(ðwire.Msg{Type: ethwire.MsgPongTy}) - case ethwire.MsgPongTy: - p.lastPong = time.Now().Unix() - } - } - - p.Stop() -} - -func (p *Peer) Start() { - if !p.inbound { - err := p.pushHandshake() - if err != nil { - log.Printf("Peer can't send outbound version ack", err) - - p.Stop() - } - } - - // Run the outbound handler in a new goroutine - go p.HandleOutbound() - // Run the inbound handler in a new goroutine - go p.HandleInbound() -} - -func (p *Peer) Stop() { - if atomic.AddInt32(&p.disconnect, 1) != 1 { - return - } - - close(p.quit) - if atomic.LoadInt32(&p.connected) != 0 { - p.conn.Close() - } - - log.Println("Peer shutdown") -} - -func (p *Peer) pushHandshake() error { - msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, ethutil.Encode([]interface{}{ - 1, 0, p.server.Nonce, - })) - - p.QueueMessage(msg) - - return nil -} - -// Pushes the list of outbound peers to the client when requested -func (p *Peer) pushPeers() { - outPeers := make([]interface{}, len(p.server.OutboundPeers())) - // Serialise each peer - for i, peer := range p.server.OutboundPeers() { - outPeers[i] = peer.RlpEncode() - } - - // Send message to the peer with the known list of connected clients - msg := ethwire.NewMessage(ethwire.MsgPeersTy, ethutil.Encode(outPeers)) - - p.QueueMessage(msg) -} - -func (p *Peer) handleHandshake(msg *ethwire.Msg) { - c := ethutil.Conv(msg.Data) - // [PROTOCOL_VERSION, NETWORK_ID, CLIENT_ID] - if c.Get(2).AsUint() == p.server.Nonce { - //if msg.Nonce == p.server.Nonce { - log.Println("Peer connected to self, disconnecting") - - p.Stop() - - return - } - - p.versionKnown = true - - // If this is an inbound connection send an ack back - if p.inbound { - err := p.pushHandshake() - if err != nil { - log.Println("Peer can't send ack back") - - p.Stop() - } - } -} - -func (p *Peer) RlpEncode() []byte { - host, prt, err := net.SplitHostPort(p.conn.RemoteAddr().String()) - if err != nil { - return nil - } - - i, err := strconv.Atoi(prt) - if err != nil { - return nil - } - - port := ethutil.NumberToBytes(uint16(i), 16) - - return ethutil.Encode([]interface{}{host, port}) -} diff --git a/server.go b/server.go deleted file mode 100644 index 2927f023a..000000000 --- a/server.go +++ /dev/null @@ -1,208 +0,0 @@ -package main - -import ( - "container/list" - "github.com/ethereum/ethdb-go" - "github.com/ethereum/ethutil-go" - "github.com/ethereum/ethwire-go" - "log" - "net" - "sync/atomic" - "time" -) - -func eachPeer(peers *list.List, callback func(*Peer, *list.Element)) { - // Loop thru the peers and close them (if we had them) - for e := peers.Front(); e != nil; e = e.Next() { - if peer, ok := e.Value.(*Peer); ok { - callback(peer, e) - } - } -} - -const ( - processReapingTimeout = 60 // TODO increase -) - -type Server struct { - // Channel for shutting down the server - shutdownChan chan bool - // DB interface - //db *ethdb.LDBDatabase - db *ethdb.MemDatabase - // Block manager for processing new blocks and managing the block chain - blockManager *BlockManager - // The transaction pool. Transaction can be pushed on this pool - // for later including in the blocks - txPool *TxPool - // Peers (NYI) - peers *list.List - // Nonce - Nonce uint64 -} - -func NewServer() (*Server, error) { - //db, err := ethdb.NewLDBDatabase() - db, err := ethdb.NewMemDatabase() - if err != nil { - return nil, err - } - - ethutil.Config.Db = db - - nonce, _ := ethutil.RandomUint64() - server := &Server{ - shutdownChan: make(chan bool), - db: db, - peers: list.New(), - Nonce: nonce, - } - server.txPool = NewTxPool(server) - server.blockManager = NewBlockManager(server) - - return server, nil -} - -func (s *Server) AddPeer(conn net.Conn) { - peer := NewPeer(conn, s, true) - - if peer != nil { - s.peers.PushBack(peer) - peer.Start() - - log.Println("Peer connected ::", conn.RemoteAddr()) - } -} - -func (s *Server) ProcessPeerList(addrs []string) { - for _, addr := range addrs { - // TODO Probably requires some sanity checks - s.ConnectToPeer(addr) - } -} - -func (s *Server) ConnectToPeer(addr string) error { - peer := NewOutboundPeer(addr, s) - - s.peers.PushBack(peer) - - return nil -} - -func (s *Server) OutboundPeers() []*Peer { - // Create a new peer slice with at least the length of the total peers - outboundPeers := make([]*Peer, s.peers.Len()) - length := 0 - eachPeer(s.peers, func(p *Peer, e *list.Element) { - if !p.inbound { - outboundPeers[length] = p - length++ - } - }) - - return outboundPeers[:length] -} - -func (s *Server) InboundPeers() []*Peer { - // Create a new peer slice with at least the length of the total peers - inboundPeers := make([]*Peer, s.peers.Len()) - length := 0 - eachPeer(s.peers, func(p *Peer, e *list.Element) { - if p.inbound { - inboundPeers[length] = p - length++ - } - }) - - return inboundPeers[:length] -} - -func (s *Server) Broadcast(msgType ethwire.MsgType, data []byte) { - eachPeer(s.peers, func(p *Peer, e *list.Element) { - p.QueueMessage(ethwire.NewMessage(msgType, data)) - }) -} - -func (s *Server) ReapDeadPeers() { - for { - eachPeer(s.peers, func(p *Peer, e *list.Element) { - if atomic.LoadInt32(&p.disconnect) == 1 || (p.inbound && (time.Now().Unix()-p.lastPong) > int64(5*time.Minute)) { - log.Println("Dead peer found .. reaping") - - s.peers.Remove(e) - } - }) - - time.Sleep(processReapingTimeout * time.Second) - } -} - -// Start the server -func (s *Server) Start() { - // For now this function just blocks the main thread - ln, err := net.Listen("tcp", ":12345") - if err != nil { - // This is mainly for testing to create a "network" - if Debug { - log.Println("Connection listening disabled. Acting as client") - - err = s.ConnectToPeer("localhost:12345") - if err != nil { - log.Println("Error starting server", err) - - s.Stop() - } - } else { - log.Fatal(err) - } - } else { - // Starting accepting connections - go func() { - for { - conn, err := ln.Accept() - if err != nil { - log.Println(err) - - continue - } - - go s.AddPeer(conn) - } - }() - } - - // Start the reaping processes - go s.ReapDeadPeers() - - // Start the tx pool - s.txPool.Start() - - // TMP - /* - go func() { - for { - s.Broadcast("block", s.blockManager.bc.GenesisBlock().RlpEncode()) - - time.Sleep(1000 * time.Millisecond) - } - }() - */ -} - -func (s *Server) Stop() { - // Close the database - defer s.db.Close() - - eachPeer(s.peers, func(p *Peer, e *list.Element) { - p.Stop() - }) - - s.shutdownChan <- true - - s.txPool.Stop() -} - -// This function will wait for a shutdown and resumes main thread execution -func (s *Server) WaitForShutdown() { - <-s.shutdownChan -} diff --git a/stack.go b/stack.go deleted file mode 100644 index 9d595d85b..000000000 --- a/stack.go +++ /dev/null @@ -1,167 +0,0 @@ -package main - -import ( - "fmt" - "math/big" -) - -type OpCode int - -// Op codes -const ( - oSTOP OpCode = iota - oADD - oMUL - oSUB - oDIV - oSDIV - oMOD - oSMOD - oEXP - oNEG - oLT - oLE - oGT - oGE - oEQ - oNOT - oMYADDRESS - oTXSENDER - oTXVALUE - oTXFEE - oTXDATAN - oTXDATA - oBLK_PREVHASH - oBLK_COINBASE - oBLK_TIMESTAMP - oBLK_NUMBER - oBLK_DIFFICULTY - oBASEFEE - oSHA256 OpCode = 32 - oRIPEMD160 OpCode = 33 - oECMUL OpCode = 34 - oECADD OpCode = 35 - oECSIGN OpCode = 36 - oECRECOVER OpCode = 37 - oECVALID OpCode = 38 - oSHA3 OpCode = 39 - oPUSH OpCode = 48 - oPOP OpCode = 49 - oDUP OpCode = 50 - oSWAP OpCode = 51 - oMLOAD OpCode = 52 - oMSTORE OpCode = 53 - oSLOAD OpCode = 54 - oSSTORE OpCode = 55 - oJMP OpCode = 56 - oJMPI OpCode = 57 - oIND OpCode = 58 - oEXTRO OpCode = 59 - oBALANCE OpCode = 60 - oMKTX OpCode = 61 - oSUICIDE OpCode = 62 -) - -// Since the opcodes aren't all in order we can't use a regular slice -var opCodeToString = map[OpCode]string{ - oSTOP: "STOP", - oADD: "ADD", - oMUL: "MUL", - oSUB: "SUB", - oDIV: "DIV", - oSDIV: "SDIV", - oMOD: "MOD", - oSMOD: "SMOD", - oEXP: "EXP", - oNEG: "NEG", - oLT: "LT", - oLE: "LE", - oGT: "GT", - oGE: "GE", - oEQ: "EQ", - oNOT: "NOT", - oMYADDRESS: "MYADDRESS", - oTXSENDER: "TXSENDER", - oTXVALUE: "TXVALUE", - oTXFEE: "TXFEE", - oTXDATAN: "TXDATAN", - oTXDATA: "TXDATA", - oBLK_PREVHASH: "BLK_PREVHASH", - oBLK_COINBASE: "BLK_COINBASE", - oBLK_TIMESTAMP: "BLK_TIMESTAMP", - oBLK_NUMBER: "BLK_NUMBER", - oBLK_DIFFICULTY: "BLK_DIFFICULTY", - oBASEFEE: "BASEFEE", - oSHA256: "SHA256", - oRIPEMD160: "RIPEMD160", - oECMUL: "ECMUL", - oECADD: "ECADD", - oECSIGN: "ECSIGN", - oECRECOVER: "ECRECOVER", - oECVALID: "ECVALID", - oSHA3: "SHA3", - oPUSH: "PUSH", - oPOP: "POP", - oDUP: "DUP", - oSWAP: "SWAP", - oMLOAD: "MLOAD", - oMSTORE: "MSTORE", - oSLOAD: "SLOAD", - oSSTORE: "SSTORE", - oJMP: "JMP", - oJMPI: "JMPI", - oIND: "IND", - oEXTRO: "EXTRO", - oBALANCE: "BALANCE", - oMKTX: "MKTX", - oSUICIDE: "SUICIDE", -} - -func (o OpCode) String() string { - return opCodeToString[o] -} - -type OpType int - -const ( - tNorm = iota - tData - tExtro - tCrypto -) - -type TxCallback func(opType OpType) bool - -// Simple push/pop stack mechanism -type Stack struct { - data []*big.Int -} - -func NewStack() *Stack { - return &Stack{} -} - -func (st *Stack) Pop() *big.Int { - s := len(st.data) - - str := st.data[s-1] - st.data = st.data[:s-1] - - return str -} - -func (st *Stack) Popn() (*big.Int, *big.Int) { - s := len(st.data) - - ints := st.data[s-2:] - st.data = st.data[:s-2] - - return ints[0], ints[1] -} - -func (st *Stack) Push(d *big.Int) { - st.data = append(st.data, d) -} -func (st *Stack) Print() { - fmt.Println(st.data) -} diff --git a/transaction_pool.go b/transaction_pool.go deleted file mode 100644 index b302931de..000000000 --- a/transaction_pool.go +++ /dev/null @@ -1,177 +0,0 @@ -package main - -import ( - "bytes" - "container/list" - "errors" - "github.com/ethereum/ethutil-go" - "github.com/ethereum/ethwire-go" - "log" - "math/big" - "sync" -) - -const ( - txPoolQueueSize = 50 -) - -func FindTx(pool *list.List, finder func(*ethutil.Transaction, *list.Element) bool) *ethutil.Transaction { - for e := pool.Front(); e != nil; e = e.Next() { - if tx, ok := e.Value.(*ethutil.Transaction); ok { - if finder(tx, e) { - return tx - } - } - } - - return nil -} - -// The tx pool a thread safe transaction pool handler. In order to -// guarantee a non blocking pool we use a queue channel which can be -// independently read without needing access to the actual pool. If the -// pool is being drained or synced for whatever reason the transactions -// will simple queue up and handled when the mutex is freed. -type TxPool struct { - server *Server - // The mutex for accessing the Tx pool. - mutex sync.Mutex - // Queueing channel for reading and writing incoming - // transactions to - queueChan chan *ethutil.Transaction - // Quiting channel - quit chan bool - - pool *list.List -} - -func NewTxPool(s *Server) *TxPool { - return &TxPool{ - server: s, - mutex: sync.Mutex{}, - pool: list.New(), - queueChan: make(chan *ethutil.Transaction, txPoolQueueSize), - quit: make(chan bool), - } -} - -// Blocking function. Don't use directly. Use QueueTransaction instead -func (pool *TxPool) addTransaction(tx *ethutil.Transaction) { - pool.mutex.Lock() - pool.pool.PushBack(tx) - pool.mutex.Unlock() - - // Broadcast the transaction to the rest of the peers - pool.server.Broadcast(ethwire.MsgTxTy, tx.RlpEncode()) -} - -// Process transaction validates the Tx and processes funds from the -// sender to the recipient. -func (pool *TxPool) processTransaction(tx *ethutil.Transaction) error { - // Get the last block so we can retrieve the sender and receiver from - // the merkle trie - block := pool.server.blockManager.bc.LastBlock - // Something has gone horribly wrong if this happens - if block == nil { - return errors.New("No last block on the block chain") - } - - var sender, receiver *ethutil.Ether - - // Get the sender - data := block.State().Get(string(tx.Sender())) - // If it doesn't exist create a new account. Of course trying to send funds - // from this account will fail since it will hold 0 Wei - if data == "" { - sender = ethutil.NewEther(big.NewInt(0)) - } else { - sender = ethutil.NewEtherFromData([]byte(data)) - } - // Defer the update. Whatever happens it should be persisted - defer block.State().Update(string(tx.Sender()), string(sender.RlpEncode())) - - // Make sure there's enough in the sender's account. Having insufficient - // funds won't invalidate this transaction but simple ignores it. - if sender.Amount.Cmp(tx.Value) < 0 { - if Debug { - log.Println("Insufficient amount in sender's account. Adding 1 ETH for debug") - sender.Amount = ethutil.BigPow(10, 18) - } else { - return errors.New("Insufficient amount in sender's account") - } - } - - // Subtract the amount from the senders account - sender.Amount.Sub(sender.Amount, tx.Value) - // Increment the nonce making each tx valid only once to prevent replay - // attacks - sender.Nonce += 1 - - // Get the receiver - data = block.State().Get(tx.Recipient) - // If the receiver doesn't exist yet, create a new account to which the - // funds will be send. - if data == "" { - receiver = ethutil.NewEther(big.NewInt(0)) - } else { - receiver = ethutil.NewEtherFromData([]byte(data)) - } - // Defer the update - defer block.State().Update(tx.Recipient, string(receiver.RlpEncode())) - - // Add the amount to receivers account which should conclude this transaction - receiver.Amount.Add(receiver.Amount, tx.Value) - - return nil -} - -func (pool *TxPool) queueHandler() { -out: - for { - select { - case tx := <-pool.queueChan: - hash := tx.Hash() - foundTx := FindTx(pool.pool, func(tx *ethutil.Transaction, e *list.Element) bool { - return bytes.Compare(tx.Hash(), hash) == 0 - }) - - if foundTx != nil { - break - } - - // Process the transaction - err := pool.processTransaction(tx) - if err != nil { - log.Println("Error processing Tx", err) - } else { - // Call blocking version. At this point it - // doesn't matter since this is a goroutine - pool.addTransaction(tx) - } - case <-pool.quit: - break out - } - } -} - -func (pool *TxPool) QueueTransaction(tx *ethutil.Transaction) { - pool.queueChan <- tx -} - -func (pool *TxPool) Flush() { - pool.mutex.Lock() - - defer pool.mutex.Unlock() -} - -func (pool *TxPool) Start() { - go pool.queueHandler() -} - -func (pool *TxPool) Stop() { - log.Println("[TXP] Stopping...") - - close(pool.quit) - - pool.Flush() -} From 501db83dfd4061c75822c622512cee31935ab0a6 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 23 Jan 2014 21:14:44 +0100 Subject: [PATCH 125/459] Updated readme --- README.md | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 05e0156b9..dadafcbc6 100644 --- a/README.md +++ b/README.md @@ -9,11 +9,29 @@ A fair warning; Ethereum is not yet to be used in production. There's no test-net and you aren't mining real blocks (just one which is the genesis block). -Ethereum Go is split up in several sub packages. Please refer to each +Ethereum Go is split up in several sub packages Please refer to each individual package for more information. - 1. [ethutil](https://github.com/ethereum/ethutil-go) - 2. [ethdb](https://github.com/ethereum/ethdb-go) + 1. [eth](https://github.com/ethereum/eth-go) + 2. [ethchain](https://github.com/ethereum/ethchain-go) 3. [ethwire](https://github.com/ethereum/ethwire-go) + 4. [ethdb](https://github.com/ethereum/ethdb-go) + 5. [ethutil](https://github.com/ethereum/ethutil-go) + +The [eth](https://github.com/ethereum/eth-go) is the top-level package +of the Ethereum protocol. It functions as the Ethereum bootstrapping and +peer communication layer. The [ethchain](https://github.com/ethereum/ethchain-go) +contains the Ethereum blockchain, block manager, transaction and +transaction handlers. The [ethwire](https://github.com/ethereum/ethwire-go) contains +the Ethereum [wire protocol](http://wiki.ethereum.org/index.php/Wire_Protocol) which can be used +to hook in to the Ethereum network. [ethutil](https://github.com/ethereum/ethutil-go) contains +utility functions which are not Ethereum specific. The utility package +contains the [patricia trie](http://wiki.ethereum.org/index.php/Patricia_Tree), +[RLP Encoding](http://wiki.ethereum.org/index.php/RLP) and hex encoding +helpers. The [ethdb](https://github.com/ethereum/ethdb-go) package +contains the LevelDB interface and memory DB interface. + +This executable is the front-end (currently nothing but a dev console) for +the Ethereum Go implementation. Deps ==== From 7bf4f2a908235c75e795d0ca3796c76f9fc99454 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 23 Jan 2014 22:33:51 +0100 Subject: [PATCH 126/459] tx is now part of the chain package --- dev_console.go | 2 +- ethereum.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dev_console.go b/dev_console.go index b3e0d73f9..b515b3e5c 100644 --- a/dev_console.go +++ b/dev_console.go @@ -112,7 +112,7 @@ func (i *Console) ParseInput(input string) bool { case "encode": fmt.Printf("%q\n", ethutil.Encode(tokens[1])) case "tx": - tx := ethutil.NewTransaction(tokens[1], ethutil.Big(tokens[2]), []string{""}) + tx := ethchain.NewTransaction(tokens[1], ethutil.Big(tokens[2]), []string{""}) i.ethereum.TxPool.QueueTransaction(tx) case "exit", "quit", "q": diff --git a/ethereum.go b/ethereum.go index 7988f8418..e7775f143 100644 --- a/ethereum.go +++ b/ethereum.go @@ -44,7 +44,7 @@ func main() { runtime.GOMAXPROCS(runtime.NumCPU()) Init() - ethutil.InitFees() + ethchain.InitFees() ethutil.ReadConfig() // Instantiated a eth stack From c636f8e3e66a24a13d2cc6b2e89280f362e0f91b Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 24 Jan 2014 17:51:35 +0100 Subject: [PATCH 127/459] Broadcast block --- dev_console.go | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/dev_console.go b/dev_console.go index b515b3e5c..252860fc8 100644 --- a/dev_console.go +++ b/dev_console.go @@ -9,6 +9,8 @@ import ( "github.com/ethereum/ethchain-go" "github.com/ethereum/ethdb-go" "github.com/ethereum/ethutil-go" + "github.com/ethereum/ethwire-go" + "math/big" "os" "strings" ) @@ -49,6 +51,9 @@ func (i *Console) ValidateInput(action string, argumentLength int) error { case action == "tx" && argumentLength != 2: err = true expArgCount = 2 + case action == "getaddr" && argumentLength != 1: + err = true + expArgCount = 1 } if err { @@ -109,8 +114,35 @@ func (i *Console) ParseInput(input string) bool { case "decode": d, _ := ethutil.Decode([]byte(tokens[1]), 0) fmt.Printf("%q\n", d) + case "getaddr": + encoded, _ := hex.DecodeString(tokens[1]) + d := i.ethereum.BlockManager.BlockChain().LastBlock.State().Get(string(encoded)) + if d != "" { + decoder := ethutil.NewRlpDecoder([]byte(d)) + fmt.Println(decoder) + } else { + fmt.Println("getaddr: address unknown") + } case "encode": fmt.Printf("%q\n", ethutil.Encode(tokens[1])) + case "newblk": + block := ethchain.CreateBlock( + i.ethereum.BlockManager.BlockChain().LastBlock.State().Root, + i.ethereum.BlockManager.LastBlockHash, + "123", + big.NewInt(1), + big.NewInt(1), + "", + i.ethereum.TxPool.Flush(), + ) + i.ethereum.Broadcast(ethwire.MsgBlockTy, block.RlpData()) + //fmt.Println(ethutil.NewRlpValue(block.RlpData()).Get(0)) + //err := i.ethereum.BlockManager.ProcessBlock(block) + //if err != nil { + // fmt.Println(err) + //} else { + + // } case "tx": tx := ethchain.NewTransaction(tokens[1], ethutil.Big(tokens[2]), []string{""}) From 97882a65bbe87beed8f939591f13ee01f7af6fa7 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 24 Jan 2014 20:16:48 +0100 Subject: [PATCH 128/459] Dev test mining --- dev_console.go | 54 +++++++++++++++++++++++++++++++------------------- ethereum.go | 30 ++++++++++++++++++++-------- 2 files changed, 56 insertions(+), 28 deletions(-) diff --git a/dev_console.go b/dev_console.go index 252860fc8..f2aa4e08d 100644 --- a/dev_console.go +++ b/dev_console.go @@ -9,8 +9,8 @@ import ( "github.com/ethereum/ethchain-go" "github.com/ethereum/ethdb-go" "github.com/ethereum/ethutil-go" - "github.com/ethereum/ethwire-go" - "math/big" + _ "github.com/ethereum/ethwire-go" + _ "math/big" "os" "strings" ) @@ -48,6 +48,9 @@ func (i *Console) ValidateInput(action string, argumentLength int) error { case action == "encode" && argumentLength != 1: err = true expArgCount = 1 + case action == "gettx" && argumentLength != 1: + err = true + expArgCount = 1 case action == "tx" && argumentLength != 2: err = true expArgCount = 2 @@ -125,28 +128,39 @@ func (i *Console) ParseInput(input string) bool { } case "encode": fmt.Printf("%q\n", ethutil.Encode(tokens[1])) - case "newblk": - block := ethchain.CreateBlock( - i.ethereum.BlockManager.BlockChain().LastBlock.State().Root, - i.ethereum.BlockManager.LastBlockHash, - "123", - big.NewInt(1), - big.NewInt(1), - "", - i.ethereum.TxPool.Flush(), - ) - i.ethereum.Broadcast(ethwire.MsgBlockTy, block.RlpData()) - //fmt.Println(ethutil.NewRlpValue(block.RlpData()).Get(0)) - //err := i.ethereum.BlockManager.ProcessBlock(block) - //if err != nil { - // fmt.Println(err) - //} else { - - // } + /* + case "newblk": + block := ethchain.CreateBlock( + i.ethereum.BlockManager.BlockChain().LastBlock.State().Root, + i.ethereum.BlockManager.LastBlockHash, + "123", + big.NewInt(1), + big.NewInt(1), + "", + i.ethereum.TxPool.Flush(), + ) + err := i.ethereum.BlockManager.ProcessBlock(block) + if err != nil { + fmt.Println(err) + } else { + i.ethereum.Broadcast(ethwire.MsgBlockTy, block.RlpData()) + } + //fmt.Println(ethutil.NewRlpValue(block.RlpData()).Get(0)) + */ case "tx": tx := ethchain.NewTransaction(tokens[1], ethutil.Big(tokens[2]), []string{""}) + fmt.Printf("tx: %x\n", tx.Hash()) i.ethereum.TxPool.QueueTransaction(tx) + case "gettx": + addr, _ := hex.DecodeString(tokens[1]) + data, _ := ethutil.Config.Db.Get(addr) + if len(data) != 0 { + decoder := ethutil.NewRlpDecoder(data) + fmt.Println(decoder) + } else { + fmt.Println("gettx: tx not found") + } case "exit", "quit", "q": return false case "help": diff --git a/ethereum.go b/ethereum.go index e7775f143..9d81880f2 100644 --- a/ethereum.go +++ b/ethereum.go @@ -6,11 +6,14 @@ import ( "github.com/ethereum/eth-go" "github.com/ethereum/ethchain-go" "github.com/ethereum/ethutil-go" + "github.com/ethereum/ethwire-go" "log" + "math/big" "os" "os/signal" "path" "runtime" + "time" ) const Debug = true @@ -78,21 +81,32 @@ func main() { RegisterInterupts(ethereum) - if StartMining { - log.Println("Mining started") - dagger := ðchain.Dagger{} + ethereum.Start() + if StartMining { + log.Println("Dev Test Mining started") + + // Fake block mining. It broadcasts a new block every 5 seconds go func() { for { - res := dagger.Search(ethutil.Big("01001"), ethutil.BigPow(2, 36)) - log.Println("Res dagger", res) - //ethereum.Broadcast("blockmine", ethutil.Encode(res.String())) + time.Sleep(5 * time.Second) + + block := ethchain.CreateBlock( + ethereum.BlockManager.BlockChain().LastBlock.State().Root, + ethereum.BlockManager.LastBlockHash, + "123", + big.NewInt(1), + big.NewInt(1), + "", + ethereum.TxPool.Flush()) + + ethereum.BlockManager.ProcessBlockWithState(block, block.State()) + ethereum.Broadcast(ethwire.MsgBlockTy, block.RlpData()) + log.Println("\n", block.String()) } }() } - ethereum.Start() - // Wait for shutdown ethereum.WaitForShutdown() } From e32b1a1d975e1bd8dfc3211b400872ba42bf1498 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 25 Jan 2014 01:25:36 +0100 Subject: [PATCH 129/459] Fake block mining --- ethereum.go | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/ethereum.go b/ethereum.go index 9d81880f2..2d79659b0 100644 --- a/ethereum.go +++ b/ethereum.go @@ -6,7 +6,7 @@ import ( "github.com/ethereum/eth-go" "github.com/ethereum/ethchain-go" "github.com/ethereum/ethutil-go" - "github.com/ethereum/ethwire-go" + _ "github.com/ethereum/ethwire-go" "log" "math/big" "os" @@ -84,12 +84,15 @@ func main() { ethereum.Start() if StartMining { - log.Println("Dev Test Mining started") + blockTime := time.Duration(15) + log.Printf("Dev Test Mining started. Blocks found each %d seconds\n", blockTime) // Fake block mining. It broadcasts a new block every 5 seconds go func() { for { - time.Sleep(5 * time.Second) + txs := ethereum.TxPool.Flush() + + time.Sleep(blockTime * time.Second) block := ethchain.CreateBlock( ethereum.BlockManager.BlockChain().LastBlock.State().Root, @@ -98,11 +101,13 @@ func main() { big.NewInt(1), big.NewInt(1), "", - ethereum.TxPool.Flush()) - - ethereum.BlockManager.ProcessBlockWithState(block, block.State()) - ethereum.Broadcast(ethwire.MsgBlockTy, block.RlpData()) - log.Println("\n", block.String()) + txs) + err := ethereum.BlockManager.ProcessBlockWithState(block, block.State()) + if err != nil { + log.Println(err) + } else { + log.Println("\n+++++++ MINED BLK +++++++\n", block.String()) + } } }() } From 42e8930b37ddd89d17a069912a91df13f41df244 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 25 Jan 2014 15:19:29 +0100 Subject: [PATCH 130/459] Dev contracts --- dev_console.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dev_console.go b/dev_console.go index f2aa4e08d..1817ca9a8 100644 --- a/dev_console.go +++ b/dev_console.go @@ -57,6 +57,9 @@ func (i *Console) ValidateInput(action string, argumentLength int) error { case action == "getaddr" && argumentLength != 1: err = true expArgCount = 1 + case action == "contract" && argumentLength != 1: + err = true + expArgCount = 1 } if err { @@ -149,7 +152,7 @@ func (i *Console) ParseInput(input string) bool { */ case "tx": tx := ethchain.NewTransaction(tokens[1], ethutil.Big(tokens[2]), []string{""}) - fmt.Printf("tx: %x\n", tx.Hash()) + fmt.Printf("%x\n", tx.Hash()) i.ethereum.TxPool.QueueTransaction(tx) case "gettx": @@ -161,6 +164,11 @@ func (i *Console) ParseInput(input string) bool { } else { fmt.Println("gettx: tx not found") } + case "contract": + contract := ethchain.NewTransaction("", ethutil.Big(tokens[1]), []string{"PUSH", "1234"}) + fmt.Printf("%x\n", contract.Hash()) + + i.ethereum.TxPool.QueueTransaction(contract) case "exit", "quit", "q": return false case "help": From d753eb77ec1e2298a8b386f0ddae5e34d450b805 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 25 Jan 2014 15:57:35 +0100 Subject: [PATCH 131/459] Removed the last block of the block chain Added CurrentBlock to block manager --- README.md | 2 +- dev_console.go | 2 +- ethereum.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index dadafcbc6..fe3ec304d 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Ethereum [![Build Status](https://travis-ci.org/ethereum/go-ethereum.png?branch=master)](https://travis-ci.org/ethereum/go-ethereum) -Ethereum Go (c) [0255c7881](https://github.com/ethereum/go-ethereum#copy) +Ethereum Go developer client (c) [0255c7881](https://github.com/ethereum/go-ethereum#copy) A fair warning; Ethereum is not yet to be used in production. There's no test-net and you aren't mining real blocks (just one which is the genesis block). diff --git a/dev_console.go b/dev_console.go index 1817ca9a8..6beafc447 100644 --- a/dev_console.go +++ b/dev_console.go @@ -122,7 +122,7 @@ func (i *Console) ParseInput(input string) bool { fmt.Printf("%q\n", d) case "getaddr": encoded, _ := hex.DecodeString(tokens[1]) - d := i.ethereum.BlockManager.BlockChain().LastBlock.State().Get(string(encoded)) + d := i.ethereum.BlockManager.CurrentBlock.State().Get(string(encoded)) if d != "" { decoder := ethutil.NewRlpDecoder([]byte(d)) fmt.Println(decoder) diff --git a/ethereum.go b/ethereum.go index 2d79659b0..e434f3c8e 100644 --- a/ethereum.go +++ b/ethereum.go @@ -95,7 +95,7 @@ func main() { time.Sleep(blockTime * time.Second) block := ethchain.CreateBlock( - ethereum.BlockManager.BlockChain().LastBlock.State().Root, + ethereum.BlockManager.CurrentBlock.State().Root, ethereum.BlockManager.LastBlockHash, "123", big.NewInt(1), From c6062a0f73c01bd069394d81a506c64a4272b124 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 25 Jan 2014 16:45:51 +0100 Subject: [PATCH 132/459] Added MIT license #5 --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..803f2ef4e --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013 Geff Obscura + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. From 8b9dcdcdf04eb13e39101532a90b4a552754cb7f Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 27 Jan 2014 15:34:10 +0100 Subject: [PATCH 133/459] Debugging handles --- dev_console.go | 12 +++++++++++- ethereum.go | 7 ++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/dev_console.go b/dev_console.go index 6beafc447..3395124dc 100644 --- a/dev_console.go +++ b/dev_console.go @@ -9,7 +9,7 @@ import ( "github.com/ethereum/ethchain-go" "github.com/ethereum/ethdb-go" "github.com/ethereum/ethutil-go" - _ "github.com/ethereum/ethwire-go" + "github.com/ethereum/ethwire-go" _ "math/big" "os" "strings" @@ -60,6 +60,12 @@ func (i *Console) ValidateInput(action string, argumentLength int) error { case action == "contract" && argumentLength != 1: err = true expArgCount = 1 + case action == "say" && argumentLength != 1: + err = true + expArgCount = 1 + case action == "addp" && argumentLength != 1: + err = true + expArgCount = 1 } if err { @@ -129,6 +135,10 @@ func (i *Console) ParseInput(input string) bool { } else { fmt.Println("getaddr: address unknown") } + case "say": + i.ethereum.Broadcast(ethwire.MsgTalkTy, tokens[1]) + case "addp": + i.ethereum.ConnectToPeer(tokens[1]) case "encode": fmt.Printf("%q\n", ethutil.Encode(tokens[1])) /* diff --git a/ethereum.go b/ethereum.go index e434f3c8e..d58033cdc 100644 --- a/ethereum.go +++ b/ethereum.go @@ -50,6 +50,8 @@ func main() { ethchain.InitFees() ethutil.ReadConfig() + log.Printf("Starting Ethereum v%s\n", ethutil.Config.Ver) + // Instantiated a eth stack ethereum, err := eth.New() if err != nil { @@ -77,8 +79,6 @@ func main() { go console.Start() } - log.Println("Starting Ethereum") - RegisterInterupts(ethereum) ethereum.Start() @@ -90,10 +90,11 @@ func main() { // Fake block mining. It broadcasts a new block every 5 seconds go func() { for { - txs := ethereum.TxPool.Flush() time.Sleep(blockTime * time.Second) + txs := ethereum.TxPool.Flush() + block := ethchain.CreateBlock( ethereum.BlockManager.CurrentBlock.State().Root, ethereum.BlockManager.LastBlockHash, From 2619604549ee632289fbde2a3065fa8dcfe65a23 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 27 Jan 2014 22:15:06 +0100 Subject: [PATCH 134/459] Added help --- dev_console.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dev_console.go b/dev_console.go index 3395124dc..91d911ec2 100644 --- a/dev_console.go +++ b/dev_console.go @@ -192,7 +192,11 @@ func (i *Console) ParseInput(input string) bool { "dag HASH NONCE - Verifies a nonce with the given hash with dagger\n" + "\033[1m= Encoding =\033[0m\n" + "decode STR\n" + - "encode STR\n") + "encode STR\n" + + "\033[1m= Other =\033[0m\n" + + "addp HOST:PORT\n" + + "tx TO AMOUNT\n" + + "contract AMOUNT\n") default: fmt.Println("Unknown command:", tokens[0]) From 6ab368cf7426195a0d44b14ad6d82c020c024395 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 28 Jan 2014 15:35:19 +0100 Subject: [PATCH 135/459] Changed block chain specific methods --- dev_console.go | 2 +- ethereum.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dev_console.go b/dev_console.go index 91d911ec2..74ba343cd 100644 --- a/dev_console.go +++ b/dev_console.go @@ -128,7 +128,7 @@ func (i *Console) ParseInput(input string) bool { fmt.Printf("%q\n", d) case "getaddr": encoded, _ := hex.DecodeString(tokens[1]) - d := i.ethereum.BlockManager.CurrentBlock.State().Get(string(encoded)) + d := i.ethereum.BlockManager.BlockChain().CurrentBlock.State().Get(string(encoded)) if d != "" { decoder := ethutil.NewRlpDecoder([]byte(d)) fmt.Println(decoder) diff --git a/ethereum.go b/ethereum.go index d58033cdc..8608ca47a 100644 --- a/ethereum.go +++ b/ethereum.go @@ -84,7 +84,7 @@ func main() { ethereum.Start() if StartMining { - blockTime := time.Duration(15) + blockTime := time.Duration(2) log.Printf("Dev Test Mining started. Blocks found each %d seconds\n", blockTime) // Fake block mining. It broadcasts a new block every 5 seconds @@ -96,8 +96,8 @@ func main() { txs := ethereum.TxPool.Flush() block := ethchain.CreateBlock( - ethereum.BlockManager.CurrentBlock.State().Root, - ethereum.BlockManager.LastBlockHash, + ethereum.BlockManager.BlockChain().CurrentBlock.State().Root, + ethereum.BlockManager.BlockChain().LastBlockHash, "123", big.NewInt(1), big.NewInt(1), From ab43c001f7642eaacb8d3bbcde5f0016ce73a85d Mon Sep 17 00:00:00 2001 From: Joey Zhou Date: Wed, 29 Jan 2014 14:08:40 -0800 Subject: [PATCH 136/459] typo? --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fe3ec304d..3693fb6b0 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ Ethereum Go makes use of a modified `secp256k1-go` and therefor GMP. Install ======= -```go get -u -t https://github.com/ethereum/go-ethereum``` +```go get -u -t github.com/ethereum/go-ethereum``` Command line options From 27a03d3eea5451ddb84dbb1ff33ee916259635d0 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 30 Jan 2014 00:47:09 +0100 Subject: [PATCH 137/459] Updated to the new Trie --- dev_console.go | 10 +++++----- ethereum.go | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dev_console.go b/dev_console.go index 74ba343cd..106c372f2 100644 --- a/dev_console.go +++ b/dev_console.go @@ -76,11 +76,11 @@ func (i *Console) ValidateInput(action string, argumentLength int) error { } func (i *Console) PrintRoot() { - root := ethutil.Conv(i.trie.RootT) + root := ethutil.Conv(i.trie.Root) if len(root.AsBytes()) != 0 { fmt.Println(hex.EncodeToString(root.AsBytes())) } else { - fmt.Println(i.trie.RootT) + fmt.Println(i.trie.Root) } } @@ -108,15 +108,15 @@ func (i *Console) ParseInput(input string) bool { } else { switch tokens[0] { case "update": - i.trie.UpdateT(tokens[1], tokens[2]) + i.trie.Update(tokens[1], tokens[2]) i.PrintRoot() case "get": - fmt.Println(i.trie.GetT(tokens[1])) + fmt.Println(i.trie.Get(tokens[1])) case "root": i.PrintRoot() case "rawroot": - fmt.Println(i.trie.RootT) + fmt.Println(i.trie.Root) case "print": i.db.Print() case "dag": diff --git a/ethereum.go b/ethereum.go index 8608ca47a..2ffb6c929 100644 --- a/ethereum.go +++ b/ethereum.go @@ -84,7 +84,7 @@ func main() { ethereum.Start() if StartMining { - blockTime := time.Duration(2) + blockTime := time.Duration(10) log.Printf("Dev Test Mining started. Blocks found each %d seconds\n", blockTime) // Fake block mining. It broadcasts a new block every 5 seconds @@ -107,7 +107,7 @@ func main() { if err != nil { log.Println(err) } else { - log.Println("\n+++++++ MINED BLK +++++++\n", block.String()) + //log.Println("\n+++++++ MINED BLK +++++++\n", block.String()) } } }() From e28632b997b4097fb6f899067ead02b90d9b887b Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 30 Jan 2014 23:50:15 +0100 Subject: [PATCH 138/459] Mine? --- dev_console.go | 4 ++-- ethereum.go | 44 ++++++++++++++++++++++++++------------------ 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/dev_console.go b/dev_console.go index 106c372f2..39176eeba 100644 --- a/dev_console.go +++ b/dev_console.go @@ -124,8 +124,8 @@ func (i *Console) ParseInput(input string) bool { ethutil.BigPow(2, 36), // diff ethutil.Big(tokens[2]))) // nonce case "decode": - d, _ := ethutil.Decode([]byte(tokens[1]), 0) - fmt.Printf("%q\n", d) + value := ethutil.NewRlpDecoder([]byte(tokens[1])) + fmt.Println(value) case "getaddr": encoded, _ := hex.DecodeString(tokens[1]) d := i.ethereum.BlockManager.BlockChain().CurrentBlock.State().Get(string(encoded)) diff --git a/ethereum.go b/ethereum.go index 2ffb6c929..810c30f49 100644 --- a/ethereum.go +++ b/ethereum.go @@ -8,7 +8,6 @@ import ( "github.com/ethereum/ethutil-go" _ "github.com/ethereum/ethwire-go" "log" - "math/big" "os" "os/signal" "path" @@ -89,26 +88,35 @@ func main() { // Fake block mining. It broadcasts a new block every 5 seconds go func() { + pow := ðchain.EasyPow{} + for { - - time.Sleep(blockTime * time.Second) - txs := ethereum.TxPool.Flush() + block := ethereum.BlockManager.BlockChain().NewBlock("82c3b0b72cf62f1a9ce97c64da8072efa28225d8", txs) - block := ethchain.CreateBlock( - ethereum.BlockManager.BlockChain().CurrentBlock.State().Root, - ethereum.BlockManager.BlockChain().LastBlockHash, - "123", - big.NewInt(1), - big.NewInt(1), - "", - txs) - err := ethereum.BlockManager.ProcessBlockWithState(block, block.State()) - if err != nil { - log.Println(err) - } else { - //log.Println("\n+++++++ MINED BLK +++++++\n", block.String()) - } + nonce := pow.Search(block) + block.Nonce = nonce + + log.Println("nonce found:", nonce) + /* + time.Sleep(blockTime * time.Second) + + + block := ethchain.CreateBlock( + ethereum.BlockManager.BlockChain().CurrentBlock.State().Root, + ethereum.BlockManager.BlockChain().LastBlockHash, + "123", + big.NewInt(1), + big.NewInt(1), + "", + txs) + err := ethereum.BlockManager.ProcessBlockWithState(block, block.State()) + if err != nil { + log.Println(err) + } else { + //log.Println("\n+++++++ MINED BLK +++++++\n", block.String()) + } + */ } }() } From a0704364ce7e4e65e805083a54362a53182cec7a Mon Sep 17 00:00:00 2001 From: Joey Zhou Date: Fri, 31 Jan 2014 01:59:30 -0800 Subject: [PATCH 139/459] fix build failure --- test_runner_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test_runner_test.go b/test_runner_test.go index 0a0b0d69c..5c8461ad8 100644 --- a/test_runner_test.go +++ b/test_runner_test.go @@ -27,8 +27,7 @@ func TestTestRunner(t *testing.T) { for key, value := range source.Inputs { trie.Update(key, value) } - - if hex.EncodeToString([]byte(trie.Root)) != source.Expectation { + if hex.EncodeToString(trie.Root.([]byte)) != source.Expectation { t.Error("trie root did not match") } }) From 6a7cd0c676f56ab1bf2205ee29f6bb24a2449f29 Mon Sep 17 00:00:00 2001 From: Ramesh Nair Date: Sat, 1 Feb 2014 11:10:18 +0800 Subject: [PATCH 140/459] Update README --- README.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fe3ec304d..ac3235e93 100644 --- a/README.md +++ b/README.md @@ -38,10 +38,22 @@ Deps Ethereum Go makes use of a modified `secp256k1-go` and therefor GMP. -Install +Ubuntu 12+ +* `apt-get install libgmp3-dev` + +OS X 10.9+: +* `brew install gmp4` +* Symlink the headers and libs if necessary: + * `sudo ln -s /usr/local/opt/gmp4/include/gmp.h /usr/local/include/gmp.h` + * `sudo ln -s /usr/local/opt/gmp4/lib/libgmp.a /usr/local/lib/libgmp.a` + * `sudo ln -s /usr/local/opt/gmp4/lib/libgmpxx.a /usr/local/lib/libgmpxx.a` + +Build ======= -```go get -u -t https://github.com/ethereum/go-ethereum``` +* `go get -u -t github.com/ethereum/go-ethereum` +* `cd $GOPATH/src/github.com/ethereum/go-etherum` +* `go build` Command line options From 9cdf8f2cba0469429f3d3f2aeacdbb4844928a0a Mon Sep 17 00:00:00 2001 From: Ramesh Nair Date: Sat, 1 Feb 2014 11:20:29 +0800 Subject: [PATCH 141/459] Updated build instructions --- README.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ac3235e93..10527931e 100644 --- a/README.md +++ b/README.md @@ -39,14 +39,10 @@ Deps Ethereum Go makes use of a modified `secp256k1-go` and therefor GMP. Ubuntu 12+ -* `apt-get install libgmp3-dev` +* `apt-get install gmp-dev` OS X 10.9+: -* `brew install gmp4` -* Symlink the headers and libs if necessary: - * `sudo ln -s /usr/local/opt/gmp4/include/gmp.h /usr/local/include/gmp.h` - * `sudo ln -s /usr/local/opt/gmp4/lib/libgmp.a /usr/local/lib/libgmp.a` - * `sudo ln -s /usr/local/opt/gmp4/lib/libgmpxx.a /usr/local/lib/libgmpxx.a` +* `brew install gmp` Build ======= From 20671758084b5f3889659231c6e4c9ef59d1b740 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 1 Feb 2014 21:51:50 +0100 Subject: [PATCH 142/459] RLP Updates --- dev_console.go | 27 +++++---------------------- ethereum.go | 19 ++++++++++++++++--- 2 files changed, 21 insertions(+), 25 deletions(-) diff --git a/dev_console.go b/dev_console.go index 39176eeba..4153e33bf 100644 --- a/dev_console.go +++ b/dev_console.go @@ -124,13 +124,13 @@ func (i *Console) ParseInput(input string) bool { ethutil.BigPow(2, 36), // diff ethutil.Big(tokens[2]))) // nonce case "decode": - value := ethutil.NewRlpDecoder([]byte(tokens[1])) + value := ethutil.NewRlpValueFromBytes([]byte(tokens[1])) fmt.Println(value) case "getaddr": encoded, _ := hex.DecodeString(tokens[1]) d := i.ethereum.BlockManager.BlockChain().CurrentBlock.State().Get(string(encoded)) if d != "" { - decoder := ethutil.NewRlpDecoder([]byte(d)) + decoder := ethutil.NewRlpValueFromBytes([]byte(d)) fmt.Println(decoder) } else { fmt.Println("getaddr: address unknown") @@ -139,27 +139,10 @@ func (i *Console) ParseInput(input string) bool { i.ethereum.Broadcast(ethwire.MsgTalkTy, tokens[1]) case "addp": i.ethereum.ConnectToPeer(tokens[1]) + case "pcount": + fmt.Println("peers:", i.ethereum.Peers().Len()) case "encode": fmt.Printf("%q\n", ethutil.Encode(tokens[1])) - /* - case "newblk": - block := ethchain.CreateBlock( - i.ethereum.BlockManager.BlockChain().LastBlock.State().Root, - i.ethereum.BlockManager.LastBlockHash, - "123", - big.NewInt(1), - big.NewInt(1), - "", - i.ethereum.TxPool.Flush(), - ) - err := i.ethereum.BlockManager.ProcessBlock(block) - if err != nil { - fmt.Println(err) - } else { - i.ethereum.Broadcast(ethwire.MsgBlockTy, block.RlpData()) - } - //fmt.Println(ethutil.NewRlpValue(block.RlpData()).Get(0)) - */ case "tx": tx := ethchain.NewTransaction(tokens[1], ethutil.Big(tokens[2]), []string{""}) fmt.Printf("%x\n", tx.Hash()) @@ -169,7 +152,7 @@ func (i *Console) ParseInput(input string) bool { addr, _ := hex.DecodeString(tokens[1]) data, _ := ethutil.Config.Db.Get(addr) if len(data) != 0 { - decoder := ethutil.NewRlpDecoder(data) + decoder := ethutil.NewRlpValueFromBytes(data) fmt.Println(decoder) } else { fmt.Println("gettx: tx not found") diff --git a/ethereum.go b/ethereum.go index 810c30f49..7f5570110 100644 --- a/ethereum.go +++ b/ethereum.go @@ -1,6 +1,7 @@ package main import ( + "encoding/hex" "flag" "fmt" "github.com/ethereum/eth-go" @@ -46,6 +47,8 @@ func main() { runtime.GOMAXPROCS(runtime.NumCPU()) Init() + //fmt.Printf("%x\n", ethutil.Encode([]interface{}{ethutil.BigPow(2, 36).Bytes()})) + ethchain.InitFees() ethutil.ReadConfig() @@ -89,17 +92,27 @@ func main() { // Fake block mining. It broadcasts a new block every 5 seconds go func() { pow := ðchain.EasyPow{} + addr, _ := hex.DecodeString("82c3b0b72cf62f1a9ce97c64da8072efa28225d8") for { + time.Sleep(blockTime * time.Second) + txs := ethereum.TxPool.Flush() - block := ethereum.BlockManager.BlockChain().NewBlock("82c3b0b72cf62f1a9ce97c64da8072efa28225d8", txs) + block := ethereum.BlockManager.BlockChain().NewBlock(addr, txs) nonce := pow.Search(block) block.Nonce = nonce - log.Println("nonce found:", nonce) + err := ethereum.BlockManager.ProcessBlockWithState(block, block.State()) + if err != nil { + log.Println(err) + } else { + //log.Println("nonce found:", nonce) + log.Println("\n+++++++ MINED BLK +++++++\n", block.String()) + } + //os.Exit(1) + /* - time.Sleep(blockTime * time.Second) block := ethchain.CreateBlock( From f56a595954fc6641f0b7300a82850b7923d357c5 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 2 Feb 2014 01:40:03 +0100 Subject: [PATCH 143/459] Reverted back to old messages --- dev_console.go | 2 +- ethereum.go | 12 +----------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/dev_console.go b/dev_console.go index 4153e33bf..76f8ec72e 100644 --- a/dev_console.go +++ b/dev_console.go @@ -136,7 +136,7 @@ func (i *Console) ParseInput(input string) bool { fmt.Println("getaddr: address unknown") } case "say": - i.ethereum.Broadcast(ethwire.MsgTalkTy, tokens[1]) + i.ethereum.Broadcast(ethwire.MsgTalkTy, []interface{}{tokens[1]}) case "addp": i.ethereum.ConnectToPeer(tokens[1]) case "pcount": diff --git a/ethereum.go b/ethereum.go index 7f5570110..8ad4ae524 100644 --- a/ethereum.go +++ b/ethereum.go @@ -11,7 +11,6 @@ import ( "log" "os" "os/signal" - "path" "runtime" "time" ) @@ -65,18 +64,9 @@ func main() { err := os.Mkdir(ethutil.Config.ExecPath, os.ModePerm) // Error is OK if the error is ErrExist if err != nil && !os.IsExist(err) { - log.Panic("Unable to create EXECPATH. Exiting") + log.Panic("Unable to create EXECPATH:", err) } - // TODO The logger will eventually be a non blocking logger. Logging is a expensive task - // Log to file only - file, err := os.OpenFile(path.Join(ethutil.Config.ExecPath, "debug.log"), os.O_RDWR|os.O_CREATE, os.ModePerm) - if err != nil { - log.Panic("Unable to set proper logger", err) - } - - ethutil.Config.Log = log.New(file, "", 0) - console := NewConsole(ethereum) go console.Start() } From f07b53da2db90aa84dbb5044de15d072e19fb849 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 2 Feb 2014 16:15:24 +0100 Subject: [PATCH 144/459] upnp test --- ethereum.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ethereum.go b/ethereum.go index 8ad4ae524..b0e242819 100644 --- a/ethereum.go +++ b/ethereum.go @@ -46,15 +46,13 @@ func main() { runtime.GOMAXPROCS(runtime.NumCPU()) Init() - //fmt.Printf("%x\n", ethutil.Encode([]interface{}{ethutil.BigPow(2, 36).Bytes()})) - ethchain.InitFees() ethutil.ReadConfig() log.Printf("Starting Ethereum v%s\n", ethutil.Config.Ver) // Instantiated a eth stack - ethereum, err := eth.New() + ethereum, err := eth.New(eth.CapDefault) if err != nil { log.Println(err) return From cce842314fa61fcd2a4b205b04313d9728ea2a57 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 2 Feb 2014 19:44:59 +0100 Subject: [PATCH 145/459] UPnP support --- ethereum.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ethereum.go b/ethereum.go index b0e242819..6d6d25bd4 100644 --- a/ethereum.go +++ b/ethereum.go @@ -19,10 +19,14 @@ const Debug = true var StartConsole bool var StartMining bool +var UseUPnP bool +var OutboundPort string func Init() { flag.BoolVar(&StartConsole, "c", false, "debug and testing console") flag.BoolVar(&StartMining, "m", false, "start dagger mining") + flag.BoolVar(&UseUPnP, "upnp", false, "enable UPnP support") + flag.StringVar(&OutboundPort, "port", "30303", "listening port") flag.Parse() } @@ -52,7 +56,7 @@ func main() { log.Printf("Starting Ethereum v%s\n", ethutil.Config.Ver) // Instantiated a eth stack - ethereum, err := eth.New(eth.CapDefault) + ethereum, err := eth.New(eth.CapDefault, UseUPnP) if err != nil { log.Println(err) return From c3ee0e92b8f782aa51eae384d05d62f0ea9b753d Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 2 Feb 2014 20:53:49 +0100 Subject: [PATCH 146/459] Recipient as bytes --- dev_console.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dev_console.go b/dev_console.go index 76f8ec72e..f93300aad 100644 --- a/dev_console.go +++ b/dev_console.go @@ -144,7 +144,8 @@ func (i *Console) ParseInput(input string) bool { case "encode": fmt.Printf("%q\n", ethutil.Encode(tokens[1])) case "tx": - tx := ethchain.NewTransaction(tokens[1], ethutil.Big(tokens[2]), []string{""}) + recipient, _ := hex.DecodeString(tokens[1]) + tx := ethchain.NewTransaction(recipient, ethutil.Big(tokens[2]), []string{""}) fmt.Printf("%x\n", tx.Hash()) i.ethereum.TxPool.QueueTransaction(tx) @@ -158,7 +159,7 @@ func (i *Console) ParseInput(input string) bool { fmt.Println("gettx: tx not found") } case "contract": - contract := ethchain.NewTransaction("", ethutil.Big(tokens[1]), []string{"PUSH", "1234"}) + contract := ethchain.NewTransaction([]byte{}, ethutil.Big(tokens[1]), []string{"PUSH", "1234"}) fmt.Printf("%x\n", contract.Hash()) i.ethereum.TxPool.QueueTransaction(contract) From 7f8f008253c9928b556df238984f3046304be86e Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 2 Feb 2014 23:52:06 +0100 Subject: [PATCH 147/459] Changed mining --- ethereum.go | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/ethereum.go b/ethereum.go index 6d6d25bd4..74c545edc 100644 --- a/ethereum.go +++ b/ethereum.go @@ -7,12 +7,10 @@ import ( "github.com/ethereum/eth-go" "github.com/ethereum/ethchain-go" "github.com/ethereum/ethutil-go" - _ "github.com/ethereum/ethwire-go" "log" "os" "os/signal" "runtime" - "time" ) const Debug = true @@ -78,8 +76,7 @@ func main() { ethereum.Start() if StartMining { - blockTime := time.Duration(10) - log.Printf("Dev Test Mining started. Blocks found each %d seconds\n", blockTime) + log.Printf("Dev Test Mining started...\n") // Fake block mining. It broadcasts a new block every 5 seconds go func() { @@ -87,13 +84,12 @@ func main() { addr, _ := hex.DecodeString("82c3b0b72cf62f1a9ce97c64da8072efa28225d8") for { - time.Sleep(blockTime * time.Second) + //time.Sleep(blockTime * time.Second) txs := ethereum.TxPool.Flush() block := ethereum.BlockManager.BlockChain().NewBlock(addr, txs) - nonce := pow.Search(block) - block.Nonce = nonce + block.Nonce = pow.Search(block) err := ethereum.BlockManager.ProcessBlockWithState(block, block.State()) if err != nil { From 00ec15c82eafc493c3349aea24c4fef315e5692e Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 3 Feb 2014 00:09:02 +0100 Subject: [PATCH 148/459] Fixed mining --- ethereum.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethereum.go b/ethereum.go index 74c545edc..8a241f4cc 100644 --- a/ethereum.go +++ b/ethereum.go @@ -91,7 +91,7 @@ func main() { block.Nonce = pow.Search(block) - err := ethereum.BlockManager.ProcessBlockWithState(block, block.State()) + err := ethereum.BlockManager.ProcessBlock(block) if err != nil { log.Println(err) } else { From ec883db3b1172f75761c066d4b022858d1f9df5d Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 3 Feb 2014 01:09:45 +0100 Subject: [PATCH 149/459] TApply transactions --- ethereum.go | 30 +++++------------------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/ethereum.go b/ethereum.go index 8a241f4cc..bae473854 100644 --- a/ethereum.go +++ b/ethereum.go @@ -84,40 +84,20 @@ func main() { addr, _ := hex.DecodeString("82c3b0b72cf62f1a9ce97c64da8072efa28225d8") for { - //time.Sleep(blockTime * time.Second) - txs := ethereum.TxPool.Flush() + // Create a new block which we're going to mine block := ethereum.BlockManager.BlockChain().NewBlock(addr, txs) - + // Apply all transactions to the block + ethereum.BlockManager.ApplyTransactions(block) + // Search the nonce block.Nonce = pow.Search(block) - + // Process the block and verify err := ethereum.BlockManager.ProcessBlock(block) if err != nil { log.Println(err) } else { - //log.Println("nonce found:", nonce) log.Println("\n+++++++ MINED BLK +++++++\n", block.String()) } - //os.Exit(1) - - /* - - - block := ethchain.CreateBlock( - ethereum.BlockManager.BlockChain().CurrentBlock.State().Root, - ethereum.BlockManager.BlockChain().LastBlockHash, - "123", - big.NewInt(1), - big.NewInt(1), - "", - txs) - err := ethereum.BlockManager.ProcessBlockWithState(block, block.State()) - if err != nil { - log.Println(err) - } else { - //log.Println("\n+++++++ MINED BLK +++++++\n", block.String()) - } - */ } }() } From 5e36e3ccc7fad6d0b40c7f95be4f02e0cafdb2e2 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 3 Feb 2014 02:01:31 +0100 Subject: [PATCH 150/459] Process transactions --- dev_console.go | 12 ++++++++---- ethereum.go | 12 ++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/dev_console.go b/dev_console.go index f93300aad..e93b39c3a 100644 --- a/dev_console.go +++ b/dev_console.go @@ -144,11 +144,15 @@ func (i *Console) ParseInput(input string) bool { case "encode": fmt.Printf("%q\n", ethutil.Encode(tokens[1])) case "tx": - recipient, _ := hex.DecodeString(tokens[1]) - tx := ethchain.NewTransaction(recipient, ethutil.Big(tokens[2]), []string{""}) - fmt.Printf("%x\n", tx.Hash()) + recipient, err := hex.DecodeString(tokens[1]) + if err != nil { + fmt.Println("recipient err:", err) + } else { + tx := ethchain.NewTransaction(recipient, ethutil.Big(tokens[2]), []string{""}) + fmt.Printf("%x\n", tx.Hash()) + i.ethereum.TxPool.QueueTransaction(tx) + } - i.ethereum.TxPool.QueueTransaction(tx) case "gettx": addr, _ := hex.DecodeString(tokens[1]) data, _ := ethutil.Config.Db.Get(addr) diff --git a/ethereum.go b/ethereum.go index bae473854..680e52325 100644 --- a/ethereum.go +++ b/ethereum.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum/eth-go" "github.com/ethereum/ethchain-go" "github.com/ethereum/ethutil-go" + "github.com/ethereum/ethwire-go" "log" "os" "os/signal" @@ -88,16 +89,11 @@ func main() { // Create a new block which we're going to mine block := ethereum.BlockManager.BlockChain().NewBlock(addr, txs) // Apply all transactions to the block - ethereum.BlockManager.ApplyTransactions(block) + ethereum.BlockManager.ApplyTransactions(block, block.Transactions()) // Search the nonce block.Nonce = pow.Search(block) - // Process the block and verify - err := ethereum.BlockManager.ProcessBlock(block) - if err != nil { - log.Println(err) - } else { - log.Println("\n+++++++ MINED BLK +++++++\n", block.String()) - } + ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{block.RlpValue().Value}) + log.Println("\n+++++++ MINED BLK +++++++\n", block.String()) } }() } From 7730949221a95b89282713901bf4db25673cd95c Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 3 Feb 2014 14:26:52 +0100 Subject: [PATCH 151/459] Block processing during mining --- ethereum.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ethereum.go b/ethereum.go index 680e52325..5cbf86665 100644 --- a/ethereum.go +++ b/ethereum.go @@ -7,7 +7,7 @@ import ( "github.com/ethereum/eth-go" "github.com/ethereum/ethchain-go" "github.com/ethereum/ethutil-go" - "github.com/ethereum/ethwire-go" + _ "github.com/ethereum/ethwire-go" "log" "os" "os/signal" @@ -92,7 +92,8 @@ func main() { ethereum.BlockManager.ApplyTransactions(block, block.Transactions()) // Search the nonce block.Nonce = pow.Search(block) - ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{block.RlpValue().Value}) + ethereum.BlockManager.ProcessBlock(block) + //ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{block.RlpValue().Value}) log.Println("\n+++++++ MINED BLK +++++++\n", block.String()) } }() From dbe42ce44e7f931b712fc461bea6f98f870331c5 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 6 Feb 2014 13:28:30 +0100 Subject: [PATCH 152/459] Mining using a different hash now --- README.md | 4 +--- ethereum.go | 10 +++++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 10527931e..157601b39 100644 --- a/README.md +++ b/README.md @@ -47,9 +47,7 @@ OS X 10.9+: Build ======= -* `go get -u -t github.com/ethereum/go-ethereum` -* `cd $GOPATH/src/github.com/ethereum/go-etherum` -* `go build` +`go get -u -t github.com/ethereum/go-ethereum` Command line options diff --git a/ethereum.go b/ethereum.go index 5cbf86665..8ba99a388 100644 --- a/ethereum.go +++ b/ethereum.go @@ -92,9 +92,13 @@ func main() { ethereum.BlockManager.ApplyTransactions(block, block.Transactions()) // Search the nonce block.Nonce = pow.Search(block) - ethereum.BlockManager.ProcessBlock(block) - //ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{block.RlpValue().Value}) - log.Println("\n+++++++ MINED BLK +++++++\n", block.String()) + err := ethereum.BlockManager.ProcessBlock(block) + if err != nil { + log.Println(err) + } else { + //ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{block.RlpValue().Value}) + log.Println("\n+++++++ MINED BLK +++++++\n", block.String()) + } } }() } From 9f4a81a02e6d84a192c3cdcb42866563456f5267 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 6 Feb 2014 23:47:04 +0100 Subject: [PATCH 153/459] Removed test --- dev_console.go | 1 + test_runner_test.go | 2 ++ 2 files changed, 3 insertions(+) diff --git a/dev_console.go b/dev_console.go index e93b39c3a..8ef7341b2 100644 --- a/dev_console.go +++ b/dev_console.go @@ -149,6 +149,7 @@ func (i *Console) ParseInput(input string) bool { fmt.Println("recipient err:", err) } else { tx := ethchain.NewTransaction(recipient, ethutil.Big(tokens[2]), []string{""}) + tx.Sign([]byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")) fmt.Printf("%x\n", tx.Hash()) i.ethereum.TxPool.QueueTransaction(tx) } diff --git a/test_runner_test.go b/test_runner_test.go index 5c8461ad8..a5672eb7a 100644 --- a/test_runner_test.go +++ b/test_runner_test.go @@ -1,5 +1,6 @@ package main +/* import ( "encoding/hex" _ "fmt" @@ -32,3 +33,4 @@ func TestTestRunner(t *testing.T) { } }) } +*/ From 827f341c97e9243b0c04a2fbde363b949bc3215d Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 7 Feb 2014 22:25:59 +0100 Subject: [PATCH 154/459] Genesis logging --- ethereum.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/ethereum.go b/ethereum.go index 8ba99a388..659134ffd 100644 --- a/ethereum.go +++ b/ethereum.go @@ -20,10 +20,12 @@ var StartConsole bool var StartMining bool var UseUPnP bool var OutboundPort string +var ShowGenesis bool func Init() { flag.BoolVar(&StartConsole, "c", false, "debug and testing console") flag.BoolVar(&StartMining, "m", false, "start dagger mining") + flag.BoolVar(&ShowGenesis, "g", false, "prints genesis header and exits") flag.BoolVar(&UseUPnP, "upnp", false, "enable UPnP support") flag.StringVar(&OutboundPort, "port", "30303", "listening port") @@ -52,8 +54,6 @@ func main() { ethchain.InitFees() ethutil.ReadConfig() - log.Printf("Starting Ethereum v%s\n", ethutil.Config.Ver) - // Instantiated a eth stack ethereum, err := eth.New(eth.CapDefault, UseUPnP) if err != nil { @@ -61,6 +61,13 @@ func main() { return } + if ShowGenesis { + fmt.Println(ethereum.BlockManager.BlockChain().Genesis()) + os.Exit(0) + } + + log.Printf("Starting Ethereum v%s\n", ethutil.Config.Ver) + if StartConsole { err := os.Mkdir(ethutil.Config.ExecPath, os.ModePerm) // Error is OK if the error is ErrExist From f1ba1df16565614fdf04392463191f9c276270d4 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 8 Feb 2014 22:07:17 +0100 Subject: [PATCH 155/459] Added key address and key generation --- README.md | 5 +--- config.go | 26 +++++++++++++++++++++ dev_console.go | 3 ++- ethereum.go | 62 +++++++++++++++++++++++++++++++++----------------- 4 files changed, 70 insertions(+), 26 deletions(-) create mode 100644 config.go diff --git a/README.md b/README.md index 157601b39..a9b047c6b 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Ethereum [![Build Status](https://travis-ci.org/ethereum/go-ethereum.png?branch=master)](https://travis-ci.org/ethereum/go-ethereum) -Ethereum Go developer client (c) [0255c7881](https://github.com/ethereum/go-ethereum#copy) +Ethereum Go developer client (c) Jeffrey Wilcke A fair warning; Ethereum is not yet to be used in production. There's no test-net and you aren't mining real blocks (just one which is the genesis block). @@ -95,6 +95,3 @@ expect you to write tests for me so I don't have to test your code manually. (If you want to contribute by just writing tests that's fine too!) -### Copy - -69bce990a619e747b4f57483724b0e8a1732bb3b44ccf70b0dd6abd272af94550fc9d8b21232d33ebf30d38a148612f68e936094b4daeb9ea7174088a439070401 0255c78815d4f056f84c96de438ed9e38c69c0f8af24f5032248be5a79fe9071c3 diff --git a/config.go b/config.go new file mode 100644 index 000000000..6b5b9b62f --- /dev/null +++ b/config.go @@ -0,0 +1,26 @@ +package main + +import ( + "flag" +) + +var StartConsole bool +var StartMining bool +var UseUPnP bool +var OutboundPort string +var ShowGenesis bool +var AddPeer string +var MaxPeer int +var GenAddr bool + +func Init() { + flag.BoolVar(&StartConsole, "c", false, "debug and testing console") + flag.BoolVar(&StartMining, "m", false, "start dagger mining") + flag.BoolVar(&ShowGenesis, "g", false, "prints genesis header and exits") + flag.BoolVar(&UseUPnP, "upnp", false, "enable UPnP support") + flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key") + flag.StringVar(&OutboundPort, "p", "30303", "listening port") + flag.IntVar(&MaxPeer, "x", 5, "maximum desired peers") + + flag.Parse() +} diff --git a/dev_console.go b/dev_console.go index 8ef7341b2..d2f3befb2 100644 --- a/dev_console.go +++ b/dev_console.go @@ -149,7 +149,8 @@ func (i *Console) ParseInput(input string) bool { fmt.Println("recipient err:", err) } else { tx := ethchain.NewTransaction(recipient, ethutil.Big(tokens[2]), []string{""}) - tx.Sign([]byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")) + privKey, _ := ethutil.Config.Db.Get([]byte("KeyRing")) + tx.Sign(privKey) fmt.Printf("%x\n", tx.Hash()) i.ethereum.TxPool.QueueTransaction(tx) } diff --git a/ethereum.go b/ethereum.go index 659134ffd..674f7d88c 100644 --- a/ethereum.go +++ b/ethereum.go @@ -2,12 +2,11 @@ package main import ( "encoding/hex" - "flag" "fmt" "github.com/ethereum/eth-go" "github.com/ethereum/ethchain-go" "github.com/ethereum/ethutil-go" - _ "github.com/ethereum/ethwire-go" + "github.com/obscuren/secp256k1-go" "log" "os" "os/signal" @@ -16,22 +15,6 @@ import ( const Debug = true -var StartConsole bool -var StartMining bool -var UseUPnP bool -var OutboundPort string -var ShowGenesis bool - -func Init() { - flag.BoolVar(&StartConsole, "c", false, "debug and testing console") - flag.BoolVar(&StartMining, "m", false, "start dagger mining") - flag.BoolVar(&ShowGenesis, "g", false, "prints genesis header and exits") - flag.BoolVar(&UseUPnP, "upnp", false, "enable UPnP support") - flag.StringVar(&OutboundPort, "port", "30303", "listening port") - - flag.Parse() -} - // Register interrupt handlers so we can stop the ethereum func RegisterInterupts(s *eth.Ethereum) { // Buffered chan of one is enough @@ -47,6 +30,17 @@ func RegisterInterupts(s *eth.Ethereum) { }() } +func CreateKeyPair(force bool) { + data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) + if len(data) == 0 || force { + log.Println("Generating new address and keypair") + + pub, prv := secp256k1.GenerateKeyPair() + + ethutil.Config.Db.Put([]byte("KeyRing"), prv) + } +} + func main() { runtime.GOMAXPROCS(runtime.NumCPU()) Init() @@ -57,10 +51,31 @@ func main() { // Instantiated a eth stack ethereum, err := eth.New(eth.CapDefault, UseUPnP) if err != nil { - log.Println(err) + log.Println("eth start err:", err) return } + if GenAddr { + fmt.Println("This action overwrites your old private key. Are you sure? (y/n)") + + var r string + fmt.Scanln(&r) + for ; ; fmt.Scanln(&r) { + if r == "n" || r == "y" { + break + } else { + fmt.Println("Yes or no?", r) + } + } + + if r == "y" { + CreateKeyPair(true) + } + os.Exit(0) + } else { + CreateKeyPair(false) + } + if ShowGenesis { fmt.Println(ethereum.BlockManager.BlockChain().Genesis()) os.Exit(0) @@ -68,6 +83,9 @@ func main() { log.Printf("Starting Ethereum v%s\n", ethutil.Config.Ver) + // Set the max peers + ethereum.MaxPeers = MaxPeer + if StartConsole { err := os.Mkdir(ethutil.Config.ExecPath, os.ModePerm) // Error is OK if the error is ErrExist @@ -97,14 +115,16 @@ func main() { block := ethereum.BlockManager.BlockChain().NewBlock(addr, txs) // Apply all transactions to the block ethereum.BlockManager.ApplyTransactions(block, block.Transactions()) + + ethereum.BlockManager.AccumelateRewards(block, block) + // Search the nonce block.Nonce = pow.Search(block) err := ethereum.BlockManager.ProcessBlock(block) if err != nil { log.Println(err) } else { - //ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{block.RlpValue().Value}) - log.Println("\n+++++++ MINED BLK +++++++\n", block.String()) + log.Println("\n+++++++ MINED BLK +++++++\n", ethereum.BlockManager.BlockChain().CurrentBlock) } } }() From d7205b7affeacf2977a896a24f1ba88c933c8dce Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 8 Feb 2014 22:16:11 +0100 Subject: [PATCH 156/459] Updated readme --- README.md | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index a9b047c6b..1cf3e1b04 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,8 @@ Ethereum Ethereum Go developer client (c) Jeffrey Wilcke -A fair warning; Ethereum is not yet to be used in production. There's no -test-net and you aren't mining real blocks (just one which is the genesis block). - +Ethereum is currently in its testing phase. The current state is "Proof +of Concept 1". For build instructions see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Edge). Ethereum Go is split up in several sub packages Please refer to each individual package for more information. @@ -33,31 +32,35 @@ contains the LevelDB interface and memory DB interface. This executable is the front-end (currently nothing but a dev console) for the Ethereum Go implementation. -Deps -==== - -Ethereum Go makes use of a modified `secp256k1-go` and therefor GMP. - -Ubuntu 12+ -* `apt-get install gmp-dev` - -OS X 10.9+: -* `brew install gmp` - Build ======= -`go get -u -t github.com/ethereum/go-ethereum` +For build instruction please see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Edge) Command line options ==================== ``` --c launch the developer console --m start mining fake blocks and broadcast fake messages to the net +-c Launch the developer console +-m Start mining blocks +-genaddr Generates a new address and private key (destructive action) +-p Port on which the server will accept incomming connections (= 30303) +-upnp Enable UPnP (= false) +-x Desired amount of peers (= 5) +-h This help ``` +Developer console commands +========================== + +``` +addp : Connect to the given host +tx Send Wei to the specified +``` + +See the "help" command for *developer* options. + Contribution ============ From 542bc2fce4c6d65fd5346b64f2aa0a80f23d3480 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 8 Feb 2014 22:57:40 +0100 Subject: [PATCH 157/459] Woops --- ethereum.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ethereum.go b/ethereum.go index 674f7d88c..902b9ae9c 100644 --- a/ethereum.go +++ b/ethereum.go @@ -37,6 +37,8 @@ func CreateKeyPair(force bool) { pub, prv := secp256k1.GenerateKeyPair() + log.Printf("Your new address is %x\n", pub[12:]) + ethutil.Config.Db.Put([]byte("KeyRing"), prv) } } From 67572417c6522647d7d14c1042c427b5edd9973e Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 8 Feb 2014 23:21:09 +0100 Subject: [PATCH 158/459] Use the generated key --- ethereum.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethereum.go b/ethereum.go index 902b9ae9c..8bbb797d3 100644 --- a/ethereum.go +++ b/ethereum.go @@ -109,7 +109,7 @@ func main() { // Fake block mining. It broadcasts a new block every 5 seconds go func() { pow := ðchain.EasyPow{} - addr, _ := hex.DecodeString("82c3b0b72cf62f1a9ce97c64da8072efa28225d8") + addr, _ := ethutil.Config.Db.Get([]byte("KeyRing")) for { txs := ethereum.TxPool.Flush() From c2bb5e39e10e781404034b3018d753699247edd1 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 8 Feb 2014 23:21:29 +0100 Subject: [PATCH 159/459] Unused package --- ethereum.go | 1 - 1 file changed, 1 deletion(-) diff --git a/ethereum.go b/ethereum.go index 8bbb797d3..716507d53 100644 --- a/ethereum.go +++ b/ethereum.go @@ -1,7 +1,6 @@ package main import ( - "encoding/hex" "fmt" "github.com/ethereum/eth-go" "github.com/ethereum/ethchain-go" From 7b7242b9ea85ccdcc29dc9b515eb2d2776e2b50d Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 8 Feb 2014 23:25:48 +0100 Subject: [PATCH 160/459] Proper keys --- ethereum.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ethereum.go b/ethereum.go index 716507d53..bf379184f 100644 --- a/ethereum.go +++ b/ethereum.go @@ -38,7 +38,7 @@ func CreateKeyPair(force bool) { log.Printf("Your new address is %x\n", pub[12:]) - ethutil.Config.Db.Put([]byte("KeyRing"), prv) + ethutil.Config.Db.Put([]byte("KeyRing"), ethutil.Encode([]interface{}{prv, pub})) } } @@ -108,7 +108,9 @@ func main() { // Fake block mining. It broadcasts a new block every 5 seconds go func() { pow := ðchain.EasyPow{} - addr, _ := ethutil.Config.Db.Get([]byte("KeyRing")) + data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) + keyRing := ethutil.NewValueFromBytes(data) + addr := keyRing.Get(1).Bytes() for { txs := ethereum.TxPool.Flush() From 9ac81c5b2b8304fe8e1efed7298998f36267612b Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 8 Feb 2014 23:26:43 +0100 Subject: [PATCH 161/459] Proper keys --- dev_console.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dev_console.go b/dev_console.go index d2f3befb2..64a40a1c4 100644 --- a/dev_console.go +++ b/dev_console.go @@ -149,8 +149,9 @@ func (i *Console) ParseInput(input string) bool { fmt.Println("recipient err:", err) } else { tx := ethchain.NewTransaction(recipient, ethutil.Big(tokens[2]), []string{""}) - privKey, _ := ethutil.Config.Db.Get([]byte("KeyRing")) - tx.Sign(privKey) + data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) + keyRing := ethutil.NewValueFromBytes(data) + tx.Sign(keyRing.Get(0).Bytes()) fmt.Printf("%x\n", tx.Hash()) i.ethereum.TxPool.QueueTransaction(tx) } From 37a89e577c25afe0e0388f154eba1fb97a972971 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 8 Feb 2014 23:50:08 +0100 Subject: [PATCH 162/459] Added address --- ethereum.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ethereum.go b/ethereum.go index bf379184f..4584ff85c 100644 --- a/ethereum.go +++ b/ethereum.go @@ -36,9 +36,9 @@ func CreateKeyPair(force bool) { pub, prv := secp256k1.GenerateKeyPair() - log.Printf("Your new address is %x\n", pub[12:]) + log.Printf("Your new address is %x\n", ethutil.Sha3Bin(pub)[12:]) - ethutil.Config.Db.Put([]byte("KeyRing"), ethutil.Encode([]interface{}{prv, pub})) + ethutil.Config.Db.Put([]byte("KeyRing"), ethutil.Encode([]interface{}{prv, ethutil.Sha3Bin(pub)[12:]})) } } From 8320fd998ee5d140b7bc99d071567f4c4c97901f Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 9 Feb 2014 23:35:02 +0100 Subject: [PATCH 163/459] Added pub key to keyring --- ethereum.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ethereum.go b/ethereum.go index 4584ff85c..df9eb2387 100644 --- a/ethereum.go +++ b/ethereum.go @@ -35,10 +35,13 @@ func CreateKeyPair(force bool) { log.Println("Generating new address and keypair") pub, prv := secp256k1.GenerateKeyPair() + addr := ethutil.Sha3Bin(pub)[12:] - log.Printf("Your new address is %x\n", ethutil.Sha3Bin(pub)[12:]) + log.Printf("Your new address is %x\n", addr) + log.Printf("Your new pubkey is %x (%d)\n", pub, len(pub)) - ethutil.Config.Db.Put([]byte("KeyRing"), ethutil.Encode([]interface{}{prv, ethutil.Sha3Bin(pub)[12:]})) + keyRing := ethutil.NewValue([]interface{}{prv, addr, pub}) + ethutil.Config.Db.Put([]byte("KeyRing"), keyRing.Encode()) } } @@ -103,7 +106,7 @@ func main() { ethereum.Start() if StartMining { - log.Printf("Dev Test Mining started...\n") + log.Printf("Miner started\n") // Fake block mining. It broadcasts a new block every 5 seconds go func() { From 3ecb2ef29cb5a9a0d2be8e9719875692a305bf3b Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 10 Feb 2014 11:37:11 +0100 Subject: [PATCH 164/459] removed pub key log --- ethereum.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ethereum.go b/ethereum.go index df9eb2387..78a22614f 100644 --- a/ethereum.go +++ b/ethereum.go @@ -38,9 +38,8 @@ func CreateKeyPair(force bool) { addr := ethutil.Sha3Bin(pub)[12:] log.Printf("Your new address is %x\n", addr) - log.Printf("Your new pubkey is %x (%d)\n", pub, len(pub)) - keyRing := ethutil.NewValue([]interface{}{prv, addr, pub}) + keyRing := ethutil.NewValue([]interface{}{prv, addr, pub[1:]}) ethutil.Config.Db.Put([]byte("KeyRing"), keyRing.Encode()) } } From d831064f6597220f5013000048cdb0d2285d82a8 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 10 Feb 2014 20:22:52 +0100 Subject: [PATCH 165/459] Skip the first byte in generating addresses --- ethereum.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ethereum.go b/ethereum.go index 78a22614f..dfb2a955c 100644 --- a/ethereum.go +++ b/ethereum.go @@ -35,7 +35,7 @@ func CreateKeyPair(force bool) { log.Println("Generating new address and keypair") pub, prv := secp256k1.GenerateKeyPair() - addr := ethutil.Sha3Bin(pub)[12:] + addr := ethutil.Sha3Bin(pub[1:])[12:] log.Printf("Your new address is %x\n", addr) @@ -67,7 +67,7 @@ func main() { if r == "n" || r == "y" { break } else { - fmt.Println("Yes or no?", r) + fmt.Printf("Yes or no?", r) } } From 980987ae8f2783549125d7f503f6f948ebbef665 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 10 Feb 2014 20:24:36 +0100 Subject: [PATCH 166/459] Added block retrieval --- dev_console.go | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/dev_console.go b/dev_console.go index 64a40a1c4..d3635986b 100644 --- a/dev_console.go +++ b/dev_console.go @@ -66,6 +66,9 @@ func (i *Console) ValidateInput(action string, argumentLength int) error { case action == "addp" && argumentLength != 1: err = true expArgCount = 1 + case action == "block" && argumentLength != 1: + err = true + expArgCount = 1 } if err { @@ -128,13 +131,12 @@ func (i *Console) ParseInput(input string) bool { fmt.Println(value) case "getaddr": encoded, _ := hex.DecodeString(tokens[1]) - d := i.ethereum.BlockManager.BlockChain().CurrentBlock.State().Get(string(encoded)) - if d != "" { - decoder := ethutil.NewRlpValueFromBytes([]byte(d)) - fmt.Println(decoder) - } else { - fmt.Println("getaddr: address unknown") - } + addr := i.ethereum.BlockManager.BlockChain().CurrentBlock.GetAddr(encoded) + fmt.Println("addr:", addr) + case "block": + encoded, _ := hex.DecodeString(tokens[1]) + block := i.ethereum.BlockManager.BlockChain().GetBlock(encoded) + fmt.Println(block) case "say": i.ethereum.Broadcast(ethwire.MsgTalkTy, []interface{}{tokens[1]}) case "addp": @@ -179,6 +181,8 @@ func (i *Console) ParseInput(input string) bool { "get KEY - Retrieves the given key\n" + "root - Prints the hex encoded merkle root\n" + "rawroot - Prints the raw merkle root\n" + + "block HASH - Prints the block\n" + + "getaddr ADDR - Prints the account associated with the address\n" + "\033[1m= Dagger =\033[0m\n" + "dag HASH NONCE - Verifies a nonce with the given hash with dagger\n" + "\033[1m= Encoding =\033[0m\n" + From 954f8979386d75c3038d65cea94f481f5c15aba2 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 11 Feb 2014 18:46:10 +0100 Subject: [PATCH 167/459] Use seed --- config.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config.go b/config.go index 6b5b9b62f..d13bb863b 100644 --- a/config.go +++ b/config.go @@ -12,12 +12,14 @@ var ShowGenesis bool var AddPeer string var MaxPeer int var GenAddr bool +var UseSeed bool func Init() { flag.BoolVar(&StartConsole, "c", false, "debug and testing console") flag.BoolVar(&StartMining, "m", false, "start dagger mining") flag.BoolVar(&ShowGenesis, "g", false, "prints genesis header and exits") flag.BoolVar(&UseUPnP, "upnp", false, "enable UPnP support") + flag.BoolVar(&UseSeed, "seed", true, "seed peers") flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key") flag.StringVar(&OutboundPort, "p", "30303", "listening port") flag.IntVar(&MaxPeer, "x", 5, "maximum desired peers") From 68fbfe70dadd1e63baff6ecf5b59e4c9ba0eb2ca Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 12 Feb 2014 16:34:35 +0100 Subject: [PATCH 168/459] Default to .ethereum --- ethereum.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ethereum.go b/ethereum.go index dfb2a955c..51a2783ad 100644 --- a/ethereum.go +++ b/ethereum.go @@ -49,7 +49,8 @@ func main() { Init() ethchain.InitFees() - ethutil.ReadConfig() + ethutil.ReadConfig(".ethereum") + ethutil.Config.Seed = UseSeed // Instantiated a eth stack ethereum, err := eth.New(eth.CapDefault, UseUPnP) From fe59a2b26deb11705c524dc52dc78ce1e00eb713 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 15 Feb 2014 00:05:04 +0100 Subject: [PATCH 169/459] Updated to the great merge package --- README.md | 2 +- dev_console.go | 8 ++++---- ethereum.go | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 1cf3e1b04..4deaf4579 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Ethereum Ethereum Go developer client (c) Jeffrey Wilcke Ethereum is currently in its testing phase. The current state is "Proof -of Concept 1". For build instructions see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Edge). +of Concept 2". For build instructions see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Edge). Ethereum Go is split up in several sub packages Please refer to each individual package for more information. diff --git a/dev_console.go b/dev_console.go index d3635986b..ff2539b03 100644 --- a/dev_console.go +++ b/dev_console.go @@ -6,10 +6,10 @@ import ( "errors" "fmt" "github.com/ethereum/eth-go" - "github.com/ethereum/ethchain-go" - "github.com/ethereum/ethdb-go" - "github.com/ethereum/ethutil-go" - "github.com/ethereum/ethwire-go" + "github.com/ethereum/eth-go/ethchain" + "github.com/ethereum/eth-go/ethdb" + "github.com/ethereum/eth-go/ethutil" + "github.com/ethereum/eth-go/ethwire" _ "math/big" "os" "strings" diff --git a/ethereum.go b/ethereum.go index 51a2783ad..9907de740 100644 --- a/ethereum.go +++ b/ethereum.go @@ -3,8 +3,8 @@ package main import ( "fmt" "github.com/ethereum/eth-go" - "github.com/ethereum/ethchain-go" - "github.com/ethereum/ethutil-go" + "github.com/ethereum/eth-go/ethchain" + "github.com/ethereum/eth-go/ethutil" "github.com/obscuren/secp256k1-go" "log" "os" From 3a03d091eb337ac2d5fdec50b49bf9ac5cda86f5 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 15 Feb 2014 01:34:35 +0100 Subject: [PATCH 170/459] Removed RlpValue in favour of Value --- dev_console.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dev_console.go b/dev_console.go index ff2539b03..f2283e341 100644 --- a/dev_console.go +++ b/dev_console.go @@ -79,9 +79,9 @@ func (i *Console) ValidateInput(action string, argumentLength int) error { } func (i *Console) PrintRoot() { - root := ethutil.Conv(i.trie.Root) - if len(root.AsBytes()) != 0 { - fmt.Println(hex.EncodeToString(root.AsBytes())) + root := ethutil.NewValue(i.trie.Root) + if len(root.Bytes()) != 0 { + fmt.Println(hex.EncodeToString(root.Bytes())) } else { fmt.Println(i.trie.Root) } @@ -127,7 +127,7 @@ func (i *Console) ParseInput(input string) bool { ethutil.BigPow(2, 36), // diff ethutil.Big(tokens[2]))) // nonce case "decode": - value := ethutil.NewRlpValueFromBytes([]byte(tokens[1])) + value := ethutil.NewValueFromBytes([]byte(tokens[1])) fmt.Println(value) case "getaddr": encoded, _ := hex.DecodeString(tokens[1]) @@ -162,7 +162,7 @@ func (i *Console) ParseInput(input string) bool { addr, _ := hex.DecodeString(tokens[1]) data, _ := ethutil.Config.Db.Get(addr) if len(data) != 0 { - decoder := ethutil.NewRlpValueFromBytes(data) + decoder := ethutil.NewValueFromBytes(data) fmt.Println(decoder) } else { fmt.Println("gettx: tx not found") From 3fd5715872152fdd07c724dbbd8b1e06b062826b Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 15 Feb 2014 11:49:29 +0100 Subject: [PATCH 171/459] Added git flow explanation --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4deaf4579..4fa8d3c5a 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,12 @@ Contribution If you'd like to contribute to Ethereum Go please fork, fix, commit and send a pull request. Commits who do not comply with the coding standards -are ignored. +are ignored. If you send pull requests make absolute sure that you +commit on the `develop` branch and that you do not merge to master. +Commits that are directly based on master are simply ignored. + +To make life easier try [git flow](http://nvie.com/posts/a-successful-git-branching-model/) it sets +this all up and streamlines your work flow. Coding standards ================ From 1ba7ffe9f8eb468c11c20c933a85022a3b2dabe1 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 15 Feb 2014 12:10:13 +0100 Subject: [PATCH 172/459] Added text for keys --- ethereum.go | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/ethereum.go b/ethereum.go index 9907de740..372d434af 100644 --- a/ethereum.go +++ b/ethereum.go @@ -32,12 +32,22 @@ func RegisterInterupts(s *eth.Ethereum) { func CreateKeyPair(force bool) { data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) if len(data) == 0 || force { - log.Println("Generating new address and keypair") - pub, prv := secp256k1.GenerateKeyPair() addr := ethutil.Sha3Bin(pub[1:])[12:] - log.Printf("Your new address is %x\n", addr) + fmt.Printf(` +Generating new address and keypair. +Please keep your keys somewhere save. +Currently Ethereum(G) does not support +exporting keys. + +++++++++++++++++ KeyRing +++++++++++++++++++ +addr: %x +prvk: %x +pubk: %x +++++++++++++++++++++++++++++++++++++++++++++ + +`, addr, prv, pub) keyRing := ethutil.NewValue([]interface{}{prv, addr, pub[1:]}) ethutil.Config.Db.Put([]byte("KeyRing"), keyRing.Encode()) From 6db8b5d06a41ef573ec43394a11fd0e668372860 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 15 Feb 2014 13:27:23 +0100 Subject: [PATCH 173/459] Added link to dev package --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 4fa8d3c5a..d0a08f7b8 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,9 @@ contains the LevelDB interface and memory DB interface. This executable is the front-end (currently nothing but a dev console) for the Ethereum Go implementation. +If you'd like to start developing your own tools please check out the +[development](https://github.com/ethereum/eth-go) package. + Build ======= From 8c8554f5584dcc0efb4526c1d5f4d50bf2ed3b01 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 18 Feb 2014 01:34:33 +0100 Subject: [PATCH 174/459] Added license name and updated block output from the dev console --- LICENSE | 2 +- dev_console.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/LICENSE b/LICENSE index 803f2ef4e..b77f7909a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2013 Geff Obscura +Copyright (c) 2013 Jeffrey Wilcke Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/dev_console.go b/dev_console.go index f2283e341..6670d2a44 100644 --- a/dev_console.go +++ b/dev_console.go @@ -136,7 +136,8 @@ func (i *Console) ParseInput(input string) bool { case "block": encoded, _ := hex.DecodeString(tokens[1]) block := i.ethereum.BlockManager.BlockChain().GetBlock(encoded) - fmt.Println(block) + info := block.BlockInfo() + fmt.Printf("++++++++++ #%d ++++++++++\n%v\n", info.Number, block) case "say": i.ethereum.Broadcast(ethwire.MsgTalkTy, []interface{}{tokens[1]}) case "addp": From ab7dc924042b4cdb36ec7f2b26ab14c40d34ec9d Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 18 Feb 2014 12:09:26 +0100 Subject: [PATCH 175/459] Added import/exporting of private keys --- config.go | 4 ++++ ethereum.go | 51 ++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/config.go b/config.go index d13bb863b..573f5ded2 100644 --- a/config.go +++ b/config.go @@ -13,6 +13,8 @@ var AddPeer string var MaxPeer int var GenAddr bool var UseSeed bool +var ImportKey string +var ExportKey bool func Init() { flag.BoolVar(&StartConsole, "c", false, "debug and testing console") @@ -21,7 +23,9 @@ func Init() { flag.BoolVar(&UseUPnP, "upnp", false, "enable UPnP support") flag.BoolVar(&UseSeed, "seed", true, "seed peers") flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key") + flag.BoolVar(&ExportKey, "export", false, "export private key") flag.StringVar(&OutboundPort, "p", "30303", "listening port") + flag.StringVar(&ImportKey, "import", "", "imports the given private key (hex)") flag.IntVar(&MaxPeer, "x", 5, "maximum desired peers") flag.Parse() diff --git a/ethereum.go b/ethereum.go index 372d434af..36700a6d4 100644 --- a/ethereum.go +++ b/ethereum.go @@ -38,8 +38,6 @@ func CreateKeyPair(force bool) { fmt.Printf(` Generating new address and keypair. Please keep your keys somewhere save. -Currently Ethereum(G) does not support -exporting keys. ++++++++++++++++ KeyRing +++++++++++++++++++ addr: %x @@ -54,6 +52,29 @@ pubk: %x } } +func ImportPrivateKey(prvKey string) { + key := ethutil.FromHex(prvKey) + msg := []byte("tmp") + // Couldn't think of a better way to get the pub key + sig, _ := secp256k1.Sign(msg, key) + pub, _ := secp256k1.RecoverPubkey(msg, sig) + addr := ethutil.Sha3Bin(pub[1:])[12:] + + fmt.Printf(` +Importing private key + +++++++++++++++++ KeyRing +++++++++++++++++++ +addr: %x +prvk: %x +pubk: %x +++++++++++++++++++++++++++++++++++++++++++++ + +`, addr, key, pub) + + keyRing := ethutil.NewValue([]interface{}{key, addr, pub[1:]}) + ethutil.Config.Db.Put([]byte("KeyRing"), keyRing.Encode()) +} + func main() { runtime.GOMAXPROCS(runtime.NumCPU()) Init() @@ -87,7 +108,31 @@ func main() { } os.Exit(0) } else { - CreateKeyPair(false) + if len(ImportKey) > 0 { + fmt.Println("This action overwrites your old private key. Are you sure? (y/n)") + var r string + fmt.Scanln(&r) + for ; ; fmt.Scanln(&r) { + if r == "n" || r == "y" { + break + } else { + fmt.Printf("Yes or no?", r) + } + } + + if r == "y" { + ImportPrivateKey(ImportKey) + } + } else { + CreateKeyPair(false) + } + } + + if ExportKey { + data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) + keyRing := ethutil.NewValueFromBytes(data) + fmt.Printf("%x\n", keyRing.Get(0).Bytes()) + os.Exit(0) } if ShowGenesis { From 6736c03711b3ef35285392c12a79bbf6e4cdf914 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 18 Feb 2014 12:09:36 +0100 Subject: [PATCH 176/459] Added editor for contracts --- dev_console.go | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/dev_console.go b/dev_console.go index 6670d2a44..2e6b385df 100644 --- a/dev_console.go +++ b/dev_console.go @@ -2,6 +2,7 @@ package main import ( "bufio" + "bytes" "encoding/hex" "errors" "fmt" @@ -78,6 +79,32 @@ func (i *Console) ValidateInput(action string, argumentLength int) error { } } +func (i *Console) Editor() []string { + var buff bytes.Buffer + for { + reader := bufio.NewReader(os.Stdin) + str, _, err := reader.ReadLine() + if len(str) > 0 { + buff.Write(str) + buff.WriteString("\n") + } + + if err != nil && err.Error() == "EOF" { + break + } + } + + scanner := bufio.NewScanner(strings.NewReader(buff.String())) + scanner.Split(bufio.ScanLines) + + var lines []string + for scanner.Scan() { + lines = append(lines, scanner.Text()) + } + + return lines +} + func (i *Console) PrintRoot() { root := ethutil.NewValue(i.trie.Root) if len(root.Bytes()) != 0 { @@ -169,10 +196,17 @@ func (i *Console) ParseInput(input string) bool { fmt.Println("gettx: tx not found") } case "contract": - contract := ethchain.NewTransaction([]byte{}, ethutil.Big(tokens[1]), []string{"PUSH", "1234"}) - fmt.Printf("%x\n", contract.Hash()) + fmt.Println("Contract editor (Ctrl-D = done)") + code := i.Editor() + + contract := ethchain.NewTransaction([]byte{}, ethutil.Big(tokens[1]), code) + data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) + keyRing := ethutil.NewValueFromBytes(data) + contract.Sign(keyRing.Get(0).Bytes()) i.ethereum.TxPool.QueueTransaction(contract) + + fmt.Printf("%x\n", contract.Hash()) case "exit", "quit", "q": return false case "help": From d7ecc92c4134e3987b2b370bb53b0cd560fc0f7b Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 21 Feb 2014 00:47:07 +0100 Subject: [PATCH 177/459] Fixed broken links. Fixes #18 --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d0a08f7b8..e0d19b712 100644 --- a/README.md +++ b/README.md @@ -11,10 +11,10 @@ of Concept 2". For build instructions see the [Wiki](https://github.com/ethereum Ethereum Go is split up in several sub packages Please refer to each individual package for more information. 1. [eth](https://github.com/ethereum/eth-go) - 2. [ethchain](https://github.com/ethereum/ethchain-go) - 3. [ethwire](https://github.com/ethereum/ethwire-go) - 4. [ethdb](https://github.com/ethereum/ethdb-go) - 5. [ethutil](https://github.com/ethereum/ethutil-go) + 2. [ethchain](https://github.com/ethereum/eth-go/ethchain) + 3. [ethwire](https://github.com/ethereum/eth-go/ethwire) + 4. [ethdb](https://github.com/ethereum/eth-go/ethdb) + 5. [ethutil](https://github.com/ethereum/eth-go/ethutil) The [eth](https://github.com/ethereum/eth-go) is the top-level package of the Ethereum protocol. It functions as the Ethereum bootstrapping and From 05c353eca0c4e01457412dd643529200816ab159 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 21 Feb 2014 12:37:40 +0100 Subject: [PATCH 178/459] Added a basic UI --- config.go | 2 ++ ethereum.go | 76 ++++++++++++++++++++++++++++-------------------- ui/gui.go | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++ wallet.qml | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 211 insertions(+), 31 deletions(-) create mode 100644 ui/gui.go create mode 100644 wallet.qml diff --git a/config.go b/config.go index 573f5ded2..c25c8f2a3 100644 --- a/config.go +++ b/config.go @@ -15,11 +15,13 @@ var GenAddr bool var UseSeed bool var ImportKey string var ExportKey bool +var UseGui bool func Init() { flag.BoolVar(&StartConsole, "c", false, "debug and testing console") flag.BoolVar(&StartMining, "m", false, "start dagger mining") flag.BoolVar(&ShowGenesis, "g", false, "prints genesis header and exits") + flag.BoolVar(&UseGui, "gui", false, "use the gui") flag.BoolVar(&UseUPnP, "upnp", false, "enable UPnP support") flag.BoolVar(&UseSeed, "seed", true, "seed peers") flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key") diff --git a/ethereum.go b/ethereum.go index 36700a6d4..5eda09a44 100644 --- a/ethereum.go +++ b/ethereum.go @@ -5,6 +5,8 @@ import ( "github.com/ethereum/eth-go" "github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethutil" + "github.com/ethereum/go-ethereum/ui" + "github.com/niemeyer/qml" "github.com/obscuren/secp256k1-go" "log" "os" @@ -76,9 +78,16 @@ pubk: %x } func main() { - runtime.GOMAXPROCS(runtime.NumCPU()) Init() + // Qt has to be initialized in the main thread or it will throw errors + // It has to be called BEFORE setting the maximum procs. + if UseGui { + qml.Init(nil) + } + + runtime.GOMAXPROCS(runtime.NumCPU()) + ethchain.InitFees() ethutil.ReadConfig(".ethereum") ethutil.Config.Seed = UseSeed @@ -156,41 +165,46 @@ func main() { go console.Start() } - RegisterInterupts(ethereum) + if UseGui { + gui := ethui.New(ethereum) + gui.Start() + //ethereum.Stop() + } else { + RegisterInterupts(ethereum) + ethereum.Start() - ethereum.Start() + if StartMining { + log.Printf("Miner started\n") - if StartMining { - log.Printf("Miner started\n") + // Fake block mining. It broadcasts a new block every 5 seconds + go func() { + pow := ðchain.EasyPow{} + data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) + keyRing := ethutil.NewValueFromBytes(data) + addr := keyRing.Get(1).Bytes() - // Fake block mining. It broadcasts a new block every 5 seconds - go func() { - pow := ðchain.EasyPow{} - data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) - keyRing := ethutil.NewValueFromBytes(data) - addr := keyRing.Get(1).Bytes() + for { + txs := ethereum.TxPool.Flush() + // Create a new block which we're going to mine + block := ethereum.BlockManager.BlockChain().NewBlock(addr, txs) + // Apply all transactions to the block + ethereum.BlockManager.ApplyTransactions(block, block.Transactions()) - for { - txs := ethereum.TxPool.Flush() - // Create a new block which we're going to mine - block := ethereum.BlockManager.BlockChain().NewBlock(addr, txs) - // Apply all transactions to the block - ethereum.BlockManager.ApplyTransactions(block, block.Transactions()) + ethereum.BlockManager.AccumelateRewards(block, block) - ethereum.BlockManager.AccumelateRewards(block, block) - - // Search the nonce - block.Nonce = pow.Search(block) - err := ethereum.BlockManager.ProcessBlock(block) - if err != nil { - log.Println(err) - } else { - log.Println("\n+++++++ MINED BLK +++++++\n", ethereum.BlockManager.BlockChain().CurrentBlock) + // Search the nonce + block.Nonce = pow.Search(block) + err := ethereum.BlockManager.ProcessBlock(block) + if err != nil { + log.Println(err) + } else { + log.Println("\n+++++++ MINED BLK +++++++\n", ethereum.BlockManager.BlockChain().CurrentBlock) + } } - } - }() - } + }() + } - // Wait for shutdown - ethereum.WaitForShutdown() + // Wait for shutdown + ethereum.WaitForShutdown() + } } diff --git a/ui/gui.go b/ui/gui.go new file mode 100644 index 000000000..b2a8dad73 --- /dev/null +++ b/ui/gui.go @@ -0,0 +1,83 @@ +package ethui + +import ( + "bufio" + "encoding/hex" + "fmt" + "github.com/ethereum/eth-go" + "github.com/ethereum/eth-go/ethchain" + "github.com/ethereum/eth-go/ethutil" + "github.com/niemeyer/qml" + "strings" +) + +type Gui struct { + win *qml.Window + engine *qml.Engine + component *qml.Common + eth *eth.Ethereum +} + +func New(ethereum *eth.Ethereum) *Gui { + return &Gui{eth: ethereum} +} + +type Block struct { + Number int + Hash string +} + +func NewBlockFromBlock(block *ethchain.Block) *Block { + info := block.BlockInfo() + hash := hex.EncodeToString(block.Hash()) + + return &Block{Number: int(info.Number), Hash: hash} +} + +func (ui *Gui) Start() { + qml.RegisterTypes("GoExtensions", 1, 0, []qml.TypeSpec{{ + Init: func(p *Block, obj qml.Object) { p.Number = 0; p.Hash = "" }, + }}) + + ethutil.Config.Log.Infoln("[GUI] Starting GUI") + ui.engine = qml.NewEngine() + component, err := ui.engine.LoadFile("wallet.qml") + if err != nil { + panic(err) + } + + ui.win = component.CreateWindow(nil) + root := ui.win.Root() + + context := ui.engine.Context() + context.SetVar("tester", &Tester{root: root}) + + ui.eth.BlockManager.SecondaryBlockProcessor = ui + ui.eth.Start() + + ui.win.Show() + ui.win.Wait() +} + +func (ui *Gui) ProcessBlock(block *ethchain.Block) { + ui.win.Root().Call("addBlock", NewBlockFromBlock(block)) +} + +type Tester struct { + root qml.Object +} + +func (t *Tester) Compile(area qml.Object) { + fmt.Println(area) + ethutil.Config.Log.Infoln("[TESTER] Compiling") + + code := area.String("text") + + scanner := bufio.NewScanner(strings.NewReader(code)) + scanner.Split(bufio.ScanLines) + + var lines []string + for scanner.Scan() { + lines = append(lines, scanner.Text()) + } +} diff --git a/wallet.qml b/wallet.qml new file mode 100644 index 000000000..2bf4e4576 --- /dev/null +++ b/wallet.qml @@ -0,0 +1,81 @@ +import QtQuick 2.0 +import QtQuick.Controls 1.0; +import QtQuick.Layouts 1.0; +import GoExtensions 1.0 + +ApplicationWindow { + id: root + + width: 800 + height: 600 + minimumHeight: 300 + + title: "Ethereal" + + toolBar: ToolBar { + id: mainToolbar + + RowLayout { + width: parent.width + Button { + text: "Send" + onClicked: tester.compile(codeView) + } + + TextField { + width: 200 + placeholderText: "Amount" + } + + TextField { + width: 300 + placeholderText: "Receiver Address (or empty for contract)" + Layout.fillWidth: true + } + + } + } + + SplitView { + id: splitView + height: 200 + anchors.top: parent.top + anchors.right: parent.right + anchors.left: parent.left + + TextArea { + id: codeView + width: parent.width /2 + } + + TextArea { + readOnly: true + } + } + + property var blockModel: ListModel { + id: blockModel + } + + TableView { + width: parent.width + height: 100 + anchors.bottom: parent.bottom + anchors.top: splitView.bottom + TableViewColumn{ role: "number" ; title: "#" ; width: 100 } + TableViewColumn{ role: "hash" ; title: "Hash" ; width: 560 } + + model: blockModel + } + + + statusBar: StatusBar { + RowLayout { + Label { text: "0.0.1" } + } + } + + function addBlock(block) { + blockModel.append({number: block.number, hash: block.hash}) + } +} From aaac0c9998ee78d796c1dbab118f721f886ce426 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 21 Feb 2014 13:06:17 +0100 Subject: [PATCH 179/459] Initial block chain fetching of existing blocks --- ui/gui.go | 12 +++++++++++- wallet.qml | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ui/gui.go b/ui/gui.go index b2a8dad73..aae1320fc 100644 --- a/ui/gui.go +++ b/ui/gui.go @@ -53,12 +53,22 @@ func (ui *Gui) Start() { context.SetVar("tester", &Tester{root: root}) ui.eth.BlockManager.SecondaryBlockProcessor = ui - ui.eth.Start() + + go ui.setInitialBlockChain() ui.win.Show() ui.win.Wait() } +func (ui *Gui) setInitialBlockChain() { + chain := ui.eth.BlockManager.BlockChain().GetChain(ui.eth.BlockManager.BlockChain().CurrentBlock.Hash(), 10) + for _, block := range chain { + ui.ProcessBlock(block) + } + + ui.eth.Start() +} + func (ui *Gui) ProcessBlock(block *ethchain.Block) { ui.win.Root().Call("addBlock", NewBlockFromBlock(block)) } diff --git a/wallet.qml b/wallet.qml index 2bf4e4576..cbce7ebcc 100644 --- a/wallet.qml +++ b/wallet.qml @@ -76,6 +76,6 @@ ApplicationWindow { } function addBlock(block) { - blockModel.append({number: block.number, hash: block.hash}) + blockModel.insert(0, {number: block.number, hash: block.hash}) } } From 95a48cea18eccd4ea2cb298027dbd01bd21f43e8 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 21 Feb 2014 13:23:35 +0100 Subject: [PATCH 180/459] Peer amount update --- network.png | Bin 0 -> 2900 bytes ui/gui.go | 9 +++++++++ wallet.qml | 19 +++++++++++++++++++ 3 files changed, 28 insertions(+) create mode 100644 network.png diff --git a/network.png b/network.png new file mode 100644 index 0000000000000000000000000000000000000000..0a9ffe2ec6023846413a040c75b44710249d355b GIT binary patch literal 2900 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 Date: Fri, 21 Feb 2014 17:29:59 +0100 Subject: [PATCH 181/459] WIP library, sample app --- test_app.qml | 35 ++++++++++++++++++++++++++++++ ui/gui.go | 28 +++++++++++++++++++++--- ui/library.go | 42 ++++++++++++++++++++++++++++++++++++ wallet.qml | 59 +++++++++++++++++++++++++++++++++------------------ 4 files changed, 140 insertions(+), 24 deletions(-) create mode 100644 test_app.qml create mode 100644 ui/library.go diff --git a/test_app.qml b/test_app.qml new file mode 100644 index 000000000..c7593bf12 --- /dev/null +++ b/test_app.qml @@ -0,0 +1,35 @@ +import QtQuick 2.0 +import QtQuick.Controls 1.0; +import QtQuick.Layouts 1.0; +import GoExtensions 1.0 + +ApplicationWindow { + minimumWidth: 500 + maximumWidth: 500 + maximumHeight: 100 + minimumHeight: 100 + + title: "Ethereum Dice" + + TextField { + id: textField + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + placeholderText: "Amount" + } + Label { + id: txHash + anchors.bottom: textField.top + anchors.bottomMargin: 5 + anchors.horizontalCenter: parent.horizontalCenter + } + Button { + anchors.top: textField.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.topMargin: 5 + text: "Place bet" + onClicked: { + txHash.text = eth.createTx("e6716f9544a56c530d868e4bfbacb172315bdead", parseInt(textField.text)) + } + } +} diff --git a/ui/gui.go b/ui/gui.go index e223fe262..8f063843c 100644 --- a/ui/gui.go +++ b/ui/gui.go @@ -17,10 +17,15 @@ type Gui struct { engine *qml.Engine component *qml.Common eth *eth.Ethereum + + // The Ethereum library + lib *EthLib } func New(ethereum *eth.Ethereum) *Gui { - return &Gui{eth: ethereum} + lib := &EthLib{blockManager: ethereum.BlockManager, blockChain: ethereum.BlockManager.BlockChain(), txPool: ethereum.TxPool} + + return &Gui{eth: ethereum, lib: lib} } type Block struct { @@ -48,10 +53,10 @@ func (ui *Gui) Start() { } ui.win = component.CreateWindow(nil) - root := ui.win.Root() context := ui.engine.Context() - context.SetVar("tester", &Tester{root: root}) + context.SetVar("eth", ui.lib) + context.SetVar("ui", &UiLib{engine: ui.engine}) ui.eth.BlockManager.SecondaryBlockProcessor = ui @@ -82,6 +87,23 @@ func (ui *Gui) updatePeers() { } } +type UiLib struct { + engine *qml.Engine +} + +func (ui *UiLib) Open(path string) { + component, err := ui.engine.LoadFile(path[7:]) + if err != nil { + ethutil.Config.Log.Debugln(err) + } + win := component.CreateWindow(nil) + + go func() { + win.Show() + win.Wait() + }() +} + type Tester struct { root qml.Object } diff --git a/ui/library.go b/ui/library.go new file mode 100644 index 000000000..36952e198 --- /dev/null +++ b/ui/library.go @@ -0,0 +1,42 @@ +package ethui + +import ( + "encoding/hex" + "fmt" + "github.com/ethereum/eth-go/ethchain" + "github.com/ethereum/eth-go/ethutil" + "math/big" +) + +type EthLib struct { + blockManager *ethchain.BlockManager + blockChain *ethchain.BlockChain + txPool *ethchain.TxPool +} + +func (lib *EthLib) CreateTx(receiver string, amount uint64) string { + hash, err := hex.DecodeString(receiver) + if err != nil { + return err.Error() + } + + tx := ethchain.NewTransaction(hash, big.NewInt(int64(amount)), []string{""}) + data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) + keyRing := ethutil.NewValueFromBytes(data) + tx.Sign(keyRing.Get(0).Bytes()) + + lib.txPool.QueueTransaction(tx) + + return ethutil.Hex(tx.Hash()) +} + +func (lib *EthLib) GetBlock(hexHash string) *Block { + hash, err := hex.DecodeString(hexHash) + if err != nil { + return nil + } + + block := lib.blockChain.GetBlock(hash) + fmt.Println(block) + return &Block{Number: int(block.BlockInfo().Number), Hash: ethutil.Hex(block.Hash())} +} diff --git a/wallet.qml b/wallet.qml index b19e7f32b..f9bd8ec76 100644 --- a/wallet.qml +++ b/wallet.qml @@ -1,6 +1,7 @@ import QtQuick 2.0 import QtQuick.Controls 1.0; import QtQuick.Layouts 1.0; +import QtQuick.Dialogs 1.0; import GoExtensions 1.0 ApplicationWindow { @@ -12,6 +13,7 @@ ApplicationWindow { title: "Ethereal" + toolBar: ToolBar { id: mainToolbar @@ -19,7 +21,7 @@ ApplicationWindow { width: parent.width Button { text: "Send" - onClicked: tester.compile(codeView) + onClicked: console.log("SEND") } TextField { @@ -66,35 +68,50 @@ ApplicationWindow { TableViewColumn{ role: "hash" ; title: "Hash" ; width: 560 } model: blockModel + + onDoubleClicked: { + console.log(eth.getBlock(blockModel.get(row).hash)) + } } + FileDialog { + id: openAppDialog + title: "Open QML Application" + onAccepted: { + ui.open(openAppDialog.fileUrl.toString()) + } + } statusBar: StatusBar { - RowLayout { - anchors.fill: parent - Label { text: "0.0.1" } - Label { - anchors.right: peerImage.left - anchors.rightMargin: 5 - id: peerLabel - font.pixelSize: 8 - text: "0 / 0" - } - - Image { - id: peerImage - anchors.right: parent.right - width: 10; height: 10 - source: "network.png" - } + RowLayout { + anchors.fill: parent + Button { + onClicked: openAppDialog.open() + text: "Import App" } + + Label { text: "0.0.1" } + Label { + anchors.right: peerImage.left + anchors.rightMargin: 5 + id: peerLabel + font.pixelSize: 8 + text: "0 / 0" + } + Image { + id: peerImage + anchors.right: parent.right + width: 10; height: 10 + source: "network.png" + } + } } function addBlock(block) { - blockModel.insert(0, {number: block.number, hash: block.hash}) + blockModel.insert(0, {number: block.number, hash: block.hash}) } function setPeers(text) { - peerLabel.text = text - } + peerLabel.text = text + } } From 2b967558cebcef9d3ef9719cbb28a5e596982a5d Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 22 Feb 2014 01:52:47 +0100 Subject: [PATCH 182/459] Working out UI --- config.go | 2 +- ui/gui.go | 21 +++++++++++++++++++-- wallet.qml | 46 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/config.go b/config.go index c25c8f2a3..79d40d706 100644 --- a/config.go +++ b/config.go @@ -21,7 +21,7 @@ func Init() { flag.BoolVar(&StartConsole, "c", false, "debug and testing console") flag.BoolVar(&StartMining, "m", false, "start dagger mining") flag.BoolVar(&ShowGenesis, "g", false, "prints genesis header and exits") - flag.BoolVar(&UseGui, "gui", false, "use the gui") + flag.BoolVar(&UseGui, "gui", true, "use the gui") flag.BoolVar(&UseUPnP, "upnp", false, "enable UPnP support") flag.BoolVar(&UseSeed, "seed", true, "seed peers") flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key") diff --git a/ui/gui.go b/ui/gui.go index 8f063843c..fad7e9591 100644 --- a/ui/gui.go +++ b/ui/gui.go @@ -56,10 +56,12 @@ func (ui *Gui) Start() { context := ui.engine.Context() context.SetVar("eth", ui.lib) - context.SetVar("ui", &UiLib{engine: ui.engine}) + context.SetVar("ui", &UiLib{engine: ui.engine, eth: ui.eth}) ui.eth.BlockManager.SecondaryBlockProcessor = ui + ethutil.Config.Log.AddLogSystem(ui) + go ui.setInitialBlockChain() go ui.updatePeers() @@ -73,13 +75,23 @@ func (ui *Gui) setInitialBlockChain() { ui.ProcessBlock(block) } - ui.eth.Start() } func (ui *Gui) ProcessBlock(block *ethchain.Block) { ui.win.Root().Call("addBlock", NewBlockFromBlock(block)) } +func (ui *Gui) Println(v ...interface{}) { + str := fmt.Sprintln(v...) + // remove last \n + ui.win.Root().Call("addLog", str[:len(str)-1]) +} + +func (ui *Gui) Printf(format string, v ...interface{}) { + str := strings.TrimRight(fmt.Sprintf(format, v...), "\n") + ui.win.Root().Call("addLog", str) +} + func (ui *Gui) updatePeers() { for { ui.win.Root().Call("setPeers", fmt.Sprintf("%d / %d", ui.eth.Peers().Len(), ui.eth.MaxPeers)) @@ -89,6 +101,7 @@ func (ui *Gui) updatePeers() { type UiLib struct { engine *qml.Engine + eth *eth.Ethereum } func (ui *UiLib) Open(path string) { @@ -104,6 +117,10 @@ func (ui *UiLib) Open(path string) { }() } +func (ui *UiLib) Connect() { + ui.eth.Start() +} + type Tester struct { root qml.Object } diff --git a/wallet.qml b/wallet.qml index f9bd8ec76..e6cb32b18 100644 --- a/wallet.qml +++ b/wallet.qml @@ -2,6 +2,7 @@ import QtQuick 2.0 import QtQuick.Controls 1.0; import QtQuick.Layouts 1.0; import QtQuick.Dialogs 1.0; +import QtQuick.Window 2.1; import GoExtensions 1.0 ApplicationWindow { @@ -60,20 +61,36 @@ ApplicationWindow { } TableView { + id: blockTable width: parent.width - height: 100 - anchors.bottom: parent.bottom anchors.top: splitView.bottom + anchors.bottom: logView.top TableViewColumn{ role: "number" ; title: "#" ; width: 100 } TableViewColumn{ role: "hash" ; title: "Hash" ; width: 560 } model: blockModel onDoubleClicked: { - console.log(eth.getBlock(blockModel.get(row).hash)) + popup.visible = true + popup.block = eth.getBlock(blockModel.get(row).hash) + popup.hashLabel.text = popup.block.hash } } + property var logModel: ListModel { + id: logModel + } + + TableView { + id: logView + width: parent.width + height: 150 + anchors.bottom: parent.bottom + TableViewColumn{ role: "description" ; title: "log" } + + model: logModel + } + FileDialog { id: openAppDialog title: "Open QML Application" @@ -86,6 +103,13 @@ ApplicationWindow { RowLayout { anchors.fill: parent Button { + id: connectButton + onClicked: ui.connect() + text: "Connect" + } + Button { + anchors.left: connectButton.right + anchors.leftMargin: 5 onClicked: openAppDialog.open() text: "Import App" } @@ -107,10 +131,26 @@ ApplicationWindow { } } + Window { + id: popup + visible: false + property var block + Label { + id: hashLabel + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + } + } + function addBlock(block) { blockModel.insert(0, {number: block.number, hash: block.hash}) } + function addLog(str) { + console.log(str) + logModel.insert(0, {description: str}) + } + function setPeers(text) { peerLabel.text = text } From aa33a4b2fb9dc07468498decceb6fdb56d38f54d Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 22 Feb 2014 23:19:38 +0100 Subject: [PATCH 183/459] Added some ui elements to make it easier to connect to nodes --- config.go | 2 ++ ethereum.go | 3 +- test_app.qml | 4 +-- ui/gui.go | 85 ++++++++++++++++++++++++++++++++++++--------------- ui/library.go | 10 +++--- wallet.qml | 70 +++++++++++++++++++++++++++++++++++++++--- 6 files changed, 138 insertions(+), 36 deletions(-) diff --git a/config.go b/config.go index 79d40d706..bafc3e300 100644 --- a/config.go +++ b/config.go @@ -16,6 +16,7 @@ var UseSeed bool var ImportKey string var ExportKey bool var UseGui bool +var DataDir string func Init() { flag.BoolVar(&StartConsole, "c", false, "debug and testing console") @@ -27,6 +28,7 @@ func Init() { flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key") flag.BoolVar(&ExportKey, "export", false, "export private key") flag.StringVar(&OutboundPort, "p", "30303", "listening port") + flag.StringVar(&DataDir, "dir", ".ethereum", "ethereum data directory") flag.StringVar(&ImportKey, "import", "", "imports the given private key (hex)") flag.IntVar(&MaxPeer, "x", 5, "maximum desired peers") diff --git a/ethereum.go b/ethereum.go index 5eda09a44..384b22748 100644 --- a/ethereum.go +++ b/ethereum.go @@ -89,11 +89,12 @@ func main() { runtime.GOMAXPROCS(runtime.NumCPU()) ethchain.InitFees() - ethutil.ReadConfig(".ethereum") + ethutil.ReadConfig(DataDir) ethutil.Config.Seed = UseSeed // Instantiated a eth stack ethereum, err := eth.New(eth.CapDefault, UseUPnP) + ethereum.Port = OutboundPort if err != nil { log.Println("eth start err:", err) return diff --git a/test_app.qml b/test_app.qml index c7593bf12..aace4e881 100644 --- a/test_app.qml +++ b/test_app.qml @@ -1,7 +1,7 @@ import QtQuick 2.0 import QtQuick.Controls 1.0; import QtQuick.Layouts 1.0; -import GoExtensions 1.0 +import Ethereum 1.0 ApplicationWindow { minimumWidth: 500 @@ -29,7 +29,7 @@ ApplicationWindow { anchors.topMargin: 5 text: "Place bet" onClicked: { - txHash.text = eth.createTx("e6716f9544a56c530d868e4bfbacb172315bdead", parseInt(textField.text)) + txHash.text = eth.createTx("e6716f9544a56c530d868e4bfbacb172315bdead", textField.text) } } } diff --git a/ui/gui.go b/ui/gui.go index fad7e9591..51fd6d9a8 100644 --- a/ui/gui.go +++ b/ui/gui.go @@ -12,27 +12,13 @@ import ( "time" ) -type Gui struct { - win *qml.Window - engine *qml.Engine - component *qml.Common - eth *eth.Ethereum - - // The Ethereum library - lib *EthLib -} - -func New(ethereum *eth.Ethereum) *Gui { - lib := &EthLib{blockManager: ethereum.BlockManager, blockChain: ethereum.BlockManager.BlockChain(), txPool: ethereum.TxPool} - - return &Gui{eth: ethereum, lib: lib} -} - +// Block interface exposed to QML type Block struct { Number int Hash string } +// Creates a new QML Block from a chain block func NewBlockFromBlock(block *ethchain.Block) *Block { info := block.BlockInfo() hash := hex.EncodeToString(block.Hash()) @@ -40,13 +26,42 @@ func NewBlockFromBlock(block *ethchain.Block) *Block { return &Block{Number: int(info.Number), Hash: hash} } +type Gui struct { + // The main application window + win *qml.Window + // QML Engine + engine *qml.Engine + component *qml.Common + // The ethereum interface + eth *eth.Ethereum + + // The public Ethereum library + lib *EthLib +} + +// Create GUI, but doesn't start it +func New(ethereum *eth.Ethereum) *Gui { + lib := &EthLib{blockManager: ethereum.BlockManager, blockChain: ethereum.BlockManager.BlockChain(), txPool: ethereum.TxPool} + + data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) + keyRing := ethutil.NewValueFromBytes(data) + addr := keyRing.Get(1).Bytes() + + ethereum.BlockManager.WatchAddr(addr) + + return &Gui{eth: ethereum, lib: lib} +} + func (ui *Gui) Start() { - qml.RegisterTypes("GoExtensions", 1, 0, []qml.TypeSpec{{ + // Register ethereum functions + qml.RegisterTypes("Ethereum", 1, 0, []qml.TypeSpec{{ Init: func(p *Block, obj qml.Object) { p.Number = 0; p.Hash = "" }, }}) ethutil.Config.Log.Infoln("[GUI] Starting GUI") + // Create a new QML engine ui.engine = qml.NewEngine() + // Load the main QML interface component, err := ui.engine.LoadFile("wallet.qml") if err != nil { panic(err) @@ -55,13 +70,18 @@ func (ui *Gui) Start() { ui.win = component.CreateWindow(nil) context := ui.engine.Context() + + // Expose the eth library and the ui library to QML context.SetVar("eth", ui.lib) context.SetVar("ui", &UiLib{engine: ui.engine, eth: ui.eth}) + // Register the ui as a block processor ui.eth.BlockManager.SecondaryBlockProcessor = ui + // Add the ui as a log system so we can log directly to the UGI ethutil.Config.Log.AddLogSystem(ui) + // Loads previous blocks go ui.setInitialBlockChain() go ui.updatePeers() @@ -70,6 +90,7 @@ func (ui *Gui) Start() { } func (ui *Gui) setInitialBlockChain() { + // Load previous 10 blocks chain := ui.eth.BlockManager.BlockChain().GetChain(ui.eth.BlockManager.BlockChain().CurrentBlock.Hash(), 10) for _, block := range chain { ui.ProcessBlock(block) @@ -81,17 +102,24 @@ func (ui *Gui) ProcessBlock(block *ethchain.Block) { ui.win.Root().Call("addBlock", NewBlockFromBlock(block)) } +// Logging functions that log directly to the GUI interface func (ui *Gui) Println(v ...interface{}) { - str := fmt.Sprintln(v...) - // remove last \n - ui.win.Root().Call("addLog", str[:len(str)-1]) + str := strings.TrimRight(fmt.Sprintln(v...), "\n") + lines := strings.Split(str, "\n") + for _, line := range lines { + ui.win.Root().Call("addLog", line) + } } func (ui *Gui) Printf(format string, v ...interface{}) { str := strings.TrimRight(fmt.Sprintf(format, v...), "\n") - ui.win.Root().Call("addLog", str) + lines := strings.Split(str, "\n") + for _, line := range lines { + ui.win.Root().Call("addLog", line) + } } +// Simple go routine function that updates the list of peers in the GUI func (ui *Gui) updatePeers() { for { ui.win.Root().Call("setPeers", fmt.Sprintf("%d / %d", ui.eth.Peers().Len(), ui.eth.MaxPeers)) @@ -99,11 +127,14 @@ func (ui *Gui) updatePeers() { } } +// UI Library that has some basic functionality exposed type UiLib struct { - engine *qml.Engine - eth *eth.Ethereum + engine *qml.Engine + eth *eth.Ethereum + connected bool } +// Opens a QML file (external application) func (ui *UiLib) Open(path string) { component, err := ui.engine.LoadFile(path[7:]) if err != nil { @@ -118,7 +149,13 @@ func (ui *UiLib) Open(path string) { } func (ui *UiLib) Connect() { - ui.eth.Start() + if !ui.connected { + ui.eth.Start() + } +} + +func (ui *UiLib) ConnectToPeer(addr string) { + ui.eth.ConnectToPeer(addr) } type Tester struct { diff --git a/ui/library.go b/ui/library.go index 36952e198..0dfb10ac7 100644 --- a/ui/library.go +++ b/ui/library.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethutil" - "math/big" ) type EthLib struct { @@ -14,15 +13,18 @@ type EthLib struct { txPool *ethchain.TxPool } -func (lib *EthLib) CreateTx(receiver string, amount uint64) string { +func (lib *EthLib) CreateTx(receiver, a string) string { hash, err := hex.DecodeString(receiver) if err != nil { return err.Error() } - - tx := ethchain.NewTransaction(hash, big.NewInt(int64(amount)), []string{""}) data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) keyRing := ethutil.NewValueFromBytes(data) + + amount := ethutil.Big(a) + tx := ethchain.NewTransaction(hash, amount, []string{""}) + tx.Nonce = lib.blockManager.GetAddrState(keyRing.Get(1).Bytes()).Nonce + tx.Sign(keyRing.Get(0).Bytes()) lib.txPool.QueueTransaction(tx) diff --git a/wallet.qml b/wallet.qml index e6cb32b18..b18614801 100644 --- a/wallet.qml +++ b/wallet.qml @@ -3,7 +3,7 @@ import QtQuick.Controls 1.0; import QtQuick.Layouts 1.0; import QtQuick.Dialogs 1.0; import QtQuick.Window 2.1; -import GoExtensions 1.0 +import Ethereum 1.0 ApplicationWindow { id: root @@ -22,15 +22,19 @@ ApplicationWindow { width: parent.width Button { text: "Send" - onClicked: console.log("SEND") + onClicked: { + console.log(eth.createTx(txReceiver.text, txAmount.text)) + } } TextField { + id: txAmount width: 200 placeholderText: "Amount" } TextField { + id: txReceiver width: 300 placeholderText: "Receiver Address (or empty for contract)" Layout.fillWidth: true @@ -47,15 +51,43 @@ ApplicationWindow { anchors.left: parent.left TextArea { - id: codeView - width: parent.width /2 + id: codeView + width: parent.width /2 } TextArea { - readOnly: true + readOnly: true } } + MenuBar { + Menu { + title: "File" + MenuItem { + text: "Import App" + shortcut: "Ctrl+o" + onTriggered: openAppDialog.open() + } + } + + Menu { + title: "Network" + MenuItem { + text: "Add Peer" + shortcut: "Ctrl+p" + onTriggered: { + addPeerWin.visible = true + } + } + + MenuItem { + text: "Start" + onTriggered: ui.connect() + } + } + } + + property var blockModel: ListModel { id: blockModel } @@ -142,6 +174,34 @@ ApplicationWindow { } } + Window { + id: addPeerWin + visible: false + minimumWidth: 230 + maximumWidth: 230 + maximumHeight: 50 + minimumHeight: 50 + + TextField { + id: addrField + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: 10 + placeholderText: "address:port" + } + Button { + anchors.left: addrField.right + anchors.verticalCenter: parent.verticalCenter + anchors.leftMargin: 5 + text: "Add" + onClicked: { + ui.connectToPeer(addrField.text) + addrPeerWin.visible = false + } + } + } + + function addBlock(block) { blockModel.insert(0, {number: block.number, hash: block.hash}) } From 0656f465b0c0690f237e42ac1e8f306dcda6c40b Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 23 Feb 2014 01:56:04 +0100 Subject: [PATCH 184/459] Added transactions window --- transactions.qml | 9 +++ ui/gui.go | 19 +++++ wallet.qml | 183 +++++++++++++++++++++++++++++++++++------------ 3 files changed, 166 insertions(+), 45 deletions(-) create mode 100644 transactions.qml diff --git a/transactions.qml b/transactions.qml new file mode 100644 index 000000000..e9a035a85 --- /dev/null +++ b/transactions.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 +import QtQuick.Controls 1.0; +import QtQuick.Layouts 1.0; + +Rectangle { + id: transactionView + visible: false + Text { text: "TX VIEW" } +} diff --git a/ui/gui.go b/ui/gui.go index 51fd6d9a8..f0e281de1 100644 --- a/ui/gui.go +++ b/ui/gui.go @@ -18,6 +18,17 @@ type Block struct { Hash string } +type Tx struct { + Value, Hash, Address string +} + +func NewTxFromTransaction(tx *ethchain.Transaction) *Tx { + hash := hex.EncodeToString(tx.Hash()) + sender := hex.EncodeToString(tx.Recipient) + + return &Tx{Hash: hash[:4], Value: tx.Value.String(), Address: sender} +} + // Creates a new QML Block from a chain block func NewBlockFromBlock(block *ethchain.Block) *Block { info := block.BlockInfo() @@ -56,6 +67,8 @@ func (ui *Gui) Start() { // Register ethereum functions qml.RegisterTypes("Ethereum", 1, 0, []qml.TypeSpec{{ Init: func(p *Block, obj qml.Object) { p.Number = 0; p.Hash = "" }, + }, { + Init: func(p *Tx, obj qml.Object) { p.Value = ""; p.Hash = ""; p.Address = "" }, }}) ethutil.Config.Log.Infoln("[GUI] Starting GUI") @@ -66,6 +79,7 @@ func (ui *Gui) Start() { if err != nil { panic(err) } + ui.engine.LoadFile("transactions.qml") ui.win = component.CreateWindow(nil) @@ -77,6 +91,7 @@ func (ui *Gui) Start() { // Register the ui as a block processor ui.eth.BlockManager.SecondaryBlockProcessor = ui + ui.eth.TxPool.SecondaryProcessor = ui // Add the ui as a log system so we can log directly to the UGI ethutil.Config.Log.AddLogSystem(ui) @@ -102,6 +117,10 @@ func (ui *Gui) ProcessBlock(block *ethchain.Block) { ui.win.Root().Call("addBlock", NewBlockFromBlock(block)) } +func (ui *Gui) ProcessTransaction(tx *ethchain.Transaction) { + ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) +} + // Logging functions that log directly to the GUI interface func (ui *Gui) Println(v ...interface{}) { str := strings.TrimRight(fmt.Sprintln(v...), "\n") diff --git a/wallet.qml b/wallet.qml index b18614801..6ee6ff110 100644 --- a/wallet.qml +++ b/wallet.qml @@ -3,18 +3,18 @@ import QtQuick.Controls 1.0; import QtQuick.Layouts 1.0; import QtQuick.Dialogs 1.0; import QtQuick.Window 2.1; +import QtQuick.Controls.Styles 1.1 import Ethereum 1.0 ApplicationWindow { id: root - width: 800 + width: 900 height: 600 minimumHeight: 300 title: "Ethereal" - toolBar: ToolBar { id: mainToolbar @@ -43,22 +43,6 @@ ApplicationWindow { } } - SplitView { - id: splitView - height: 200 - anchors.top: parent.top - anchors.right: parent.right - anchors.left: parent.left - - TextArea { - id: codeView - width: parent.width /2 - } - - TextArea { - readOnly: true - } - } MenuBar { Menu { @@ -85,42 +69,133 @@ ApplicationWindow { onTriggered: ui.connect() } } + + Menu { + title: "Help" + MenuItem { + text: "About" + onTriggered: { + aboutWin.visible = true + } + } + } + } property var blockModel: ListModel { id: blockModel } - - TableView { - id: blockTable - width: parent.width - anchors.top: splitView.bottom - anchors.bottom: logView.top - TableViewColumn{ role: "number" ; title: "#" ; width: 100 } - TableViewColumn{ role: "hash" ; title: "Hash" ; width: 560 } - - model: blockModel - - onDoubleClicked: { - popup.visible = true - popup.block = eth.getBlock(blockModel.get(row).hash) - popup.hashLabel.text = popup.block.hash + function setView(view) { + mainView.visible = false + transactionView.visible = false + view.visible = true } - } - property var logModel: ListModel { - id: logModel - } + SplitView { + anchors.fill: parent - TableView { - id: logView - width: parent.width - height: 150 - anchors.bottom: parent.bottom - TableViewColumn{ role: "description" ; title: "log" } - model: logModel + Rectangle { + id: menu + width: 200 + anchors.bottom: parent.bottom + anchors.top: parent.top + color: "#D9DDE7" + + GridLayout { + columns: 1 + Button { + text: "Main" + onClicked: { + setView(mainView) + } + } + Button { + text: "Transactions" + onClicked: { + setView(transactionView) + } + } + } + + } + + property var txModel: ListModel { + id: txModel + } + + Rectangle { + id: transactionView + visible: false + anchors.right: parent.right + anchors.left: menu.right + anchors.bottom: parent.bottom + anchors.top: parent.top + TableView { + id: txTableView + anchors.fill: parent + TableViewColumn{ role: "hash" ; title: "#" ; width: 150 } + TableViewColumn{ role: "value" ; title: "Value" ; width: 100 } + TableViewColumn{ role: "address" ; title: "Address" ; } + + model: txModel + } + } + + Rectangle { + id: mainView + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.top: parent.top + SplitView { + id: splitView + height: 200 + anchors.top: parent.top + anchors.right: parent.right + anchors.left: parent.left + + TextArea { + id: codeView + width: parent.width /2 + } + + TextArea { + readOnly: true + } + } + + TableView { + id: blockTable + width: parent.width + anchors.top: splitView.bottom + anchors.bottom: logView.top + TableViewColumn{ role: "number" ; title: "#" ; width: 100 } + TableViewColumn{ role: "hash" ; title: "Hash" ; width: 560 } + + model: blockModel + + onDoubleClicked: { + popup.visible = true + popup.block = eth.getBlock(blockModel.get(row).hash) + popup.hashLabel.text = popup.block.hash + } + } + + property var logModel: ListModel { + id: logModel + } + + TableView { + id: logView + width: parent.width + height: 150 + anchors.bottom: parent.bottom + TableViewColumn{ role: "description" ; title: "log" } + + model: logModel + } + } } FileDialog { @@ -146,7 +221,6 @@ ApplicationWindow { text: "Import App" } - Label { text: "0.0.1" } Label { anchors.right: peerImage.left anchors.rightMargin: 5 @@ -201,6 +275,25 @@ ApplicationWindow { } } + Window { + id: aboutWin + visible: false + title: "About" + minimumWidth: 300 + maximumWidth: 300 + maximumHeight: 200 + minimumHeight: 200 + + Text { + font.pointSize: 18 + text: "Eth Go" + } + + } + + function addTx(tx) { + txModel.insert(0, {hash: tx.hash, address: tx.address, value: tx.value}) + } function addBlock(block) { blockModel.insert(0, {number: block.number, hash: block.hash}) From fe9eb472887baec464cc50657affd85b13bcbeba Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 24 Feb 2014 13:51:16 +0100 Subject: [PATCH 185/459] Minor fixes that to reflect changes in library --- dev_console.go | 6 +++--- ethereum.go | 2 ++ ui/library.go | 28 +++++++++++++++++++++------- wallet.qml | 7 ++++--- 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/dev_console.go b/dev_console.go index 2e6b385df..696493cdd 100644 --- a/dev_console.go +++ b/dev_console.go @@ -197,16 +197,16 @@ func (i *Console) ParseInput(input string) bool { } case "contract": fmt.Println("Contract editor (Ctrl-D = done)") - code := i.Editor() + code := ethchain.Compile(i.Editor()) - contract := ethchain.NewTransaction([]byte{}, ethutil.Big(tokens[1]), code) + contract := ethchain.NewTransaction(ethchain.ContractAddr, ethutil.Big(tokens[1]), code) data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) keyRing := ethutil.NewValueFromBytes(data) contract.Sign(keyRing.Get(0).Bytes()) i.ethereum.TxPool.QueueTransaction(contract) - fmt.Printf("%x\n", contract.Hash()) + fmt.Printf("%x\n", contract.Hash()[12:]) case "exit", "quit", "q": return false case "help": diff --git a/ethereum.go b/ethereum.go index 384b22748..0b941dce3 100644 --- a/ethereum.go +++ b/ethereum.go @@ -5,6 +5,7 @@ import ( "github.com/ethereum/eth-go" "github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethutil" + "github.com/ethereum/eth-go/ethwire" "github.com/ethereum/go-ethereum/ui" "github.com/niemeyer/qml" "github.com/obscuren/secp256k1-go" @@ -195,6 +196,7 @@ func main() { // Search the nonce block.Nonce = pow.Search(block) + ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{block.Value().Val}) err := ethereum.BlockManager.ProcessBlock(block) if err != nil { log.Println(err) diff --git a/ui/library.go b/ui/library.go index 0dfb10ac7..c9273e8c5 100644 --- a/ui/library.go +++ b/ui/library.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethutil" + "strings" ) type EthLib struct { @@ -13,22 +14,34 @@ type EthLib struct { txPool *ethchain.TxPool } -func (lib *EthLib) CreateTx(receiver, a string) string { - hash, err := hex.DecodeString(receiver) - if err != nil { - return err.Error() +func (lib *EthLib) CreateTx(receiver, a, data string) string { + var hash []byte + if len(receiver) == 0 { + hash = ethchain.ContractAddr + } else { + var err error + hash, err = hex.DecodeString(receiver) + if err != nil { + return err.Error() + } } - data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) - keyRing := ethutil.NewValueFromBytes(data) + + k, _ := ethutil.Config.Db.Get([]byte("KeyRing")) + keyRing := ethutil.NewValueFromBytes(k) amount := ethutil.Big(a) - tx := ethchain.NewTransaction(hash, amount, []string{""}) + code := ethchain.Compile(strings.Split(data, "\n")) + tx := ethchain.NewTransaction(hash, amount, code) tx.Nonce = lib.blockManager.GetAddrState(keyRing.Get(1).Bytes()).Nonce tx.Sign(keyRing.Get(0).Bytes()) lib.txPool.QueueTransaction(tx) + if len(receiver) == 0 { + ethutil.Config.Log.Infof("Contract addr %x", tx.Hash()[12:]) + } + return ethutil.Hex(tx.Hash()) } @@ -40,5 +53,6 @@ func (lib *EthLib) GetBlock(hexHash string) *Block { block := lib.blockChain.GetBlock(hash) fmt.Println(block) + return &Block{Number: int(block.BlockInfo().Number), Hash: ethutil.Hex(block.Hash())} } diff --git a/wallet.qml b/wallet.qml index 6ee6ff110..e7145cef3 100644 --- a/wallet.qml +++ b/wallet.qml @@ -23,7 +23,7 @@ ApplicationWindow { Button { text: "Send" onClicked: { - console.log(eth.createTx(txReceiver.text, txAmount.text)) + console.log(eth.createTx(txReceiver.text, txAmount.text, codeView.text)) } } @@ -300,8 +300,9 @@ ApplicationWindow { } function addLog(str) { - console.log(str) - logModel.insert(0, {description: str}) + if(str.len != 0) { + logModel.append({description: str}) + } } function setPeers(text) { From e60ff6ca41832c8124acfab6b8408516d60ac140 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 25 Feb 2014 10:54:15 +0100 Subject: [PATCH 186/459] Moved ui lib --- ui/ui_lib.go | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 ui/ui_lib.go diff --git a/ui/ui_lib.go b/ui/ui_lib.go new file mode 100644 index 000000000..93712eba2 --- /dev/null +++ b/ui/ui_lib.go @@ -0,0 +1,38 @@ +package ethui + +import ( + "github.com/ethereum/eth-go" + "github.com/ethereum/eth-go/ethutil" + "github.com/niemeyer/qml" +) + +// UI Library that has some basic functionality exposed +type UiLib struct { + engine *qml.Engine + eth *eth.Ethereum + connected bool +} + +// Opens a QML file (external application) +func (ui *UiLib) Open(path string) { + component, err := ui.engine.LoadFile(path[7:]) + if err != nil { + ethutil.Config.Log.Debugln(err) + } + win := component.CreateWindow(nil) + + go func() { + win.Show() + win.Wait() + }() +} + +func (ui *UiLib) Connect() { + if !ui.connected { + ui.eth.Start() + } +} + +func (ui *UiLib) ConnectToPeer(addr string) { + ui.eth.ConnectToPeer(addr) +} From 78b6e7ad9531461f389c5de3cef10fc665607050 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 25 Feb 2014 10:54:37 +0100 Subject: [PATCH 187/459] Proper Nonce --- ui/gui.go | 143 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 79 insertions(+), 64 deletions(-) diff --git a/ui/gui.go b/ui/gui.go index f0e281de1..72e5b976a 100644 --- a/ui/gui.go +++ b/ui/gui.go @@ -1,15 +1,15 @@ package ethui import ( - "bufio" + "bytes" "encoding/hex" "fmt" "github.com/ethereum/eth-go" "github.com/ethereum/eth-go/ethchain" + "github.com/ethereum/eth-go/ethdb" "github.com/ethereum/eth-go/ethutil" "github.com/niemeyer/qml" "strings" - "time" ) // Block interface exposed to QML @@ -26,7 +26,7 @@ func NewTxFromTransaction(tx *ethchain.Transaction) *Tx { hash := hex.EncodeToString(tx.Hash()) sender := hex.EncodeToString(tx.Recipient) - return &Tx{Hash: hash[:4], Value: tx.Value.String(), Address: sender} + return &Tx{Hash: hash, Value: tx.Value.String(), Address: sender} } // Creates a new QML Block from a chain block @@ -48,11 +48,19 @@ type Gui struct { // The public Ethereum library lib *EthLib + + txDb *ethdb.LDBDatabase + + addr []byte } // Create GUI, but doesn't start it func New(ethereum *eth.Ethereum) *Gui { lib := &EthLib{blockManager: ethereum.BlockManager, blockChain: ethereum.BlockManager.BlockChain(), txPool: ethereum.TxPool} + db, err := ethdb.NewLDBDatabase("tx_database") + if err != nil { + panic(err) + } data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) keyRing := ethutil.NewValueFromBytes(data) @@ -60,10 +68,12 @@ func New(ethereum *eth.Ethereum) *Gui { ethereum.BlockManager.WatchAddr(addr) - return &Gui{eth: ethereum, lib: lib} + return &Gui{eth: ethereum, lib: lib, txDb: db, addr: addr} } func (ui *Gui) Start() { + defer ui.txDb.Close() + // Register ethereum functions qml.RegisterTypes("Ethereum", 1, 0, []qml.TypeSpec{{ Init: func(p *Block, obj qml.Object) { p.Number = 0; p.Hash = "" }, @@ -91,17 +101,20 @@ func (ui *Gui) Start() { // Register the ui as a block processor ui.eth.BlockManager.SecondaryBlockProcessor = ui - ui.eth.TxPool.SecondaryProcessor = ui + //ui.eth.TxPool.SecondaryProcessor = ui // Add the ui as a log system so we can log directly to the UGI ethutil.Config.Log.AddLogSystem(ui) // Loads previous blocks go ui.setInitialBlockChain() - go ui.updatePeers() + go ui.readPreviousTransactions() + go ui.update() ui.win.Show() ui.win.Wait() + + ui.eth.Stop() } func (ui *Gui) setInitialBlockChain() { @@ -113,12 +126,72 @@ func (ui *Gui) setInitialBlockChain() { } +func (ui *Gui) readPreviousTransactions() { + it := ui.txDb.Db().NewIterator(nil) + for it.Next() { + tx := ethchain.NewTransactionFromBytes(it.Value()) + + ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) + } + it.Release() +} + func (ui *Gui) ProcessBlock(block *ethchain.Block) { ui.win.Root().Call("addBlock", NewBlockFromBlock(block)) } func (ui *Gui) ProcessTransaction(tx *ethchain.Transaction) { + ui.txDb.Put(tx.Hash(), tx.RlpEncode()) + ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) + + // TODO replace with general subscribe model +} + +// Simple go routine function that updates the list of peers in the GUI +func (ui *Gui) update() { + txChan := make(chan ethchain.TxMsg) + ui.eth.TxPool.Subscribe(txChan) + + account := ui.eth.BlockManager.GetAddrState(ui.addr).Account + ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", account.Amount)) + for { + select { + case txMsg := <-txChan: + tx := txMsg.Tx + ui.txDb.Put(tx.Hash(), tx.RlpEncode()) + + ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) + // Yeah, yeah, stupid code. Refactor next week + if txMsg.Type == ethchain.TxPre { + if bytes.Compare(tx.Sender(), ui.addr) == 0 { + ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v (- %v)", account.Amount, tx.Value)) + ui.eth.BlockManager.GetAddrState(ui.addr).Nonce += 1 + fmt.Println("Nonce", ui.eth.BlockManager.GetAddrState(ui.addr).Nonce) + } else if bytes.Compare(tx.Recipient, ui.addr) == 0 { + ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v (+ %v)", account.Amount, tx.Value)) + } + } else { + if bytes.Compare(tx.Sender(), ui.addr) == 0 { + amount := account.Amount.Sub(account.Amount, tx.Value) + ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", amount)) + } else if bytes.Compare(tx.Recipient, ui.addr) == 0 { + amount := account.Amount.Sub(account.Amount, tx.Value) + ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", amount)) + } + } + } + + /* + accountAmount := ui.eth.BlockManager.GetAddrState(ui.addr).Account.Amount + ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", accountAmount)) + + ui.win.Root().Call("setPeers", fmt.Sprintf("%d / %d", ui.eth.Peers().Len(), ui.eth.MaxPeers)) + + time.Sleep(1 * time.Second) + */ + + } } // Logging functions that log directly to the GUI interface @@ -137,61 +210,3 @@ func (ui *Gui) Printf(format string, v ...interface{}) { ui.win.Root().Call("addLog", line) } } - -// Simple go routine function that updates the list of peers in the GUI -func (ui *Gui) updatePeers() { - for { - ui.win.Root().Call("setPeers", fmt.Sprintf("%d / %d", ui.eth.Peers().Len(), ui.eth.MaxPeers)) - time.Sleep(1 * time.Second) - } -} - -// UI Library that has some basic functionality exposed -type UiLib struct { - engine *qml.Engine - eth *eth.Ethereum - connected bool -} - -// Opens a QML file (external application) -func (ui *UiLib) Open(path string) { - component, err := ui.engine.LoadFile(path[7:]) - if err != nil { - ethutil.Config.Log.Debugln(err) - } - win := component.CreateWindow(nil) - - go func() { - win.Show() - win.Wait() - }() -} - -func (ui *UiLib) Connect() { - if !ui.connected { - ui.eth.Start() - } -} - -func (ui *UiLib) ConnectToPeer(addr string) { - ui.eth.ConnectToPeer(addr) -} - -type Tester struct { - root qml.Object -} - -func (t *Tester) Compile(area qml.Object) { - fmt.Println(area) - ethutil.Config.Log.Infoln("[TESTER] Compiling") - - code := area.String("text") - - scanner := bufio.NewScanner(strings.NewReader(code)) - scanner.Split(bufio.ScanLines) - - var lines []string - for scanner.Scan() { - lines = append(lines, scanner.Text()) - } -} From 6451a7187a5eeff6ac819ded11b6e7f0a5aa1b1b Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 25 Feb 2014 10:55:44 +0100 Subject: [PATCH 188/459] Minor UI change --- ui/library.go | 2 ++ wallet.qml | 10 +++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/ui/library.go b/ui/library.go index c9273e8c5..3bbb01314 100644 --- a/ui/library.go +++ b/ui/library.go @@ -40,6 +40,8 @@ func (lib *EthLib) CreateTx(receiver, a, data string) string { if len(receiver) == 0 { ethutil.Config.Log.Infof("Contract addr %x", tx.Hash()[12:]) + } else { + ethutil.Config.Log.Infof("Tx hash %x", tx.Hash()) } return ethutil.Hex(tx.Hash()) diff --git a/wallet.qml b/wallet.qml index e7145cef3..3e921b78d 100644 --- a/wallet.qml +++ b/wallet.qml @@ -221,6 +221,10 @@ ApplicationWindow { text: "Import App" } + Label { + id: walletValueLabel + } + Label { anchors.right: peerImage.left anchors.rightMargin: 5 @@ -270,7 +274,7 @@ ApplicationWindow { text: "Add" onClicked: { ui.connectToPeer(addrField.text) - addrPeerWin.visible = false + addPeerWin.visible = false } } } @@ -291,6 +295,10 @@ ApplicationWindow { } + function setWalletValue(value) { + walletValueLabel.text = value + } + function addTx(tx) { txModel.insert(0, {hash: tx.hash, address: tx.address, value: tx.value}) } From dba1ba38220c92f96aaeeb2d4cc99c1991220dc4 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 25 Feb 2014 11:24:04 +0100 Subject: [PATCH 189/459] Currency to string --- ui/gui.go | 14 +++++++------- wallet.qml | 3 +++ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/ui/gui.go b/ui/gui.go index 72e5b976a..6e30b5891 100644 --- a/ui/gui.go +++ b/ui/gui.go @@ -26,7 +26,7 @@ func NewTxFromTransaction(tx *ethchain.Transaction) *Tx { hash := hex.EncodeToString(tx.Hash()) sender := hex.EncodeToString(tx.Recipient) - return &Tx{Hash: hash, Value: tx.Value.String(), Address: sender} + return &Tx{Hash: hash, Value: ethutil.CurrencyToString(tx.Value), Address: sender} } // Creates a new QML Block from a chain block @@ -154,7 +154,7 @@ func (ui *Gui) update() { ui.eth.TxPool.Subscribe(txChan) account := ui.eth.BlockManager.GetAddrState(ui.addr).Account - ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", account.Amount)) + ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(account.Amount))) for { select { case txMsg := <-txChan: @@ -162,22 +162,22 @@ func (ui *Gui) update() { ui.txDb.Put(tx.Hash(), tx.RlpEncode()) ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) - // Yeah, yeah, stupid code. Refactor next week + // TODO FOR THE LOVE OF EVERYTHING GOOD IN THIS WORLD REFACTOR ME if txMsg.Type == ethchain.TxPre { if bytes.Compare(tx.Sender(), ui.addr) == 0 { - ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v (- %v)", account.Amount, tx.Value)) + ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v (- %v)", ethutil.CurrencyToString(account.Amount), ethutil.CurrencyToString(tx.Value))) ui.eth.BlockManager.GetAddrState(ui.addr).Nonce += 1 fmt.Println("Nonce", ui.eth.BlockManager.GetAddrState(ui.addr).Nonce) } else if bytes.Compare(tx.Recipient, ui.addr) == 0 { - ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v (+ %v)", account.Amount, tx.Value)) + ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v (+ %v)", ethutil.CurrencyToString(account.Amount), ethutil.CurrencyToString(tx.Value))) } } else { if bytes.Compare(tx.Sender(), ui.addr) == 0 { amount := account.Amount.Sub(account.Amount, tx.Value) - ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", amount)) + ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(amount))) } else if bytes.Compare(tx.Recipient, ui.addr) == 0 { amount := account.Amount.Sub(account.Amount, tx.Value) - ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", amount)) + ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(amount))) } } } diff --git a/wallet.qml b/wallet.qml index 3e921b78d..04c1ffaed 100644 --- a/wallet.qml +++ b/wallet.qml @@ -215,6 +215,7 @@ ApplicationWindow { text: "Connect" } Button { + id: importAppButton anchors.left: connectButton.right anchors.leftMargin: 5 onClicked: openAppDialog.open() @@ -222,6 +223,8 @@ ApplicationWindow { } Label { + anchors.left: importAppButton.right + anchors.leftMargin: 5 id: walletValueLabel } From 8d1d72abeeee68ddcdffe02a28587a9bec1647e9 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 28 Feb 2014 12:16:46 +0100 Subject: [PATCH 190/459] Improved overall UI design and added a bunch of icons --- net.png | Bin 0 -> 4669 bytes net.pxm | Bin 0 -> 95418 bytes new.png | Bin 0 -> 4776 bytes tx.png | Bin 0 -> 4070 bytes tx.pxm | Bin 0 -> 93227 bytes ui/gui.go | 51 +++++++++-------- wallet.qml | 159 ++++++++++++++++++++++++++++++++--------------------- 7 files changed, 125 insertions(+), 85 deletions(-) create mode 100644 net.png create mode 100644 net.pxm create mode 100644 new.png create mode 100644 tx.png create mode 100644 tx.pxm diff --git a/net.png b/net.png new file mode 100644 index 0000000000000000000000000000000000000000..65a20ea00cc191087fd90704f5874dc376c0433b GIT binary patch literal 4669 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

xNm z3CVb#5CiroL*Jys9^+6TUNvr2hjST+wz7D&=%t*JjFy9 zH8zz`#?m&YnxQ@FWgnzNnH)!BSjvm+)f(2Xm&1+5mv0s8ul9Nx2oy$$i^k_7Zypop zPtdQ)y#7nNJ&C^)f>#80tf%p6ZW<%u>z#&Z^Pc}!e{Bfk`%rYBC|!x&WG z5DTB9Ol|!4fnx;*{R>;da!w(aWxPhnE!k)}QtZe@zOcvr4)NSZ^+}w>L;lGQd#`7y zHg)P4cu0X7_Sdod>;UNFb8w(p8D#-Z8*567r^@c3blGUP)H^~9yd>&S!qhCG{N zjL=g&S_~pKE{A$yPdc?1H59c(KJu^DSi}L`lryi1;Ne)%5hnv49LsUDXVrSCGF4Cc zF!0wL@YtiRmNUiyjr$Tk@}eE)N{!;Bp7P^!z~LMl&d~?&1rN!{2ia(IVTXR}@rb#W z1CJYG2Y$kG4&jIAC48d~o(J@Z;dx6kEk48xz1MRBCweYN?&rjQNOG`YFqS!Z?E#1N z;`z&15g*43F7kykYE(DWaV&CSY}8=hT;lbDdSHy)9^|yGuqQc>2l*sBtxhOIorpoh ziaF1lFwk>e;>KK22lM97J7QokCY&eA1%_hud>-r&BlsBdz+BB8wk?d&POYcZ3k>H3 zpBOha7~@7B(yQA8WMl)sCp6~1$X@XB`U@T&KaMd^(c>8HQHS{uhbmWn^L!~z zh=pt@PR@n<0_PyE>(`qJK3*TRYXrmnVSdnXj983^@ zqYcSboSFm5v|0d$VnYm%PsmV?IT0ttr^-b>fI&IR2uFJKqvosDo$M(W>d}sLXiIg) zaecYNkLL@jKh;*+!HtTS`06UeMHz2AKD_8=LkK{H68d;=XG30 zSd52{ffH>h-}wv+?a4*8{8pg*(+JjI0ZP;7`*{Q(B#v`q-Z{h%D0 zHU=(^6L<}a7-*Cq-VXM_Z{OPR5WpT90Oe z6XRkegE61KggyA=z2r~mkxSzP42^jW#hhe>Rp-b_b%*^O`5WN1IsuM!9M>R5#F39? zh^5#BKjx(Ag^n=wY&9Hms63dr95;dSZPjm;oAoJkQZwqxZPi_E5fk}A&OorIJhg4!AP(ff+E9;UhksQk*G|SYtQG3WKaQz2W{)`8FZ!gp ztRoIprq&j5gvFlkhaxY+W3OWBv^Ypc_GC*ovb+u0Hx>uQsd9slSJZ7J+j2jz$oZ?7 zhJMh8JKzGbiFm1}SP|p!rD93v{xTf@`!}%VTvE;$MR|tAmT$mWJh_S9~s*Q{R1c3Q6mh^ zF$Wx@oW?juPQs84_A0J^jYv;*(r{QK!G&=lANG7Z3BQ_e4X5rets!on3-8rB;vDk{ z5RGH_xK6DFj7diJ$WJn|<#_>?;-Pr?9Oaw`;(#7~wtfxxaZC+lq@&zP$GHF}>p2Ew z=$~SdbDjvG5p$POX*5ZL7LnQO4yBY=|cSaFjc75w`>5;Gj4;FV-A+w_U&P4^5Mi z9D9lr^qfz~I99}soN62@M$?IyTSJUmY#1-dxj*ztO~{&(a~$#k-hW%2BVNfKbv!=_ zLwqDR6CQiuqgZ4dj%hBB5l?gKF*oF-xy(mCwHzfJ;?-Q#IQU%4PnGdH3LIgHpLAFY z(ot^2-D*3aWQBSzti`@veN4P$P#Lp1aYjpr_Uic9YO0grYX7VU*Cj|Ilm^L-S# z1P0|e=C(WPu6KZOhwXK$J&d^?xezBfspp)M9PN01$S-VgyKo$EYh02Zafrbjcn^Gt z<2Hm7@gcX2;W?uYV-T^bd8l)$Bd-r~2_NW_kI@zy$AOIEXa%vN%un?GkQdg4Y&c%n zk{o5+568i_7C!3B!3XGheR(f@a~nr2XiL0)0#9=-2IR->gtpul#HjgH<&+!e035}H z{^gobz8d%I_2X&<^A21l{E2vxm;1*aF=Ebp#B&=JgSAATq^pM&_JnU#C%Dn4pWxN} zlW)l%acJ>zAGjUW98iz;7!&q5$0o;!w&a8JN&Lji<$zP?_3OiBI|a9}<#m*Ka14$7 z@G;J1xfr7@$$71iTgZ4`FmHu2>_Lt_>UnO2d%aGpAI7J}1NwTlILC(dq8{r(a^U7M zqc6m8pN`s63@9fX?u%*#JiPA6$89lQ*giBznUG^oa?Z=;Y91&@nIB?A~RiqZYRcajO2@Ot-wbssJCN|d?H7QPvwwsq~krv zF-9TdV<~2wV~jk1fu|U;m+|sg%eNkv>Wl2CZ}|rJfX01Ec;b+I!ti*&hWEH#$qu=s zxX705-81tlH{S-<%J|h}U!w7tF~Y z`NEzz35PZqFaAyw4*g?8InPhbX-vHur<4=mkdNy{?3f469ZmIvzEqiroAB66xf37R zlbz-p@LEn9XZ<+H207}D8^$W^38VFx1CPm(OUpOaJUW97)|uktJz@nn$%#vjp`NT^ zESkOQQ|3cEnz!5~^2Zp&n0#Vv91F3M4ExTz)YwTzT!<$ba%p2p&N+n+xg9=4Z5zbE zInW=``iyg*Xk3Dj7{}hMFOUQ^%j+w_P>@@#0 zm$*<@&kxQe9JdvCim{;|#PGOfJFubrnu?Ftl;hOxPq{b5Q+zl0MO)ghg+HD*j2p!Y zd1L(OTeHO)z?@|CJAri}8Q+H_KMgslZjLw{`;J5A@JYO+<2eI=i``N#Fvj0o!eCFh z&N5EKjxtRzWEvlGaT}G7e;xovkJ?l2 z)N^jZg=6$dI&BR4da;l{A#acNB*VOLE@Ge_?c49h{6$R#hRZn?t5%!(I2Io9Z zkf}NcmSQG9#6j_5PxfjI$fd@Ba+L9ULC^K513A@``;%}y4oQzTsvYL1Ha^EO=y-bz z_^^SDVnHm9`5b!GQ5>2KZIDCO3oc$ukdu!VAV)j&O|i>ya8AIqe@oO8#-!&u^dmU1 z=G-U9P=_%fKjuLBlOE@shkC@w+YH92Ck)wRj40#$+{O_<#)15(=edY^JM1BTE(1N) zMavCiMLFPjtWuBhb3F8jr+he0vf(9V;(>B$VFrF zfpZ+o{M;vSac*HJ`y(5awUcq^U(}p@kspk&-5wF6utOefgynpw6OHubTa8iOraVT# z5kL7QK9plaTz63yjFoDnjRlV6gvFj?P%qh$zwUcQoX~fIR?iM?P>y!8f5C;koS)Z3 zs-f%$$HamBV2gHG3-X2h6er2lywn<@p5rCIa!km{=jcmtQQfo{DF(#g7+O2gwD{1E z&|zIV?Nzrkj|Jwc%wbEhlAPP(zJYcU5062}x`SSw0}sZEywnRHTn1wvAH^#$JQf@a zIbq}&C|=}OV^V!#Ok_u6%{O9^SNNs4G#tqJxIy3P9aXON=tH!Ic#09_a*YTl>)Qe^ z@pPBQ94qFs9oZt5^J6a>*9ke{2!r(@nLJkYu&qcB_J|`a*Yi9`R;THB%_SYT6ZXW{ z{T&rAa}o~YM!i~7z+voMCUV0#VBQ;jkdFKjj^xw}8|3XRFx_#Vl<=HW(@|c+2ij{K z4!@m5oM?-B+^%xGTn@U1emF+>ryT0_!WYUgPvYcr&IftyQ{||`oK&6apXR9RCgE`0 zNi@{m$m_sUJZM84+#Y>NoahVX6b~N@4983MvQO1FZ38tQ@`+rs53<9aa>Jf;pl=~> zEC%Ex9QG6|_TAo9LB zF$UR&FgzE;W8NYL^3iKQ9RD{%of;GJ5uWPO4ed}bHOd9$Yasr^O)jBo8{^ z*e57%t^=HAqw%7DH3l9NV7Ncz6iuGvnC29lEJK?R86(DILp4BLLmBaqT<*2pz)rR$ zn}#x+QzH!Vk-T9~dJT`;0OJ(3()7}tWSFz%kc!718|i3{T!afDy}Ac2p4S6$*kF!6ET~7F)Z>_Aq30N~K|D1P2cM&@;IbTsx=VAOhp-_G z`A5GYuzzs5uqPey$~nk5O^+Pp4>&kRlBqt>kD4ReQNBFS_k~>8a2eS{PxHol&Mhz@ zz$4EQkMnTUlMa0~;*a7%tb+sUg0_-On@b#x#YHj)mxGr$2t)i@j17E}Ugpwd??a3b zOE5I82YZ|oAC1F7Mzug4pCb>f z9mh&`ge45OK|5-KI~=wf=fwHZI)`tG3%MzVhJ46N@eoFfn{%r9a2)cWO!VBZ@Pj$y zocEHR*8=CLmwMtLJlPXR_y;N%_S}|w^dWRyj=YkNuw=)1B|OQ=hQ~*7BbR7$Jc#9X z=!bKuHP^5*zhqC`SUY))c3K>gjxf|~{DM=SBZlT0pNNxUjRH)Vh&c*+Y&1s<#egzd zN44R-(BYVDNsfL|h7IGPp8WIpKu37;Njx~$#+VQCh(=?%$1%o|b-I7S)ziWG9}c?>v*#_ffU$A~hTi(bQtxH!MSkxwlz#DI=`U{7Nn z8|t9(c%(7TqdutP@o=2TLCa5IdELaA@(ezv+MyqnN38+*pn7AE7>!f-h&&E>Xu;Hg zALl6Nxj;|)u;X=Hj&qC?F&rl_=#%?}c|$(3K{@v+*&`RPCF)?zxrLtma62xm)8Zrl zyhpnRaZoI>T;+p2IG%ddC)N`6i03hiz9EmsNB*!sQQxj1rlH;udxLyVz#O>*ALo(B zJSKHJM1q|25T1G|E{7k1MSE@s$N$Y6@ zvDOn#^r{a>4LC3I)YIQMM}8R-Bk_`4?s;5|a1w^wW8A{GEXOgQH_#J?^fX6~dhv)@ zQHG81RCBFv#@LvZr#LAF9h zeq{{hNHUF6@RAMByD>iDTh?=%Mq<&pK_|yoF9wN^*GA&uF`kn07I|?T$hluh&;2!+ zYcVuY6IsvwHG+#2zPMj02EtQ+GcK~Fn8^mY8`_ahwrLC_<2bJrTMWhw?KaW#93)?; zCk&54;J6>sNwpv>*=apsC=NLn^h-^{q7RA@eaK^)H|&WY`m=;G#L=$uIWY9&Ct*^!-l3-cju4RL7wY4|&Venm`VgEGR9E$0Rt$s@@|_$0lY8|OhiH4zia z36DJFgKW7>lB1ruP)9a|r|m=ebByGR^oU1{>>IH-=lm2G`Xjl}@fcuCwL-ki%jd$5 z^5J^47k1>A?CQ-0hHS9c^u#M+B7~lDLOjYyj<(z$Y^j&y(DZ<7=!;@#h$kH96Luuy zIX9F^b6HQkC_^rcnS5eTdh#Rp{muX$8sTvsE#@+g$0g%{7jcB)ddWA+8#c`c=m^g- zlE21mP*!g{0G@oyv2vN~?_eu#(1D)AwXxQVZxEyg1-+%Nc{eSqSon8=6RQ>?@xb929f zo8;sp8vLM)c`NYhcsQO^SO)x~NMi#Zo8avs+Z3aa16XkuV*`x+80h)y3tiz&Gb#^a znu#%J;iWPT{uYGKV@g{IKSCO3@-h0|y`Y@AFy=WJ#_xe2#$3gJ3i!nTKsVH0Tw;K? z;T08El#NJ{CpI=Y&4A@D_;0&|b zA^(>~ez~P(6_6!VkA>yg%5z~{4dcR@6{RS@0^`7(X*f1utpdv+Kp3~galSh4!!hc3 z5RUVTit_-2F_-2QHTu#_P_ddBcH2zYe6=v{Qdn7Jhw<+)4lJ@+%Na9yqP)VETL9x= z7<-mwjYxp;ZBR(hd}*8`jVo-kAXdf_N=j#!+4Bo3%sp~@nnU1yr{=-7nT58B3QLAH zcbc^<&zw+FRBA1r4O@rjjaJMb>uZKWM~1{iMp{CHU=wIRH&tq=n-6gNstEnXnevXT zzc}+>dU2+q+@8<(pM()v=G@A%8S1`-znaX6xicRY$Xc=XtTXGuEG(2ov3_h2OJcXP zbe6@&vPmqL6|f>!#%8iR**sRm9$=5aD}Gn8C)ftInZ3wfW!u@CY!7>n9cIVaDfS6F z$1bwV>l&(r|B@|v8H9$#%S2>MP#wwGQe5F{aRPI#nQ65kh zE31@s%4X#i<#lC`a!@(0e59OLzEOTs{xld3o`yg}J3}`^UqiGZ&M?G~WteElH%vF& zVW>7dWLRNXZ+PCY&9KLC*l@~l&T!dq6+Xm0jQUG6^_OPqFU{0nnyJ4uQ-5h@znxp( z2zuk0H#@$$dRMbu5ASy0UA_DITX(#5_3hHPzuS|)=fd9Xy`Q`@=AGJo!}lG1cgVX3 z-b;S(o&9n9-#XC$z?%nS559gV`q1{nk%zY(i8!+L{fPIs9*sP@?SrTfb{va2w)6OH z$9JC?cw*1V#FOvUrq&)lm3Hd*>5->DJTu|UxexO`{Q9H9kAD1k#>dw_sXFU)_WnaV=MT6U?!rOjW5e*NY* z$=@9NcKo*&FPC1v_Fc{Qe&4V8p~nwf{xRquN3M*ya`DHqAFuzk=;u~HKl4lYFMF?M zT>b3VqF=B5cK`3Ke&6&*^dI~G9R25|Ycv0H`D?{LrI%)^uYJr=hG+Zwre((4D~hb8 z{Kbv%V#TN6k8>uoHKG|O-tGt>PQad3My_YiGTTXZ0=_Y{QAV>`mX#Q64rWy@s*7>T zczFLKr(Um&ug(D zX2tA6+j?aRyroi>Wc&K0We%~;w&lf@}rfLCK-nt^Ni)j$Bb)@uNqGnFPfZ8txXnFUsH%F%oJgYGR2tsnfjXsn&M0erbJV+ zDaDj(8e$q|N;eHRjWA`IMw&*OCYUCfCYy3hxh9+G4$}hDgQiucmrU=OelT4z{baiC zWO8zM@^tcc@^xzE)X}fVuf%Vb-#vbd{8ss`^V{V2ir-GZ{eDOMKJxp*?_0lr__y`% z<{$1K=b!FB-apUZ?tiEM{r)TcSNlKdzux~T|EK+*@!#zKoc|X8-TrU;U-G{aU7LRvB{pSj%J`ItDN|CWr4*%4M%CV4JGwTz)>>O!JEL}1?Y!EDY9Fh8vi8;5 z?X`Q=@Aw9T+AGu4p8l=fSF^Z!`3k@6jJOd=X<6ArrY2*E(G*DGv#3D7noE!ywq%g<-{pVqo_8w=2hVoxlGLhI?vqQ#A3ApA=`Q!X8E;?r z$h3n;s?X+r>5~!t)P=jQ-SzFW$P~^>lO{%8~a>X*y;D`b~JzZi+5k% zKfS;AzMU)D{W-aRMu)7KXWLC5xZCT%*7U>GYWnu?Qwv>R zFDU)dm{ex}dW@w2<_`#EIE#ex-2d^q5TA15!g z6g^b_WB$U3Wv^C7@3Yn&`u6UyZVPt2l{kBk0#)sY*WX?5J3g%@GUSKUU5^i$ zQ~zz=b<5Zd&|(#}_Zo{i)BE?d30Cdu?0i{&$~DSbgcG&l0|G`|aAZ z&+J$>b4A(oH@&BSl`;3wD=PwXuFcxs*8P>IzpDD<*ImZB(;jbC`N0p*`Idb4=b1Sj zKL2Q>b=Q}Z)1F^=xTEvjPw$C6dSOd&&45Fr`Yq^s{>V2A`p@dHwf*g%kD2z5wRipU z&lvx$#dC98ln?s!+E=r-{B~^l8yDMb?(;!z?tulbt!sN;fueuuV~%#CjI=efeC28{c&^3t9qrCx?dPwH{j!a4<0>sZ06>l$84zotF-0Qii8R$#<1ZTy5W`f z+-XBgN~ZPADu7?uVynF{sKP#Fiuzh*)3z#R&WP^P+{>jp-kPx^FS4D_!o-~6(Hllt zT2!+OgMvM0^l!It;D+=|-z~k?a!JyKbE%X4Q@T8M`{dy-w{$Nw+?AI7@E;fIYy+86 zFlcP;4|80NCkCB&pFAia-L$9u)u=b#d;Z5eM`imSYT4|!?77D}{yeA47nLTDaq;iG zVcYg$?;Y;%j1E2)`km+e{w3+7Bd#7f^>)OV-y{14c)Ubhg(Zt(qP||gGx1>c;0xU!>XBHr?#X)#pC9$Whyz=lp2#Tk zP917`F;GwC0Gb5JgRG;n9{^Wh%xujK^(kFuUfi*-zt`YF$A>%^xa7#1R}1H~p7;J2^KyqTGZzhYe!Kd} z9W~9a+9!pMGIn*J>3V9@qH$-OUWk3H+mf3;YUBKX!5*eP z({qf5UFp59oWI>NU|x@Bzx#0F>Aj%? z#^l~x(=5MZOaJikdH25Z;A1QH9L;L`<)HR%1?N6YZdP;tRJTr#=S+6)weE}Gk48Oo z;j(G|J!cMD=RURkc=W2V_In>|H)(P~d-os5<&1j1Yuh^x?k^s{?Vn$LY#!IzbX(y) z`&K1>I<{wFtMBKneWv-7cl2|wet6l^k8fX9+N0&=4<6c(pO|cZ*gE^<@_Ff5f#3gGXNk<} zx8ZWX^nkO!KRh<^^NL}gUAp6q-b;6m`f~sC3;#&Cu%xrglHibqpLAHd;I=&lZg*5I z+415VUk~&hI{3okO>@>iI^}5eo%hW5d)>S`(b}#4~>}+lRmbh|E0Gde4^8qxvqnjE{Gp_%w_aj zF0Nzq%++stCuT%2ll1DP;CFH#3?Yi>a=tOg2((so%e)0B#l$?d%1cpsXa{Y5x zpD(=@ZQozG^FcS$xPrGwMs3^@{r+@Iq|?H0mj2}Xsxm9~;Xz-wN;#J2)`fMMH+;~% z&ci?GxIboIaI$aCf#dg2Yj1Bozgv9xBO?mNcKX93=v>I&B~N;1-M?;hZ>NG614Hkh zy{L$ZjAGUB^-;ke9Od9gh+`eC#_L#pkNf&$C!=(wj z*n?y3VvkdvcCiOO1OM%dJ;@mGq?_y7Xaj^%!R49#J_;D)a-)$OP>}mRwx_P}% z>WnfQUKi0nr}fWi{c~FXoYp_5;bRsra5s8U{=emOS}_E|RkV6PlOX_Ta11H^JOx+X z@=9_mi)_UeeeK0lN-~DrXi8tl@k8G6^G=Z>eL0su@^8k0U+En`tqNq0`d{!HW08-s d9V|!llv{MfoiW788F@|cUkuc1S~>i~{ujT#WeETP literal 0 HcmV?d00001 diff --git a/new.png b/new.png new file mode 100644 index 0000000000000000000000000000000000000000..e8009674889f3b244c595866ff2003ce24149d1e GIT binary patch literal 4776 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 literal 0 HcmV?d00001 diff --git a/tx.png b/tx.png new file mode 100644 index 0000000000000000000000000000000000000000..62204c3152f55b9fa0265bb322721bf352518025 GIT binary patch literal 4070 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 literal 0 HcmV?d00001 diff --git a/tx.pxm b/tx.pxm new file mode 100644 index 0000000000000000000000000000000000000000..881420da9670686061c113d6fb2c6f27c72ac1bb GIT binary patch literal 93227 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 literal 0 HcmV?d00001 diff --git a/ui/gui.go b/ui/gui.go index 6e30b5891..556e682a9 100644 --- a/ui/gui.go +++ b/ui/gui.go @@ -9,6 +9,7 @@ import ( "github.com/ethereum/eth-go/ethdb" "github.com/ethereum/eth-go/ethutil" "github.com/niemeyer/qml" + "math/big" "strings" ) @@ -62,9 +63,8 @@ func New(ethereum *eth.Ethereum) *Gui { panic(err) } - data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) - keyRing := ethutil.NewValueFromBytes(data) - addr := keyRing.Get(1).Bytes() + key := ethutil.Config.Db.GetKeys()[0] + addr := key.Address() ethereum.BlockManager.WatchAddr(addr) @@ -127,7 +127,7 @@ func (ui *Gui) setInitialBlockChain() { } func (ui *Gui) readPreviousTransactions() { - it := ui.txDb.Db().NewIterator(nil) + it := ui.txDb.Db().NewIterator(nil, nil) for it.Next() { tx := ethchain.NewTransactionFromBytes(it.Value()) @@ -140,45 +140,50 @@ func (ui *Gui) ProcessBlock(block *ethchain.Block) { ui.win.Root().Call("addBlock", NewBlockFromBlock(block)) } -func (ui *Gui) ProcessTransaction(tx *ethchain.Transaction) { - ui.txDb.Put(tx.Hash(), tx.RlpEncode()) - - ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) - - // TODO replace with general subscribe model -} - // Simple go routine function that updates the list of peers in the GUI func (ui *Gui) update() { - txChan := make(chan ethchain.TxMsg) + txChan := make(chan ethchain.TxMsg, 1) ui.eth.TxPool.Subscribe(txChan) account := ui.eth.BlockManager.GetAddrState(ui.addr).Account + unconfirmedFunds := new(big.Int) ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(account.Amount))) for { select { case txMsg := <-txChan: tx := txMsg.Tx - ui.txDb.Put(tx.Hash(), tx.RlpEncode()) - ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) - // TODO FOR THE LOVE OF EVERYTHING GOOD IN THIS WORLD REFACTOR ME if txMsg.Type == ethchain.TxPre { if bytes.Compare(tx.Sender(), ui.addr) == 0 { - ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v (- %v)", ethutil.CurrencyToString(account.Amount), ethutil.CurrencyToString(tx.Value))) + ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) + ui.txDb.Put(tx.Hash(), tx.RlpEncode()) + ui.eth.BlockManager.GetAddrState(ui.addr).Nonce += 1 - fmt.Println("Nonce", ui.eth.BlockManager.GetAddrState(ui.addr).Nonce) + unconfirmedFunds.Sub(unconfirmedFunds, tx.Value) } else if bytes.Compare(tx.Recipient, ui.addr) == 0 { - ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v (+ %v)", ethutil.CurrencyToString(account.Amount), ethutil.CurrencyToString(tx.Value))) + ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) + ui.txDb.Put(tx.Hash(), tx.RlpEncode()) + + unconfirmedFunds.Add(unconfirmedFunds, tx.Value) } + + pos := "+" + if unconfirmedFunds.Cmp(big.NewInt(0)) >= 0 { + pos = "-" + } + val := ethutil.CurrencyToString(new(big.Int).Abs(ethutil.BigCopy(unconfirmedFunds))) + str := fmt.Sprintf("%v (%s %v)", ethutil.CurrencyToString(account.Amount), pos, val) + + ui.win.Root().Call("setWalletValue", str) } else { + amount := account.Amount if bytes.Compare(tx.Sender(), ui.addr) == 0 { - amount := account.Amount.Sub(account.Amount, tx.Value) - ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(amount))) + amount.Sub(account.Amount, tx.Value) } else if bytes.Compare(tx.Recipient, ui.addr) == 0 { - amount := account.Amount.Sub(account.Amount, tx.Value) - ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(amount))) + amount.Add(account.Amount, tx.Value) } + + ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(amount))) } } diff --git a/wallet.qml b/wallet.qml index 04c1ffaed..8c91039fc 100644 --- a/wallet.qml +++ b/wallet.qml @@ -15,35 +15,6 @@ ApplicationWindow { title: "Ethereal" - toolBar: ToolBar { - id: mainToolbar - - RowLayout { - width: parent.width - Button { - text: "Send" - onClicked: { - console.log(eth.createTx(txReceiver.text, txAmount.text, codeView.text)) - } - } - - TextField { - id: txAmount - width: 200 - placeholderText: "Amount" - } - - TextField { - id: txReceiver - width: 300 - placeholderText: "Receiver Address (or empty for contract)" - Layout.fillWidth: true - } - - } - } - - MenuBar { Menu { title: "File" @@ -86,35 +57,61 @@ ApplicationWindow { property var blockModel: ListModel { id: blockModel } - function setView(view) { - mainView.visible = false - transactionView.visible = false - view.visible = true - } + + function setView(view) { + networkView.visible = false + historyView.visible = false + newTxView.visible = false + view.visible = true + //root.title = "Ethereal - " = view.title + } SplitView { anchors.fill: parent - + resizing: false Rectangle { id: menu - width: 200 + Layout.minimumWidth: 80 + Layout.maximumWidth: 80 anchors.bottom: parent.bottom anchors.top: parent.top - color: "#D9DDE7" + //color: "#D9DDE7" + color: "#252525" - GridLayout { - columns: 1 - Button { - text: "Main" - onClicked: { - setView(mainView) + ColumnLayout { + y: 50 + anchors.left: parent.left + anchors.right: parent.right + height: 200 + Image { + source: "tx.png" + anchors.horizontalCenter: parent.horizontalCenter + MouseArea { + anchors.fill: parent + onClicked: { + setView(historyView) + } } } - Button { - text: "Transactions" - onClicked: { - setView(transactionView) + Image { + source: "new.png" + anchors.horizontalCenter: parent.horizontalCenter + MouseArea { + anchors.fill: parent + onClicked: { + setView(newTxView) + } + } + } + Image { + source: "net.png" + anchors.horizontalCenter: parent.horizontalCenter + MouseArea { + anchors.fill: parent + onClicked: { + setView(networkView) + } } } } @@ -126,8 +123,8 @@ ApplicationWindow { } Rectangle { - id: transactionView - visible: false + id: historyView + property var title: "Transactions" anchors.right: parent.right anchors.left: menu.right anchors.bottom: parent.bottom @@ -135,40 +132,73 @@ ApplicationWindow { TableView { id: txTableView anchors.fill: parent - TableViewColumn{ role: "hash" ; title: "#" ; width: 150 } TableViewColumn{ role: "value" ; title: "Value" ; width: 100 } - TableViewColumn{ role: "address" ; title: "Address" ; } + TableViewColumn{ role: "address" ; title: "Address" ; width: 430 } model: txModel } } Rectangle { - id: mainView + id: newTxView + property var title: "New transaction" + visible: false anchors.right: parent.right + anchors.left: menu.right anchors.bottom: parent.bottom anchors.top: parent.top - SplitView { - id: splitView - height: 200 - anchors.top: parent.top - anchors.right: parent.right - anchors.left: parent.left + color: "#00000000" + ColumnLayout { + width: 400 + anchors.left: parent.left + anchors.top: parent.top + anchors.leftMargin: 5 + anchors.topMargin: 5 + TextField { + id: txAmount + width: 200 + placeholderText: "Amount" + } + + TextField { + id: txReceiver + placeholderText: "Receiver Address (or empty for contract)" + Layout.fillWidth: true + } + + Label { + text: "Transaction data" + } TextArea { id: codeView + anchors.topMargin: 5 + Layout.fillWidth: true width: parent.width /2 } - TextArea { - readOnly: true + Button { + text: "Send" + onClicked: { + console.log(eth.createTx(txReceiver.text, txAmount.text, codeView.text)) + } } } + } + + + Rectangle { + id: networkView + property var title: "Network" + visible: false + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.top: parent.top TableView { id: blockTable width: parent.width - anchors.top: splitView.bottom + anchors.top: parent.top anchors.bottom: logView.top TableViewColumn{ role: "number" ; title: "#" ; width: 100 } TableViewColumn{ role: "hash" ; title: "Hash" ; width: 560 } @@ -210,8 +240,13 @@ ApplicationWindow { RowLayout { anchors.fill: parent Button { + property var enabled: true id: connectButton - onClicked: ui.connect() + onClicked: { + if(this.enabled) { + ui.connect(this) + } + } text: "Connect" } Button { From 5e7f8cca4f83566fdfbd1eb76c8b565094958e6c Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 28 Feb 2014 12:17:02 +0100 Subject: [PATCH 191/459] Exit after importing a key --- ethereum.go | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/ethereum.go b/ethereum.go index 0b941dce3..336cd4d00 100644 --- a/ethereum.go +++ b/ethereum.go @@ -36,7 +36,8 @@ func CreateKeyPair(force bool) { data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) if len(data) == 0 || force { pub, prv := secp256k1.GenerateKeyPair() - addr := ethutil.Sha3Bin(pub[1:])[12:] + pair := ðutil.Key{PrivateKey: prv, PublicKey: pub} + ethutil.Config.Db.Put([]byte("KeyRing"), pair.RlpEncode()) fmt.Printf(` Generating new address and keypair. @@ -48,10 +49,8 @@ prvk: %x pubk: %x ++++++++++++++++++++++++++++++++++++++++++++ -`, addr, prv, pub) +`, pair.Address(), prv, pub) - keyRing := ethutil.NewValue([]interface{}{prv, addr, pub[1:]}) - ethutil.Config.Db.Put([]byte("KeyRing"), keyRing.Encode()) } } @@ -61,7 +60,8 @@ func ImportPrivateKey(prvKey string) { // Couldn't think of a better way to get the pub key sig, _ := secp256k1.Sign(msg, key) pub, _ := secp256k1.RecoverPubkey(msg, sig) - addr := ethutil.Sha3Bin(pub[1:])[12:] + pair := ðutil.Key{PrivateKey: key, PublicKey: pub} + ethutil.Config.Db.Put([]byte("KeyRing"), pair.RlpEncode()) fmt.Printf(` Importing private key @@ -72,10 +72,7 @@ prvk: %x pubk: %x ++++++++++++++++++++++++++++++++++++++++++++ -`, addr, key, pub) - - keyRing := ethutil.NewValue([]interface{}{key, addr, pub[1:]}) - ethutil.Config.Db.Put([]byte("KeyRing"), keyRing.Encode()) +`, pair.Address(), key, pub) } func main() { @@ -95,11 +92,11 @@ func main() { // Instantiated a eth stack ethereum, err := eth.New(eth.CapDefault, UseUPnP) - ethereum.Port = OutboundPort if err != nil { log.Println("eth start err:", err) return } + ethereum.Port = OutboundPort if GenAddr { fmt.Println("This action overwrites your old private key. Are you sure? (y/n)") @@ -133,6 +130,7 @@ func main() { if r == "y" { ImportPrivateKey(ImportKey) + os.Exit(0) } } else { CreateKeyPair(false) @@ -140,9 +138,8 @@ func main() { } if ExportKey { - data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) - keyRing := ethutil.NewValueFromBytes(data) - fmt.Printf("%x\n", keyRing.Get(0).Bytes()) + key := ethutil.Config.Db.GetKeys()[0] + fmt.Printf("%x\n", key.PrivateKey) os.Exit(0) } From 075acec9e709d3cda8a791cb0829720f5a1ae142 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 28 Feb 2014 12:17:26 +0100 Subject: [PATCH 192/459] Changed to new get keys method on database interface --- dev_console.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dev_console.go b/dev_console.go index 696493cdd..09e06aa22 100644 --- a/dev_console.go +++ b/dev_console.go @@ -179,13 +179,13 @@ func (i *Console) ParseInput(input string) bool { fmt.Println("recipient err:", err) } else { tx := ethchain.NewTransaction(recipient, ethutil.Big(tokens[2]), []string{""}) - data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) - keyRing := ethutil.NewValueFromBytes(data) - tx.Sign(keyRing.Get(0).Bytes()) - fmt.Printf("%x\n", tx.Hash()) - i.ethereum.TxPool.QueueTransaction(tx) - } + key := ethutil.Config.Db.GetKeys()[0] + tx.Sign(key.PrivateKey) + i.ethereum.TxPool.QueueTransaction(tx) + + fmt.Printf("%x\n", tx.Hash()) + } case "gettx": addr, _ := hex.DecodeString(tokens[1]) data, _ := ethutil.Config.Db.Get(addr) @@ -200,9 +200,9 @@ func (i *Console) ParseInput(input string) bool { code := ethchain.Compile(i.Editor()) contract := ethchain.NewTransaction(ethchain.ContractAddr, ethutil.Big(tokens[1]), code) - data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) - keyRing := ethutil.NewValueFromBytes(data) - contract.Sign(keyRing.Get(0).Bytes()) + + key := ethutil.Config.Db.GetKeys()[0] + contract.Sign(key.PrivateKey) i.ethereum.TxPool.QueueTransaction(contract) From 3a35d45ea84e055a4574a7a1d1b4b5485bea1331 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 28 Feb 2014 12:17:43 +0100 Subject: [PATCH 193/459] Updated readme --- README.md | 37 +++++++------------------------------ 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index e0d19b712..034b35f97 100644 --- a/README.md +++ b/README.md @@ -3,44 +3,18 @@ Ethereum [![Build Status](https://travis-ci.org/ethereum/go-ethereum.png?branch=master)](https://travis-ci.org/ethereum/go-ethereum) -Ethereum Go developer client (c) Jeffrey Wilcke +Ethereum Go Client (c) Jeffrey Wilcke -Ethereum is currently in its testing phase. The current state is "Proof -of Concept 2". For build instructions see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Edge). +The current state is "Proof of Concept 3". For build instructions see +the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Edge). -Ethereum Go is split up in several sub packages Please refer to each -individual package for more information. - 1. [eth](https://github.com/ethereum/eth-go) - 2. [ethchain](https://github.com/ethereum/eth-go/ethchain) - 3. [ethwire](https://github.com/ethereum/eth-go/ethwire) - 4. [ethdb](https://github.com/ethereum/eth-go/ethdb) - 5. [ethutil](https://github.com/ethereum/eth-go/ethutil) - -The [eth](https://github.com/ethereum/eth-go) is the top-level package -of the Ethereum protocol. It functions as the Ethereum bootstrapping and -peer communication layer. The [ethchain](https://github.com/ethereum/ethchain-go) -contains the Ethereum blockchain, block manager, transaction and -transaction handlers. The [ethwire](https://github.com/ethereum/ethwire-go) contains -the Ethereum [wire protocol](http://wiki.ethereum.org/index.php/Wire_Protocol) which can be used -to hook in to the Ethereum network. [ethutil](https://github.com/ethereum/ethutil-go) contains -utility functions which are not Ethereum specific. The utility package -contains the [patricia trie](http://wiki.ethereum.org/index.php/Patricia_Tree), -[RLP Encoding](http://wiki.ethereum.org/index.php/RLP) and hex encoding -helpers. The [ethdb](https://github.com/ethereum/ethdb-go) package -contains the LevelDB interface and memory DB interface. - -This executable is the front-end (currently nothing but a dev console) for -the Ethereum Go implementation. - -If you'd like to start developing your own tools please check out the -[development](https://github.com/ethereum/eth-go) package. +For the development Go Package please see [eth-go package](https://github.com/ethereum/eth-go). Build ======= For build instruction please see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Edge) - Command line options ==================== @@ -52,6 +26,9 @@ Command line options -upnp Enable UPnP (= false) -x Desired amount of peers (= 5) -h This help +-gui Launch with GUI (= true) +-dir Data directory used to store configs and databases (=".ethereum") +-import Import a private key (hex) ``` Developer console commands From 560a7073f457a32c9d053f1a4b20f76d949f519d Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 28 Feb 2014 12:18:19 +0100 Subject: [PATCH 194/459] Fixed connection button spamming --- ui/ui_lib.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ui/ui_lib.go b/ui/ui_lib.go index 93712eba2..c956fd032 100644 --- a/ui/ui_lib.go +++ b/ui/ui_lib.go @@ -27,9 +27,11 @@ func (ui *UiLib) Open(path string) { }() } -func (ui *UiLib) Connect() { +func (ui *UiLib) Connect(button qml.Object) { if !ui.connected { ui.eth.Start() + ui.connected = true + button.Set("enabled", false) } } From f6a9aa41101b6154ce5f019a77e6c897df662466 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 28 Feb 2014 13:08:41 +0100 Subject: [PATCH 195/459] fixed about window --- facet.png | Bin 0 -> 27302 bytes wallet.qml | 21 +++++++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 facet.png diff --git a/facet.png b/facet.png new file mode 100644 index 0000000000000000000000000000000000000000..49a266e96a6c0322cfa927698b10efd35b97fa05 GIT binary patch literal 27302 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 R{2>4=4K-cW!fRGf{|D(@9S8sb literal 0 HcmV?d00001 diff --git a/wallet.qml b/wallet.qml index 8c91039fc..e86551ad6 100644 --- a/wallet.qml +++ b/wallet.qml @@ -321,14 +321,27 @@ ApplicationWindow { id: aboutWin visible: false title: "About" - minimumWidth: 300 - maximumWidth: 300 + minimumWidth: 350 + maximumWidth: 350 maximumHeight: 200 minimumHeight: 200 + Image { + id: aboutIcon + height: 150 + width: 150 + fillMode: Image.PreserveAspectFit + smooth: true + source: "facet.png" + x: 10 + y: 10 + } + Text { - font.pointSize: 18 - text: "Eth Go" + anchors.left: aboutIcon.right + anchors.leftMargin: 10 + font.pointSize: 12 + text: "

Ethereum(Go)


Development

Jeffrey Wilcke

Binary Distribution

Jarrad Hope
" } } From aa7c53b7efacb35b23668f95df4349ff380b6910 Mon Sep 17 00:00:00 2001 From: Jarrad Hope Date: Fri, 28 Feb 2014 16:41:30 +0100 Subject: [PATCH 196/459] Search bin directory for qml --- ui/gui.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/ui/gui.go b/ui/gui.go index 556e682a9..389fe4f68 100644 --- a/ui/gui.go +++ b/ui/gui.go @@ -9,6 +9,8 @@ import ( "github.com/ethereum/eth-go/ethdb" "github.com/ethereum/eth-go/ethutil" "github.com/niemeyer/qml" + "bitbucket.org/kardianos/osext" + "path/filepath" "math/big" "strings" ) @@ -84,12 +86,16 @@ func (ui *Gui) Start() { ethutil.Config.Log.Infoln("[GUI] Starting GUI") // Create a new QML engine ui.engine = qml.NewEngine() + + // Get Binary Directory + exedir , _ := osext.ExecutableFolder() + // Load the main QML interface - component, err := ui.engine.LoadFile("wallet.qml") + component, err := ui.engine.LoadFile(filepath.Join(exedir, "wallet.qml")) if err != nil { panic(err) } - ui.engine.LoadFile("transactions.qml") + ui.engine.LoadFile(filepath.Join(exedir, "transactions.qml")) ui.win = component.CreateWindow(nil) From 59a68b316f18aadd916aec3255af3d7e81f5b05c Mon Sep 17 00:00:00 2001 From: Jeffrey Wilcke Date: Fri, 28 Feb 2014 17:02:24 +0100 Subject: [PATCH 197/459] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 034b35f97..f9f6ddbe6 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,7 @@ For the development Go Package please see [eth-go package](https://github.com/et Build ======= -For build instruction please see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Edge) - +For build instruction please see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum(Go) Command line options ==================== From 30c5922aa4c5d3e0bc730f2bf05b18be661c78b2 Mon Sep 17 00:00:00 2001 From: Jeffrey Wilcke Date: Fri, 28 Feb 2014 17:02:38 +0100 Subject: [PATCH 198/459] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f9f6ddbe6..11f5f9f96 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ For the development Go Package please see [eth-go package](https://github.com/et Build ======= -For build instruction please see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum(Go) +For build instruction please see the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum(Go)) Command line options ==================== From c6d6ca283d24f7860dfa185c95a3d7b4a90afc60 Mon Sep 17 00:00:00 2001 From: Jeffrey Wilcke Date: Fri, 28 Feb 2014 17:04:45 +0100 Subject: [PATCH 199/459] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 034b35f97..986c5e486 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,7 @@ Ethereum Ethereum Go Client (c) Jeffrey Wilcke -The current state is "Proof of Concept 3". For build instructions see -the [Wiki](https://github.com/ethereum/go-ethereum/wiki/Building-Edge). +The current state is "Proof of Concept 3". For the development Go Package please see [eth-go package](https://github.com/ethereum/eth-go). From b0be8474162bd3d12669600f4072c422089bc77a Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 3 Mar 2014 00:53:10 +0100 Subject: [PATCH 200/459] Updated to use the state on the blocks --- dev_console.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_console.go b/dev_console.go index 09e06aa22..5a69ffa9e 100644 --- a/dev_console.go +++ b/dev_console.go @@ -158,7 +158,7 @@ func (i *Console) ParseInput(input string) bool { fmt.Println(value) case "getaddr": encoded, _ := hex.DecodeString(tokens[1]) - addr := i.ethereum.BlockManager.BlockChain().CurrentBlock.GetAddr(encoded) + addr := i.ethereum.BlockManager.BlockChain().CurrentBlock.State().GetAccount(encoded) fmt.Println("addr:", addr) case "block": encoded, _ := hex.DecodeString(tokens[1]) From 00533003b7e5369260f63e65b88e2f08ab33350b Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 3 Mar 2014 00:53:24 +0100 Subject: [PATCH 201/459] Get rid of the xpm files --- net.pxm | Bin 95418 -> 0 bytes tx.pxm | Bin 93227 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 net.pxm delete mode 100644 tx.pxm diff --git a/net.pxm b/net.pxm deleted file mode 100644 index 20d45d08c652610fe5942b6156e047736e501e17..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 95418 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

xNm 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 diff --git a/tx.pxm b/tx.pxm deleted file mode 100644 index 881420da9670686061c113d6fb2c6f27c72ac1bb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 93227 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 From a482b0cc1b7ddbeae00988c7dd10391df01b0009 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 3 Mar 2014 00:54:05 +0100 Subject: [PATCH 202/459] WIP Makefile --- Makefile | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..4da4c551c --- /dev/null +++ b/Makefile @@ -0,0 +1,20 @@ +UNAME = $(shell uname) + +# Default is building +all: + go install + +install: +# Linux build +ifeq ($(UNAME),Linux) + mkdir /usr/local/ethereal + files=(wallet.qml net.png network.png new.png tx.png) + for file in "${files[@]}"; do + cp $file /usr/share/ethereal + done + cp $GOPATH/bin/go-ethereum /usr/local/bin/ethereal +endif +# OS X build +ifeq ($(UNAME),Darwin) + # Execute py script +endif From 3d2c3b0107d438dd081c57ef74036f4c5a03855f Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 3 Mar 2014 00:54:41 +0100 Subject: [PATCH 203/459] Using asset path helper (includes a debug path atm) --- ui/gui.go | 9 +-- ui/ui_lib.go | 27 +++++++ wallet.qml | 210 ++++++++++++++++++++++++++++++--------------------- 3 files changed, 153 insertions(+), 93 deletions(-) diff --git a/ui/gui.go b/ui/gui.go index 389fe4f68..196d2cd76 100644 --- a/ui/gui.go +++ b/ui/gui.go @@ -9,8 +9,6 @@ import ( "github.com/ethereum/eth-go/ethdb" "github.com/ethereum/eth-go/ethutil" "github.com/niemeyer/qml" - "bitbucket.org/kardianos/osext" - "path/filepath" "math/big" "strings" ) @@ -87,15 +85,12 @@ func (ui *Gui) Start() { // Create a new QML engine ui.engine = qml.NewEngine() - // Get Binary Directory - exedir , _ := osext.ExecutableFolder() - // Load the main QML interface - component, err := ui.engine.LoadFile(filepath.Join(exedir, "wallet.qml")) + component, err := ui.engine.LoadFile(AssetPath("wallet.qml")) if err != nil { panic(err) } - ui.engine.LoadFile(filepath.Join(exedir, "transactions.qml")) + ui.engine.LoadFile(AssetPath("transactions.qml")) ui.win = component.CreateWindow(nil) diff --git a/ui/ui_lib.go b/ui/ui_lib.go index c956fd032..2a1abee23 100644 --- a/ui/ui_lib.go +++ b/ui/ui_lib.go @@ -1,9 +1,13 @@ package ethui import ( + "bitbucket.org/kardianos/osext" "github.com/ethereum/eth-go" "github.com/ethereum/eth-go/ethutil" "github.com/niemeyer/qml" + "path" + "path/filepath" + "runtime" ) // UI Library that has some basic functionality exposed @@ -38,3 +42,26 @@ func (ui *UiLib) Connect(button qml.Object) { func (ui *UiLib) ConnectToPeer(addr string) { ui.eth.ConnectToPeer(addr) } + +func (ui *UiLib) AssetPath(p string) string { + return AssetPath(p) +} + +func AssetPath(p string) string { + var base string + switch runtime.GOOS { + case "darwin": + // Get Binary Directory + exedir, _ := osext.ExecutableFolder() + base = filepath.Join(exedir, "../Resources") + base = "/Users/jeffrey/go/src/github.com/ethereum/go-ethereum" + case "linux": + base = "/usr/share/ethereal" + case "window": + fallthrough + default: + base = "." + } + + return path.Join(base, p) +} diff --git a/wallet.qml b/wallet.qml index e86551ad6..39bc21f39 100644 --- a/wallet.qml +++ b/wallet.qml @@ -115,116 +115,141 @@ ApplicationWindow { } } } - - } - - property var txModel: ListModel { - id: txModel } Rectangle { - id: historyView - property var title: "Transactions" - anchors.right: parent.right - anchors.left: menu.right - anchors.bottom: parent.bottom - anchors.top: parent.top - TableView { - id: txTableView - anchors.fill: parent - TableViewColumn{ role: "value" ; title: "Value" ; width: 100 } - TableViewColumn{ role: "address" ; title: "Address" ; width: 430 } - - model: txModel - } - } - - Rectangle { - id: newTxView - property var title: "New transaction" - visible: false - anchors.right: parent.right - anchors.left: menu.right - anchors.bottom: parent.bottom - anchors.top: parent.top + id: mainView color: "#00000000" + anchors.right: parent.right + anchors.left: menu.right + anchors.bottom: parent.bottom + anchors.top: parent.top - ColumnLayout { - width: 400 - anchors.left: parent.left - anchors.top: parent.top - anchors.leftMargin: 5 - anchors.topMargin: 5 - TextField { - id: txAmount - width: 200 - placeholderText: "Amount" - } + property var txModel: ListModel { + id: txModel + } - TextField { - id: txReceiver - placeholderText: "Receiver Address (or empty for contract)" - Layout.fillWidth: true - } + Rectangle { + id: historyView + anchors.fill: parent - Label { - text: "Transaction data" + property var title: "Transactions" + TableView { + id: txTableView + anchors.fill: parent + TableViewColumn{ role: "value" ; title: "Value" ; width: 100 } + TableViewColumn{ role: "address" ; title: "Address" ; width: 430 } + + model: txModel } - TextArea { - id: codeView + } + + Rectangle { + id: newTxView + property var title: "New transaction" + visible: false + anchors.fill: parent + color: "#00000000" + + ColumnLayout { + width: 400 + anchors.left: parent.left + anchors.top: parent.top + anchors.leftMargin: 5 anchors.topMargin: 5 - Layout.fillWidth: true - width: parent.width /2 - } + TextField { + id: txAmount + width: 200 + placeholderText: "Amount" + } - Button { - text: "Send" - onClicked: { - console.log(eth.createTx(txReceiver.text, txAmount.text, codeView.text)) + TextField { + id: txReceiver + placeholderText: "Receiver Address (or empty for contract)" + Layout.fillWidth: true + } + + Label { + text: "Transaction data" + } + TextArea { + id: codeView + anchors.topMargin: 5 + Layout.fillWidth: true + width: parent.width /2 + } + + Button { + text: "Send" + onClicked: { + console.log(eth.createTx(txReceiver.text, txAmount.text, codeView.text)) + } } } } - } - Rectangle { - id: networkView - property var title: "Network" - visible: false - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.top: parent.top + Rectangle { + id: networkView + property var title: "Network" + visible: false + anchors.fill: parent - TableView { - id: blockTable - width: parent.width - anchors.top: parent.top - anchors.bottom: logView.top - TableViewColumn{ role: "number" ; title: "#" ; width: 100 } - TableViewColumn{ role: "hash" ; title: "Hash" ; width: 560 } + TableView { + id: blockTable + width: parent.width + anchors.top: parent.top + anchors.bottom: logView.top + TableViewColumn{ role: "number" ; title: "#" ; width: 100 } + TableViewColumn{ role: "hash" ; title: "Hash" ; width: 560 } - model: blockModel + model: blockModel - onDoubleClicked: { - popup.visible = true - popup.block = eth.getBlock(blockModel.get(row).hash) - popup.hashLabel.text = popup.block.hash + /* + onDoubleClicked: { + popup.visible = true + popup.block = eth.getBlock(blockModel.get(row).hash) + popup.hashLabel.text = popup.block.hash + } + */ + } + + property var logModel: ListModel { + id: logModel + } + + TableView { + id: logView + width: parent.width + height: 150 + anchors.bottom: parent.bottom + TableViewColumn{ role: "description" ; title: "log" } + + model: logModel } } - property var logModel: ListModel { - id: logModel + /* + signal addPlugin(string name) + Component { + id: pluginWindow + Rectangle { + anchors.fill: parent + Label { + id: pluginTitle + anchors.centerIn: parent + text: "Hello world" + } + Component.onCompleted: setView(this) + } } - TableView { - id: logView - width: parent.width - height: 150 - anchors.bottom: parent.bottom - TableViewColumn{ role: "description" ; title: "log" } - - model: logModel + onAddPlugin: { + var pluginWin = pluginWindow.createObject(mainView) + console.log(pluginWin) + pluginWin.pluginTitle.text = "Test" } + */ } } @@ -249,6 +274,7 @@ ApplicationWindow { } text: "Connect" } + Button { id: importAppButton anchors.left: connectButton.right @@ -304,6 +330,10 @@ ApplicationWindow { anchors.left: parent.left anchors.leftMargin: 10 placeholderText: "address:port" + onAccepted: { + ui.connectToPeer(addrField.text) + addPeerWin.visible = false + } } Button { anchors.left: addrField.right @@ -315,6 +345,9 @@ ApplicationWindow { addPeerWin.visible = false } } + Component.onCompleted: { + addrField.focus = true + } } Window { @@ -346,6 +379,11 @@ ApplicationWindow { } + function loadPlugin(name) { + console.log("Loading plugin" + name) + mainView.addPlugin(name) + } + function setWalletValue(value) { walletValueLabel.text = value } From 833a1a4eab01392b69339762cf8fe443697138a2 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 3 Mar 2014 11:32:58 +0100 Subject: [PATCH 204/459] Block mining log --- ethereum.go | 1 + 1 file changed, 1 insertion(+) diff --git a/ethereum.go b/ethereum.go index 336cd4d00..07a40b10f 100644 --- a/ethereum.go +++ b/ethereum.go @@ -186,6 +186,7 @@ func main() { txs := ethereum.TxPool.Flush() // Create a new block which we're going to mine block := ethereum.BlockManager.BlockChain().NewBlock(addr, txs) + log.Println("Mining on new block. Includes", len(block.Transactions()), "transactions") // Apply all transactions to the block ethereum.BlockManager.ApplyTransactions(block, block.Transactions()) From 827505985652ac164d1f670797396d0f46774fb2 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 5 Mar 2014 10:44:33 +0100 Subject: [PATCH 205/459] Moved qml files, conform to the new server model. QML files got moved to their own directories. QML now has a ui helper which should find assets in the correct resource directory --- ethereum.go | 15 ++++++----- test_app.qml => qml/test_app.qml | 0 transactions.qml => qml/transactions.qml | 0 wallet.qml => qml/wallet.qml | 10 +++---- ui/gui.go | 33 ++++++++++++------------ 5 files changed, 29 insertions(+), 29 deletions(-) rename test_app.qml => qml/test_app.qml (100%) rename transactions.qml => qml/transactions.qml (100%) rename wallet.qml => qml/wallet.qml (97%) diff --git a/ethereum.go b/ethereum.go index 07a40b10f..36cd75e47 100644 --- a/ethereum.go +++ b/ethereum.go @@ -144,7 +144,7 @@ func main() { } if ShowGenesis { - fmt.Println(ethereum.BlockManager.BlockChain().Genesis()) + fmt.Println(ethereum.BlockChain().Genesis()) os.Exit(0) } @@ -183,23 +183,24 @@ func main() { addr := keyRing.Get(1).Bytes() for { - txs := ethereum.TxPool.Flush() + txs := ethereum.TxPool().Flush() // Create a new block which we're going to mine - block := ethereum.BlockManager.BlockChain().NewBlock(addr, txs) + block := ethereum.BlockChain().NewBlock(addr, txs) log.Println("Mining on new block. Includes", len(block.Transactions()), "transactions") // Apply all transactions to the block - ethereum.BlockManager.ApplyTransactions(block, block.Transactions()) + ethereum.StateManager().ApplyTransactions(block, block.Transactions()) - ethereum.BlockManager.AccumelateRewards(block, block) + ethereum.StateManager().AccumelateRewards(block, block) // Search the nonce block.Nonce = pow.Search(block) ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{block.Value().Val}) - err := ethereum.BlockManager.ProcessBlock(block) + err := ethereum.StateManager().ProcessBlock(block) if err != nil { log.Println(err) } else { - log.Println("\n+++++++ MINED BLK +++++++\n", ethereum.BlockManager.BlockChain().CurrentBlock) + //log.Println("\n+++++++ MINED BLK +++++++\n", ethereum.BlockChain().CurrentBlock) + log.Printf("🔨 Mined block %x\n", block.Hash()) } } }() diff --git a/test_app.qml b/qml/test_app.qml similarity index 100% rename from test_app.qml rename to qml/test_app.qml diff --git a/transactions.qml b/qml/transactions.qml similarity index 100% rename from transactions.qml rename to qml/transactions.qml diff --git a/wallet.qml b/qml/wallet.qml similarity index 97% rename from wallet.qml rename to qml/wallet.qml index 39bc21f39..7fc7f5447 100644 --- a/wallet.qml +++ b/qml/wallet.qml @@ -85,7 +85,7 @@ ApplicationWindow { anchors.right: parent.right height: 200 Image { - source: "tx.png" + source: ui.assetPath("tx.png") anchors.horizontalCenter: parent.horizontalCenter MouseArea { anchors.fill: parent @@ -95,7 +95,7 @@ ApplicationWindow { } } Image { - source: "new.png" + source: ui.assetPath("new.png") anchors.horizontalCenter: parent.horizontalCenter MouseArea { anchors.fill: parent @@ -105,7 +105,7 @@ ApplicationWindow { } } Image { - source: "net.png" + source: ui.assetPath("net.png") anchors.horizontalCenter: parent.horizontalCenter MouseArea { anchors.fill: parent @@ -300,7 +300,7 @@ ApplicationWindow { id: peerImage anchors.right: parent.right width: 10; height: 10 - source: "network.png" + source: ui.assetPath("network.png") } } } @@ -365,7 +365,7 @@ ApplicationWindow { width: 150 fillMode: Image.PreserveAspectFit smooth: true - source: "facet.png" + source: ui.assetPath("facet.png") x: 10 y: 10 } diff --git a/ui/gui.go b/ui/gui.go index 196d2cd76..fa65ea4f6 100644 --- a/ui/gui.go +++ b/ui/gui.go @@ -57,7 +57,7 @@ type Gui struct { // Create GUI, but doesn't start it func New(ethereum *eth.Ethereum) *Gui { - lib := &EthLib{blockManager: ethereum.BlockManager, blockChain: ethereum.BlockManager.BlockChain(), txPool: ethereum.TxPool} + lib := &EthLib{blockManager: ethereum.StateManager(), blockChain: ethereum.BlockChain(), txPool: ethereum.TxPool()} db, err := ethdb.NewLDBDatabase("tx_database") if err != nil { panic(err) @@ -66,7 +66,7 @@ func New(ethereum *eth.Ethereum) *Gui { key := ethutil.Config.Db.GetKeys()[0] addr := key.Address() - ethereum.BlockManager.WatchAddr(addr) + ethereum.StateManager().WatchAddr(addr) return &Gui{eth: ethereum, lib: lib, txDb: db, addr: addr} } @@ -84,24 +84,23 @@ func (ui *Gui) Start() { ethutil.Config.Log.Infoln("[GUI] Starting GUI") // Create a new QML engine ui.engine = qml.NewEngine() - - // Load the main QML interface - component, err := ui.engine.LoadFile(AssetPath("wallet.qml")) - if err != nil { - panic(err) - } - ui.engine.LoadFile(AssetPath("transactions.qml")) - - ui.win = component.CreateWindow(nil) - context := ui.engine.Context() // Expose the eth library and the ui library to QML context.SetVar("eth", ui.lib) context.SetVar("ui", &UiLib{engine: ui.engine, eth: ui.eth}) + // Load the main QML interface + component, err := ui.engine.LoadFile(AssetPath("qml/wallet.qml")) + if err != nil { + panic(err) + } + ui.engine.LoadFile(AssetPath("qml/transactions.qml")) + + ui.win = component.CreateWindow(nil) + // Register the ui as a block processor - ui.eth.BlockManager.SecondaryBlockProcessor = ui + //ui.eth.BlockManager.SecondaryBlockProcessor = ui //ui.eth.TxPool.SecondaryProcessor = ui // Add the ui as a log system so we can log directly to the UGI @@ -120,7 +119,7 @@ func (ui *Gui) Start() { func (ui *Gui) setInitialBlockChain() { // Load previous 10 blocks - chain := ui.eth.BlockManager.BlockChain().GetChain(ui.eth.BlockManager.BlockChain().CurrentBlock.Hash(), 10) + chain := ui.eth.BlockChain().GetChain(ui.eth.BlockChain().CurrentBlock.Hash(), 10) for _, block := range chain { ui.ProcessBlock(block) } @@ -144,9 +143,9 @@ func (ui *Gui) ProcessBlock(block *ethchain.Block) { // Simple go routine function that updates the list of peers in the GUI func (ui *Gui) update() { txChan := make(chan ethchain.TxMsg, 1) - ui.eth.TxPool.Subscribe(txChan) + ui.eth.TxPool().Subscribe(txChan) - account := ui.eth.BlockManager.GetAddrState(ui.addr).Account + account := ui.eth.StateManager().GetAddrState(ui.addr).Account unconfirmedFunds := new(big.Int) ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(account.Amount))) for { @@ -159,7 +158,7 @@ func (ui *Gui) update() { ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) ui.txDb.Put(tx.Hash(), tx.RlpEncode()) - ui.eth.BlockManager.GetAddrState(ui.addr).Nonce += 1 + ui.eth.StateManager().GetAddrState(ui.addr).Nonce += 1 unconfirmedFunds.Sub(unconfirmedFunds, tx.Value) } else if bytes.Compare(tx.Recipient, ui.addr) == 0 { ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) From f7fb5b902c8b216c835c10fc4676b7b08fb90d04 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 5 Mar 2014 10:44:43 +0100 Subject: [PATCH 206/459] Conform to the new server model --- dev_console.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dev_console.go b/dev_console.go index 5a69ffa9e..ead4b55e5 100644 --- a/dev_console.go +++ b/dev_console.go @@ -158,11 +158,11 @@ func (i *Console) ParseInput(input string) bool { fmt.Println(value) case "getaddr": encoded, _ := hex.DecodeString(tokens[1]) - addr := i.ethereum.BlockManager.BlockChain().CurrentBlock.State().GetAccount(encoded) + addr := i.ethereum.BlockChain().CurrentBlock.State().GetAccount(encoded) fmt.Println("addr:", addr) case "block": encoded, _ := hex.DecodeString(tokens[1]) - block := i.ethereum.BlockManager.BlockChain().GetBlock(encoded) + block := i.ethereum.BlockChain().GetBlock(encoded) info := block.BlockInfo() fmt.Printf("++++++++++ #%d ++++++++++\n%v\n", info.Number, block) case "say": @@ -182,7 +182,7 @@ func (i *Console) ParseInput(input string) bool { key := ethutil.Config.Db.GetKeys()[0] tx.Sign(key.PrivateKey) - i.ethereum.TxPool.QueueTransaction(tx) + i.ethereum.TxPool().QueueTransaction(tx) fmt.Printf("%x\n", tx.Hash()) } @@ -204,7 +204,7 @@ func (i *Console) ParseInput(input string) bool { key := ethutil.Config.Db.GetKeys()[0] contract.Sign(key.PrivateKey) - i.ethereum.TxPool.QueueTransaction(contract) + i.ethereum.TxPool().QueueTransaction(contract) fmt.Printf("%x\n", contract.Hash()[12:]) case "exit", "quit", "q": From fbd53f0e34b636074941f5ea7b151bf173c5ed17 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 5 Mar 2014 10:57:14 +0100 Subject: [PATCH 207/459] Renamed block manager to state manager --- ui/gui.go | 2 +- ui/library.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/gui.go b/ui/gui.go index fa65ea4f6..5f0b6e52d 100644 --- a/ui/gui.go +++ b/ui/gui.go @@ -57,7 +57,7 @@ type Gui struct { // Create GUI, but doesn't start it func New(ethereum *eth.Ethereum) *Gui { - lib := &EthLib{blockManager: ethereum.StateManager(), blockChain: ethereum.BlockChain(), txPool: ethereum.TxPool()} + lib := &EthLib{stateManager: ethereum.StateManager(), blockChain: ethereum.BlockChain(), txPool: ethereum.TxPool()} db, err := ethdb.NewLDBDatabase("tx_database") if err != nil { panic(err) diff --git a/ui/library.go b/ui/library.go index 3bbb01314..8dda0a89e 100644 --- a/ui/library.go +++ b/ui/library.go @@ -9,7 +9,7 @@ import ( ) type EthLib struct { - blockManager *ethchain.BlockManager + stateManager *ethchain.StateManager blockChain *ethchain.BlockChain txPool *ethchain.TxPool } @@ -32,7 +32,7 @@ func (lib *EthLib) CreateTx(receiver, a, data string) string { amount := ethutil.Big(a) code := ethchain.Compile(strings.Split(data, "\n")) tx := ethchain.NewTransaction(hash, amount, code) - tx.Nonce = lib.blockManager.GetAddrState(keyRing.Get(1).Bytes()).Nonce + tx.Nonce = lib.stateManager.GetAddrState(keyRing.Get(1).Bytes()).Nonce tx.Sign(keyRing.Get(0).Bytes()) From 96fcc1da323ae37489721f58d04f6ebf1c14ff91 Mon Sep 17 00:00:00 2001 From: Maran Date: Mon, 10 Mar 2014 11:53:31 +0100 Subject: [PATCH 208/459] Initial smart-miner stuff --- ethereum.go | 87 ++++++++++++++++++++++++++++++++++++++++++---------- ui/ui_lib.go | 2 +- 2 files changed, 72 insertions(+), 17 deletions(-) diff --git a/ethereum.go b/ethereum.go index 36cd75e47..ed14a7feb 100644 --- a/ethereum.go +++ b/ethereum.go @@ -1,6 +1,7 @@ package main import ( + "bytes" "fmt" "github.com/ethereum/eth-go" "github.com/ethereum/eth-go/ethchain" @@ -172,6 +173,16 @@ func main() { RegisterInterupts(ethereum) ethereum.Start() + minerChan := make(chan ethutil.React, 5) + ethereum.Reactor().Subscribe("newBlock", minerChan) + ethereum.Reactor().Subscribe("newTx", minerChan) + + minerChan2 := make(chan ethutil.React, 5) + ethereum.Reactor().Subscribe("newBlock", minerChan2) + ethereum.Reactor().Subscribe("newTx", minerChan2) + + ethereum.StateManager().PrepareMiningState() + if StartMining { log.Printf("Miner started\n") @@ -181,26 +192,70 @@ func main() { data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) keyRing := ethutil.NewValueFromBytes(data) addr := keyRing.Get(1).Bytes() + txs := ethereum.TxPool().Flush() + block := ethereum.BlockChain().NewBlock(addr, txs) for { - txs := ethereum.TxPool().Flush() - // Create a new block which we're going to mine - block := ethereum.BlockChain().NewBlock(addr, txs) - log.Println("Mining on new block. Includes", len(block.Transactions()), "transactions") - // Apply all transactions to the block - ethereum.StateManager().ApplyTransactions(block, block.Transactions()) + select { + case chanMessage := <-minerChan: + log.Println("REACTOR: Got new block") - ethereum.StateManager().AccumelateRewards(block, block) + if block, ok := chanMessage.Resource.(*ethchain.Block); ok { + if bytes.Compare(ethereum.BlockChain().CurrentBlock.Hash(), block.Hash()) == 0 { + // TODO: Perhaps continue mining to get some uncle rewards + log.Println("New top block found resetting state") + // Reapplies the latest block to the mining state, thus resetting + ethereum.StateManager().PrepareMiningState() + block = ethereum.BlockChain().NewBlock(addr, txs) + log.Println("Block set") + } else { + if bytes.Compare(block.PrevHash, ethereum.BlockChain().CurrentBlock.PrevHash) == 0 { + log.Println("HELLO UNCLE") + // TODO: Add uncle to block + } + } + } - // Search the nonce - block.Nonce = pow.Search(block) - ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{block.Value().Val}) - err := ethereum.StateManager().ProcessBlock(block) - if err != nil { - log.Println(err) - } else { - //log.Println("\n+++++++ MINED BLK +++++++\n", ethereum.BlockChain().CurrentBlock) - log.Printf("🔨 Mined block %x\n", block.Hash()) + if tx, ok := chanMessage.Resource.(*ethchain.Transaction); ok { + log.Println("REACTOR: Got new transaction", tx) + found := false + for _, ctx := range txs { + if found = bytes.Compare(ctx.Hash(), tx.Hash()) == 0; found { + break + } + + } + if found == false { + log.Println("We did not know about this transaction, adding") + txs = append(txs, tx) + } else { + log.Println("We already had this transaction, ignoring") + } + } + log.Println("Sending block reset") + // Start mining over + log.Println("Block reset done") + default: + // Create a new block which we're going to mine + log.Println("Mining on block. Includes", len(txs), "transactions") + + // Apply all transactions to the block + ethereum.StateManager().ApplyTransactions(block, txs) + ethereum.StateManager().AccumelateRewards(block, block) + + // Search the nonce + block.Nonce = pow.Search(block, minerChan2) + if block.Nonce != nil { + ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{block.Value().Val}) + err := ethereum.StateManager().ProcessBlock(block) + if err != nil { + log.Println(err) + } else { + //log.Println("\n+++++++ MINED BLK +++++++\n", ethereum.BlockChain().CurrentBlock) + log.Printf("🔨 Mined block %x\n", block.Hash()) + block = ethereum.BlockChain().NewBlock(addr, txs) + } + } } } }() diff --git a/ui/ui_lib.go b/ui/ui_lib.go index 2a1abee23..fb5957cc3 100644 --- a/ui/ui_lib.go +++ b/ui/ui_lib.go @@ -54,7 +54,7 @@ func AssetPath(p string) string { // Get Binary Directory exedir, _ := osext.ExecutableFolder() base = filepath.Join(exedir, "../Resources") - base = "/Users/jeffrey/go/src/github.com/ethereum/go-ethereum" + base = "/Users/maranhidskes/projects/go/src/github.com/ethereum/go-ethereum" case "linux": base = "/usr/share/ethereal" case "window": From 1c983ed80cc71e7451c7223bae7e30fc41e07b20 Mon Sep 17 00:00:00 2001 From: Maran Date: Tue, 11 Mar 2014 15:17:23 +0100 Subject: [PATCH 209/459] More mining stuff --- ethereum.go | 16 +++++++++++----- ui/library.go | 1 + 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/ethereum.go b/ethereum.go index ed14a7feb..4d1a74ed1 100644 --- a/ethereum.go +++ b/ethereum.go @@ -173,11 +173,11 @@ func main() { RegisterInterupts(ethereum) ethereum.Start() - minerChan := make(chan ethutil.React, 5) + minerChan := make(chan ethutil.React, 1) ethereum.Reactor().Subscribe("newBlock", minerChan) ethereum.Reactor().Subscribe("newTx", minerChan) - minerChan2 := make(chan ethutil.React, 5) + minerChan2 := make(chan ethutil.React, 1) ethereum.Reactor().Subscribe("newBlock", minerChan2) ethereum.Reactor().Subscribe("newTx", minerChan2) @@ -186,7 +186,6 @@ func main() { if StartMining { log.Printf("Miner started\n") - // Fake block mining. It broadcasts a new block every 5 seconds go func() { pow := ðchain.EasyPow{} data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) @@ -194,6 +193,7 @@ func main() { addr := keyRing.Get(1).Bytes() txs := ethereum.TxPool().Flush() block := ethereum.BlockChain().NewBlock(addr, txs) + var uncles []*ethchain.Block for { select { @@ -204,6 +204,7 @@ func main() { if bytes.Compare(ethereum.BlockChain().CurrentBlock.Hash(), block.Hash()) == 0 { // TODO: Perhaps continue mining to get some uncle rewards log.Println("New top block found resetting state") + // TODO: We probably want to skip this if it's our own block // Reapplies the latest block to the mining state, thus resetting ethereum.StateManager().PrepareMiningState() block = ethereum.BlockChain().NewBlock(addr, txs) @@ -212,6 +213,7 @@ func main() { if bytes.Compare(block.PrevHash, ethereum.BlockChain().CurrentBlock.PrevHash) == 0 { log.Println("HELLO UNCLE") // TODO: Add uncle to block + uncles = append(uncles, block) } } } @@ -227,7 +229,7 @@ func main() { } if found == false { log.Println("We did not know about this transaction, adding") - txs = append(txs, tx) + txs = ethereum.TxPool().Flush() } else { log.Println("We already had this transaction, ignoring") } @@ -239,6 +241,11 @@ func main() { // Create a new block which we're going to mine log.Println("Mining on block. Includes", len(txs), "transactions") + // Apply uncles + if len(uncles) > 0 { + block.SetUncles(uncles) + } + // Apply all transactions to the block ethereum.StateManager().ApplyTransactions(block, txs) ethereum.StateManager().AccumelateRewards(block, block) @@ -253,7 +260,6 @@ func main() { } else { //log.Println("\n+++++++ MINED BLK +++++++\n", ethereum.BlockChain().CurrentBlock) log.Printf("🔨 Mined block %x\n", block.Hash()) - block = ethereum.BlockChain().NewBlock(addr, txs) } } } diff --git a/ui/library.go b/ui/library.go index 8dda0a89e..8412a8d6c 100644 --- a/ui/library.go +++ b/ui/library.go @@ -35,6 +35,7 @@ func (lib *EthLib) CreateTx(receiver, a, data string) string { tx.Nonce = lib.stateManager.GetAddrState(keyRing.Get(1).Bytes()).Nonce tx.Sign(keyRing.Get(0).Bytes()) + ethutil.Config.Log.Infof("nonce: %x", tx.Nonce) lib.txPool.QueueTransaction(tx) From 13e18e1d8f717ffab1b59a39cf67ef169a542e74 Mon Sep 17 00:00:00 2001 From: Cayman Nava Date: Sat, 15 Mar 2014 16:46:10 -0700 Subject: [PATCH 210/459] working linux makefile when building develop branch, checkout of eth-go develop branch is required --- Makefile | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 4da4c551c..709c416db 100644 --- a/Makefile +++ b/Makefile @@ -1,18 +1,23 @@ UNAME = $(shell uname) +FILES=qml *.png +GOPATH=$(PWD) + # Default is building all: - go install + go get -d + cp *.go $(GOPATH)/src/github.com/ethereum/go-ethereum + cp -r ui $(GOPATH)/src/github.com/ethereum/go-ethereum + go build install: # Linux build ifeq ($(UNAME),Linux) - mkdir /usr/local/ethereal - files=(wallet.qml net.png network.png new.png tx.png) - for file in "${files[@]}"; do - cp $file /usr/share/ethereal + mkdir -p /usr/share/ethereal + for file in $(FILES); do \ + cp -r $$file /usr/share/ethereal; \ done - cp $GOPATH/bin/go-ethereum /usr/local/bin/ethereal + cp go-ethereum /usr/local/bin/ethereal endif # OS X build ifeq ($(UNAME),Darwin) From 85e04476845a5a41836824b133d939faf4e1c3fa Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 16 Mar 2014 18:34:34 +0100 Subject: [PATCH 211/459] Fixed asset path error. Fixes #29 --- ui/ui_lib.go | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/ui/ui_lib.go b/ui/ui_lib.go index 2a1abee23..83e8bf2d1 100644 --- a/ui/ui_lib.go +++ b/ui/ui_lib.go @@ -5,6 +5,7 @@ import ( "github.com/ethereum/eth-go" "github.com/ethereum/eth-go/ethutil" "github.com/niemeyer/qml" + "os" "path" "path/filepath" "runtime" @@ -49,18 +50,26 @@ func (ui *UiLib) AssetPath(p string) string { func AssetPath(p string) string { var base string - switch runtime.GOOS { - case "darwin": - // Get Binary Directory - exedir, _ := osext.ExecutableFolder() - base = filepath.Join(exedir, "../Resources") - base = "/Users/jeffrey/go/src/github.com/ethereum/go-ethereum" - case "linux": - base = "/usr/share/ethereal" - case "window": - fallthrough - default: - base = "." + + // If the current working directory is the go-ethereum dir + // assume a debug build and use the source directory as + // asset directory. + pwd, _ := os.Getwd() + if pwd == path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum") { + base = pwd + } else { + switch runtime.GOOS { + case "darwin": + // Get Binary Directory + exedir, _ := osext.ExecutableFolder() + base = filepath.Join(exedir, "../Resources") + case "linux": + base = "/usr/share/ethereal" + case "window": + fallthrough + default: + base = "." + } } return path.Join(base, p) From 3002570085c6823da4b8e12015eafa4bd87177fb Mon Sep 17 00:00:00 2001 From: Maran Date: Thu, 20 Mar 2014 11:20:10 +0100 Subject: [PATCH 212/459] Mining rework --- ethereum.go | 87 ++------------------------------------------------- ui/library.go | 7 +++-- 2 files changed, 7 insertions(+), 87 deletions(-) diff --git a/ethereum.go b/ethereum.go index 4d1a74ed1..556a33851 100644 --- a/ethereum.go +++ b/ethereum.go @@ -1,12 +1,11 @@ package main import ( - "bytes" "fmt" "github.com/ethereum/eth-go" "github.com/ethereum/eth-go/ethchain" + "github.com/ethereum/eth-go/ethminer" "github.com/ethereum/eth-go/ethutil" - "github.com/ethereum/eth-go/ethwire" "github.com/ethereum/go-ethereum/ui" "github.com/niemeyer/qml" "github.com/obscuren/secp256k1-go" @@ -173,97 +172,17 @@ func main() { RegisterInterupts(ethereum) ethereum.Start() - minerChan := make(chan ethutil.React, 1) - ethereum.Reactor().Subscribe("newBlock", minerChan) - ethereum.Reactor().Subscribe("newTx", minerChan) - - minerChan2 := make(chan ethutil.React, 1) - ethereum.Reactor().Subscribe("newBlock", minerChan2) - ethereum.Reactor().Subscribe("newTx", minerChan2) - - ethereum.StateManager().PrepareMiningState() - if StartMining { log.Printf("Miner started\n") go func() { - pow := ðchain.EasyPow{} data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) keyRing := ethutil.NewValueFromBytes(data) addr := keyRing.Get(1).Bytes() - txs := ethereum.TxPool().Flush() - block := ethereum.BlockChain().NewBlock(addr, txs) - var uncles []*ethchain.Block - for { - select { - case chanMessage := <-minerChan: - log.Println("REACTOR: Got new block") + miner := ethminer.NewDefaultMiner(addr, ethereum) + miner.Start() - if block, ok := chanMessage.Resource.(*ethchain.Block); ok { - if bytes.Compare(ethereum.BlockChain().CurrentBlock.Hash(), block.Hash()) == 0 { - // TODO: Perhaps continue mining to get some uncle rewards - log.Println("New top block found resetting state") - // TODO: We probably want to skip this if it's our own block - // Reapplies the latest block to the mining state, thus resetting - ethereum.StateManager().PrepareMiningState() - block = ethereum.BlockChain().NewBlock(addr, txs) - log.Println("Block set") - } else { - if bytes.Compare(block.PrevHash, ethereum.BlockChain().CurrentBlock.PrevHash) == 0 { - log.Println("HELLO UNCLE") - // TODO: Add uncle to block - uncles = append(uncles, block) - } - } - } - - if tx, ok := chanMessage.Resource.(*ethchain.Transaction); ok { - log.Println("REACTOR: Got new transaction", tx) - found := false - for _, ctx := range txs { - if found = bytes.Compare(ctx.Hash(), tx.Hash()) == 0; found { - break - } - - } - if found == false { - log.Println("We did not know about this transaction, adding") - txs = ethereum.TxPool().Flush() - } else { - log.Println("We already had this transaction, ignoring") - } - } - log.Println("Sending block reset") - // Start mining over - log.Println("Block reset done") - default: - // Create a new block which we're going to mine - log.Println("Mining on block. Includes", len(txs), "transactions") - - // Apply uncles - if len(uncles) > 0 { - block.SetUncles(uncles) - } - - // Apply all transactions to the block - ethereum.StateManager().ApplyTransactions(block, txs) - ethereum.StateManager().AccumelateRewards(block, block) - - // Search the nonce - block.Nonce = pow.Search(block, minerChan2) - if block.Nonce != nil { - ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{block.Value().Val}) - err := ethereum.StateManager().ProcessBlock(block) - if err != nil { - log.Println(err) - } else { - //log.Println("\n+++++++ MINED BLK +++++++\n", ethereum.BlockChain().CurrentBlock) - log.Printf("🔨 Mined block %x\n", block.Hash()) - } - } - } - } }() } diff --git a/ui/library.go b/ui/library.go index 8412a8d6c..d6ce94b75 100644 --- a/ui/library.go +++ b/ui/library.go @@ -27,14 +27,15 @@ func (lib *EthLib) CreateTx(receiver, a, data string) string { } k, _ := ethutil.Config.Db.Get([]byte("KeyRing")) - keyRing := ethutil.NewValueFromBytes(k) + keyPair := ethutil.NewKeyFromBytes(k) amount := ethutil.Big(a) code := ethchain.Compile(strings.Split(data, "\n")) tx := ethchain.NewTransaction(hash, amount, code) - tx.Nonce = lib.stateManager.GetAddrState(keyRing.Get(1).Bytes()).Nonce + tx.Nonce = lib.stateManager.GetAddrState(keyPair.Address()).Nonce + + tx.Sign(keyPair.PrivateKey) - tx.Sign(keyRing.Get(0).Bytes()) ethutil.Config.Log.Infof("nonce: %x", tx.Nonce) lib.txPool.QueueTransaction(tx) From 0db86e4485176aff7c45f0ce673174ec8407c0fc Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 21 Mar 2014 11:16:41 +0100 Subject: [PATCH 213/459] Updated to work with the new chain --- Makefile | 5 +++-- ethereum.go | 7 +++++-- ui/gui.go | 1 + ui/library.go | 6 +++--- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 4da4c551c..02d127963 100644 --- a/Makefile +++ b/Makefile @@ -7,11 +7,12 @@ all: install: # Linux build ifeq ($(UNAME),Linux) - mkdir /usr/local/ethereal - files=(wallet.qml net.png network.png new.png tx.png) + mkdir -p /usr/local/ethereal + files=(net.png network.png new.png tx.png) for file in "${files[@]}"; do cp $file /usr/share/ethereal done + cp -r qml /usr/share/ethereal/qml cp $GOPATH/bin/go-ethereum /usr/local/bin/ethereal endif # OS X build diff --git a/ethereum.go b/ethereum.go index 36cd75e47..ac1de5af4 100644 --- a/ethereum.go +++ b/ethereum.go @@ -190,16 +190,19 @@ func main() { // Apply all transactions to the block ethereum.StateManager().ApplyTransactions(block, block.Transactions()) - ethereum.StateManager().AccumelateRewards(block, block) + ethereum.StateManager().Prepare(block.State(), block.State()) + ethereum.StateManager().AccumelateRewards(block) // Search the nonce block.Nonce = pow.Search(block) ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{block.Value().Val}) + + ethereum.StateManager().PrepareDefault(block) err := ethereum.StateManager().ProcessBlock(block) if err != nil { log.Println(err) } else { - //log.Println("\n+++++++ MINED BLK +++++++\n", ethereum.BlockChain().CurrentBlock) + log.Println("\n+++++++ MINED BLK +++++++\n", ethereum.BlockChain().CurrentBlock) log.Printf("🔨 Mined block %x\n", block.Hash()) } } diff --git a/ui/gui.go b/ui/gui.go index 5f0b6e52d..c8f4bedab 100644 --- a/ui/gui.go +++ b/ui/gui.go @@ -81,6 +81,7 @@ func (ui *Gui) Start() { Init: func(p *Tx, obj qml.Object) { p.Value = ""; p.Hash = ""; p.Address = "" }, }}) + ethutil.Config.SetClientString(fmt.Sprintf("/Ethereal v%s", "0.1")) ethutil.Config.Log.Infoln("[GUI] Starting GUI") // Create a new QML engine ui.engine = qml.NewEngine() diff --git a/ui/library.go b/ui/library.go index 8dda0a89e..05fffd579 100644 --- a/ui/library.go +++ b/ui/library.go @@ -27,14 +27,14 @@ func (lib *EthLib) CreateTx(receiver, a, data string) string { } k, _ := ethutil.Config.Db.Get([]byte("KeyRing")) - keyRing := ethutil.NewValueFromBytes(k) + keyPair := ethutil.NewKeyFromBytes(k) amount := ethutil.Big(a) code := ethchain.Compile(strings.Split(data, "\n")) tx := ethchain.NewTransaction(hash, amount, code) - tx.Nonce = lib.stateManager.GetAddrState(keyRing.Get(1).Bytes()).Nonce + tx.Nonce = lib.stateManager.GetAddrState(keyPair.Address()).Nonce - tx.Sign(keyRing.Get(0).Bytes()) + tx.Sign(keyPair.PrivateKey) lib.txPool.QueueTransaction(tx) From 22b4e9b6173437b28045d69e8fd0b468e526e559 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 22 Mar 2014 00:35:53 +0100 Subject: [PATCH 214/459] . --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cd9286659..a29bfb6d3 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Ethereum Ethereum Go Client (c) Jeffrey Wilcke -The current state is "Proof of Concept 3". +The current state is "Proof of Concept 3.5". For the development Go Package please see [eth-go package](https://github.com/ethereum/eth-go). From 1f2547b8a7cfe100f64428d20f4bcf95eb9ecc5c Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 22 Mar 2014 01:02:24 +0100 Subject: [PATCH 215/459] Major re-organisation. The Ethereum node and Gui are now separated. --- Makefile => ethereal/Makefile | 0 facet.png => ethereal/assets/facet.png | Bin net.png => ethereal/assets/net.png | Bin network.png => ethereal/assets/network.png | Bin new.png => ethereal/assets/new.png | Bin {qml => ethereal/assets/qml}/test_app.qml | 0 {qml => ethereal/assets/qml}/transactions.qml | 0 {qml => ethereal/assets/qml}/wallet.qml | 0 tx.png => ethereal/assets/tx.png | Bin ethereal/config.go | 34 +++ ethereal/ethereum.go | 110 +++++++++ {ui => ethereal/ui}/gui.go | 0 {ui => ethereal/ui}/library.go | 0 {ui => ethereal/ui}/ui_lib.go | 4 +- ethereum.go | 215 ------------------ config.go => node/config.go | 5 +- dev_console.go => node/dev_console.go | 0 node/ethereum.go | 158 +++++++++++++ node/node | Bin 0 -> 8154988 bytes test_runner.go | 35 --- test_runner_test.go | 36 --- testing.go | 33 --- utils/keys.go | 50 ++++ 23 files changed, 357 insertions(+), 323 deletions(-) rename Makefile => ethereal/Makefile (100%) rename facet.png => ethereal/assets/facet.png (100%) rename net.png => ethereal/assets/net.png (100%) rename network.png => ethereal/assets/network.png (100%) rename new.png => ethereal/assets/new.png (100%) rename {qml => ethereal/assets/qml}/test_app.qml (100%) rename {qml => ethereal/assets/qml}/transactions.qml (100%) rename {qml => ethereal/assets/qml}/wallet.qml (100%) rename tx.png => ethereal/assets/tx.png (100%) create mode 100644 ethereal/config.go create mode 100644 ethereal/ethereum.go rename {ui => ethereal/ui}/gui.go (100%) rename {ui => ethereal/ui}/library.go (100%) rename {ui => ethereal/ui}/ui_lib.go (95%) delete mode 100644 ethereum.go rename config.go => node/config.go (93%) rename dev_console.go => node/dev_console.go (100%) create mode 100644 node/ethereum.go create mode 100755 node/node delete mode 100644 test_runner.go delete mode 100644 test_runner_test.go delete mode 100644 testing.go create mode 100644 utils/keys.go diff --git a/Makefile b/ethereal/Makefile similarity index 100% rename from Makefile rename to ethereal/Makefile diff --git a/facet.png b/ethereal/assets/facet.png similarity index 100% rename from facet.png rename to ethereal/assets/facet.png diff --git a/net.png b/ethereal/assets/net.png similarity index 100% rename from net.png rename to ethereal/assets/net.png diff --git a/network.png b/ethereal/assets/network.png similarity index 100% rename from network.png rename to ethereal/assets/network.png diff --git a/new.png b/ethereal/assets/new.png similarity index 100% rename from new.png rename to ethereal/assets/new.png diff --git a/qml/test_app.qml b/ethereal/assets/qml/test_app.qml similarity index 100% rename from qml/test_app.qml rename to ethereal/assets/qml/test_app.qml diff --git a/qml/transactions.qml b/ethereal/assets/qml/transactions.qml similarity index 100% rename from qml/transactions.qml rename to ethereal/assets/qml/transactions.qml diff --git a/qml/wallet.qml b/ethereal/assets/qml/wallet.qml similarity index 100% rename from qml/wallet.qml rename to ethereal/assets/qml/wallet.qml diff --git a/tx.png b/ethereal/assets/tx.png similarity index 100% rename from tx.png rename to ethereal/assets/tx.png diff --git a/ethereal/config.go b/ethereal/config.go new file mode 100644 index 000000000..a534bb182 --- /dev/null +++ b/ethereal/config.go @@ -0,0 +1,34 @@ +package main + +import ( + "flag" +) + +var StartConsole bool +var StartMining bool +var UseUPnP bool +var OutboundPort string +var ShowGenesis bool +var AddPeer string +var MaxPeer int +var GenAddr bool +var UseSeed bool +var ImportKey string +var ExportKey bool +var DataDir string + +func Init() { + flag.BoolVar(&StartConsole, "c", false, "debug and testing console") + flag.BoolVar(&StartMining, "m", false, "start dagger mining") + flag.BoolVar(&ShowGenesis, "g", false, "prints genesis header and exits") + flag.BoolVar(&UseUPnP, "upnp", false, "enable UPnP support") + flag.BoolVar(&UseSeed, "seed", true, "seed peers") + flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key") + flag.BoolVar(&ExportKey, "export", false, "export private key") + flag.StringVar(&OutboundPort, "p", "30303", "listening port") + flag.StringVar(&DataDir, "dir", ".ethereal", "ethereum data directory") + flag.StringVar(&ImportKey, "import", "", "imports the given private key (hex)") + flag.IntVar(&MaxPeer, "x", 5, "maximum desired peers") + + flag.Parse() +} diff --git a/ethereal/ethereum.go b/ethereal/ethereum.go new file mode 100644 index 000000000..618d2b00f --- /dev/null +++ b/ethereal/ethereum.go @@ -0,0 +1,110 @@ +package main + +import ( + "fmt" + "github.com/ethereum/eth-go" + "github.com/ethereum/eth-go/ethchain" + "github.com/ethereum/eth-go/ethutil" + "github.com/ethereum/go-ethereum/ethereal/ui" + "github.com/ethereum/go-ethereum/utils" + "github.com/niemeyer/qml" + "log" + "os" + "os/signal" + "runtime" +) + +const Debug = true + +// Register interrupt handlers so we can stop the ethereum +func RegisterInterupts(s *eth.Ethereum) { + // Buffered chan of one is enough + c := make(chan os.Signal, 1) + // Notify about interrupts for now + signal.Notify(c, os.Interrupt) + go func() { + for sig := range c { + fmt.Printf("Shutting down (%v) ... \n", sig) + + s.Stop() + } + }() +} + +func main() { + Init() + + qml.Init(nil) + + runtime.GOMAXPROCS(runtime.NumCPU()) + + ethchain.InitFees() + ethutil.ReadConfig(DataDir) + ethutil.Config.Seed = UseSeed + + // Instantiated a eth stack + ethereum, err := eth.New(eth.CapDefault, UseUPnP) + if err != nil { + log.Println("eth start err:", err) + return + } + ethereum.Port = OutboundPort + + if GenAddr { + fmt.Println("This action overwrites your old private key. Are you sure? (y/n)") + + var r string + fmt.Scanln(&r) + for ; ; fmt.Scanln(&r) { + if r == "n" || r == "y" { + break + } else { + fmt.Printf("Yes or no?", r) + } + } + + if r == "y" { + utils.CreateKeyPair(true) + } + os.Exit(0) + } else { + if len(ImportKey) > 0 { + fmt.Println("This action overwrites your old private key. Are you sure? (y/n)") + var r string + fmt.Scanln(&r) + for ; ; fmt.Scanln(&r) { + if r == "n" || r == "y" { + break + } else { + fmt.Printf("Yes or no?", r) + } + } + + if r == "y" { + utils.ImportPrivateKey(ImportKey) + os.Exit(0) + } + } else { + utils.CreateKeyPair(false) + } + } + + if ExportKey { + key := ethutil.Config.Db.GetKeys()[0] + fmt.Printf("%x\n", key.PrivateKey) + os.Exit(0) + } + + if ShowGenesis { + fmt.Println(ethereum.BlockChain().Genesis()) + os.Exit(0) + } + + log.Printf("Starting Ethereum v%s\n", ethutil.Config.Ver) + + // Set the max peers + ethereum.MaxPeers = MaxPeer + + gui := ethui.New(ethereum) + gui.Start() +} diff --git a/ui/gui.go b/ethereal/ui/gui.go similarity index 100% rename from ui/gui.go rename to ethereal/ui/gui.go diff --git a/ui/library.go b/ethereal/ui/library.go similarity index 100% rename from ui/library.go rename to ethereal/ui/library.go diff --git a/ui/ui_lib.go b/ethereal/ui/ui_lib.go similarity index 95% rename from ui/ui_lib.go rename to ethereal/ui/ui_lib.go index 83e8bf2d1..3997191fa 100644 --- a/ui/ui_lib.go +++ b/ethereal/ui/ui_lib.go @@ -55,8 +55,8 @@ func AssetPath(p string) string { // assume a debug build and use the source directory as // asset directory. pwd, _ := os.Getwd() - if pwd == path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum") { - base = pwd + if pwd == path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "ethereal") { + base = path.Join(pwd, "assets") } else { switch runtime.GOOS { case "darwin": diff --git a/ethereum.go b/ethereum.go deleted file mode 100644 index ac1de5af4..000000000 --- a/ethereum.go +++ /dev/null @@ -1,215 +0,0 @@ -package main - -import ( - "fmt" - "github.com/ethereum/eth-go" - "github.com/ethereum/eth-go/ethchain" - "github.com/ethereum/eth-go/ethutil" - "github.com/ethereum/eth-go/ethwire" - "github.com/ethereum/go-ethereum/ui" - "github.com/niemeyer/qml" - "github.com/obscuren/secp256k1-go" - "log" - "os" - "os/signal" - "runtime" -) - -const Debug = true - -// Register interrupt handlers so we can stop the ethereum -func RegisterInterupts(s *eth.Ethereum) { - // Buffered chan of one is enough - c := make(chan os.Signal, 1) - // Notify about interrupts for now - signal.Notify(c, os.Interrupt) - go func() { - for sig := range c { - fmt.Printf("Shutting down (%v) ... \n", sig) - - s.Stop() - } - }() -} - -func CreateKeyPair(force bool) { - data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) - if len(data) == 0 || force { - pub, prv := secp256k1.GenerateKeyPair() - pair := ðutil.Key{PrivateKey: prv, PublicKey: pub} - ethutil.Config.Db.Put([]byte("KeyRing"), pair.RlpEncode()) - - fmt.Printf(` -Generating new address and keypair. -Please keep your keys somewhere save. - -++++++++++++++++ KeyRing +++++++++++++++++++ -addr: %x -prvk: %x -pubk: %x -++++++++++++++++++++++++++++++++++++++++++++ - -`, pair.Address(), prv, pub) - - } -} - -func ImportPrivateKey(prvKey string) { - key := ethutil.FromHex(prvKey) - msg := []byte("tmp") - // Couldn't think of a better way to get the pub key - sig, _ := secp256k1.Sign(msg, key) - pub, _ := secp256k1.RecoverPubkey(msg, sig) - pair := ðutil.Key{PrivateKey: key, PublicKey: pub} - ethutil.Config.Db.Put([]byte("KeyRing"), pair.RlpEncode()) - - fmt.Printf(` -Importing private key - -++++++++++++++++ KeyRing +++++++++++++++++++ -addr: %x -prvk: %x -pubk: %x -++++++++++++++++++++++++++++++++++++++++++++ - -`, pair.Address(), key, pub) -} - -func main() { - Init() - - // Qt has to be initialized in the main thread or it will throw errors - // It has to be called BEFORE setting the maximum procs. - if UseGui { - qml.Init(nil) - } - - runtime.GOMAXPROCS(runtime.NumCPU()) - - ethchain.InitFees() - ethutil.ReadConfig(DataDir) - ethutil.Config.Seed = UseSeed - - // Instantiated a eth stack - ethereum, err := eth.New(eth.CapDefault, UseUPnP) - if err != nil { - log.Println("eth start err:", err) - return - } - ethereum.Port = OutboundPort - - if GenAddr { - fmt.Println("This action overwrites your old private key. Are you sure? (y/n)") - - var r string - fmt.Scanln(&r) - for ; ; fmt.Scanln(&r) { - if r == "n" || r == "y" { - break - } else { - fmt.Printf("Yes or no?", r) - } - } - - if r == "y" { - CreateKeyPair(true) - } - os.Exit(0) - } else { - if len(ImportKey) > 0 { - fmt.Println("This action overwrites your old private key. Are you sure? (y/n)") - var r string - fmt.Scanln(&r) - for ; ; fmt.Scanln(&r) { - if r == "n" || r == "y" { - break - } else { - fmt.Printf("Yes or no?", r) - } - } - - if r == "y" { - ImportPrivateKey(ImportKey) - os.Exit(0) - } - } else { - CreateKeyPair(false) - } - } - - if ExportKey { - key := ethutil.Config.Db.GetKeys()[0] - fmt.Printf("%x\n", key.PrivateKey) - os.Exit(0) - } - - if ShowGenesis { - fmt.Println(ethereum.BlockChain().Genesis()) - os.Exit(0) - } - - log.Printf("Starting Ethereum v%s\n", ethutil.Config.Ver) - - // Set the max peers - ethereum.MaxPeers = MaxPeer - - if StartConsole { - err := os.Mkdir(ethutil.Config.ExecPath, os.ModePerm) - // Error is OK if the error is ErrExist - if err != nil && !os.IsExist(err) { - log.Panic("Unable to create EXECPATH:", err) - } - - console := NewConsole(ethereum) - go console.Start() - } - - if UseGui { - gui := ethui.New(ethereum) - gui.Start() - //ethereum.Stop() - } else { - RegisterInterupts(ethereum) - ethereum.Start() - - if StartMining { - log.Printf("Miner started\n") - - // Fake block mining. It broadcasts a new block every 5 seconds - go func() { - pow := ðchain.EasyPow{} - data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) - keyRing := ethutil.NewValueFromBytes(data) - addr := keyRing.Get(1).Bytes() - - for { - txs := ethereum.TxPool().Flush() - // Create a new block which we're going to mine - block := ethereum.BlockChain().NewBlock(addr, txs) - log.Println("Mining on new block. Includes", len(block.Transactions()), "transactions") - // Apply all transactions to the block - ethereum.StateManager().ApplyTransactions(block, block.Transactions()) - - ethereum.StateManager().Prepare(block.State(), block.State()) - ethereum.StateManager().AccumelateRewards(block) - - // Search the nonce - block.Nonce = pow.Search(block) - ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{block.Value().Val}) - - ethereum.StateManager().PrepareDefault(block) - err := ethereum.StateManager().ProcessBlock(block) - if err != nil { - log.Println(err) - } else { - log.Println("\n+++++++ MINED BLK +++++++\n", ethereum.BlockChain().CurrentBlock) - log.Printf("🔨 Mined block %x\n", block.Hash()) - } - } - }() - } - - // Wait for shutdown - ethereum.WaitForShutdown() - } -} diff --git a/config.go b/node/config.go similarity index 93% rename from config.go rename to node/config.go index bafc3e300..e4935dfed 100644 --- a/config.go +++ b/node/config.go @@ -15,14 +15,15 @@ var GenAddr bool var UseSeed bool var ImportKey string var ExportKey bool -var UseGui bool + +//var UseGui bool var DataDir string func Init() { flag.BoolVar(&StartConsole, "c", false, "debug and testing console") flag.BoolVar(&StartMining, "m", false, "start dagger mining") flag.BoolVar(&ShowGenesis, "g", false, "prints genesis header and exits") - flag.BoolVar(&UseGui, "gui", true, "use the gui") + //flag.BoolVar(&UseGui, "gui", true, "use the gui") flag.BoolVar(&UseUPnP, "upnp", false, "enable UPnP support") flag.BoolVar(&UseSeed, "seed", true, "seed peers") flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key") diff --git a/dev_console.go b/node/dev_console.go similarity index 100% rename from dev_console.go rename to node/dev_console.go diff --git a/node/ethereum.go b/node/ethereum.go new file mode 100644 index 000000000..3f5e4a8f5 --- /dev/null +++ b/node/ethereum.go @@ -0,0 +1,158 @@ +package main + +import ( + "fmt" + "github.com/ethereum/eth-go" + "github.com/ethereum/eth-go/ethchain" + "github.com/ethereum/eth-go/ethutil" + "github.com/ethereum/eth-go/ethwire" + "github.com/ethereum/go-ethereum/utils" + "log" + "os" + "os/signal" + "runtime" +) + +const Debug = true + +// Register interrupt handlers so we can stop the ethereum +func RegisterInterupts(s *eth.Ethereum) { + // Buffered chan of one is enough + c := make(chan os.Signal, 1) + // Notify about interrupts for now + signal.Notify(c, os.Interrupt) + go func() { + for sig := range c { + fmt.Printf("Shutting down (%v) ... \n", sig) + + s.Stop() + } + }() +} + +func main() { + Init() + + runtime.GOMAXPROCS(runtime.NumCPU()) + + ethchain.InitFees() + ethutil.ReadConfig(DataDir) + ethutil.Config.Seed = UseSeed + + // Instantiated a eth stack + ethereum, err := eth.New(eth.CapDefault, UseUPnP) + if err != nil { + log.Println("eth start err:", err) + return + } + ethereum.Port = OutboundPort + + if GenAddr { + fmt.Println("This action overwrites your old private key. Are you sure? (y/n)") + + var r string + fmt.Scanln(&r) + for ; ; fmt.Scanln(&r) { + if r == "n" || r == "y" { + break + } else { + fmt.Printf("Yes or no?", r) + } + } + + if r == "y" { + utils.CreateKeyPair(true) + } + os.Exit(0) + } else { + if len(ImportKey) > 0 { + fmt.Println("This action overwrites your old private key. Are you sure? (y/n)") + var r string + fmt.Scanln(&r) + for ; ; fmt.Scanln(&r) { + if r == "n" || r == "y" { + break + } else { + fmt.Printf("Yes or no?", r) + } + } + + if r == "y" { + utils.ImportPrivateKey(ImportKey) + os.Exit(0) + } + } else { + utils.CreateKeyPair(false) + } + } + + if ExportKey { + key := ethutil.Config.Db.GetKeys()[0] + fmt.Printf("%x\n", key.PrivateKey) + os.Exit(0) + } + + if ShowGenesis { + fmt.Println(ethereum.BlockChain().Genesis()) + os.Exit(0) + } + + log.Printf("Starting Ethereum v%s\n", ethutil.Config.Ver) + + // Set the max peers + ethereum.MaxPeers = MaxPeer + + if StartConsole { + err := os.Mkdir(ethutil.Config.ExecPath, os.ModePerm) + // Error is OK if the error is ErrExist + if err != nil && !os.IsExist(err) { + log.Panic("Unable to create EXECPATH:", err) + } + + console := NewConsole(ethereum) + go console.Start() + } + + RegisterInterupts(ethereum) + ethereum.Start() + + if StartMining { + log.Printf("Miner started\n") + + // Fake block mining. It broadcasts a new block every 5 seconds + go func() { + pow := ðchain.EasyPow{} + data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) + keyRing := ethutil.NewValueFromBytes(data) + addr := keyRing.Get(1).Bytes() + + for { + txs := ethereum.TxPool().Flush() + // Create a new block which we're going to mine + block := ethereum.BlockChain().NewBlock(addr, txs) + log.Println("Mining on new block. Includes", len(block.Transactions()), "transactions") + // Apply all transactions to the block + ethereum.StateManager().ApplyTransactions(block, block.Transactions()) + + ethereum.StateManager().Prepare(block.State(), block.State()) + ethereum.StateManager().AccumelateRewards(block) + + // Search the nonce + block.Nonce = pow.Search(block) + ethereum.Broadcast(ethwire.MsgBlockTy, []interface{}{block.Value().Val}) + + ethereum.StateManager().PrepareDefault(block) + err := ethereum.StateManager().ProcessBlock(block) + if err != nil { + log.Println(err) + } else { + log.Println("\n+++++++ MINED BLK +++++++\n", ethereum.BlockChain().CurrentBlock) + log.Printf("🔨 Mined block %x\n", block.Hash()) + } + } + }() + } + + // Wait for shutdown + ethereum.WaitForShutdown() +} diff --git a/node/node b/node/node new file mode 100755 index 0000000000000000000000000000000000000000..48452886c43235a25b82479886ed49e63db101a6 GIT binary patch literal 8154988 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

s%O+&`c@Z_cP5Oafl|NV{`Tc;(qY_OU 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%0D!t@%~KrZR*yXr|UF3nfO;5{obj-oBHB^ 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

-9ODLrkl-J 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∈bU0?deb1Pp2o`|QYQv}UB>#;P)4f*a;j^;P5->RjBPpEj2+s12Gv<{ z5+9)gBGO5nSHUEU-~;N%IC~x9^I)&#Axi8tyT<7l^|7l68u^YO2v}qy^^-gDv8{yO z-!J^OqW(qjd}1xQQzx#4JG^J;XxAj>WE{1QWE|M{qI|5W0knp+aR~!0v0Tg`4|6iZ z8M~q1V1~Y3W`;u6fbMwA@VfBj2$>;Pmc-v>houeh3wutzIe`F} zQ~|IQ7L`?qj{5*#-y%zH;8;FEo%tAxQ+ptFKwdAU>U4ST}ZezXoWjCv*`JtVR`ZT8JW^D(f-CeS9G?2ySG zVbS+myD51`+8=i#4OqdC-Pg@YJe)$Xi_MBOczZoRfGY08FBI=IqMTx%OB>3=UE$pA zY{aJxdwEX|CHNX2)P}d*o=+RXIFwIxCk19<@P#}ZraS*2-rkYRb1)K3sV>+B27h;u zEb7Pk(7N>TzRBSGoGTWl|LA*kukZRZ3=}C$hkaAVw{^V8QvMW`0|}w@&#-`mQh$X{ z(mr~W*Tv};-=n9PP6L#T=AxuL+*#iL6HTxT-hW6;y}Y~+X4eKMJsU93wW`X&^C@(k zqp{4`gw0`NMmaaoJkQCIHB5;D7^vDV9o4MoeNl2#BbmE`s=HEro=4EG%soS0WM-&v zg#bP2nX==ksJv?uEG60U5bn6YguSih0$-7qPxap>02RG~sU^zE!YpdRS{-uZH7|d^`g1c!PWtaEjuqk z3ArA@1b#2p>eFt*^H#f+3c0A=mh&VC>33j?g2_hj++7`rV>5R_PfdGGjQ&%g@SkEo zLGfY71=RzMF|-W;7nN;dcM)C0A#fwEF&aen zY|#Ffhalxn+y9$|eR54#0ldc(Ke;szPoNaRqd2g;0=A5JJ+}=%;ze`%%11Kd{rl`) z;G}|AhlbKqp+4?57}e=Beou#mkh}_d5Bz=stL; zba1(tDI~Wi$T8u9T^3}a_KpR4Ghyha0?Q%DyX-Z%`fIy@{)Mmn?+fx*9vDWDZHR!C zM=j`9K6hG>A(TErhF{{85Edb=&m-Ik+gOa6-b}j7?XD|uIW%X-bpO}4^V5Ccr4x2> zCiT^`NOw1m4LV9Yb+pekeU#4@tn$Mzn%^7_QYjm8_7GRiBArx!rXP-KO_nb9R)UxeF3iIRJ&$^oEC*lYw+~*HMC(b$!4}C_VRepn2jS(x>BB{a#*K zEPhFOU*7Rg?;6pax#GRMJIW%c->m_-=__=LrtukdUEng)x-N4QQ5Oi?F$Tx;d7nxD7--*sbxTC+!Er4PvyQSp>9OuJ z=Xv~N|2Z1+&*|24!AC-0KBS1Vif%;RNK-HjaIL$pH|0z%b2sIjN-Tq|MYe*YycReK z)Mpe9_*4kS7I)5-q4Ss+i8 z;w(_M!hCeGZx-m#!l+;`g)MMX$s2Mm2NFI+_&w7H8&d=mj`JdTiIV6zZ9QDUSTtq? z?3W%+3t`>jWCHAKP}pN(<`G?l&oe*d7B$q9VMzeC#cL8ku2FM+4g$zRmL&knU;)HP zQ9EnEO+;Ot%1;gHbKFT<9s*O11mS1JwSp7`S!`9g*a9F9>r}OuxMp-SFvCRI9qbP| zF~Z**DlRNdXL1 zy|SUmO8?mMrRH8hjS*B+)$2ZI*(10{$IV|xyxLYhI5!-R!I|;Fl5(UuZ zKKT&|mmRp_j{W#$>WVnaH9n+|S=`e}HlbC}vdk!Ps15+I51apaiX?Bi5 zciv(IXi*s{kiN!abR5xUnCza)`GY2_C)4-3`-oQYX zxR40P!F_B8coeJ?;o=cO)8US>04sGi1{JO@ad#nDtyK?jFgffIq%uHbb37uwVG2MX zrfNqsSrB6;ITCVF4@Lb?d0kW%oq0qNg;3p>aK|k&v0ZjEi7M+K(u=+Hm_vN%G3WYp zlFFF_2&yhoi>M#FDLWWX(9$|^h#R*M%HaSaJopmj#rYzZmtpLv`gkg(&Shs5aVg~u z8lQfKd@BrUcQXn&ngHo*J)Zx6?7a(kT}9P5o-~1;Ldyw)8lm7p5=beRlxxEEv=rQd z6oP_=n?~i8v=oSKS^~5+%}Gnndm1QGUyA}p5pAVt5yYZY69S}wl_DQdRG`Rh4xv!) z1+4jgzqMxe*?XUpwkZDp&+|R+foAq)_RN|!>o#lF%w%^72>m?+&tLNiFGp`0AAST# z4ZHTd3i*Nn2p~)l+Tbo4-9?jJ1OZf9Tkc57y!l~4TASlCI9fZPJVa|aSphQE4uE9g zYXk}qoLl$`?sU`#v@SNMv#6BrX)g4t%U<&f=(Q_drGPc|rfG1sm)^a?)Wt~F!rYiC z_0ppuvJ1|5l$}cwri2C^C-_Mf`=wfDJh0Jr9s)(6pd*{IvXh0|viwpo$Y;GFZss|* zve)ifzJ@97&||FsplM$l|X*T z&=$Bp71!)f{37(Q*I^$UJ^cOs?W2c1KJ~HD!wD?v-=>FJ4u^-KhtSxk=0z zus%u;z5D5ba%D|nde~{+$4L*QrqGRR+Uj|N1@Xh>&!@FYhsx%HK6s;$22;Rn!B zE0OZYYw9Tes0@}#8q`E5`l{-V_ed^<^6cjFI0<5QBgHI{qE%rX6ci#MokdV`QbUKl zi_NEYM+tWI3_K$$J3c4uXiZl4oeB&6ZV+cxLSB4^L-u_7FcW13fLm8bI{}%%v@{c} zlJj);`KXeUfc}BLfRbw=ODDGOHd%$%(py?PS$m!hGiVu#yY+aZb-o z_@nAMK(j<6hEN6|Qsie(4hXQF1A6YcfPr#Y54t#P2M#cqW24ea#}lL0H+?V#BY7;E||H|m1*1vjb$j5))W@u?sX zjPA_a#}Y}_d!nNY>pkfqKz2}Jjmp6#sVyUNpu#tz3yjcZ(t|ZDspek+HF@;5L9P3! zpyD8Dht*+54*v?MP1^zLO~-sBton{P#-JWTG7rs?n@cZOzQFXk_NFqIxp3Fv*5BPW z-s;n4b_uu|mhe;%DOX2;SSTbwYjOZgAXb-p9h6n21QGFfk}Sac)jTzk)W*21)Rv;w zGraCupk};rM239**f_xkstGxP%^{CsG;qqy;(vSynxl*YG_Yg2kP_a$b`o5Q2PU3W zH28Bza`bxO7viUtI$l|SfaRxk$Uq#@jy9iric*@|15Igis5Lvw<5oQGhDVSeL_JvY z5Z}O9!yk|aPNEc7;4$U()y_ z{KPr!TPp@8GOPpTGXOt>^X$`8V>p?86P^`AIuP^R2DfAu&gjw#rLKmeBlGHda0k|9 ztMO|Xg&LsPiUx16#Zu^KvFNCktUKCK@^E`PiZ;M79rcm>s9l8VHu~s^zq5}VCh4ER zM8_;55u=fPM)8@T0w= z<|LjAuvmSGfJ}Bw8WQos(@}+#K;e(Hg z;)8VhwHJeaHoc4=m<2OvBui0%W$*#EUVah$joHudzkxoC3whQjB<)By>4cV4=}g3| zBjD!(O(0~p6bz1yFCK>Uq4o6OS{19gb^~^b3hiMK1?1|3h3mhq($-(?V}}<>DVbLu zuTZkp^yOyf6O~HPJtCs$Qn47}+GRY9rQGh=?O#SnCP|X)V zx_5TVj<5~#Uem{zyrR&XLipXXuWcW6&M6SaI20jOThzL%m%$A;&W2vq1LIP9;9I1B zR=e+8^!szlh!3E)7W$wUHTvq53$9@g3BJU+(Il)7ifC3DAjC(qw}$jp^0n3Lf1(aG zKjgVFIXgJ#=;=x2%p_-ETMm-GX(Ci;qHhC#@-PY{Khi+DRAoazA6NH*no>BE$;q6H zL0*Ez+@A9{ESOm)v6%DE>(J&43*}RW*2BB1E4)9SEk3tI@Td!=6)}))7l~&4r zX85S5COSefzs~zeeM+U`%(TeiuFm1z+Jp9v$oHrBar{|uf8pv8d2|7Iik9%HRarSA zDzv}zUavmSAP~?;O=dip!5k}bTtOuOSunZK2}?>N5&AgD!CMY^6DT&3hP-_lGdb)m z@Ep|<)K3))t@c00R>lb+1AEW=k95D-r?Ksy_zQ)&6CO&Vkd0xM3bNj61@QEoin5~C zoy;#vz(6d=S&gs*cUGN;>;EzQD4I&d`+1HMFHNtS=_s5^G_4o6VTYrD`z~`81R*>GEp{p{5=-!Ox#xe!2TF;Vuf)__a!u!215h?~C`d-)q^y zg0$KYyx%y|hc^NgJ}h%!D&V0HPpOj+nFBwvGZx{YbK4Sasu+sk!o- zP$iPzRuCzFiYvbgx*Gi=(I&W9a%YvW z%G^uYubo4F30#5+?S=~gJeP}mxbx^3jtO4K|K2L6%oGUvlSEUa(SRmgfNg82e&W+^ zmAb4PoyPNqYS8E;IjV(OdC?{p+ImF;+Gx>$afBUeH1Vq3RF5M<{8$uV1;`T@ha1`j z!QyzQrr&>}@OY@tlskCz{3A>fv=a>cIAPGGmts!9dRM3f7T{p3v#Cu7D15+XZn?vm zbZTME5le@2i>3Q8p#$N&!4XDyXn+2@0REaky$$>Uk&XPG7;SPF&2o{CS~CuEi4G*t z@N^CmA_#5e0FGXsZK0Os=h_m0ch#ppR(Q|;55h}TWnvCqJv5~t5^EeK$be2LK`6D% zoC2GPNCYM&rph|%fJAx*!7R;wpQ67Z7DIb_`R|B7oM%f=I3KR^0iZMx%j{Uchm-CJ ziP>4bu&SSf@y9L&aQ@_vN{;CiE@yHqx=k4pfoJX~Ej(hs6O4#51$`xm8goYtYY*D= zU{08feu0H0u>V@yzn7~oEPu&(=mARL53Qu%P6-?;-^!!%-M2xX`AkCq(4%2_)KjHB z4?X0MthdE95qQ{zrfW9~&&Mo}R$6)aG0G$1m-U~p@cv8uvd2Lm8^4TRCHV6kJRdjy zPF6@iM*Io9OLzUx^moGh*x^l*J`Hvh{5bUYI*dN^)XhiJ-vUqLw%`d$%OQPiroAU>ceI6ZQ$>t!8_^`MB{%3Ug7V}yZk%+eYEA8k3k<=dEM;b`8Vyyc5zil z%$<)yeCQ-7ix9jbkkQNy3SFUo2|K&f1&)(Ux5> zoKr_sgLBTqISuR7%Uljf&HzLc0m;2HU`IURVFP{~2{I0w1b@cX4>4(nOA@6|i=)ik zFsQSz0GU$;$N_Ufyxu6-%=;h;FULBlh$s5tAj)xrqH~9{k4Ku-*rQSU1MOjiBEE)2 z{Xx+jY}%PCqxP{mllXKNrk9fCM2(m6%Dv)8y-WiRv3+R9UiS1%G+{bNeE8psd1<_4 z`^}T@%PCxpj^h?oK-PxS=uD=ql^gp$dNy5wJ`|vh=sf)&-iS6gY(I}QPh;moX%7%C z{fyxUq(h7_nNhU84)=o94GZwp&-)6zynEU8R(M)bb#@zOmLk`#KT|&;#+`IoLTL6R0BHdgZg6Z ztcj9CA%ZKjRZmK55WT*rMVONil6eQ&YeB>}KNIxn6Iu7ujjVqnwWVA(~Z} zHvR_p_j`|S;r4RZ$lk-5HuM6@Car)-uEf3k9YhVflzf|C5&nO;)ja)!8h1!kqUWn_$k8 z1btTKJ^DQR0tK55Tvi5xLm?b8qurk91qOFO`bzyoapnrNBPU2M;49!--osJD*n*@t zu20$mX8(j&e6KX*4K`$rEr<=FRFa15m}`g-3Ee%Qx1^9uwwi$7{I1Y?gg%cOW$C+$ z#bPjo(`MwT6USIh1sJRCOF9h}Wv7EAn_u6I z{c=*&^U{x5Dcay=_O?=tZUda^`NBH_ew06_#B%b6@+=Sjo&xZ%I;$}JD>pj$0gA#e zW6GGpu4ba*(VqhUX`uW*N-1oCL;~qfmKTS+BKvjke5UwA~*z3 zMF{|QOxT&bVIJ|BsEDQlAkmLwzW8>8o)E#ZN#lPuBX~vD=PX9Mxi!gBroq@xT=!a> zgyKUfF*xm8J2+<#FC7$vOXQ>mTNEV^vyIDo^WW#v%6PY|fm2Rx@-i*4`b-jeD1aXJ z=6}dMbC0v^>do)xy_W{d%8pSELbMquAkt{fg}D}mhNMrt<7Elouns7XOxuztfGGJ2 zi6GR37g8PN(C1-g_;|`d(^1z#kf6YJf2KbTTGzeVmEl zgm$4EttRHZ;y2|k3;D2$OoEE|Cyg8AA=Jf-B#fxOc3{?pRD?BN`q+wkkYJL3 z>}H*r11n>!4<(eF*T3?D$m=A-+G>0l{FtT0utYZhKGGs0qIk^WJqXv~!3C@Es2;w+ zUP5Vem@CC5Fs+(gtjRZhLm|Y!I1jtT%AacTNfHHt&|&kqiw0gaZ$2MqViuX?%W9B# z8l;SX5qqSR3UZof8^0AW&(KWEnV?89BKryzY@J zy(U8V6E0Dvi+7(OgqE|^K%>BOgz_f{HNoVBdW6Xtpr%H`*=Q-7BO*slU98AbQ@d13 zYEl?MI0;faD1$yRlpx9wqE|E+7yi^{=S^`DgEaSwp3OJ+{(ic}uCMvp7^@LgQV#=r zP*TOPA<*?ApW&q%WuQ6u9^ikvEv7HD-M zdSNO?L&mEem1k|bPNNzNosQGdi0t|P^Zj9$XG20 z4ads(L8A-*=Xw$`TVQY_92j=gCiW2yxLL>D`tJQffl((>Mef7LM=eJ zcG$dJ6wY>0DiM?X73zs9Knp7j5pM(OopTi)Oh94`$*Wzrj-uoam2u zpXR9V52>&5zP(gxN>u7sm5^uUBI4l)V)0Q2xB5FE`9<7H%;{Kb z8Hf=Bj|iL~!h287IE1`+K+Y-CWQS6UbLSsHuYqgDR9~1S&zWya!e;ru5WYs5EgxF` ztD^44k8P^f&T`!<;#xYe+>AjMJWrrz&Ma2-N6K66%B$wrX`luwW%E%qc-a4VCtE^kF^N<;7iCpyc;TN9qpEur0$FL<7|da1QFj#Fv57I(i zma;qz@(qPKz)@glO(XEH z-fZ#xF~Hw&MLzsv0`Tt{r1PW?NO)4$f2{MFQyhFUpNpndqhE;x5y%A@&eUP>Z;{a8 z7l&G?Evs^r4(1B-7eXsy_$thd!OxXR{3i7lcc{T+s2_#J_!-jCV)Aae>Rsqe z8d)6FmAL@Uau_9NW4{bJ%J`Ge1!&G5x@&xbPjT`)z|4h}{#b#*-v~T=Ie4V2p)(vj zCzwgAx!{ySP^DONi zvrly?TT;ev%^?$60o+Q1z0B3VGmbwSe>1HhNO%9l@?Kyjymkl(NBaPcEJ~fu@z*p= z4WI-z#}SDsJ4}m*mXQ7cMQo$V*0Kde=DH*Kaj214b}u@}H8T4tI--YfUPIC~?*VLb zQ;W>bgMCS0EovREb3_p7{~O=3{olg6+q|^j+c)7G^ZVawZ?{SJxyDI1LiK@t(QZ?B z6v5!F^21~u=AtMwuU20vvBJ7+N2&ZOW)746p`{RHd^}vntb4-XAXNLr-wBEPiw}Gf z&wdFFN3r^gv~TsB!?kZU@|$Pw-j4Q7m7XftzME=-?F-rcyYWC4MH1TgPPh!T&mq&N zrhBVd7M&!(B@osKeu2kPq~lIzGJArCvtw+>;n|~t&5z2L+upG4hrFW|i-AB)ZJT(f zIKwdc5(7`d`;ciw%@8t}!8wZ}2VT!CHlrSxn4~1k$-7xeQZWD=U13fe%{MHVtHt)E zi?XaP(_HP1Yer$ALce{hO2neUr=%>7d|{wX1s_7NXU+y#cmi39m^X?~N>N@;jSXId zA@R%j_oyT9lXFdu^!FHT@BCNW0W+4$twaJH5%x4K<3s#B5M-C6qGHf4SaP~;$WlmI z)B77zhdmMvVkC*PIboo46}D_?1Ps{hn^B7S(JE%QE@85Q!F=NU``Ymi>H^GiFEm8_ zE^rtog3!lkIXPW>TSi}^ks#-A)K8Z>BU>*NLYY!sYG&LN7F@00&J$Wq6k6yyP!8l3 zq!+}lOq)%E5-F{0bMn-*0vdZBsM|iz0SdZI9Irb$#CnGgR%yyF&2z_)K&4O^l7p)u zbFK);oPR*h068OOVZzWNrge;2L>$_(9qGQpHi;l6{u>kZ#mu}n>@4N!E36g=UVhd&(_m?}TnBxon3e@{zet0ZbR25XCgVG?yJs1W1_{(}Ul2v_F+7ADKNAiO)yaQ6j=eVCOtO%DzFZP%`)e z{{2bGxRj-U!_m|tX+FnPm5L4SL{)rg8!=*jDleeYv}MF z{JKzwi**#GebG6@+5k(^zUK zH5Fe1oF86c4wX&ofb;ByFs*TB>Kb%=U4Y@vL#IUL{YHdS$oRQNF{bevRbJYcY(EE& zn3sNqP6AT_FgwdXk@=C&VYtft`3}v4-5V&&T1P(s4}+6q@Y6NYkpp+7wKyMf*nkqT z*g%OMd$P>zxT}f|AQQHa(nlp+K`h0KVrwggC6hHP6ri_ zo7NUkUni2ht3`cXvjg&qrypQp#$;kry443LZq@=(Y%5o5<=Sd|&f886w#e6DBeG;* zk(1ZtS{^qS*owkPHIC~~aYkH3-#v}3`q1C1@2GrKpP?hC1JAB=18N9;R@gl^;kUDxm>rN_97 zf_R@qyo0l0HhfyfFuZdp_pAA11d0VzF;0PeRJ3>dXfKhV4geOx-;Kud3!23SkY6mT zw4P}G@Jq6QwNZH?f+=P$qpHixzmxglO5_iYL!FT}cqgisU!?xMT>ZdQXGJ@**zgX3 zVmXsj7j6CR_oxFJM*uPtW>|$($!pR66d=pYuf}VC%7CBbzrEjSxabIwX+Qxu{)V%zmRUv4fp+S?-ua_G}G*6h)sGD{$Z|J!pA1U8ERi4Zb!Io){c-iWwaOZ zga+{;5U2QrCNgG0`Q$SyV6BOa{!cf@_)#%uj-JQAwGKB-Blx-T#TwI` zV&ra!dQ2Jyxj{(;-iy9<&-Kr!BfWesmw1OosBgVfggvj9KwhGrLvfpi`zt=t=mT#y;Yp$ce zD`uXamGifKR%HNaJ9ECs5Rk|DRce$`sL}C}U|qbZl8d0M<8U&+{jPrSla)SN|EW^H z8~h?we_MAe{B3!zwj3v$8!U#DK*tMpIgG3*Q2*bh{q$e1i1;r%)>;20U%-EPCp5k0 z3i>YzHb|a-bV^`{?DFNCoTFv%%>wVQ|9Rkjgr1L6ctZY1B7sIIivoR;Oi-1qPv7PK z=Sipm$wG4lxTNk>p#sm?IE>j_OR*rbKXXnDBLR1ZMdtmv`nzpB)aX?WsLUMp95C}7 zEC)4{>}U%k<@I>WA4km_nuYD@s@qL>EV9T5$0-V$R@}8ZiJ-CSje5`JrJrzgqdg--r zjug-Sk~egJ{H}|O`d*BULTP+BV)oHq>i!Y>w9Gv%nY|aDmgv)RKDFolxQL+IwIp0~ zs3zkzsnBGKB!JQVa{aISLp*EcK@$n78R!f5D|=7+6-d^8t!6i3(x(?uxiFXAF1I!8 z#&sk8Ze&LVyHQ3_?86lm?f6Q%QM!&VT))BD745XYZDgm3sANtce&}IhKzqBh1&=ImHh!nuWCXD zGxKT7ziRPYw-ff15`GTyF0PF&k~|&c?{$Ias{+@(fot*vf5UpwP$s#PKbUycJWcJI z8*?|UU*k++?~>y%5is703|bKs8PwSxwp03_3_UCLl(hAb2G}Y7FUu7+- ztOxhh(4CvKag?sHcWMZSuZ8N<>*|Ypz2Y@f(ht`a_tzCaRu66^jn#1we)WrTwHa69 zjD!Cpe)Xg5vh-W^#eelOmx5jpPyc&)^oCcAFyJ>4BaC?d`poAOb+zl_9Y5eZMvY3) zJ!7&(A}qt>ddObA6aA1OF6Cv9l=l{}A;IwLf$aKXcwN7oU?lxX=!zLh7wN5s#<*Z_ z-L=}2qR@M~xhILBDj!OO_s=;KPDnS zVLw{AIU+a5D}+aBQY{HE6Zl2s=UVK3DE^}+f}LnRtkisPmGAZZK;u=vRe}x?g)kN+ z!FNVRMH^(o47BM)KI{No6Ibw>$vCy>xys!9natA>6m!+*6*J9t@dGV=v9&R)5byjD zEK}c|tdi{rb+_1Cyn*%}eu^J1NecYI>wsQbCbTfno)c*8z4BTzK;JD}!@P(%pRlp6 zHXHB!01Q$mJ9OP4FX-t{kFKce9!Dt9i_f}4#&0oy+!4S4#gGe#N+hzA>dt~ME8dw9 z?#8T5X8BSnN(UhT3gbsWhYp8vVJ_rZT=J>#ae6)*KpF!QA!sto>^K z;|mh<(iUw7d8e>nuV5?}bb^bo=1Ly|QA1`(aHYer68|R)*yS?6D(w>4+Um=Gc(g_K zW2gPF?Ei|F?x5E4(!W|S$&=Xr7cMK^VD?r9m8S-hk^AP*{rrJ;ewq8kh26rsAk`0} zLH_!H1=Qq5Hk`auQ_rZj4;u#r>=JfZ@H|nKH&WAl2sqnl0Xi~V7VXy*U&%96&sI4u)+HvHh3Sz#v@(? z8{4q2&VSs>2T?&aUS??zV8w8J#H?>%!mo{ui+9ii;Z686+6aO^5Cn~XX}(iPVOn1*+`fHD|jp;nvs! z1QgGLV`ixZNWiNdRBujkzxZ?pHzR+^EG*J#Y(fFOEC3@l>+lf|&fsSC{@|7Sk=0P& z@*X^p`tbePjd&nLmiIlYXni_RN<_Zj_L%LzB;}XqrB;!KuoW6UX+Q*fO=)pr4R`O`Z$ev zm}97n=rM@FmDeCGFrV+0PD@I{_T_#NeBAiw|3~lvsSM@;J~E7}h~VR>KL|dmCCTA} zR}p-ye$?Wlf%MTBqK`JxM+1CjAB8^rkHB)21eSB5+Hk#6fEL=2m={{oss+X4BZfB& zFLTuEsxLwJJkA0_xQ5_?hNqK;Arqkc<_m#-Y=RK9?O;z|t89I($eG$V<5&My0AGg* zJb-k45AS5^LzjiR2gUKu`H~TebqOy3eWUgb6l?2Oyv(6qW*6CyxqAlOC01c`3-()x zhb9gy5UIwx|981_lfQf;ra_Y))1+Q0TY@49q8pV3eZlrF5jHH)SVU zA9}9;yE`j9zC5NF`^+qO1a$B`yhAmj?mH_O1d{7{v}_D51uH({3x>qD$Potg_f`c5 z>Jo~be;+Fd&=l;A{iLknL_8hRzVwWDf0-5+{J=t7&;VjI4e;o5O#3R(bSA)#Uo1T^ zM@dYuimzP6y?EXdckxwev>IX60~C>84TL7kaK$c=n5V6v{5dg{ajxO*xIEW zm=*re38FIO{{Zb-VR!9%$^36yeR)(hyczu0Ptyz*Sh*iRxT0KV=b}tFX(Lg%B+P^Y zFG70CNf`&tip!FGcl8|es#Gkz5K=)!_b_@qA`__>sw`u7F{d58eTH#sKk z=mECb^?A86r+^7Jd9`oEJI*1%Y4{VTp=C<&q;q9H$BcS_GnsG$iu05StNCRiCKN`7 zDgcd0e2LG5f2bt|-C41jg@6gAFo#q5N^t6MDHVXMj0=n1oElay2Z8v9HuvqcLNwxBN?YDmQ~!H6;;_qPX=3KL4#rpbhq+s#d6Ml6H# z&G-_u%3_*F2#BIE)9(^f=D#G#DI}aW@^@L0twWF*7x|Xwii%#rj!g>>LuMQvv_GBb zbj>MXg=Sk(n|b!v0?c|zqC|mO@eAo!*`P!8YvmfNU)zZgcx}5Rb(RB$~ zXc{pUa7)xj%Fr|XLaq%N+EVG3p+xi|##ko(G8x}BiC%au6q*|KBE}9{Cf;!c?S~2P z;xpkB6$~rHa|poj>{}op2INJCuo;Cyq$U2u%m-4P2qc8R2pY*H6y9K$Ca?CbS@qt~ zLyQTUi}v|`qx|-vQYfWd$vskXuuv&bMzt$sn|91&LuP~Kzzxl;+Q~93h#mJBM}>3G z5dYt!m8Hz1tRRdAKeDP*O#hL4ip(2FknIRE6reUFBp$`|rE>*7jv*}Zbj8`!-FJ_D z%u62@V7z88-PWSxZreiEL2tIX$>J_lCE#)lEw1ewtQI~mAg~(*&sJbJ+8aQ2gB}hK ziIb%9+DxJD@o~F!KIhZG!$Bi9udguQ^P@ks;u5)47w> zZ>RBLdiUf^@0CS_`657OO@3#3?{_JI)I)i#^=-r9(L(tOlNq>N#RAgP{y#CmLjr3n ze&};X(*Sqix;D@Z|0aj;;BYXldPdVNjaJLifD%i#G*^eKH3L3+rrva6jSk-bv+xm2G zJ?FUN0fIZ1*61Fop=Zh^PLRzfnBP&SRIU8_apMH>qt>Go-XYaI9`wbB`g{3xk z%z@PAW(T-Rm`@%=cY!Sr(u9TiqdygM!%1zp3&sGZh}0H;gt_T{m0`qF&T9G>q<7G5 zpfe5NFu^7rD}R*YeI>XZg5P$3>Yv5&g;(+GR6m3WsL6jZV)jLH>|16xk9*fud6~Hh z#vs%_Ipb8$QJ*YZb*yna+Ti{9ZgN{X37n#x)tszPCq0PE2I%U1em`cpP;;p!Tb9Y) zetP#=P0BTSPT%dMcO{ZUjbvb%^B>mlHwz&eOM9ew9~RFWt7=Qe0-VN@`4$)hxJXFw zU>S14g91_IE)u-x=O6dmM)^sWR)&huU@af5{wU?=#$yr>)%{!R??&$k#bUI9S*gxH z0G^1EnKxCYLzAGj8X2mn1cXpV4BzG0P2gZg9LOP@2y_#Ib{<^ZO2w@wqtck0nv_{x zSaJNQ9C{4&K`zjbXccj_4*m{c<)zMlrgRsCS253cSGqWRG^%!pwW;FQ@3oLkod-?k)RTOsJ? zFYykZ(CgUgJ#IS2=xPRvaF_xB!9kE~f2rfZbm6loPC~vOM~z_LH7q_9yT=zJ;tQAY zML6_}Z%V-N`X(5|_Y4>rwV;a9c!wB&tk+9rOF7a=Z7hW_z@^=jr4i7eC_r;?1e#9| z2hDqeqEH~3h2{x;6NKg|ulAXEH<$PV6;;IIqHE=*4K(%;BaT8&aY_0rCUh`TS5Ezxu!V0O3iQBuMOwo|iebfi}!6 zcteKSKL{2Y0Dw9!6(>ZDnzPJ&IDrMjA%J&8HaL_+8(g8QEd5r=?9+mMNgJ?$i>kL4 zhIGIM)R~-BM)`n?PPeqg+BN5gA;mj;ST8L57G`gwUAp0PtVVs|8!Scq))+tI^n^Q-4j|HskrbrJ99WdHNBrYOk;(5-vziZhhWYVpyaPx+} z*~k1*9Dj(nXO~rb)~Ms0%~F=?@ReE2rVM_^trwG3qNSC1R%F}UOWS$EgW1ctn6M~2 z$r5}-{@!+nmA@cbneW1B9}ENZ7%r7ErF9Su@Y*nZHp}|`@Yys1?LfL5hofy(x%k=m z!n=_%7egCg_+x$;5~vak9beeN7h!?QHzl+GD-=tMO0X^C8hAJAu-)$@T7s@p1W$oV zV>%Lj^e*g^f==)2-E{}mdWr-ww<%o_+&c0lL{Nt?AvtAB+P|3)%M)WFG5WTPgWl>0INU zgOHFyl{6MHa>cD=5UPRcy^6VESA%etRP@S?mAE7zc0j^Qlho8oaL)VDcHcWj)}b2l z!M2`>tykjz}D;p4>(=;n)Xm=yUQXOdAcIS?Ka1^Cwu+Ja+Mu`UYafWGF6KMgb`05zkbTxPj?%T6oL-sn#T-K5 zJ9HDa4o5dw2kR1@LjseOQzSy*(n-M|udCek{QEZGQNJm_iT&RGA=dSCEe!|Py-cYF zv1w=zue*<}a7NaxIT&29s7--=h-ZvLU-BN4F0 z9BjBQ3tY1u{80d?!^JvNTpP~3k!@hCew%}{TQ>BddPZSA_?TtzdYQWhY>mXCh?0~} z;zG0iMe;!cu;t- zL!8}1w9Vy>}v?g4anMWif$l|oQT{5C^s8_AZSBr z(m!bk5L_!wik!|l(8|m@S&?n&pH$BS9peiQ=3Fu7d=CNq40v>|Vs$(%CYa9gblZ6W z<=aH$c1bIsfBjXpVEWK>@39|^Fczt+&Ng~0s&Us3&|lCh0E3$J`j1wPotwASpb`4Z z=@ZCDyI!FNuT1|6D<7r7K(gS)BHVSd$h#h7SKY`BRoKfQuX58N*tcen*cMe3Wsql# zv`0IVw674K336j+@<(>j&a_g*Efm0>?$BmrQ;0pWfUvRg{qYW2)(W-+TjVY8X(5S0 zIBw$L1Iv5j3oiwA1vOhEsjZM^6OTaw%@$uM_I!A`&w0?cq?Z(SE1G+bY6>V0Mz`T{ z&zBAYmEEK0lkI~g+Oivg^k9DE(*xV@+rrL0lbu^nE04;&o8n1q*Xw|r`fhl3aKO7p zRBM~LniOLu+yE`j2}~MQaa6@1*2iRQg_S$$#%kEL5cBLAtiq&QhkZFEe%Hi?iS00P z4}nRQ?79f1j`jq5guTEYuY2VR*RD4P?x$!Pd>D2KeV7P!J&?@Vu$0Vc>NJ_8$uXK- zAW1|YuTg!RL}BKOKezNI{SSKU#Z%AH+ZwsH48G3Zl))S*FE)FKvr_2HZ4Wb@dU+U9 zGx(Z6Hg=Pwi&XW`zmGLzi{~vn#JhX=hBD$AKPb9cJ<~LiopiXSF)SUV8^kmR*-ec_ zxL0-8=-vkG;qQK^Wwrf9(U;R^yoNt5qs(kqGm&?X`MuuS>22Jg(xKehZS z4JUrC#6~W2&mw-T;hfANql$f*xE`DGoGUp*^34J5c3XQ>#UOJP_3u||jtG|10+V%x zSgFY_DM+$>BABH?vJ`{hm<4hlbz`yd+%lL)l{A=9Fc+Aaznw_{DM=upYoxv(qF?Wq z$983dCoNdLF2>c8D2@1+?wroyAp6oQhwnDQH(>N;WC7Ek1&e12WHG#kjFyFkj*O#W zpPW<0od)?WWD+va-lR1GFTh;zSf>W34(jYlVOvCo@cRgifgwD?wR^)u_@*4maTM=l zLE(WsZCA<-+N~fH_M@z)7-k^eHlpHOBn<6y%%Ljqfso$&NZH6 zJWz$KDN3$_dmuOJ`<<{FN+ibGfSAS_4kSd1q7%Ub{!rv0DUmuIf=Ns{se@g64wdY% zhTw&ioT5#;;l&Kvt73Ai5xH4l2W3F5logrl9-=!zY*dMhD6KR(M+k!Y`4FbKAP=fU zkQqQ?qBH6Z;pb+`CL&Srr<#2}k>3rP>IM|Sg-g3JCN^iZPL_NjqjjmEL&aqeuYm|z zow@l8UtBJ#Xy+SHg5;*($Sv583e9+@j1kb5W&8xaxsoXg73#ZL3f(sK>BmZaQot~7 zq>o5_yT4wL`hudo0pfH0dC3Vo(bBcrf_q zjfF9o-W@XP2DO186P5hgayLt1x&{KQ&`7H$$_kDD0xL`sc!U*zCHKqe8(sh211&R% zt=`+{qG?AigaIWWG;iT$hI*97zrU6r*Uis~5h`F2L60r4JMwcd-nI0+ zjNj1Z`AU2NcQJ!>LLjJp@ELt@l(1>hLMXC-Oku;tCSedRhdrIIQg#S^{uNht95K*0 z7A3z0>V`yUXC-NMeBxH&TxR%`XG0v3>=J(`#u4@LyCzp0#bE;$OR!uH9d4!nlk(dm zacuJCWW4hTW)W6`7t&P(fqsUF?^pO4`gJkWfxZ|MSu$?70-Vr$EXM2i$>Ux-_-n0b z>6%<|IM8sUw7PdaTD_yRI>%b^PHBRuN35?2ta-({R`fQsHoBcnJ3QHie#f|y7R2<5 zBXNsmfu)tp{6=7>o#Du!>1$CT&(BQrD@q0pJ{e@cMbR_R3v3i+4-+wj-GTOjsSQ=f z`NQmPfea(%8p8Z0TYU0K>rp3a%_u3J0`12XS}M!3v$_1RD7!b49kXNjCVtle^iUs_ zeTE*7%sGCI+=U%TJR*B1Unp3EuK~8;_ze6vdQ~$XnN`?FQO;Xv^W`Zl%=MC=9T(Vl z1lPTR=W7Dj6lMG||1!Ol>y?4)Rqi@n~Yn_Jp3tB{gSsu&mx z_QEuEj9*iGhgs{vd)fMW2x?dz9?g^HrRU&4otSz3+ivsY+o%`tPECO>lp}mf!6?KD zrUl{Tyj$gFrq~B(;v?rzoplyR-I?#Op_oA>erR54YDWcd+VLJ#EgnSdR=+`(=h;XO z+#7qp0lAbaQoj|{#TQJ4yVlEmzXxv^sv5t#kq=ns7m}E-0`r~N;8C3CtgDMZ%}?&B zXy-TJL&!Sok--;Yg3==>)y+BBTdj*XcKk=H&n$W$G_vpV+OLmVVF5 z$7TwAxQ7A`Oh$nsve%o!I7!sCK?` zBFb@vFoNTXgxOczv2$pywz^3r6q2OnMyN;@5P;4hMDHbTq+f(!a3h_An)O=1YdX7T^R)w4J#DFo4MsZ?$l^oe1OL9LlkE@^)b@z{m<@ zPLBF$LzVbN`mY9$%=+)z{%i0+k23wz&b;`sb|RENs+cyp2y3TyzO&0Bn0K)md4*^v zuD#u+b{cN=_&MHLLeb&t zke3D6fDVypldbBIal5j8whz<T>fJr#93j&b@-BofuFXAdTsyIZ+!Rw`piczSj<7rS8(#=|tHFzP@cn@MeS_FiM$%`5} z!f2D-9r!XwKi!=b9`nhRve41u>p(}(a1k!davJl^Ox0BH?2NM;uBd@9znqtuY3NYY z%-+dN14`hm;dRL3?>tblp3@=$Bb|G@I~82<1;uU9~PH|aGb zkZqvs#%vpyM#E`ppA1u5jqcCm>I_PMkv1H%EVv8xc(6!%dX6r&b9A0yO5Gg|f+@gF z0vjc8OBjLmKoKqylKDT=j=P@DZwJA; z5U$vtpFprUqQo$0v4CTPX3$c>U*<63dMC;U`l_W_y^=sxBm^DzNDA`bSwdv&V-aPr zS7BlReL3U}LK}#sdLWFEuZS^%@E9K61q^}LB_;xklCY+rFTUV09^L>OrCE9%_6vxq zMXrU6>3IxAM!Y0LD4PfUC*S2nW+#h7bF{TqL*<$m)8BI3Ey8&lL^*(uIX+0)v%Qz#*L!(Zb zj#6?BD3%Y0ZNS$1XB8U8))xSFZ=6MMfu$J$u)#Uv9;F|QE(V`-d%t;{Qw5Q^j3^6HJ8W^x*mgZjE5-VmvA7&G)Yjy6BbK$BwuPPHrk@Yd(hxc! zVVp)N9}v_OF@m(@gQeswEgUMb^s>q7J+PiuA{K`reea%2?0zdUGw{$cQR5@tbY z2!Ft|fPkoy-Y3dHNpb`7Tgr!6n_kTnN^|jTM}YMplyTZ??Ld6dZzN)@kJlY{@EYIh zH&)_Mgnma}U*XX-(MudZ_=Eh0=jr-nwxJ8Gm} z%%~5JB$upXiyhdhetEWr&tPM3M#>+rivWRKgG77_3PbL{5uI2?gTb1_{9i(~0`k~^ z%pS?Y4N@~_%Z!^_wnk$)AY02Mif#fwhMkaWE=4OI2t+XXKzU$D^XfOz>|ArX^&H!< zUh1@7bKENocHaz00%=dYQyp)PLhJ|%O+bvDzpVyAk1y zJ@S%1AU$!}X3t!dq*=k@p^`mbvv^!L@S4R7^i0W^gj}v=K!Hd`dsAi(7ov1LD(Z=& z43K_;oY!WVfWt&QLsT66NS&{9n6LhzW^j^nYKzaQZM=de&P_Im!e@W;O~O3;bbz~7 zv56?Vnw=M89^8OA?3^2r%!feDq*McYg$BP3I{qers$ z$(SHakw+6MH_9OSZI-5hgoV1$PRZ~tTZhiDlL$bN=heOz?|w|&OK!w1foN^~z#50` zQWyey3Aele+{+{bM$qyS-EQxD*w9ozsMeKd-=Xo+ZpnA9FoqPl74G1UVB6-5KTAY8 z%W~||3XhtF5Kxc>crOs*p52_?z`h!KAp4$R6SUxg>5^sHKghj@rY4)Rdm)oKtW_fY zFnaq5d^x7V-ZCbdL%Jv7&Tx@|ixB~2N+g4ObSxGIdK^Ev_#H5|U_h;qb-Z?p^TERl zC{D?(ic>QGXB6l0f6h~!t_64V@b2z=aFhu^g~+=V|8?J>x4>pQu?xB_1EnE{T$j6R zU|rrLUyPJUUO@^DO))Ec40J8VO#Dey-z_|;Ih^hV<`Ngee(RrGo?7k#jKm8 zEnLjXm5b}Xt4C%-p^2&Pm`+Do*_$zW>Ke&u5qF)%0pM`iEqMd&wlgK?^O^xk&+kqF zGt16fd_L>tG7Y}wa=*(N^ZeW=XP@H>H_O3pFS=OgQ)2C(v&RqCoPd!9FoA72$5ysu zgLzZ(D7(gv;n5H@l6EZ2U=9b8!o~Sf9w>2!6(-EPgzK-XNgk0_{7G>eylma>6>h%FXXC zCZ;TYn%E{}=IEogZ-$(Mhe8VB2F({;62uK30dk<-T#zf4)}5}6XhS2sezWY-Tq8p8 z+w;hm&Zqy7TQCD;vCU{T;a1ifN>uvX5^nBLyJqeY_3%Ss-Er-vnMZ-v#zS~w%lR$b z1`MHJd*wpEk~M>v863jnHFF+j3v2q#>z7Cjmytw~nu7nhcN`d2jz>}c(GC$eGWkME8 zT;KlOf{K zVHnTM6GyD>0DTGb?Tus-cRZeDl18#ZHUHGGBbzz0b`;g<1$X|CUR2DW zN6fAZY4^CsMBoE)p(FxAFqx{_Vf#*L!zOOh_Mu75h#c%egZfR!GzurD&2NE0=dMq{ zwfRQq^#Dv?(;$ybohFksLveO7cMAbVu*9!>Y72xUwAr)%j^6AY*N}4FC^|{1xakEb z1h>k3QRcgH0;QUdz3fI#3>FXG!bPNIxDLtBO_ZM_P1PLAbBNBxD2;2LmLkQ<*Jc%t zzmz+>0}xANJ>8DFAy@5cY?>A;bV#?BETr06TzAssL~DVV9kXeAs<(f$DZ?RYvzq znE-o_!UL8P%9CN$>+x<91fy{0R5V~5KN%+%_-nQ6)1^+Th-*!x3cWp0aYZHpbJTS= z6*(lK43)${cD55314YVe@7b4hL9Ih&zF$21Ja4E!eShD^Sh5QPIX)XPdm`!`!G~r3 z!;;yRcv!-R<$TC}!7SX1WH(oLXiVvaqUyJNQ<8Tzd0i66R>#A54$Mc1y?OEF)}Bfb zzn~v0MO)9-^P|qcn1Yb8Far~t(dHsAqgoPDY{tQ|U5nMBj9~_7=xh5xmAqA|srwTB zW^oXlL9R|`dE!U0yMJRd)RAzNLd=SsY~43vM+CM2u*>OjCOl3YmZIcOjz6V+tJ`wz z6PI&M(JUUgmw;6Yc$@K0tUPNyf@7rfY!F7dm&Sm`pJA@@hEBxH8a^JjzJpwSPy}Sv zl&!A}^-<*X4eqSmoLSnALKI`QgL6OYfzr&SRFCpq`1PFUP%93T!!Odl+b*;1YvVGV zc4Xi|2hzm0{<@58$x}3M*ZTD63bQLpce${>mV3~|JKq$Q)(ddM#u~W(3~+l|ip*Ru z1_{hC@G~qm#-T-o)bNb{!AoRx7guYQP*af6osg0;@TL%>PlcemU4Ti?CopxHsgOJ( zP3J3&N_K@={2qKUEQ^nJEH3LJ!Qu!zcPxG!=sySiwpl#B@M=_*WAix$*!*jS*!-kn z*?cnCmi?#as$pOY0O7rk?Q9aQRD1|(vm8G7yxH<~<$q0H*ThKT#K0aXZz47i*%4Yc zkDkt-W$6jsK#h(lOxi1*2Mj|du<2(&t^7B;0HJ0|CatuFeKI*QXwc)uFuLrq7ig=T zsa8Z4vq4UaKOm&YqyW6(YgGo;n#YT2pom`yBIwHB!Mp(92=)ulqEYeyBnhsIT)yOBR-wd-O)>-lUs&}gI!!u zOy+V39UPLJnTSnXuz}UDSrRGCCEZWxc=OKGt_s?0r zEZ(*Yf^Ok<0g&7NBJIEa(qE)4ZfJiosgMvnUh7#ZZW=t?Y~T&tUwl~9%5!zuJqV!! zAKbfx?85y|vI6ph*eIxQ1-XR*`nq`PZ+wM8`U54!)aj6yFaZaFG;w&W;RlUeTw1$6 z-m%;kgOBaJE4ofw2p#NGq#2y08n~GR)&c_qMl5#j?|Wd^`44c{1NL6}K^YIp@B})z zi9-ZzB03J(bF+z3vaNxu_U!gEp9B=Xw2CjJYbsx2#TRbi^L*nZzOYwcm7wcgb7Zxn|AzA~gFn`K=~*X!18r9@pe1O$H>H2=C(+9G9%}Z+E7Lp0b(> z1T!K<<{wz_N*aM^aotS%L|-O2{*Z2ggq{6`2S}!FB-R4fz?tD0tQ*5tVTVX(;vhS0 z99eD;z|#J-@&BrrKLBrJI|p7)4Kb)<{Y);`tEYmnktNho3q}bzzmURU z8MMI1Kv^mAShyCtz*xIop0$!S=TtO9w{dNcHy_$g=6KLoko$eRGuJ@xp_19w3%S7h z@ySAdg2_z*Cw**yUv&k=SNXpC7Y&3+ri1OO?SltN4Q`N0gA|PJ1F}~LkksZw<5x*A zo>TtuPD60!m-^FNEvildvq&RQjq~I~4wLMfxv$Hx&FE%v_(YpQ`xM{+Cb*ByVBkAY#DM+f_*=$5w_RlIxf)VK(n~|PsF!RbKA3(1u9iFyWtgwUUkD^@bPLuhGnJe#!;lw^5RH@{IuU0{9tjE`-&X?_`Wx-{?@7Ot zX$VN`7Zr#LI70))ra;J>YEpWyaN07J<``a@3}fFRUOhIL7Y%a3Dx4WS;4XgRsN<*r zJ#n=RKha+ZU!!%apUqRPJZwiEdc1@`Qdi)}-UQ4>i1HN`z4B^WIj@D<=ik?kM;PXP zznKI^xA@ho1o%_%(WEL5whA(M-D3ZS{Zk^$VH_Z%n}Vh?#7z%B!JBI78#@xU0HH%M zCxdzxHLxDYnI=yB4fN4D!BhKCRTDo>3Yq|w;EU)-tJrrC#2%%f2a(2ELEp-gH3Tm+ zpM!c1%|6+B0?}hH-=*__fR`n>ZD24_W;Z2v4FbjF8YI%GhlK*Ba`WSGA*li2Rrjjk zlv;tkV$Ne#c6biPuoAA3R|!*kIVTYvW+=r#Ou*VHD0LD<;nsT%n*0+15_ucK#7iTp z2GDO$Q+_5}N;o+>*0I>viBhuIc9z3z%Pf9`6js_BAq7#&Xlu2pd5OG|SDo~i&obKw z`P$bC7A1`q;c%X0z$7L?0ZP%MXT$s6|Lr>3Ii{PwS17c=YwC3g1U5{a_R(0pN;fnnBySqXXpM`o9BY77!d zy(nmm{ZT9;|E&T6MO(nP!z}8d$=s*{2-FvOpOYW3r)0mdk){SQKw?jAkODe&hpbea z$`9@b;LZ)fsV`7Ef5r!t(qMKj1C&|*Th0FOq8IXI zB1pur=$z0$m)~0wF}H8jzSBHw#DwcSlsR?~smqaZ&MQPoGq07Mt||i6l>x^^W)G3v zi?k|W6HOwgLN6q^oCDIIex}EG=uF0oyVz*RWU^mrQ}G#ry^DF#;L0VcCXO{Z6c?IMsi`j9sL>yV1OLB}*N(gv9y9@A(n^1y%_(};Ef*)auf zWjjBJ6z);IY3{!4K*?c!8|^Gnd>il(Aj)9VoTqbHNThby2+J0Xcuz&I(90Ys1M~qn z)lyE9R|!-34ACcDVmIT15?RGhIBPtHbz$aH>kmv+`|b>(IG@B=eQuK4&V~x1HfeQt zJ*}cnfI_cHO{vXQIDA@q$W%!n&>$$pwmPMO_)-t-5eCqQ_I^7x21w^(I%iFe(g6lO z?~;a-g{W@KUz<5=Y9+Dria69-MiX#=7hyDkQP35bd~oFQFA{O8gZir){a3lct&kaR z^Q2eC_~C7ITfv{yW*3ySOUt7BfV5Wo%}bvMo;np1l*8^Vv;jqIZGp`Bx6+d;^}?0z^Y3dsO$Kv($nvBl@0zc3RSq455g4&tN1ZrLqMa>NEORid3y0m zNxEbtn`)~rYCVU=d%E_Z8R&(zlsQ}67H9IY(74Q`{I?j9>5es0g4Lp}(AZPaq;# zYjsf>Tt3_&(?C+7A~~2_=w&+sKu7#c13;GvO5OB7jW?8v z>6z?x5JiFcTZ|WE|ICqQ^VybvMRjB*#W1M`RY2q9oCNzF5S;^B;&47Qifo{azBe{* zM?N@;8FLfd9G{!w?<5pfp7R|SKg=Rp*xlfd_hk-X2+aH!bdW?9azA-&h~Li+3+-~r z7uXR0X1)mT+-J9-@6b2Fo%^1WGpO1WJ|F>uMjU|j1!m+V&!6m8^S}&5k$Sar!1)Rt z($b_SGq`OI^NHzgtvRs%d9;SfU75>J&*{Je+)V4e+Na_jf0thPY$(KzZ^Lzn=s|3X zsm#@Z(SVi=UPH;U$J>{2oPfr)uJ?*DfAi3cd8lQ^<;>VzpV_&dOJ_2uEnusJYZH5* zmD2!184N(dfCRm(0}|)+mW7Mfuk-CPY=*xS?EnMcN7CTt_`EM3e9cTgN%Z1znjERg z&}4bIS(7(3c}0`mBujw)#6LI}J0(iIF=*`+OLvpX>ob#pgCa^Bq#!dpRab2E2%HfT zKMX{J%zjAtGM@>}+_C92hA_tPcZi%lBey%`?5~FDOZEq!ePV>RbZ_weLVJVPWvZ~j z$G3T$c@=2!zH;vIUBx}VOSGB)I8jjWjwY{Z@@aVoK!fwK>L11ajM9D&Opo@TgAOA4 zh52Tn@o?Pvst^~=EQ3!P-9-~G00d4~cbi%>z{GmhRaRzxww<3G=RQf8*6sX60zp%#rP@r~&QJcpw(*ms z*(L82YP0-?x4Ta;zCJSA{8)icT4Cs+hDI|zFMA=>@{}56Z!*U*JK56d?w8%gFP#!c z(28#;9}&2Ims;8?@!tflxiy1(&d5+e8~8=&eeD-4JyemXs)-43_HJJ0N-(!54ovRM z#Mtf8_<|BD$TVe?j2&s1!y#U7-d{ls@oTqGDc<=cdsYkkBIxx>h)XH$RNTzOBrS?t z!7K%e`+0%l+5^QUP#mDu;&3w)5)Q?kHB52m7AS69pg6SoO2`x~4mUGvq&T6o0?>^v zP~4w^U)R_qiUS6Oi+_zXTiBm6jXcB9y2*wHDMH*8_S-rAkz6stDJZ z`kY#K$WFb&C&0ls3%tL38}FB2x%Kbg-^TmT%-Q<)qvme?{rlT^|J1j){{3gJ+WPwk zuiN_jQA@V|zHS@u$9;F}-`8&A{n^3y5qU8e`#y^P00)v*G31+l6#nisa{^V`%Gygx z>oIY?3MovV`r6)^pP&;A#EPh04lhZ+=Bi_8ba0^1yBz{}F~0`?(+P6sKu<#6Wq zA3(0iz%uM&UVa$AwlXaO-$ray=3L zWXf@%Ia(PP){!_rma|3G`QJ3S?gmwQvStSe(F`w1FeVDhda$U-hs@fHucen z33u%J>kGGJ-2_(SAfz>2O=4na)z{uXb615?oD}1gkdDs*R+t`+JJr$yl~ZZuRZ)Ac zy5Ib_lmYXJFN@8s<2DYN2Nt}C!ER|q`yVSy#XiEGBVxvu@xr`(H~k(mxKf(p4aO#8 z1y3-tETB0!QVkXe5r|LqK4EVG&t*2Vz2DRBY?dFp>iFa@M+88e2TfZ z@Z-hP^f3T&xy{^9J})R08yzfoV1+pV!)k&kQakCxlbVY9Esz$MO#Jtr*vH+cIDG#5 z@UE=Shj;DndGPKb@aFs^9AJWxJRhyqxi!2V#M4V9P9TfeIs6sQG*i^BPr#V#uvT=8yOz5(qJ7s#1}p( zkMG}sTkrS1=vT61eBoXCW=DPFS28lb@VokEB;T--r?iq-d||6r5(`!`D!%Yb`oXA3 zB|F6z9-(h`id3?5eBti;W@oL0tD%Uf(eZ_Eb9y(`KRQ^)nE1jcm-6(^i%YTN@dLT?04yyBd&CL>In)9&IdhCwRuGbj6JFQa z3W6eUHw_01-a25=xO*Kid<;lH`VJ>Oociq^d+X%PVOrTRpu9FQ&B}%WqYx@f?GG8y8fbRuL)s<-r{ z^!t<3?@dOW(-2Ld5KS#wu?5G?O|K}$N-Qd^qQftS(i%HnIq4*!jIxRIH*kE)diWl7 z>;SoBg~LgL#Mtn8ASO;qo8jJzM4Fu5GEDu_LBoA3!ii-AH^b$b46$3<_acB8E{BM# z$?127fq%M{8QFp(8`K~^6hcm=r^;=P#vj?#~>d|r5o!+9xj!ZTJ_O-}#0@0GI2=|}sr z2&G?FpMJhhCgScy*2!HZdJjo^BR?JL@7hhDK+1OV2}1X~cGgFbvD5TXNmt3_^cqOQ z$>|6CvMBtazE@&X(rYvywB9kAuhf+fjkk|J+QF3uRX0)}?da-+j?>uE{*i#p%9Zp7 z06+acpvP`cS^+fP@5w8v{+QnasJol>*(g^W^jumW?c^%mdG<_vwR2ZVdJ~{ezX9OW zZvu8Lcl7MjsNo#YV`jq)>>uO4-DURYaJ!2uJwAIhZsWFWPv90G`UQZ7EPvV@^wwl)#OY~rf71qCMRf8qsatK4$x#@O~z{S zNlkXqWTYlVn!JCYwBb!n1~qv>lczO#LX$@{S))mxCco9>4oy~Qa*HN6Y4SZy7E6N8 z3H%D#cgv3dU;FNV?YsY9?7O8=D=lcr+>rk=XW#WiUyAYY6M5>}F%t&2+rEoH0%I&_ z$wWYj*mn_FoP7sif|ks7+jn`Oz=F$Jy?LO7?7KWr)V@!-A z{@1<}i|qed`|jy|#Ws3ElSedJqe-78zt!XpO;%`fizYW|@;yx!Ym(NaLz62tY1QOn zO}?qgS2bzWuP)BsUgfv zgk`VGlj?Y1CkS`e|gsLFDn&LVdHKD1AOgRM-sn{rIA@ zFkS7{{waR-5ghZtJ2mt$zVK?_il-Wo9X{+Eiza8z!mBmd(H1+UNyH^~N*faY76Ks` zOvA8ma(Z1~Z%p=dK`SGkgo)|iZ4P2J&#)tT9mJ!YVMozEfa};00*DRec&sQK7Y*-C zFRe>$E{mr)qa8qV`2_kz>(hT_ZxKZc_%X(*#OpYW>YlEv-4stX>sR7Wn>^uhY}G^T z{V9IU! zFq}CFgGM+SukI7d!P4&jQl1aneLL<2tM%Q8BY^*9N_S~h9S?BJ=t5}UE>~G|ChP% zfzPrk``={9FzlX5H5GdwYt&Gbp;TL9JyYntr$c8^E&tTsvYLUp7lthxHh4DU>DdF6 z_J)PEvOg41nq{-2_G&!J*gf` z^IteARMUUA8cr#ReMOK4q-n^JM9(Cewc!k0P|`7PT0!u+$BZX37DMdH7JR_4e%Fun zJ1iCfKuFhM+V@>5Eh|F+*C9e99G#9L_oQcMdn^yl|H6$Xe_h1ixfd;|PREP0ot@<} z3g0R~1NaG2>b8;=B&Ev?jIm%bxXw85wVx2YS{zdfOR2B~3)k~e+OF*roVX$9#%9wy>WNZ%oRx7`g8GCc#=_&lAqH4`NP?ru`=$vi&Zk=G>A@|9=gOhVpwz zyi&Aiu6sxpnC?dxkJ$bD!|pe`X}~qXb#GVm+s&m-7Z6JEqVXshC)VT*{uqz3Mc>CG zPeB^|wm}YE&cP{S*n<%V-9o^y8RA&_Hy|gGMGxbGQ{iPJe}F>ygDlJS2Py0ct`=zU z+u+Ci;CtiX5AxwNKt?+O6>?1~SvE-=Vw2Fdqp%0x^vkL5Qdi&b{s%jf!})i_Z!(Ss zIsP3*rwsL%xbdYYhxm7BbNy)jCE#mtpv(J_-#u`gpLimF8S;f~VS^}>(E(cCb4QeU zMTK6`7)Ap7y!S%4pBR|X`1S=S_B`$%?e>m2BGZJ!h5s=J|6>vO5B1W*uVjQ@H-uj|gkLv=UpIuGHx7Q? zTlgOz8Ga2FaPIKnn|%!M-%|wqKb6=w!D~GSgMqhnJ5b;i)f9Qh9BaOQ;PLJGK^4@s z&wC$uyf;5M-`;LNA~?gnJtE+i9wyjc5S-}V76k8fZwrHQ?rmW(!M!aCUPPTLwbYG@gVMQTY@&+4!jEe z>GNL0wgcXs{p`BUxVH03HnKgMp7>ccz13;-#Z2#*NL9Yj(~%eH%wuM%pyPyoC!1;&_eir;obQp+w&(}*`7b) z-%d+|k*rFek&oEV)n(!V*OzE~TC%$fNhrj3@CrSH_q}>|vEAqcMP53Z4SR+MpS#NY zZN@+urB`vA6O>-PW=`&cnLE4VnVneNbDr!cK-_` zvJIn?Eaj~!r5>-fX_K2{XVDYP?tDvPVu5?k4*X<2n!V1{pRC7j9fu>zd9=MK82?Q( z%ZdAGN*u-}iD8CQmNmn{*26t4Zpr2@To_dL5nPAZyUOt@=sU^k9~hy9S0YZHYNlH` zKf^Q7+tZlkJev2#nYr`J;CojN?>u_lIL+l%ZqihM9@NZ>6Ghw=nM!a6Y`7^vFpm>y zJeFF@!nmKAX-(vpGJZj)kvKSY)m-WZJD1A4=QJ~mVXolrE8JWP-t+pg0JLr%dIS!e zJ-Pb1@Y5M{_~97`_3UNz-R01Bc9;VME`-pH9w30-Cg`@%clybpzSE1ovXSGVs^^;XE!N?1 zjM$G?@uP7KKSA*}Qx_r*US%mvF^Ubz;EXb+VaaZGUe)xzS<7I@f=$zu_O)O8sbdfe z6Rt~$fP(gccr&wR_cE6C5~?e9tZDBpr-?#y2D}dwJdg}RQ||Q=+t7OgkD)+wK>I1a zWk7>7Mg*)|X}yK~5b6=nr()BBg;mLWt8ks4#JF=Li&bMoO+mq)dBd}6FvgJ{T0XCsoKcFy)M9wR)lSLd z>>pr?k~WMSVH~Ti^Z+K&>6E!YdpBfmVskA9n=JUPeW3P4$6vOKM=O6iE*~m?P8gw4 z$A*oH`^m$QKZ8=&qw=R^H1cOvuKZ!H;QY&9kNhd0Wbp&jfQty$TG9fNU>~68FE6S> zSVWy=k~ao#BWIZ)9^D~C(X)Wbm756-&2op4N_XWu(x|Vl_`~At!iSMc>BA|!L4{Yt zGR3wjp7-+I5Hry`0E(SeQ@X2?f0e{^qOQqE)r^EZD$F6rV`lFgl{6VcwR&Yr8l zb^OmzMdG2)4d2Rp_nTI_Kwe@k6SAAt_o;e~&{SReKDe9E-s=wN!6` zL9we-$E9kq)W{fv)D+;ENQ{MMn2AGAV|Em2EyH*~sWyfY9>6A6=?8rMFF|ep;})Y# z7gFi&R2#s9Hn?9B8an_hU3pkmcovr%q-#ZxDOlt%FG}G0pa3{*_qUm&Fpk3x?KxSHRk$$Yqu|A&fw|KaGf8M=;tu(DMJ1Yr&?s-k7Xi=DDkNrta)sp@NFGlbwtlULru z2=-@FE#wfBwuH3@y?*2ReA zie|)3o4=h^fMP7T0_c-72R&qVXT0EdKLZp#6G0```}g}hpTWxvD)H`c5Fxye$%5f| z;?=?c@s5G^LH2bA`x@6Z>hou-Q*+R?DOJ-4AnqYbAWk4jlMhzo+&UH7!D85%$yc#5 ziT>1pn$tGAKCuhi8SaYmXjNuNEMsU?${FSbl zeQPg?^NI#E5q5S%7jN)mY%V8F=q=S3x*s66Rr^g8JPdMmos~cwuQ+XD{2*C!cfj~k zo$RKw+|n;7k>bWFIu$K9?o^O2)&&M?Vr_*MVqNjP1|O?IFYB2I5j{JV*a`X7#$F1# z+N%iu4aQgA@De5(*&;a7btaS9XL|r{Wu4B@=h!__P7x;rX(Tm@l9z_2e_YN|2!yfl)&|O#=U%23mGUySHtFN1e0RX*tO4y zUIJ>1hR>~=ba9mfHWm!nUQmXtdSDslfK|)_8bWw8S=Q%di5Zg-XWD*}Mm-ZyPnIJ% zEY%-PkSu7nReOj5wF)0h56B|C+H?cHp!U@zb*u>wF+SAWhf+Q?*oQI#sZJ;lR;VIF zyF73wPjH$ZuEr5KFq%}{=`DShbu*fq4$MMX!kGZGfvw@*H)U&e@=hJ*g zhtPKjz7PV{w8(x&p-L{$jfz3!;B}LQyPOX#_94!PW%dDMx$V`O;8b)Pzmb;N5i2bW z>+SO@``l@tJNUe0a}1ZBp#NnubMT-pPAJWS=yLaCBlnj=hy}kiIew-KiQX*NsIBOp z;F>1G6~*k6CXyjKh6)rQ77rR?b(&nenK=Rel@>mO!}d_m=-~SZ;hX%1@Ermz;eX^U zB>d}@m7UwdtnlLESTeAUvXsBf{2%hNCX|<~Kj<&C^0Ex*VG-&JKvzesQEuwoN@vH9 z4I?*i{y2?iHfMUM{JimbqMYuhi>oOR*&qDzeof?_9HjRcMZ3<1-i^NPBouh=wa;CA zUb30MA{ZOYR=BB#luQIzi7>M9#j!{N=btH%v5w-5rFylZn^VPaU@@V@%;OUzPoyy5 z-&?A!)DV`2Jk56!p2=;mP6~c~V?;PMg~G8R`nulI1SJTl1FCMQ#*0`XO?ZU>I*yG% zRkZ?ibxE-Wu})XZ_7NIUc5$ms3tF@^a$1oQj!jNDN-#i#IdXAhS12C=SFU_i{Q!?w zfCtwrfv4A|s*HSe3cZCSlWS^DuGmN-5^MtzIlB;*zy(p($hGF|3kY^wJdjf^%^5m-gmisD+B}YMGa_$ zx(qWsJ^r8J@MKXC8KE*rF#^P$$Cnw5cCcQcT*yM7_VF2Q=;w8G0_bK%gx+AY-e$%< zJ7^8OH!|Et<9&ZDGH2+GOc1V(+&_$9-GR5qv|kqhMYzyH%z&X8>IpZ+<~5E(P3+1S zGn}cDy76KsW@X}{V$6>}E1BG%`d>McOu}dq=bS#IV^mv#m zxEMs11#8iQ$xKp1y#cl0Uk{X4y+Auwlv78d8wJi&5q14S7l5W;PJf@3$NmOBnrQ!C zg(MVy9lUn$E%3Yh(R*BUqe^ipSsLuq!mn%v?w9GF<24?rlo1l(gnw`cz}PCFFBU9N zLmYR`WuZI0)@PUp10`s{oF0>=$Vb*Vm#{ii;tr-<`e)t?H*V^~N)So44uiTeXj^MO zWT;)#H>y5+3tdsMbMY9Rk09U(zdnS@M)x=<8{O@O&nw5Qg#RE z3r3REr{t;PhBPQ`D?yHzzE{f{`@FENw;J(mTj=Q1ln&fbM@&FPt2z`S)m!D)f` z^gZSh)5S6JSzu&$UqGgwZc?3WE-yW!th>$SXo^r{>A7fgp*s=H=7Rn7b zIK1;*CpJIeD2a=Ub=sf1Z{a&cFuA^T6+4=52j##c;%`r@`=8SVM|=J{c*|e-CaZtP z1vlQBacv%JJ@9XbnTrBf8RqZ2N&NX0fyT=`yXrD0n?0{_z`Qt7#>) z`{~l~BO)$+%X}Q;KE}e21y?OVt^)U=IQ%g7s*m8qSofhQ{BYz|r{lws?n7btVcb=3 z!H03?1J{N?WIe&)Q$oa3=JKeyJYX*Om`ks@beqeqx&UDPa`1J<%bD>IS`@mLCM*tg zjQmHJS@v4@bLCuX)@z_mVV(}a#KJFS;THs_x{(#^Lq2Wn+4Rdv*yoz2?$w zF1MP?Z_H(#x%|XjzOReHjQN{`pBw)!{3Ldpc>CYT-H(F~c~)g$vkgBY-hLi-qjD+w z33|O|Ehe=5k=7WCZ65zMX%TP4bnvtmhkLpbnvMQuAhgn##JZswsxo|fH^ zP<;tz5Omj(=+9;D=GgUR59>EQc zg|J*!bqBH8$*yEi^1)fua?NJ>qQzIX+*Z;;c)ZqI@z>wlBMlX}EA^+~82bH+P@qvL zJ^xWi@7Z}kL`iZ2@QadzzzStk8wGwTYAgbFVvLwlGQHbWr(Nkq&EHHt2&ovWOa&4> z0QY5qi=uMdTjSbW%T}trb!smwE)IUcMiZ&Q?0#}0*Ef^*v(qtI`Rl?7C=R;!n1S;- zyuVXPa`5e=y@CH%i*L}A8}M+WnpCHTILIoCckzPo9^;7ILYx7-Qa-pL7WA2!U;#0i zQ9O<)(tchrMk*VI8sv`rhJ$a-i~r~FSB=0h$1kJaH0qCWOOkSD?67AF(f}y(Pfgi}!7ILSqJQ5mKRH07PATFqppfR@_rNo9@EQL3qwC_V{zZI& z7cBl@2Z!SWQ}Mtmn)=e-^ijKmuc9ke873YDUSgX0P^1rNEVL@KFrR#+wL0zC(J8Qh2DyM9HaU8z0-i|@pNx?S`(1jF%WxFA?Kc^2Z0HGIeONT}H(i{Oa4KV;$Cz4gDz;3 z`BA1q{uEKzDTzYoYVE3?qFUs`i;Nj=>vHO@_vVZ2mF(u0Ml;<#LPU#6@+Jd!B~ZI z`uy7==ON!c&p&C4|GPby_VJ(1$2`wXaP>T`JLNeePyZ>;AM?zA(L6_nd347-AH(k# z_%RPb8a#<af zkF$Ji!uxX(zy?xpJmbZ98@DCzOYDnzi67$2eY?5`3%G_dh$t^lL(9y{z3^(6v&wLL z)s)^!Z(}dAFTD6Z#8`(h7_d{F+)8 z7D@OWvI}Eb=ET*aVDDF{Ytc{&*%v?R3dz2>pDd8FOM)rNq&gEnLPzGL^lzcde(ey5k!stRkkkRAkVnjezX)8#(t04I>I|#|YKYa2! zCa({v;4VT3D17z_R4n$0myk1thEmOwQSK!91Ywlqu!H?4ydf+ct3;G zVGn!^KKK9$1S<-Eu#$W5o59I?7re`SDwqtgaC#%;J#TW?Q*I9|KVsk|LlLRReRHIE zKe0a?EZ)x(n+#dXJ|p_HhlrG84XLp45+5FUEtx0Aloj z6j!Zr@Mt88jsv+7W>`*e`V7p4NX3I2m?}2ww1VKY|02j5fjB>~6fLkpfwp+*NDEKgMc`pM!KyPt$dsvw+K?S0 zGyIJ8FT0;@*RELIs}4=dZjA?E z?dyHYwlB{9L$|zIJUqSE5mO|idfg~7dIB9q=exw__`&G??CBv@k>2~Kl@$aZypHs4 zjd##cX`ozA84W@J2~TiGw|~jXZBh}5(e}R`V?i=*StDqdAU8{lu;`y=Gomn%mpKRi z&3v~6e93~)hOp4c+9QZ-n8K&2aKxk`j{;B7`6doJDI!YW4 zTAmoOM;c3s_Jj07G8cFEIDCC2g1fN>cUkgzT=3lEKoxBf1(Q?OR(mwhM$PXD&c2(Z z4J#`@z@Bmk&O3ecv!Lejckeq8{OyGU2kf^0PVMG@HCfVc_o!42f2%Z07G zy|BJuJ$KeJO&UzHuRRF+&mT2kDAfg|i(gj%S^dFButcqggO|Bj1#&4jav*gcczhmS zTTuWiQp2nUUu+hpKUvPB@vPE=F^v2T$$(Z#GAJ+i?gNWWrd&u1SOE(!32vv|0b8N# zs#6!B&MzYmj-f`h)1{|ll%Rf&9CiT>d+4wc`&f=1Q|@NSxha3}Q=cy7(MFI>s27{+ zd{}6vbTb0o6s(tQ^7Ap_+Jj)Lp(llrRE8m-=LF5roeWH=^H9V*-!=(bwOMf;@Ql}I z`+oY1!)!ZDa?10`IMWJJTBj;{7tFIIE;J=N?BU5GB#RqqGWyiPQRq}K>(CtfCLqK? zaP@X|@{U&f42NO>;k z2}i+KbT62J^SF`!YP>`zn%(bKmq)eKb^$ABd1gr!Hl3m~wF3IiZNzI1Ja;{8;eoxf zprq@b=>@?nNkc&>N+z|rB-!Ih5>TH&7HFL+19>IS@kvzfyV%SnN}gNeC(j0mxTd~{ z!C1(Z%ZG~9qy#HGmLtt)ML{Cbsh%XAvG{L_pC1suoM1=sDl@x5a!W{Qj`&#c@ml|j z?3Rv~X73Tke&mXQYrcj}tf1X`0PhHqod~2AMdtuk8eAlH5X>Jn^bdC_nBk1O)LPT9 zi$+K9*2e?;ku~cGo1|$9st>O4U6V3R*$lczQ{bcyAJ)fw9F>j#AQ4ja=;-+r6!BtE z90)ek8sI%=vq0!?>9iZspLl^J6PyDj%l0hh$g^d5z(J=OrSW+C)tOYnxTg(9OW$kf ze*GV{yTh0_SUuS(id~4l`d$vec>|wyv-KSLJubMSPxQ#~cSX+lyXj6l{_;b9Fy`2o zIpFdkI^gEe_wA-U`5W4X2gfZLY5w1F@cI7+gCVdSm3-i@jCau6N1FeK?a|bqbPXDd z!9<+zwf~1^4g08hc`N4ffs>fiF^TyKHu{Ih9meQpQ)b3*kla~JzxX|VdI~8(Pw;bM zZpIqNN+35@+holTa%ExqKl~-Hsh0H5KuE}0g%QNQO3-v<>_5nu+ynPdL@8g-bT?GJ z{Av|Xmb!mVMZcH$wn;da5hAg(8|yXsj|+;IY*`Dh6bKB)P2j@U@cRK|)oI!yAD@#h zSXG%SCX`5o7Y1zPIdG?gsr{265+VxoD9nmbuO0+-}XB!Ncz)0n3O*+sf_C9r@+Z z+o=zTe$i)=5LjQ9My7pvi^hU9%OEI7`LK=nc~@QICo!=R z>m$Kc^=2@XHZQt5GcMyJDRb~)_5%6mJ-I`IIa+~ zBCBQ(KILwE-s zIrzNmKH-!8C&&%Sl~W!h5~s_iyfc{wqq+uB5kf4O^jrExu;0Cn#q^3GO~rc5Vd}B4 z%m3_p`nE{l@|H!SEsY#nIc%opgRpFQc%oMAZ7f1y{C8AW+`TydS~r#|Uhby9LgU%q z##!mSyiMN5d*R~o?Yw1|;Hk&k`0%n>-_Dzbk2qZ6^do028%N=BU@P)Bcd@!MOdD9k zvcjG!7)kKnTXBbI^iH&ND=NDzore_-=o2iPC82Qq!#kYLnfDN0&R$kfQkmB^8)t!j z{%mjatTvp|VA25)q(he|^K6`OTTq$T=Mq+D61oB>*aDFyyTtsQ5{tqTCuEoC61oy6 zh9wqdmv}@@iN#@w6SGTn30;Yk!V-(KOB|C^Vk|6iQg(?hp)0W@EHRc{VnI%crD2Ic zcodH=p(}A}SYl~*iDPq0EDKAVnq8tx=t`UsmROcu;*mKemWL(I$S%<(bS2IVODxYW zaa^WElFZEPV#c*}BfjXu7ZG6ih3=QUD?h#mH#=VPzV?Ydq~7IcLmPVyTRyr)%;~rD zk&FU5JPZaIqfeAs`tl@CQ!KgJ-z@9SPZOABCy!JefUh!b$Uz-#v-XBBSE%YWDG zFWjD7d)Eue`hweEd*s$t2=%iyKH;jlrx)G6=ZSlJlF&`J#_cjeypFj|DLM5YeUGib zl=au`h5B>#Vxs~Vnn5U8P!fEd8Ucp#9T{y@kt<`ARS;p6A_=z!@oKIf%3Q(36PzB( zAUK&HrEAedJljU!Ce5F<81?@pRGjVXn^@9Znf&bOa6Gj#@u3zgimCv zBoP9#X>lR{!aB@2VW>u!o#k@>fQt%WY~2!PZp6)~xPS4R&8w~E)#IFcRP0@Rw%%g@ zTl(^eC;%QDmr%&1=bs30%uGP8?mN81Onf*uJ!uT=IAdIx$%?(rcNmD?&TMkB$^Q!G z4FV^==xVB9P$Qb*#e!`jRAUm*D<=9$&hUu#t=$4>YnLwQ3ACeGE+NLNR}(tQ^g7QQ21{U4Gs_gBCU$p5O=9d!QAkq$O=#!FMdCk4(5|m9A5+%ycL69nhJQf zBl*AIOm=2(#ho2%Yd2;Xc`yBfL@UT~;)&NvCf7kT&16D2Q^k6%JdnYo9T2+}zWW4rG zB5tB^sTN-B+hU9Zze_PDlj3xyV9eq>30eE+DU*~vz0R;W&G72ee3$1`SoX%4O41< z$PaEh@Q(w*a;%sI+y1VlExtZth`*aDFR>eQyy$#&E~@66toiEI!D(wan~WyJ2s<<( zygi_m)dmNCHmc;9)ggIZu!G4H!)-sf#dY7+pa!BP{N>>1M)>&1J`c@=3uRK-UPNl@ zy#R}*<%ju*4t@_uD$UL{&V)vkARru^OTLE_=A(rNvt0lVJegwKGsSj8gTpq3uV9-3 zR=%P|$C)TobXpj}9smk6-_4(GO@&ZxjUJr(6cjla-4Vq)`mzo$>#|;&d3-6iHY6~v zUjg*MKKl+{@&^jZI*Hw=Yd-60a9#ZSo!kK%9D1^9^c*F z^Nv~hNQYw%yT+cKUia1;zOwY9S@~OLr9NJuOmi{A#@CbjDwEyHwT-#DkZXHo636f| z*Y$5Pxi%qJq0LpuuP1d?CI^)3LFU?mT-z#>IK+;*+K(~0x{+&w%{75vPYNoNJC&=O zxi%r!A1Zk!GIOmy*5v9zt|FVOh+j|IQJLJPTm#J2ja+DHpUKr)WO8*O*F>9Z;$dN< z*ybueENo1&xh5SJHexnc?69y=VsoLF4+9&eHdpCkVPmSzHTAHtQD$?M9Tqlb*jzIX z3mfG&SNUOKW2VhD^Kh^+v1Ha6b4zCMPmF&GD|c=(+%|f?0h=*vIsd4*2`WU~H+nuo z-7H`x|CI7iku3$>IC{RCTQXtR8KzNFS;$0N2$*y9goV19SFI}JU9l|%%=%#E^lg>X zcMg#~KOB7UOOidPlUdXl;dPSD44&<-oX-41M3Bi05rnFk8EvrmjM>a!-GR#K%s)gD znaq$xb4w;MpI{dnOKfIv@XpHV%s)gRnamJKw*LXU!CtA&3qEFhk$s3*GI=4EY_|(^ zA#JM740av`zSP?ST}UglnZebgz?XViq${M&u$jT!qrjIsS0pQ>mD|kV@loJQoh#VY z;WKS!u=*$vCT0=rz#0ZOavi#SRQOWg3Unc@z-9*D9}-_9v->EprLGm=LRo~%M}aMM ztsoc5BFsGsY@ut1=jl;UmwHy93uO^jJ|wmd#>%6>m-s9=D%2ylov^}+F?F)qAnZkWx~p=$(Z#wePm*$!t5TU# zB+t~_YK$l#!rVdScr(TfRGuVdDObfZrAV-eQ-9LGH++<#3QIB2lx1;fQD%X^48D`!n0Eq#aqJj5I`< z%o4C83X+jVD3e!Wb!7Q5(gViedKSxAfmTO-PbQD93w zJFG}JB(@GF2}Xghkp;jg@HH~uj{;vKvim6TH8Piv0$(FD_bBi+GEa{JUn8^fDDX8h zD~|$UBeL=+@HH|k9|~XjeY5g+&B`B`mH*dS`8fOGPAnY0<}F>gn+qS!SVS6^{B%L` zg2Ln{CM2(f#T1*XU|P(!58HThg|}#Zhd~Lkd`;Uuf4uKBx7o|uc)v38epTeY!`;Jr z-GY1Uxrg~tK15A0h1&2M*kX?r8SJc2ea|056XvUV*UaZa#4={lLc~(7&D;{_=jb8x zL3J7{Vz8KEi39%DnY9nD(#3!C?gCb#nt7@VR!4%1A8E^ zT<1HO;FYlFx?m(`Ny#({u&2&}?H%5~*g#-nrPOd?I&n73QM?q}@YCmT?VY8fLKG)& zXZrlX8(Hf!@WN;RW>(bNw(t@4vU|DK3@}~%NaqFI$6X7E5NrwrA>V8;ujAs10c(Se zr)Hck5R){-W%~v!+j5M=Wh z!sZfixTcr-rq=GzD?3<{&%F33i19oS)?_M z=>rj@vBBVXq>oJOoMB1i!Q)9H4lcW9PN_op%DCnc(uga`UR}u`mg?k~3}EXliOd5v zE(F1!6RS$CDzl=-TV4gqtV*vbm2d%fMGoQ$b}!?KJGWDy-dI$s7$g|xBBg^QExBXm zk892^?hH8}sjLr6>byd5ED+^CBe`$R%Oi)E)*naMEP~eOAZWXK z&6QxUs8#7KH^s?K5kZ;NB*%b&Rg0PO<8WVw8>)BfdsAzG5Wb@(bOeob-EHOa_gO6Mn>M4c+o$z>y?Z` zRSyoKdl1LZIlKkqbFc_Kn{Wpz1pvY4t~vsVDVgyO6*DdF(4S07-?UIrzKzrxt$)jn{(O&~V5*im=TPVbmn}rzp5>q9GYb6?!`$rLc)n z-C|RCMecL3ZStdl9wRlkP3~O$K|cj&`Yxbye_rERe)O1Cf+L)4+3*}&rHX*Vu6Lg|MnC_~e2(GR0-JkL^z(PkXLO$XJR|z~tNcv0 z=w-O051wy`9NpbWx|uXN&Q8SD*VQk=Zc?D_ZGQ56TsD++v9UbpHHicIQt=wd_#;?a z*X@RkkciBacr(j|*3C1+l_w2x1`k6Fk$;8on3LwQ*_j=mRjE%FSEVYUxn7Q810v?y zEl7o(z%i)0IUf;Y_lM>qlJ*oz7d{u!p+15}z$<9_z10=>dTAbn?Wd;Wq-!+mau7St z;OvGd`jkbPM3_bRiVh|Qz2rTQBje3ny1~&4%mkKR?wFHHFAbJnn*8J&PA_q&omuq4 zxa(a<7-W3KU<$$9D)uh?5Q9Mt&sc5s9|L|B zswc-kXrHZeCPzjA6jlt1H2O%pIRJ0TX2K8KSu-R@`rn~>&%|{8PWaCAKb#x0awg)d zLWqNrr%qmFA7Xsyun(od%TJ>gKu{yKyi96&BTxX%yB^e664f_@t8FMZ6e#7^d8^xb zr%{kv&6$I?74d1)a74^)2E|_MJ~j$CGD!`-)F@aA5LX~gtYr^y6etkFk~kgjJ!^<# z^T)qzx&acL!!NK5Im3t*jyK+`&;T6h@vWW%77}RS8cq-$KKfD52!q(#zZecdr5wa? zJo5;oW_uDl`#F6A&R@vt$A)M>HbwifCG5v(PZ6X4QK0x4DWg2uB3r_zTqu*;9L^I%F3QXq!J{#jO$`5~;@j~{LD-bYI z{@;ieKWTFPpD0TwmHfVU%m;A;ITbwe=@$USq{*f4gLaNL#h8ajH%N|DUO7$Rb*z>* z_2vc`0faChO{RX#|2v}N-?#1f*U$2R zJx*r%<2_GkGxq@LHH>qAKgUrw`hX)M(ZK%Tz+_>y%qnmt6!OZmCQ2_(rcl^m&%#se zAq{$LBNf=zfw0_K8~6ok7Gku)Wx96?hG^#YV=Cjaeb7Q19~KPoubWacIvouKOMWafCyyjnLA zGBBgWYlaz}w1tY!t`85F5+6b^k|#40x-a{w(;a)<+OZSsT*+f$+Xg2h!n#nF%VNs! z`pTm3@tbm4>QD`KyG&YS8GIfGe{s0cmcAQ#XE|HiNU-NLyut7UMy7}d4m;F{eV`z- zj^wrdRM>#Ry8}xhW?s=`<`q_;x<34DrK3pGhdRJo9oWJm-uMoD@-ZV|K`*8Q0ZGT| zX$8T9aY6!NV0fY#bK>-sxiWC>4FgJqX3L`L*2@eRts=;&i)H1}XgenW&J8W)2Z zUpM*9T&#VaMN@yBoqnw|GE+15bw*@5OjQUztNV!Bjd&HZy8d^N_1}*UMOIe=7MFD& zBC_mi5N5g^tRDzPGmHGBj|&ADrq+;W4KeBoz~+}NHjPp%{lP?GQd&lk;Qn$bb)~og zEgJ=XM4@Jx726vx!Rj3%pT&kKxwEGZN2&ugIjemJcJ#^K{I6X^A-3pvaomiv9PxtI zjS(fr2*>&M`|fbk9R1FD-t~w$Y{)+PC4rEGD!J=BBa}SGes}XkDg2R|3l?<{viNhu z)r>xHzpU}X+Sk^sh}zd6!HsNcL`PxlYGPL6x`j9R`RNUIRmsR4^ja|cxjpE1sNOc@ zok>l52l`D1e6tr3631(;q})i|&_z`chMq-@6x(<}xsYYQ87ltMZV`)Z&Ws97z0<6x zf-Kx%5u7s5aBH~_A=<@a!MbriNFutaJXT0kzw4AbniMFhwY_-KB0a}hn!dC?KM?}i zPrctyeFB5km00XhAfXM`ermV2C*6wUtFXTSNG<$W9MBjz+YNDAiIqW!tt}eMa5P!X z3g&&$z>hX*cehoIThtO~6*p4FjARr{7^o#;DDQ*hA5C9?z$k`+U0_^jXbMMi701+( z!S%(<%~E|Wxe}ocpn4J9CKgj>*V%=Wb}qB9Ty7y%uiZ0bU7I<92m*kHmf40zI?9i9 zEBY$zzj=UyUFNgPx-8(B-Q@IN>V}n;fUY^)Pyc)wAJRZebme3O41e-{gII5tVu^+g zFaUXVYDulga!DO71F?+Kn8h!Fu}3e1Q;634g>%$WCn^0V;xaBD6SNyTj~Vkp@-K;o ztlFDetEwRNYy8w&*2fV5t9bii^mONHN`j|u>|#bR$u-m2#pY#-NBsJ!gua1l`NZ{p znh1ZXPp3#G0lytW-^Cz=waS~ES`vJ92?rWY|8i8XvR4c>7G`=QLLK*gAwrjcTy)7{ z40C}d+G*{MVsrMkC`~$WJsJq{fjEk~fiOUCa|r{nBkF(~g`|ZUoEp zcF7h;4cnfI7_hAHA;q{L4Fj}F2Iqa5rbE0o zKXOY)Mu>y8jgWV9jx2iIYxMm%vIgfQt-ikuPnnn-8!Xj)Jm#m)FZEL&E|U~)OM!Q_ z+qG>8@3w9M<>bX%ur&Fupm)l1;0PDB!<8@*+KMBas?@D5=*~H*Z!E*5D)oz%xFCQ> z^II6jqwU=&66={>;>7H-y|$l|Pm}jlrIxNz#&2|({A-kd)7OxHlh^hbQ&rsKU3))o zjM;A{xMLn3t5VhooHMZQ#sEOqf|2|GtGjzoi*XSah+Ed1jp!844!X^9rKt zzc+WCs0-^vJjT^X*C6#LYGT%!(uMX})(qt(=|R4Cq&-ea7QM5|+xXpLAV`M5+wqz& zj&m=ldqz?;ehny(;UiJrynv_7idPTxy7v`5iv@d&g?-s*VZZ0TQNa$~qYE(cM?HkB z#2>8hwr!IpH`uD1MqBmV(N%4Tp%%OYsrYBx-CV2p+V3R@hTXkUbz{9Y)2b&gX z4P$!O;F{ns<{tD|V-Z_BTExC;y`V}tWOu2_R)t}|g?)zbjVII6kI)KF(zcK5HMHwz z$+wk8zO^7@@Yz-?-(;Nt8PtP&_#;U)MDA-M_qCDxI(Ltel=ctJXa^UeyQ0rt+l?qQ zxc@o8l%hUiKV~Ib)XZ@PL*Jyyoog_zfKT)8Jq=d~hj2Z&PwTlHRG2o{C1)l`3agd1 zmK+jL3?FPHhYvOoxMSPJ%X``IB;aF}xQFsXQnKcSwSGEdtSJq86-*@KOP5nD^c3Mz ztHxmsg{+aP$44l+Onoy-sQc4Y7@BCP{O>&mFCgP=({jNcrhKXc25LLr!jj)w(vMdt zTRj@Mdr~fYp^qO>6t7Slc2OXqQ}h}J9s{89Zo3)g5r>!Hylx|7z-LxdHc5dymmMFV z17y~8(2k5l3G~+}E}Ky=xw4EJWH~hraNs3ITUBS_0h-Bb(__Ol9YvQDfk?8FO~P~B zKCiORzJ2bn&w7upSX9Sm)!{AhFXd%*NedrPhPh6iyhD~t;K79Jb?EFsGTpnRu6jU7 zFo4lE4#5!a1}f`ii{#8ovp#~5zc=E-v0a(W+M5NL5%1wi=w=-3! zCa7aQ^I@3~?QHsFLc1dd+QcHJil1rqn2dJT`*5GL224Yv1M)s8B}rFFg1{zXpo zkU`x`3e-5i(vAtMbhS3(5p@;voz+zy|3hTFcid7Ia*L%KXS%-)B7>fIN^if4nb@+y_LyeZMDizt`QP$^9&YK7bso@!ZL0 z_G9q7yNMKbCddUOB~!iaHW3c`P>t$h6?iCT3wu?clY3$U(5yNONg9N6jNo2cR&rEm zKD~)`>sAik?sWt{`m~_@Ji$8~@LU>W9z8=ZfPYw`w-A81y#aQakjUA^NbAQoRj=*CBhw=CA2}FDnI4tJ}-T) zItgn?a09J)$!j|e&sE0T9+s77z4lL7oRBIt`WBB!$Ed=k^4cCH(2(V#c(3hlwZW*( zbgl2z^Yuoq(Tw?4N_rxWUnLqi2|}wT*9};gHTAm8GHz!76U|}t9^nyn#VCVoH9EaR z&ydKxLKw76vvD~?g(#3hWOJtHQz$SNAf||n1sH7FYJ`KjQKW=Ejgz!RPw*B*$vr%B z6PRq@NY;n?}$w;HEQoV*Uev=u`D36{S-!}zG2MS^?5*|b?;6GxrEzTOZm3aHm} zyU}J)N3ourv}w0qofd}h$N|d?Nuy)sDGyNrAN}rKh;2z^^emyN#EzZ7x@y8W6;tYm z{EEB0#Iw8?r#bs7hBd1UhYdEBWbn;-dB$!P3K&#c8r&gG*vbud8yj9u6vWw2KGEk$ zuO=kDgLf-yP*JD>ByDse0uZCBQyP5ZR`xm+N;Pb?3CxHF?@{&Fm+aMbomDP+{rmxT zM4WG@?4*h28snaA^@%bSBW%)sXAA+TEcljsRMOE^!iJ(*;wTje5dGj8I z_VB0^z^*mwFn&^py`_aS)GQvk-ZsJlk4BkVZ2cxMr7A%C4d4zBHY?D@_7A)a7yclA znH+&DbRo)m)z;M|O}qm39lBc4imqB_pF1q&ugp+>3qK7@`L8@REaeBvYh!BUuKt;IjcQghKP4C0KS+k-Fs_7R2IaEPC>uDk@i>NY!(dneF zXLSvGI;xWzc+mtGlF{g-0y}ARQdfv+!UjWGXqw35c0@f4PWp_<<9J=rVEwY}1=c>_ z2aleNeI9fpiB1D~t4arm8uFmfdaVx-HJIUcpg0XAU|K9k&X`;_?!8)^0gt`lbDI0j z69<8dA&wdKoI$U{`DzA|$QBI-Pm$V2PcchE;U#NJ#vFJ`~ z3&SLfavsJ2+9J_Iu)$+Mq;);T;HnibEWSoQ12{qmp=9Iy@Rc zo?L6(t7wy|!Q`b#lNW5zJr9ae@1j#3NC4i6^Wd9uP7eWacGN}5T$}_if0~q%`x@wq z&L8CebK?S#${>Os`YO@d=nM zH@CiYc&?R%l@B=%k8t#|=9YSX}bpsZ%`pWP2z z3oo5;KP=^TKhQwl=;IZogV1oE<=!#Pjp1AR!C(6YE*E$kPiT4d;zgh2;phi&aGcFn zvBgWo`8_mXUb^VLJRrbxV!?=3x=cldB%TUZ2!167Vj0s`P# zDn0%b25on9&6K2uPAoP$QMjkodNDv489{QJR4mAj`H~%OO!$piPEJIYlf{#>z$s3>45K?c9&umKpZBR#6)Kag+T?CkvD7}RchtL85Lqi5R z{rm=e6b6%NOGekB|FrHLmB<1)^*y&<>@ELNR<~WJwc}Jm-&1Q>(Xfa^l)&R7Dd?UA_#1-=Upg(QEL{x)06;#+Ms z`KpFXt4t4iud7P^ntAbRFJDO+Fot577fRh;SFErYLok%tONbvKf}<;!>EUoQC;9T6 zihYY$z{_S%@{c&Nrw|T?2NsQm%gNwhqV>&5EzPQrCLZo>+O!yFmIJ(Q=ni)__9A!w zq6rvZ-qd&-{vOr1QQLqvH9sT(s*_L8srcK%lZXI+>liQ)*1-ONlhE=OrL!;^tp9{4 z<>$Hpjr?WCJLwOX!dplBLpga8Vqq$zHkp(1fOnvR`Q-bllN-*8Y}9D74>5jeu@9xe z`5S=8PI4pSQ)KhRkVhVu!h~g8CnB6ZM>mUfMmLLeg_}i=7^a4Cqpo2`w1&QD4gFya9lsiirNU9y zuqRr>-e?VZVNZW>m>R~9x`v`?PZvjfIu_RO2qb7O#~n558p@(Ilt*ibhc#S1Obzt+ z868j8L~E#x)=(GLP&`Zx6T%uOL-1hg%ava@es0wAYh|>*Rz>?Ov(aohc8cU;bM*47 zCR#&nw1ztSP#R1friRhWuZCz1P0<=!!Wy>22QRk`8Tpls&7tD~ynseI9_%T2E)}wV9{^E3(^NCqHv1TTi!frF9V(IJCWP6xRariAbf&RsUf0?Xc zP^>UJ_%r^gn=<{W`WCzTpnAjfZFF1^Lp?x8m%8QL)GBr@^yV>M+XgDv-o{nV!LIEl zzEB^2i+AZSmO=Fdw2>GuaI`8T9iWq-G)$UYZXX~HfFAo$8hpB*mZlI6*9(gfLWgaM zxFf}Po@RVt!qvCls5??kFn67qa04^6_MjIkNK_k23=%=HM(&>y6!qE7EK&i17=YLq__nl}7;aMd%cHCSD9Yg+C}M`peJ@_`k(C zBh(;4@S96Psf@p)1%cEI(=0H)S_EO>b6~`ef}zIUW4>7=a@jl1Tk&luQ<%UMcq=Y8 zcc8BK@NO$jO#F0|ml($vKvYK++(IEw*5C@$S#?F1mv{;Ko~Ahnx}->qUTYs;nayS` zI58OAzrn6vU2m3#mTV@#u$0kF2j~vI=m8bL9axhKP7oW#gb-wdH>>S>oopMc?Qv=( zVi?PI5Jq+w7I}JkpZX+&^}tara+*3yFzLV%xHsv{MyVl2@jwOI1rsg}sL<7BpLr_P zp~tmrY^pw8X-HUC(yx1(Xm;a#TUuy90&|z_YkBjIX7`tZtJ0hKgc$=1>=b{(i!@ui4b%$ck*D{*dl0X&qf2fbA%21ul$t4NL9d8 zICy)AIXXWKhTH8{v2qPY)?o%EDn`!s!dy6&)WE3*Cx=8nc|CA`Bp1#hfi=#dkg`EB z-fslfrP;wbj)#jp594#n3+D1NmqqvdK){C|%- zOp1r_{ax4lQ9C-@lKZdV`NWQC_&=ldx_^n*U&I(W9IbORl%aKrB1=Q-Nl%W3u01lB zhK$q_tt;glLql)=@yN8Em!b7#5n5jvh4Znoxo|3}p>?HvW8nP!O*wGBA+-MCFU2vtQBJz)+XmhP<9P7$*)&{Ib$}hz z9Nai?HQ;qjpx9~B2 z%U)e(Vn}xZMXq?3%84D1p`(X6STENZIKi#rfXScmP68<=4x zK7fxujgH*FPl=(ycBJ`F8fqe^Q1Evh7mUT4^WZLMm!dLwEQ_XutM|iv<)^QN7Hkle zY4(mAhBh1O1N8>#Xob331r&;?Xcl{#y|x}J>SK!`>bK`RnE+BYd5JZvhB>vcNQIF} zIGT6HKR{7$m*!%@ox2Pq80MwcRCB%twMJn+hEJ|&>5or=ki{M1E-(&NIm zbY(<#ub?EY*h6C7&~nOfZBc3?wRbS%P^tY!wq@0gL)!xIVpoEC+7EEq%xYg~9y%Qd zo74Ldkq{WZ8eC=OL!1|p6ePEC&+g}s?@0o>w`72rueU;O=V(7KLE~}y(KEcqHhZtF z9djp+2Xzn3Cu z-}Gi3yTcIICoEBgB*wspCYS{D%qxI06Huat1zL)eR(xoR!!hKT*|>O`)Yt9tBI0EgQy7+1;{RQi9Q)m&EIEWjm zaAm*YO4v23$dyhvvP@9SKCw&?GxuVGQuP%kcnoKD=Bp05$gLb2#50Bov9_`}CaBL1 zXZHR_S<%1B!SsJoWE{lW#t4jAv~e7S>)->=P(2{iLG;Ba^{igX0V+d5oumm%L0!Ce z6!h^|Tq7eCq|}Cjl=y#_f_lC)l!73s*AUEP0ooeffE8*6R!c5qj{*JClAUT03oiHs zR~HnCK@JeovS-1PNn=%zK~YC$4DVxo7DfHMcPKhz-!LdrYJ(yr{@+DW$A1k)5x~p) zA>!g(zn9?28OUwX!ooYzLLX_pBSpX+iy%buMv zyJwW*-!CVuIdcJL$^2-OpG>s?6MizWj2CFyYMeCf8%o%&E8|YnHm+x>?6S(tqsvT(!SBP>kyo(w{I zwd14`4`t!efk;M7oSL&J(p1q<5Da|Fu&t?)s`oDqk{aJh5U^ZxU`ti<=j(|8G!(a; zyhVX^&%C=Jxb<&@n#vZY?GiZdONYLQ=c8ovHWr({g*}wj^~CO8VY$1r>&z?_^S>To z-B|4ck9>ip*o#t!FZe_4)ScV z;tZv&Hfb4_Br7fUETxu}H+X!y%I|@v+5zgx_uEI~t~eGtpB{Lesr#Z0fpB z)s*Ve<$JxnU}mqknSIH#B&fH8vXIey6WL-p#LUgnrWg>D7kv0PhNdwYvne4EV7r2; z14mV8S=W`|zTaj`yxX7mk8(f%Wj~G0d2C2l6O1H6`vu`zUaFIb;Z1lG0vn*oAvf`A zf!Ef396sQU3c|o*Ty?P}h6S_lul@Qvn1W}DU~2cRgC|Fr^b47sJ86|=tk?GGgJ(Iy zyY}rS3nm||{u$^Ds#z;(KyleBAh?~_@aKPVxthZtT%`%Dop10yT zwl=Z<&0gDINk0@!IC>*ku!lJ3q9&H)I{5_{>|mKuRg%2QkDc+-ED6zgFA}~k31KUP zs5Q)h5J0un>9$hTOhz!Ps@T2@x{eZe`@5)UI0^)raFF0&!2yCl&C}hz9VmEk$xXsS z+ZE(Mv^{>=^n&0j?1LxtSkQ%6LZr>1>p5hjQSQ4tTV^2IbjFr+^-cf^IP}?I;1Xj_ z^4bbf33mhI|HLcfz4YCL3mjIbu0jB2au{6)$$?y=Z%1LGxF)8kxX)YO#TN*b-+kai ze)kJ!`T4xX9>xd!?$yuHgA_;NLaQpYjsS4PwtBC^zj#QtNz%c2iViNAsl zZ+mVO9nRhZdOGtym__Qzd+-|A)Mv=0xLp?AH$+=Oga%d$NtgwWx3N|`Y+KilWl6PA zQ(rCe+J2-bY|iG=>9_HKT`r%%cdFvpCrN@x)uVCiO3KYWq~p4hxb9)$=apHP@3oYz zhOXYthEf#@I|A8 z0qS+2hVe)f`(g4uhZPNXFw-ASpsmz)`5Ft3x_rGJ>`0zk+d+f?LB&E)YK<<5^}2vt z^%dioM1S_#U0n~EAO!gD8j8;gM+&J_0g7zBYnP(_wDB&mhxvnfdN&I}Bu+0@j+g zT&Ff96RXe$A#-4(!PhviZJl=WfY%cHp#;2HbY-~EXkdm5rG};I#f3E_BlJe8(q7jo z#H6}(`CczC5CRRNwd`H6U4JsPX1`%SsV0iG;9@GoHle)HLBw!!d)Z zr5!pk#G-ug@}$Wv3`>j8&@kNR;Gb_bOCK;s=wt=NX% z!{DiuTCD$u&TktsHDg0M7&|Ne)!BE!nzO13_j$V>&yWR1o`CX{H zRO=iLOVTzzI&^iiqob%S{;JF(U)LB`9N&e)3SMTM1H8&&|{I_)>h%_v=^ zY8SVw!A2Vaq845AMk8wK($OFaGs1zlM6^)^ob3}5!r{MPxJm@NV9uy!VHccGYwcmLpsE0FLC#VK`E0feFWvN{;6&-5HoMhA=tvb+CJ^DQ}Ir7iX;JJ*)|J zs0azr&+1355MqL-2Si@dM==fY%HUVmy=a(3pTs2RFfkaRiQ2g=CYV_}i-}(1<9f{D z?4Y)lHUoV}wJK&w4`h`XQjfs0H1i{#h+w&cDS+i(7L<-G-B3F7W3ED8(1V2kdswzU zhp9_BH#yR4!x@CA?lytqr>}(5^GqzcI4_v@7mZSl+(Y(*yDi_pOyO9vgqOfDVpV`ob?xBat=xO+X8S-VVc zxknAA0I=pcJ-g|ldngLd`aXb7U&4j7jJ?Kdy%^*Hn@u4)QpU^2tl0(_Rf}MRLazsG zwykfExfi$Y6*^2n4m1&I5GX+3u@|3L2!T8ipcRui$2EQP3x-qmL7a+dxj3~{Srjt` zU|_^E;M-VTU@|2D*Y3zpXe*)7%vFeiP>F0~t5dd#FqE^!skS1uxK%-$@K|gg3k5yg zC6ubQqy?aHAtVp)=T!8%gLb!AnPF{Q1_J|c#XuHpIDv)}P|eABg4t@|MrzxM{qMpC z54MwCH47(Z-u6g@db;>!Bw5Xmoq0L>-yO*CI;qE0hMB8X5i$HXVi_$F2kAyF*aIKh zjTVdc-(DP$wS2peE{R_~mGDDXAA}!;}6qtLFDb++e->{g*fEZCAIWt z3I$F6Kjyv#Fs`axH)#V6P@F+t0gFr}#Z*93c_m6=z^XeKAPQ*M*3Iv)!g|?(5 zfsSctk8-pe3Pc6%ks{?-YC#?eDQ%z@0~M?kuz=zU0SqD%T1xKseQT{fdnPk!K<~MC zpxLjr*ZSZ8zy9^uDl^H>aML-B9}4Rw=4{N+BW#IE31Aiz7)>F?`l2r*AMjWIrt?xkKHQFE)f@<;d#Bgwnrp6c|COi z4y17Ixn#L^FaYGL$lDf`QtAm$^eQf}>!2SB`1Fkw5#KLT6TV;ME|hVyjbd1kH&eY_ z@{a*WTc5w{u0sgYC<&sDNf>I0Y1*+%`2o7nAJ)VB5cyVr*xS_sl8={mh(tfh}qV3syeMUd4J zCNnKzYqAtY5sS_3dJC7feNnXkQkY9~@jl8v!-_XkbDTd7bNZOpydt{lZFO|jTUWU1 zt&)?Zwbl(9^%b3c#pba4tto3}(0uqGBBrd5N|?_O^Wo}(OjCB`J>>TLbK`2vnz98F z3Tw(1+jE(+B|OL2$O1IY9|cR#!F}{lVA5CsQk8U4$AauSV&{06vf~X6%t|-Om*a?6 zik|3>GIUc^JP~iWaYWsOe;t&$QhH=vw||bt)JRKDU9>?uQiht1y9dM04>qzx2i~cg z9K2f`<=v7f?>a-?&AkNG=HlHah$t#gu-&Z6&3Clyz!_BAMLg3EE39zzDbw-xT45M= zGV6HR-cql_(tkb2eB2Ks+87r<(`nK5>Nv{loW?aPdAf|)jcd$tteQwUtbQPDQo_bA zP#lF94N+dqj`E^8*D0kn&qMxU4 z@vG}c;f4D0{9}6+wj$S!IEBlat}{~)*iLf?Sj@(yMdzx+4} z%~WqYg*(O2$L(6BxThHia4sJVTQxp*+?5&8YJVA&FXNybW(?3_W!lxr8HNz!x{8>P zR#v95WlcRkq_(wSUQ>WX?+PV)XL9jPG|L;BQ3N&3du3;Nhuj!tEpy$7$^4t9?qZwE zLQ>DgX#lUB7wM*Pr-nG2@qYxVfdg=^2Cl#XRkzVIBu9KX2?*{;XEaA{J5yNH|LUmD5V zEvB^$mo>FL$|gbG#M$9$M{8HD<66zqq-=ox%`?CA(m)Q$>LT63V@ipC6&{)RKZYpn z5DhS&B;c3=(Z_T$Qf9QTY)-$BXn9CDSL=sNi^$_?PTt>Wb~^6tB!uAtm`OmGTTI6; z8HaA*#3{9hUxc;NcIPwhn`Q94y8Tx5l{uAQF`(cVe3lR>TzBdklU;Rvy-hda{nfn2 z)}93iCp8|iNp#_?9!&GGIVi}m_G$6a7Y5tiwGHSdP3dyijGn47^@G7~HNyWo9dA{5 zTMZd)(Dn7DvvtJu6CL5JainA}cJ~!)0O;8S4)1mHIj)=C^)g+fSFUS(%8%D%_l!>h ziIuk70nI_WJA#RMV&4u-|zIAK7Ci9QY_=Uh^lMpzk)sF_2KrYvFNlrw{;VRQs| z!^mJ39IL_w%o}>MyckJ@0E(JiXXUGptg`lOUH2!Ph;_Ie2?9PVf7OGwO?=`g*J7=e|R7zdc?KHo}A zvvkqsRBh~Uel|!zGPm1=e}>a&q(odV(?PS)>mcdV5g6(S&E?UV3pmeRVQ4`P{K$uL ze^TL3O8iN}pOpENQ66R1)5A9+_Fd~2@4##byML?*ay0zsFCMjl3iO9bc+e^NtLO)5 z?mfd=W{B-f4x61NT4t8{p~`6fhSchGRQ5aUj2HRBk0gvtcnNb*k5Zddl68WTqE`_> z1I#hI7ZgCkid(h~H|@6A+%$~FTik}T5J}_(4=t^)D?GO7{9+Tw!_!X>+Pa#aqE!0F zrUHEj-VjFKr|V5~mL9oa0i2sunpzLEi_J=GaYY1yr8b%8vIkTFrGOS`p<{Yu-;!BW zbNf&q+U`Gf*z+^(Pet$Pm@pxFC*aSDrYzZbQBgByO6}2%52)@0#1cK`d&P{&*4l@K z=4(&BJ#2n9G%#$QKMfJvLM+ZOKY#4qVe=95=V9~euCET81?Kr-GybL5hs|S{Y-JwV z7ry$>1FsF6KOOecu=y`I4KwBSe(X;UsWk&%!k=$H_42T}q!g7N`Zv__^JnndPbyLU zs|Vpv?I5cE!JCBzzbPA>j;U&srVK5(sOUH4?xHM(iv_RQC$-Uw1-N*?J~?8_YFyB{ zBqE=8MxxT3KWInnL0QEl6Q?w2kCdV*vw5Un*EoNM!W}u{CA-T?krom=VvQ34B|zby z4Ej%8U4sW^Qwf-${W0esA8*DTxfdR_$w<=|2t@hbM*)~95WL%b&C$3^u?WL5-Y)o% zy$!<|Mr+@H@p&#{hMQFrN-=k`5m)ItPAKyOJ?bw*@F1Now8I4i*oAh|L|o{7T)+gU zchjxm#R}GpC$;7mm)gLuj)7l2iQGVov|0r+Kj;_|XFfjJz~|hE6Y>A)q4;LoivvhH zq~u;HZ#g~=_z2_?k|qeMIF1xqyU0}hHc9_6V;$tk~oT81{m;uaU9DDS`o&|qOrLL3V_&BwPs zFU?LDjOQwd7qGQVu^BFqbt>^+$Q<~q>(~t3O<4HLg6G+N96WFxGM7MytH2=#*lfED z*^|cNwG+sgG9(u-DGu7Jpf@!*Cgb>+OB3Kd0``ao%-SQUlqq|I7Mzv%n3O#BTTf4@Qg?pSWDIFy*dw@`b_njGSAr|T~9OLCDoCa-nbygxlV!>aJDnnga^q&5{ z;Q#EH;h+1g;P0TNfgr(JVbtpox)A%(T=)xiVg>WeoR)3;0H=6|zYu=dW6Yg{IYZq% z$*vH*M>Zi{{JeNEBf{{8wU5(3_GydC3hGfxA*4KcST zA^Z-1w;5kpUmmo>TEh1o{(HO+{I}dYcKkQz<-a!32;qj^`&ap&Sz#VRWaE#S7`f~x zxCQp|G*u-e^UDW#UtPU z)ArHfcl*mP*&Rr{#IJgQ6>~sL^m@x|V8*p7T?kC(9aW8GCHMjcCM%o+You@X2C3~; zDLfsVRdr&=%$=ChyAUz=K)^L2eCw)5`8Hmhh8*e}*zRXj*FaG)c@sXo)ip5Ap7agy z7+Zy#u%A6<{ni(l!d|087QG$3W+LGwl*RlCNf{xB`3<}8skegR-vz^u1ug%?+7p3a zO(-n*+?UdVKY3eq>RDh=UD-G5@CXKz-wbvc2vSc9x!zfO=+Of7i!D+sd(6QW$OG-6 z#KAg3J{-Ii7T%Uu>X?OGEIEYw;e1KtoLvU~=tmlY6f8eZ>VtNh0;29fCX<+84IgNN z?jbDyF+>89k}HR29D|eF8wDeoo#DJ3XaWz?5LV)Am0P7p~I32 z)Uuw0`NO*}D^7yGr4!W^ydVNh5(%kB_IT@*F6~^3`Ml-#hM5P84VqwM00B)fF2@;~ zKyuF9`oVr5in$3DKu5K_d{0&_paFdfR_Db>H7h@Iek}Osm>CTNH{hLJwk^m@W<~-lpN#A zz#=To!bcRgfpG(198ZzH+C(A*L1oXpk5J`mpf<6qNlua;1mi7~ND@b7Z$y+QSC1eH zo{O|1vPdf;mzb(O2!|3LtPx3&vY>m*_+YBxs;+qlcrt;zA+5f3pnXU8>Om4{=Gkvi zGd*E)(Z}`21MHlr{x}A4BAX23oSjzwcz>Bag}ggKYBqjCy_k($!C++hih9b`$C7M1+>n|$wYOW<28e3Ju&)V#QVN3MY zh6n!S#xDn+@{hPh9Ut}ohNN?&n|Ix#G_vP`3wX*Ul{ zVvV5^ROBVwE}tdEAt0yX-|3EvKOK)k9{z9f0=BD5Z+b?5BU{H$0u9faszvek5%zr_y%_M!+!L#PQ@%V2po z+j#R7==YNh|Vaq@I1SPFGLC)hjS7m{mY6cwqx@`*FWR7~Vng44hBGrG_?bxlz8{{=BqFTiiD7$#(tQRej!EPHWxq6sdSJx;D zp54cV@PJd0FtCP|#Zeh$r(CKP=2JiXYIc7yXFHP=V6 zRqu9P2#{7m^>vy4hr%|5Z6ZIORBRT46Y)1EsfmB_D=Hc#nGM!h(9ilRNZ0p2%;yVbz@!q8g%T#TP|PZ>x<+&)9{N* zf?rI8?6{sxNi=42k#?C4U_rUMu#s>;Bg83u#P%nyPU3+n#y*OYpCph9*a-euq5B!qg4at%BK5F$gSJAi)7W=PqL)|J6_xSueuQ3|u%DseaY7z-do^q^N-f0#r;iYE zP;f?ReONn)VMRQ=W813$Xr|t`=Y*VdE1)V;uOMtsEyrb)GDW;LtTTs*htI4$-o&P; zzfQjCv%%X$kb+^3^o@XIMffVJb% zA>cmJl8g(oEE&(76BojfCFbFMOYhwY8tEM&GyPuza1)er3zQ#Ed_ZfWJwNgeJX-&k zFn40K04kPa04dCuX2H{ejTQwDI5dZDfkKlB^UuA1oaw<*#Ur5 zj>Eu_yyGmfkG%pHt~SCu-g27tjwq-%*+S?Yk5^Zu9XkM44m2Hs3y?&kNKG1C0=Lde zaB!&>gG-6X;8F#~B~5o+PPCSSk-fJS~9_&WbtjI9%+_T~Sf|2%-8 z{4e^?o3JgT+WTMfpS%0^{!RXKJ9bOaS7|Ew_{ z;X>&;>Dk%!3RMdxFLa^d&4@o(f_)D2`On(WpE-YE8y?|50e4npn$v$K0hcNB?d9;F zHDP;dIqtkpG(@ZmaoDl{ypTnseRNd|C#oha-mj26eFe+fn|=&BV4F;D>nHUf)aJ1 z;Y|*kZLyQfCFGwWko?|MCqU-fyVX1*zdDE`e>@+ur#jyhIo}dFH~zeRfA`U-wriBg znm8rN31;}lRKO#?*xsmV-aD)a^Ee3v=}rKUsp!N39lwt;S~e-=!dx1&mjzlLM(Q2| zE!&a0e-)|whjEJ3J@V(T?gq~{5B_t~lmg9q^9!6OO(}NQ8BL(Oo;60Zt&Sb{`@%(| zkQ4bkg;*Mg<7La+*ep;ptA~5mjvvPrjZ=q$;oczicYI?wcJ;S86PMe`UwtOe5UC`q zQr%T8{o|@qeN`<6{rw)irT9*-qMr;^`#XaH3_f7U;Q+li6K!E;=TvNl`&2M>Ee9+L zF%;&4Ekqx+(Z~zJHiyxfn-Z7WtF#*R>C;OP{B+7tg13T{1Oy4QshA*Qa|7N%odJ93 zprJasS-e4RUIL?8*qwL*38g24sc#0u8-!(0`DCo+4CFcjjOwi&FVq2+2bjB;__z_r zF19Et;G&Ngm22mMlY?oj7*~g3Fl<`f{5N8NFwb)4Ezvv+>CF11Z~@Px@SrRQAo||2 z$(IB#E5a)F%d8@rmqdLPs>RH}8UX?VaX^A_AD0j-=0mU`%s*NHEX-nWFKkbo zQttGz0>}Ofmg}WCfmB})v88~sGnoG24Qvb14SCU!8UsWPwwF;;6Rpg zb`UBk8c7Z`L8lxmg(EH?3fbdbcDxodq@SIU>Pc-%4NU97FnwxM_qO=tO{t#lZN>Ib zWDnzbczhfGa#zT6HV2cR4xsc@o+U(%m~h7+h+b6rVI&}ZRB>3Hax)dH(Hyb$L6Ka- zbGk;YMiU-=V9W{+_xMNWVrLG~q~!2Urg^ds8kGcpcM5qJ=papU{ewo`8rOw$t|FSU9%ivv!IsE{FqnFgV zUh1|obwj3t4rW>OlUcTaA}}-;sXfXws)OZ?+9`=QEDgJ?s69!#F9xLiQ959En25k! zlbu*d_A<*?{_b>3gA$4|-*sTBt2>jXvzw#Zm>u1zO5GYhy0eLD@~QR8QVi%{ekH!-xYe z=j+%diZ!h30%F+2_2sH*4^_4N9kpy!El=wNwcw=h_`a8`C-mI`U5c_Vv ziM?NA*Dd0Sz{Bd`%C}=JA7Bf1nhb&D&OX!DYC28o4Nc*BF5n5K@Ze-H+4ov7c@W?X za+b~HH-gl&!SH&`_?e7V$s4LCZ@`3_s?;CxQZVhG(Z_Glk57J5^KCF`sGHy{x&;0L z;9-N}0@$WM&cL5dsr6HPhSzs*JJ4C4)FzOrdNL;UJQ=jS348LF!eBC{5`m#u+J-l) zx#>e!b?Sv6^>$FX?$V=!)OzuIsr#^$<^EE)bG0TN_+W=7z$>6R|0#LD!|mZvdzfMm zC+mRL!e83{$bVJffvGT||BA{y&M6=KQ6-ysbh5QT=gu$GQ<>z=D zVvbfDJMFYup)kT3Uf@`FB;m0MMNJeb;@Ry8@Nz@i10P(sa5m`k1xk#Wh$^0c0hhEW;| zY)R~;w&l$ek_!%rVtDn3Ay?*t-;15++Czs9c4Aj-(JS;i8Pk6<{Yh`cpPYlu3gu5$ zlL+8t)IUUh3x$zCmdWW`ybp1_H!MrLVhXrLx3!@P1Qq(F?XqTvIkvNL;#xt9$)AAj zf=CvcFv`?{hjpZOGALZnM!*T@4D8Y?vrvQLl)OA1Y!jQoKtT_BK0WiQ1B89*`Jfx7 z9uKhGA;yTj1TZ>af_45H3t)Ed2rhx9bK1Zv(){A(NQ}}YgzU?`I+qbl2P|=tqQu<27wMPQ1#iZk zI^@*=#3+xdJrR|tL}C;tKn`|UQV~A_E?{@~Tcbs2%FNG;35|c<`X64~D%=|7u$HCP z0Xd;JyY|T-jkky2{*G6`-2Kx21o3S2d)_Z%yFl3=IV)&g0G{(lJ5%G&(WuolOH##d zvMsmnM35DqId$sfyBQ>1p*xPGte(ir!mxf$n^T*zFoeQd82=3>&fc>|CP`W_ly>Vo z%|}BPjAmq#GBO~rW=BH7Cryd7`v~>1z)YG_;;sdc|KhZl#=90}Nn<%d@Eomh7m~)L zyC^Y}Or+1Ap0xC>?7D=GtxF0F4{a8^b*T^y^x41ZYJxJjepiO5(c!8^-G_IqwQaNfZm)s1)&f*Oj`jbPHdQqOnVV zjb@|SaCy{7)T(AQ9BtVOUx3&pcFm2}5xAHc>;|d>W1E-G7?;^H7~R@x%y(xGe=E_OAyaIC^N?yo*XUVwYM3oL`^g-2-5GkVb+>k27cuVcZy0}R2 zqRdHXnfX*7f)t37f~fLfGQ0WKMtEX<1OJ6_lRA->skC}B`STAOD3dXV5J={I;Gjr^t3IST)Eo^)b z_9u@mcJ|5iKO%$wLDg+`vxnc?n;Y!mpE>~INc@?eA7VDU{siXZ+Sw8;$#W_sf1I<` z;7?}T6FbPDb0|u!Y}CAtcaggW*`>9W}2-M0IoUf3cmzg?&n{tW3IheYQ9IC zgM=^T7xbCQ;c@K3qMkUG^dKbU2d(Va^O&1Q^&Y5EphHw>jiNI!Eo*8<+k)lZk46Tu zO9pPBajd%?I~>4YlpIBWLCa%Nrj>qKi#|D#LPOp99w#+|i;ytC67q_PFsbFG%>Y&X zAWw`fFS-w@EBLaL(P6ENN=1y%q_T;Tbi@d9eBSo|7BTKPIExr09%=4>>39P2G{Kzo zG(?HxW93xXTIN>)_T$x4nUzJiaPA~h4n7}!#J*XVP@kA&=R%m?Ie%u#5!m&@$Xt4| zeTbSL%=t#32YD_LJpS(=Ax>ZQfWbExAtz z4}DZ05D#ho^#oJnWLEf#jNqbq&48jRrtr@`~vvgr&rDLT*oH_@wV zq_#)W0$yyIe@!f*HbJTgbmI&v{DG|t3*rfB_@f6|(BI9^l~~7@6d-tkR?jyg)gG>| zX2O*o1WU_9-2Bgd7COj)x)78X83f@&Wp7?lwPDC6l49D0%9;#v{Dc`%#~Y$ysbo%V%t%{fMzuNx&{QO#{PUI7i-oSv}W4 z$k#D=Hu@;qF)U#RLZ;yq10lQNU>k_qOWFJBzjyW?MvQj7ow9^6@6WEX%!2Slm<3nh zndOR0cS_8vXF|@=+O=TXv}-WSziim(+Dqb_I(3RmYK6HMrHNOEA|93eH|IxgE8>uz zJg3`|@d%hO7f~=_eVw;~J}^tV`q>cLY&kor*FKVTY5ihSehXD*7yXEeYObV{#<}6r zIgw4R#m$M*N|r-ZR7OrE+=5d3~e<#}f%U2O|%{&M#;TbS0&L_7Fq3uQN zbY--iQ38a~1PKdS+P`;J}DU}b!TJ|IO zZZl?Rj{;mt;5X-GNg%2sLo(QWzq2EOlQKL8BxJHAmfM|6&~THCo=4~I<*YEf0c(ED z+jm)R#aT%Zq&|bq?VR6yY;G1z&SIgUpo^QCS^!hcbSXj`Uqf+_nh1}{u1mV;B@j^; z1(QC*T_BHWyXaOsE>P2B4!ciL>A^a1x6^Ook=fVYjoZU6_At&Kw*5wL{6mMRJx2U$ z?07;2ETY--F<1i5mr@{uzFe=fs2TYn-0$-D;m}v(JV?TBO2p>C{kw0|WfFHl zSgT$hmwd)rk76VnQp$P0FWhO{fJj88z46K{$pUzic8MS>4=Zv$@h4B(ihwi&A}^wc zWLD&PhPq5bO-JIlIv2mWfGTdDyPI`t%*IA|kk>4NfBJsgEZ%i>Be+>XUWL8{9|+^M zhv4LplL-OGPV9!qR#KAPKI`M85su--pP#SyXtj*10Nl{ruD_TTz!p#gPk^ z1>`b&3Kh44)y1nLvAK{zVBuwi+82{Vu=~rn2n4l z&AhR+1j_>3m9r(7|74~cEHU3xYi^@9@DlRjZ4acr##;S0**IUwueIDrM}vMiT>ISP z(yxUgkRt%NA?=&u=D}YQQNKr=Z#8`Vf~2*=vwy{6d0CUAl|!Sg+#~-s=GQ@^muOO= zF7luMlM@2hU5J~1-ofWy@~;en_Ak_czYxGKTJegYojE6d)$Ck-Yatf2Uk>5A7+lh% zLjTPdKmTJJS}&no&JJtEN1w5h5R!AMlN?NAVA3PjGL6tW4+^OV$FkK0AfP1;cT-uG zJWgoE+lbbBrHGp)PVZ4uT98^OJh^jGSAQW43X+3;acrJhdL=TUFaydQGIPTw&CNTp zXD3(Ul8Go%a2$3xJ*_G95A+C1glWU)FYHWdIdn?jW_%OUei7@|TUiGpsqPP=QXr}W zsE@TfbKq}dt-JCi-#T1iI&TS3;!rkNa~8)t5ZiDv=Yz!n53ePT21E}vMj#Tm5aSJ_ z@}F_24-hr{&OvnBtrj9A8oFZ^A|0X-eTy&Ug$On-H$;ayh?hz z7HDpeo~QERwJjfkEdBYC2uQH^4DglopiYE(^wm*YqE6@3qsv`O1xKN!E21sI%glkr zmmXUCW@L;?C0eMer@cgY9POGOrSJTEZ+eJd@vjniy!j0$OJ z%_2Qfs`Ln(iN*fBTVB90MaQA&-sqEO=FuhD`}1nq1a_>{vI&mzF#YV_a2sO(=ZKdy zw;L~UZa2K)l)8~G)s1*b)4lN$r+f3IuJifDUkjUS>5vgGX*v;J(sUxcv}HZF~w-6O(SqFf*T_=`2Ak{kB6(ncHW#>41mau{+r;R z{P{~j83IWjp4QmoZ(V2Q}yZ(kgAuv5{2@FacDELv)n3PC=_7&2Dw)CsFL zbGEnr!CdVn+Q!!2f$zD!JA8Y!45%bHtTjRKtlX+NV0i*LDQ}d7!<+v zaMJ`{bFUIGrq2Nuj1{mT8?Zx11#Dn}X}_HTm!nZM-=O^OSr0h=DP#f58(};VV>Ivu zp3K$>2f9uJxm(^Xp2zL}rfkVg(R`n@rghGu=&W5sifXopleO8rv2WMT3mhDb`ZbQMfS8?8P(EZ~0VBNz>LX346m@kleGPY`c%iGCW6~V^81St$R zj#g;*VB>Zht*dFQ>Kb?zJ=uXCbILC=Xh%|H>DvMKr|G80Z#UI+ZZE5 zV$q+_1Vv86;R3aNLE?JW%P6ivb5leBbX&2UqOzy)0#bW$B(=l$Ajj{4>f0HQSvej_ zb*%Ydw_+swNf!c%Ul#t`e-qVz4M=81DkFbA)P=B#xZ4F=l5MriKN@IS)Y!%VfZENH_C6K&*zAw!|#& z9{FakUI8ljWzqkpdqsap7UT)^U3fLhusS9x=gkgM_$bD^Sf%(HRw?ons}>##y0;z| zw7j6*2Mad_EiX<8FkNQdLkhg6KFzlwx&VulvP!Br?{n>}gHP<3G+w;Iq}P_M#k1m1 z4B&DzUdNOwC@*w&^T2?aWYL2Rl@r{a40zpo{)&45H23F6+;$o}OHvptj=>(5En6mV zD?|Z>^y9;d(Wup&OwzKwIM&)oq0wOe`8*3n#mQOR-1AY2%DJVO!T=vfd4XM1J98*B zjTD+jT5|OI@vXXRCP^eWoP^~$nqIaOu1|`s!is_Ct6JVEwlk8Bf5HT*{uv8kY1FA@ zZv46*lGv#Y*cY^FxEJdWs+b=5HExE)TGveks;52=ZAVQ%;0qgHL`~_vQm+iR6UAI8 z)WIE8`(}OJSK*+T6@cE+*QV(;tl{`io zEPe;LX#(t(D1JAD6Vc$SnUmy?ew&#_{(_GC>?A@cwBPajc5Ti~TW4!^D+w2RLKs>H?Du&)wrZEyDlF-F7?2l05efmai@5YnUd(jD6rInUI3!^FOtM z_UgcVvzyLMkv(kx37_Bv|I3n>3fwm(cS~N-(}Ep>x>9?~=u+ZA<>QSzBYvvD&;&#T z6JRTSc+flR(;y0lwLTQ2-gHXz5$MRnKn=SPV@EIlqTRK39jhtqF&79TbFKp{3!Wt5 zS+LT{FK~B3CvoSG!b|-5ONUFi*~~lmMWa&6jTPj?zbwc{6h;JDoB&(kZrr2}1*AZf zQSReYka!Bm6L0*8jqyv!%-LjSf^RhwR$Ra=x|kLh&~zKm)Uz;{p&=HgzhK`>@J4}o zhbjV2)jLjU;-7=Wg9YvIU|IDp&}cS7=9YJBVjUN$3Mt)vrOm80cFn1{2hUS=?{~g! ze^?Sx_14Q(smH6j-!7_xr#NY9cXbM@F(U6FldM%t%p^kw?#Xz!p9|l+hl;prziO(f zMuc#|t7UA17clD&ska2vmed-!4#2_MEe&8!qv*qPmzYAqt*b0E9^+9+*Y=01;xUg>D{XAJpK|1F3TMJ$GNE5L3y0^Uy6+HPdbn zt@bcihYYF}TsAFOH(tnR5c9GkEfZ z>nIuOspV7}b}iiOWQfshCUG#EdI1Si`EKmGjXY_2yU5zx^4#|JJp{n-a0_(cDLMB7 znx!}0FHFE3VtDAF@~v3Qy@bHeM@HwO<;ANM_@EEs0UyTp2o7cx@WE_B6W3Ei%CU^m zKL$#R4kI%W)hGXDBk+kGBV*cc%CNY(__gd#&o5f5oLqvw&juZ2&YF3GUxsM|N%L9@ zbM$q#OMvK$N&?)wE*tUnCFoSZkT_0b1%ZQwG4oy>5VsPcu@c{!**aPj-y|xykd^Tq zO$H-O&V_8Z?f_;cqPZj1gLY}uaE5jnh41|DYd6+*lY@44kfJqpw$>U{XKUHK*`wkW zAzOkS62=u56wLV!A=<%PvcyX%QD9L5ErBiQ4DiI1pU4We6@bRXxQY@c1vM@#ZAJlF z5K)g(ifjII$;W~_oP1!&!rB~`%wRv-thYBux zpH5F<7VL+!d1Wpdpgbrf;C#<)+-PUeQE14AC3>-0_$l64w%p-YmtX$#;0^l*&j*|> ztL%i}B!?g2MKB?FISGaDTM(iO_Iqs*6(kp6l3gDk0*4B^jR3{qV-cm<5TV9d2S{W{ z6ngW$%8SV1;<}v=)k)lcP8Q!W$jn*o@%9c(T^&r5X3h%Mh4}oOy5>v2Et`?s>E!3ch+NmT z{7@A10LF_7jkEHQg3PUGq5JD|+Nx6%v15)xwK*VnftC=6+|0}1HPD(N7~i3`;g_Zd z<`233$7^xlZ2WH!h4Y7K5~~qAEWwfeuTCDJ$6IjZkLSjos{gf`_cHolZf=Ntq8$Q% zXFSS;KCz!El+-}iz|NrEW@4r~TKr<^_Ir7v?6uc%U!Z#pYlXb!^#o zVAJKK0`&y}S9;fwxOE5}Z*e_Q7BZGFt_ny1$czv7s$NIwE$#v;=$2Yx&Jl0guep*$ z=-jxMDj&LPCXk!b@GooNqBldnFI96P>q&4w+c!ej|3DZP(v?JYAZ0`q=-{NI5a81r zsf)&<<*y7-uxw(uph<`{J4B$*V>2ZU*`{ReKgNOxC5gcB$2blDF7Dhv$6|%1ODT#g1eu?&9%W)a;9QiE}Hyuag)@qkS0x_5gmzbb8XJ z>ANLmmm_5t;mFX3{G?RbEK>gJ^$016Sg6~?47yFEk--sP-~-j^n^#7x9^V2E&sn}rF`5<%)uoL=IyX16i0ND`)iB=G>&@InB> z0P?0afEHG?wv1G1+4i9(?4WNKK55zoo^;wL*aze$8mZVSXXRt7W|m%s&v(Vz+IZjB z(e9>JRpP-+J@C70ZR9HO%8jvwRlJSu7Yf%`W5V*HPw{eE7pCh-&zjt9HI22Y8ty5?&M;exL=v-WUj_WwI>%`Yn>o zJcLe)|<7jR|Me71B3;OTp z)G<)B&xwy>>u%kGz94;MgLtv#HL$0ph7?BNjT zLbld(`VD?OZ}8`&FV5LS9gny!(6wc6vCbWPJ$@PV@xeBBc#&DrJnnz}4(k{0%Sl77&UzEeUTbyoQ` zS7m+eZYIbVUx{cgNflaH(h7_x8GDcmi?v-w9MP+-(-Gk##6)`%F{n2m>qBZ1Yd_`ra2s8nM>HHGXbI{9T4ePrU%Xhh-G+EV!rtgXQ}zP zW2vnaD1s@uEH!dTdKU^Ii|rAX#TLS_*t}^iw#6NrW?Hr`bP5_8*V@py29{$hJ7d8FE%1*L8Eg6D=HwD3U|u^_RmNFMU0--xRzdfj}cV zqR}`jMT)LO$AzVdXd{R&%E>}Crj}l#;&A(fzet1LOG{<0rE=F&g<4wa(82brP72u5 z|L!#Sgq4;epgZK4Ce_i*j3?Sd?5uwVoY}+f=_8YaN9KIR!5C%Vi7i|$zT3-&!e${bF1B-Q(Sby|WoUeC(K%FLZeHBB&Vi%SDM*RNVGwM@&EcEDM?_d~bTHra zmfm7oR}Jv)>3V|OKDZu#q2p){Gs>AbUk!ZP!7SMDZ&IO)??|hVP;0wLIW`1rL_ZUu zhqw(Y1(S~~L$m#aOLAL88=1{rskni|e93dIx$v($bAifeV$JXWLXptu6cWPyFEOrd z87gWzJe)uQI$5Zwqo8w~(+5h-jqb$+iCxxzhkbG9SldrsXq*F;U%wFYMzfumk^z?# zHhC^76(heEj!|j`hZ_JWF(1in_z2tZp0P#mP$*i4CdS%YBpwK>MNP)9a|k=dV~ytH zhZYb4Rv+YxKL%Ty!tcNl2+12FJEAgyC(3O{t00AjJ5rM z)-WVuhOA!O&qpCJAcbVqlR|Xyq{sqiQU*BvA7>*iLolGD;NGiw_F;3tw+4ZY$GtW@ zAA$RwFJ|M;7t^{0331oL{l~}z0GNH65cGQC$-w)Rm)|$ur5T{~A7z``H`aD2&vG}H z_zNG&B#ce$l6M~g)@O>{?JrmwIC;MxGjq-5SJV4>w|6q5dO%=-wNMW;X`J z;4sw3b((!9VvgcuW+Gy3-=v9yOB>`7F70;w2i?~t-b?Z}__hp!jZ>Yk@aJew&sjeO z9|ny_#IG!yAF|h}P#ua>?Hhp&v>CH^UYk8Vn)Rr9^&W9SSeS@VcaXsFB4NJvQ#Pk2-)=X&9T`vwg=?=QrJVNdBcg0jP%c~u~g`CN&J1$i5^QZse%+q^~4{kR$ z!%Xhd&vlagV9k(@|K9MOuD23aM4gYVB8nY13o__9WT?$uAQsnwx$&p+e#2+QqQPDE0hre{cI-l_nqh^=NK zRiSn-yf%-8RKyh@vSo=MyKVxQIf}FSz{@L6W|q!TuCYolpr=M0Kp62Dou@7~3d~pN zxKP^(V(joLL86DKT@UdY3!Lf}8d~_u{;bH4A!U?de*~%&Thz-k)4CR*K7fMMG8D)r zE9-pVPWaO%kC9ED@miOX%@XIYZyrsYLj^+rR|uo~Uq%8HK8{XsQ2AKw>JJk{c7pfj z3C5f448KmP*&BYoAFqJCRRh1t^%C86>Vh<=?}~yb^lsXq3#y}1hfe82E~TonKh~!G z4MFiZAEeOfW5qgWmlatTmgK0sQZT(?3g&P_RNZ^&6wEV{08AHC71p_0=;2(+pk;ah zFJ`{DiGG+42?l0}w{el+MFG8&_Y}qMLQz&H1e{M4eJ;}lij#&Z+g7p8U0ZQ?5jRJ! zL?qwAwlaF#1W1i}C+ROr%sCI(HxfZ6k8QeR3{8IW$Ebk59Z(`-xRFxmLuE88gwd>s z;+s_#S_soon?L;#GzQdwAtOid^DYY;5_>aAKHA^yLCe~B(6SD5`?^6(b{gIhdOIf0 z?0ZlhKoW65{(8QGYta|i3T?gdheRx<5FmZs_FbvVD6*rHUUrs*vh$X@1|wwWV`G<{ zFK>kGbYKXB!eNP!r?ZuCf|aCTmGJ^R;Z5-5KO9eN-z#04`d$dG!oe8xY2<}r z0WYA`yjjpxF*c(Yoa3q#%a7``yimOnUa0CEdbh%priDK9BoJh@7ESQdn^oJUyF9$X)U9~*n_d?cc+fwUZ*7aZ@Y zdx|}C&I7`1DDxH_Ob2_e{}z9>iKCw(=HCBf?uD!ZA|SauB!1kr4Fiz)an~xBvhjk- zc!QtHN3!M}L#;~Zq6dfleKbG}(y*S0K&#$tfmW(^t=PBRHG^;i*jwT# z4qR@jN9i%<7bH$Kh=6&LfSrYJUemT{9@7izS065 zotlqO`@2xMCa{CYlWAOpl(CB%*7V80}1oDv+QhPL{aFvji@Al>Of`FwgZ*kX8yhb zX3P5k8?w59AcKwQZO5*?N9u%8iq`#X0v1uppGct8^3tT3zpymm5kjw{WZFGzzc3hn z(h)+FoF(r|9DNwUw`?npwP_h5_+#s{*2UK4g8WW3L@S6={-VTey$jUuAmK9+v>lBd zi@15@dQ^a(g;w06YU@{XHM-0}P-5ChJliO+30Y}Qa{Z*SSn4r=_TlIN3P7{;u(T1K z+P}t6lmd`qVvpD^OeKYg*wUU}nSDr7QuRq91~rRDA-;6;VI zsNqE&#RMW%%Zqx+%ze69(DWtNzGIA8s*F{7fYcZ+5`3b@a8YLV{()6ywaCU?mrIS} zI!lC0&{yG5BSP{nsv3Sg@Ac;`TQRQkssP@Kag{Gqwa}iG1k8+*XnUbUKgV4!lRO}4 z!XxTiOzY(8UJ^Nv`*u*K#Gj*n)tj;mQk}p}3{r)-h?{r5ma%jMNn|#{kckbj(cG20 za!4?!9Nr`1e2+*IIld=8Inog@UW;@vwIpdl(`Q+9Y<#l~I6+b?1_B%Lh6i=OEhQLF!Z}BFy-I;yVEyQOn>6ktr$of=aBZoo+O&Y%L#Yj zuD!6=@EUSg1FG`J^V-Py3ewBnU+vFHRKDkgU3Ge4SA`Px*y-8A&PFJ-Y=8~ru6&_@ zVKzlIYWM~R=Mapci-^7Gd{-|eMA6mL__u%JyLg+zF5WdyWOVVqB)qS;$!8>^ z>tsURJSlx(hPtB<%t(oR8hWu*z<+3QiCDZmD-FHCF@6j-7pr?ph_?CpcjyhBaooZt zaiK(yaTiMT4Dtd-rOw!CA!^FYgN4mSR{{-BO3czVxdWYZZ%30IES|PO`BJEY$jP7p z@@)zr$>3+(Q5__WQ6Yak@3p665d{bfOLLUsx`~n$I0@eHE#;94ivUIu864QyX~7hLU^?o(%$vo0-LV@X zp`2+r3ziDHV-8u{{1;&XGVg9;$>LvgKrj^fs`7D{XJ;}(H;ro%NV2U-%9SUE42kz}|~7iopN zNSM0$*;7AiT*O%;zY<2AaE4*L79;Dm^!=~^ z0%(?9?AFg#tZglA#vQB7wHV&k76uhP?tY=QMAKg7%o1*HP=VcYw9Kd)lhzSp)NnQx z1lKMl0k@d_LFxv=h!l`Hu7Nh&Wh@8NE6_L9qcz1B4I1*gq3cuo#oCkxJA5BD+13*m4JgXbv+%uVJ1n#HE(CuHwwv>8h7 zY5|HB1xZ2NJn%JJ0)`}IM8LZ1Q_X# zZI#x;*lJyBL3Mi;ZBoO|ux)V{39f1~x@ZK85M`F*0!^;8t$}fh07Ca~Cj6GRWCkVG zIcE}=7my1ijCcW$BZ@a3N`mi@$n)3qp-rflpLva`^aP@^`_eN5SSbtnqrp_{5))nA zKmkO%kiw%Kf z)oz#P;7tk2N;fB`k*T^Prqt{d3BH()-ME+i+Bc}L>B8K$0;I1%1*l;L7scpMZmmoN;#ggOrkG7z2_Oqpprt2HWvqpnD8@P^C>wZlga(*EEUvi+RGk+c zT~rOl!Onl{&MIapDYW%oc2#duiLU|ZKvI+c|2`D+4=sd=>^Vf6&8tid| z_P(2^y~Nb4_D&kv-t=^P_Xs@~1zRiJ%=m=iig}`hpi;`g`d*amKiekr$2Xmnr}_AU zM`oh?*yl!|y9XtPvbYbc{D7@;m%LRbFU!K{%2BH1+S2~tFjnPM^n6g(#E;5^vTT$p z@yXqS{(4pkQphUTk-M`4xZ1k?F}TqFX?!f8m|wVGID=tj>QSCwopkXgN;}a(Kep{7 zy6faB#U6ns3(sL#3KM5;{%khAVy&;yk=x{1^V`UiY2prqAa?cl0GkD?#USa=U8-DL zp}4|eNfsgbamKh*fs!OnOwZla54lRj*-lC5Cb6j)7Qiu`!axx#9!&2(5lQG`EvVlf z>0Pju)8|p#{P@e7)okhHhPgnczMZi(Py68^m0}7^ER}ZSIVx*rr5<<^>Sfux5ro1_ zd`qaN86yd`O6EveMiHuwl|m3Ml?B5t7p4eADhk`lCX(s8*OCNna2*uXw8THSU?#R+{Mk zXKj{ewOPsdR$x>f_ObWgYb3sdhm8x2r%Xx zLtmJ{FF>$8n}5E`kF8-3F1)$eX1$uu$W^_6?sH%1$!6cn*9>e!u4V>z(2Sn@X3{gM z4$9ZezPX#xoEaov@?oRrzM1r#n)}p~%0V<*n;b;boDVbu9m!w^=%q)#h4gfgGuVO` zA;%Gzjggf{!sj|90G6PPO;o}*4i#NqkH6zCKMj8in=D^pFGkeDE`)uWs|`v6UP`~k zAes9PqWkbDTWMS~@HCD)U;Y97-KlXE&l^_^ti=&Syq}a+o5?UAwjZ(xIL9)W>mWi$ zIo-0C!z`>BLWF6LGi}%pIp-OS8g>$zG-bs(2$g7%5!WE6y3htT8-l41(|KV}SZp+P zbu;QAgcZS5+*==DdNbZfIPy@_IlPbRLiZ)B3}b2jgm25GS@mg`6T%J*mZEz&_zNR? zM2g09+@IDpu+E%viZh=jjskS>*+Qk1_c!UG^VEfR(!VVGG52g|Kgy~36+wG#v7N&1 zzG>B78~4{gMkO?jbwx)MnY&}5X=Eppp0Z(Dk-1s76>lnVD&fni`eOVO6Atg#^B0yOYBF_~*{Wb1qyz#Q;PC{qVJD4F@l zy+21v1H&x(oK)xNgT~kg!}`v4eBSgdM8p@C1XBmNzlFN!?Wa4!HR6lT1Pl9-txzgf zT{lvrP?<@5R7k$2abJ{!r$xC1Di;=MSrhLG8I}dl_HQ_N@KFp}Wbwo$8F&sshbO=` zp5Fz)Uj&rLmvCq0tEW)&Quf=?TiMBJ-;diuOC=!9;EU)aNp@>M>w^@cCsYU}{aS)L z<@yT=zSh7eWjuo;R(8QfG5F%nY`Y(64ZK81mD4;`Y>jviz)5$}@ihB5N&)sT=1JQ0MwPo0Q7n^nt!bTR%Ln0p=iVscT#Z_+v z!?3Db3+6Q9o8iF)k6?>&q-d}Y|CPbUZ2|Y!-g1={KNM=*IoQ3KphVin(u!j9_D*bC z$q=o;)Y1U~q3BhrGY4pB6IlRb+nl>F7jpOzZP2~#xc)g{7}3qvm+6>Mq5f?PgNqTDBL=J6rp3bLJZMM~(o`^NOJR`SC*eOF$Xf@M7~Zp~K=fH6l!y zG_yt^1CtGG;Hq0j!DL_=VNCzX9#|-J7w8?qg{$Vp0(42^U<&={Rad=^zs++qZZ^+( z-D_-?yc~9>qX+b5VQDj~ME7q2j{NbQ-iJTvN?dEo+8$x203Clu-5m{7Tn3~|KT%|k z+cmVhR88M+AXU~J$9?VzX9{rzNC8R{6MXC{y|eyRC)myKEf*%A!>c(gq#Tn73G(s9 z8Ug@&Q8_pldo4oN>^^my38>%wYyO)Q0l(w_;G92D6k&!TieM==gXfmtKj9nEPZAU~ z&LCr9HKZMGiLn4+rvqAFVm|+l#Z#(JVp*~99i*0USMjul4Vw>+rp3D zLWTDGm&vQ3BbIrsA>nANYIOqHDi6B1aMMUcs^kj#`@IS1;eoM*r%{qydJkmy0;eR$ zuw|HRRzJ}BBN_A)dmXvO{TH@pqgPMvE5fR`+~;sqBe{HRkUFL`=xBs_ z@1Vorpyq9+^Pi!apy@!Xov1NiQA0M>(H_=Qf=5QO=!niaG5oU4 zk14+R6hX_jaaSD?-fd0ajde5=dGypc{r?)fc!0OEqpaApWc z2ps#ULCeDc?n10JRmZZ}{NPQBE_Ynckl)!HjS^}Zfv?+Lzw)Vh-%PiO#vvL{(hcKd zt$&|Y4Ofj-x$v_Hwah2e4ev_8|HseB0Y{tc?V~%L?7%{LX&7C0YO-bLiJL>&NzXii!eDLyPzQ}? z=h{Bn#dyw4S`Nd~k?BxZ4%!J*oRygP8=*etYav@7Z~CI+M?ek8HZ@+D!)DC^xq|g7R%F1W6Qt=G#$-YWWC)K%tIUP76^MJkOru;7O2Q6#@e%Nu5B<%cEcEFja5$ zvu;?P$Keac@lzeaRNN8}Fi};j)1UO{t$NGQcyw<^xos$?FTY)|c~_b(d(qNUF893b zEz*+{!ZM5qI80@OovO$T9(;RmMBBsXNAk7zW>$L@YA+gT_@=B6wUn}dv*@+qYJvR)DX)Bm&qDup^7@C|MH6)F z<35XYhWYqEtR>4QH1r`beu&^PQhJ?T=N-O&i20iwL>dfPo_uv>2_Qbpc25St{oEs? zuor? zY~HdIz8NJZ_ISTw^D+32k&Fuiq91GDskB+i78eqebnF4ZCWW$)~*#9fO zEL$+=xM2FY;(~&?M+Yfy4`?H--0dl7^4Wv_0g?zw?Jnm|>m$B}>7l$aY<;#nJ@JR3 zJ9VK4^b+pJ8y=ty)$+eAdpftu*;9!Q42U&HfW`$S4Lpl{&uaP2)JYfCHrPlEW&xb0 z&xF7<9>`PF#DE$zvzpN|=PpUBG`Pe;nb-N@w93~moyNf0?!jUU`pNGq4hM*e>;^2X zj<1_tkBTOA)A)2?`yVD~w7)t%yBWk}5$&(uTnHH8Bl>XUkLR2GIc(QrJ{Rh65jq$4 zAg8;Co6|1l%&fhpXmrxr!D_@xKx`8$#9r8K&+r7Mx=%-B?ZRnD%#0$4k8_kYJ)-%= zpOA5`ydMyZwf-kx9~)5L_zZyRpqt4Y7GWgI9U08YKSC3^3f#sP7C5xckJSH{|HGI=H3I1y#*Xy)CyatLHhDCsQz5dE z4re20Abv78JN3AF#HBmghsZ^LcZ9e~dc@PC@#l2@tK7ci`22_$Ja|}-G$L7%UVO=}I+A3ZBZGv}ic?LIG%)m6M`k!7}Qkw<-`eqy>ptn~;Qf6~77V@zB(*~^_T-w!vjUVm?Q z9c$fG@#K95SH5!|X~4`o2mv*rQ#@}>i_|4ZFs)XQ_})?{NKRO-Ac2PF zQra;I46Jq5*PQoRVZUA};T@9pIO|*>adXzWm>2M6i&26yIMkDG(q(stxrEULA{AR1WgovC^VR9 zM3TUJMF-Sb5ePTa&9487vDE+MD`ToZ6Y|7ZYR0Z1P6{I4G#BJp$of3{1etBTb1sD_ zG&PXIC7?WiMBe&cm=XA+F5YXufd@Y!id&XmcPodNkuxgB0~Cn7gmae0bPug?-OH|P zg~>rDl+$q-w0@g!r#QqcPv?TvO^kM6IPkr7Mv!Swel&}t-W}UFf>c6~%+$k(qNXaa zrwomO1;4&@3qivO5^*y+7X*Is1Wn{Ap)V4qzodwvar>qs! zxZd-Nh;dD-PG?*LcOm;x!wVoW8PCzhiq!AwFT3LJQ6ZjY@io>W!i<=uaSe7UQov`(AA$0a3*l1)=$XuVr+WfB@&lxoK7Z!@0It)&jQ;o%dW&>_ zyspCa#|MS_xHZRH$#i7W^U+1IZ9pr3X3_Jr)geRWxF5D$~42S8mxmt!oXow zwGfE9K`A#~a-1kYyTr=0OI|}#0jhv?fCURh9CkglNx}Rzq#2Td8K}f6tiTf4eVeMu z=`oP*Z3b?RL0C*)fDB?Q^7)r79~i;FW{>%C(q&v&L}kOwYKAHzvg z;VW(IH?>+h?2tWQ?mD>&7Q@fvkg1#4Foc^Exhm|$0A~#}H^42EzRk>kDq`}fx@5B~ zVupyqzBTvTj~P*`oaM{NzjTT+XvB%tGIza6*Vv3e*DI~Zjjh7cINV4s@T(3%QYeyM zh9b#Lh1Hw(XRIPY4;koWD-vQ`S)C}Ooxb{65i3hqv;D}#h-;r54fFm&_9e$AF1u@i zXDFVbV82N#KZ^B%ta1Qc83K&ieMe{ZQwbM~SQ&QV=VwqpLaT)SP6Z30zvI56piAgy zF>k~8F2)i6>wJkn2S$31atm0Fv(8v3);h?d3f-W0=AKpv8-xs~a;A#d-R?a_!g87m?W@8Qma%gu0B%Kn>DvlbA2FZO=x1q;b%JT$Ty)s359r7Kq=T zHx>|ygc^^v-NptZkRdy*amx%bNq!~6jDV1V;B2+K5#aMjxYg`%w2y3TQKMqsjGD4N zsU8q&Xk3Dp6`6Xj>`S27biO~gWI<7>DQvTvY1fMCOWrpV#v#>aYtG~CfB5B0NWDL} z?p$ZP<8WTFwx1DJNJ`xrtQ26Ny4-%tv;6`XiRJe58Z?%{$BRtQbL<7kZ!EOQ1*qR_ zfr14Au5b!7|J#eE%&tUth_n0+R(`-GOGrSQ47-Pl3tA4#nt8-GO)!Vt^R2)~4BX3( zMFZDj%KLJ^0wU0Q4evNE#;phyY_zttUZ8oQ9c`}4Quo=+OesG|K0IApURxUz`X;_hv%zRv&&6q6s9V&|K{X7Rb+SZkRb%OQ z=<#ew?+~NOh3C_|un<|E??0Zj6m%97@@eJNg^)QY$QaLI>ek@`LTlVHtH0Z=+Q(W< zj8i(iR^-I%K1-wa1Bu#d76EGYT9M*Ab}QX(1qh0Pf~t{+4XI-u|NW@&gV6HatR3gn zJ^sRg6`;!w(^2-{hEab#j`T-nl&+4f&);|mIwRcgp_i3Fd9~o_j;C#Iz{wBl?BnB< zwN8ppP=B#$tFs;!;tjh;k%i&Qnxzf(5Mxod)>wTpT6bO8~!gAxfeP$1nty6*!3*}!bgWrR{%7DHJ*1G>VxO`hvbbfEgjM62PrwOKhDn#ieh!Uv; z)h(LxUmGtf!ZN`CTKlxn{QdBkhs{}-3S~C^rGMD;Oc)q8AKw3! zVbeeV)nU_EfO`i{|BF^H!!#9`CwB9T4pK+hH6Rd>%Mg4vpj}%&I@YuYwm4Z+2-?6Yb()#6TL!W!(uZq`&G95p99|a@?OE zP3*GP7c!69RD_G}%C zrZn@&x^sLiZJui-8?&#BXvMC2F0#`DXm8#3U^^XS#kO72ytQ9Hbpr|+ymf`lIM;Sf z7KTqF7oN%6Ee=C534cO5EG(^HMv@mV+z#q)7;_`1;cfKjLbAP3GVPSFZ_cg(s zb&#WH1?ZV16v_8Z&n?}S%u#*mc-7N0DSi2zH%95OZ)-gxfb{T?vNorIp0MdPM6ou6 z8M=UKuowlpunL63FMMY4x#=VC1E0DIE4x|xzxZP#<>UTWGV#HZ3~No?G#knRyc;4y zH-%hr4OALF)|Af#rcB{*+I5D8hghx1!sm|34j9<-lPtTp(R1C7ONK`oMBu@L1$cxuX_6%FhqNEE447%UJk59Y0sxOsWp zm^k{lr^Vf#7PX*-KR?RTh1>yL>KqsM|MK1!Lr-lfmihdm2S)`=5E>y_KK! zP!4z>7)igJ_-FAqgfRo6yEdSOEc?{)A#ZQt?_r}fXqmCM$fcjo)!k;tosLeyE|-wP zwgh3_@XHAqPIF-~qYl#7{lYTVKfk)aYd?yqm}!P)p5R9yKqL!<+&`?1n--5wwd(|znCTGE9KlZm0h=8l!P1P%LKwpM z2RGd>d}ir;2SH>1CjnAuQ8^)&RjSbmnwHl$KY)BI7y)3uqmQrzKvy${!60;4HJUAx zdqEB1%?LdfU}r_qe-wIvNOb}LC-wfMK_>vol8T{GtyZLc`w^0*k@*L9m$IY7Mg-pw z#d=EN*h$64vf)qSmg(Ks!CwxdV`vmWbko7B4ja@AsUU=du^DzJ33nU;N1I%$zxM=A1KU z&RieqP4taG7bvtVU6VbYfsv!Y$SSK_dFY{qGou_ms?XrqID&F$881J;u`1GI?t=P& zLl9v|x4|2T@YCpb9Qe%=ypJgIEX0qz6e))&!v>Mzw=hsqe2`%lb0%_*`w2PZ@lN&o z=Om5#9f7E%BgKRfV;&A$4Y+j6BV=<{`5CT!9OV;qs}eHbG1HFVO2Fj(;PUgiCA?|{ z@j-@JGc0(P%i~z##L{fK0c=m;Ii}UtWImNh;VGuoiF8?_c#U}c?C4MiC=ND1fDuA6 zXT7gWAy5}A8u#2`PV5^rnOXEchIbjIy#?*%5B?Bt`R?pxe>213D?|HX|E()+c8DF~ zZWyQnOY5odn237hKy}r`Qvm~i9)QYcZ~^?^?xZsOZ}FEd5&K()cO3U*Z_qL|D)<3y zvt1Sf<@5$=jr>(+9{7`XUKt82*?4rU|HP95_PxZ+?)~Q410M5BrzX|NSlh|7+vzjnX~; zFUDIo6_yX})j=<-zq}N){KBwn*NPASD-9$M!D&%iPuVVlVKTcuctbMLakz#oV=XfQ z8n?5~m>E}$of3y`^W%yxkq_PPveA`mT|k!*qRm`FI9#^~E@_Y|w*W;rFvnz%=J5*d z(MZ2m^3V+}c^2Qr?`s24kwOUV0HZ7M;6L+aqG1!DEf`77VR=jYEx)vg^}F>E{HP@2 zi1|s0rej#dDV4o31s=x*1AMpuzlwX__YHcMe2&7~jcU(4Cj9U*yOz&}!ert_NuG?n z+`X&yIi^>6=_6b^9vD5%ONWM}o3!~d;H2UQ7ZB=nOS*+vYm!g-H++|dR$cnuUiil{(_yQ_q8j`0Q|4Oa>gFIy~iqqDKy==u>3N25!lkRf`q z(pJQV=LF$k}tRCm6 z-M~NtF)@tUUMkE>aYt|{t<6U6=?sx;_cPHja{2^$F@GnBdFvxy7tmgfLTm&YFwY7x zX2!VT#(x{KhL_^7;muvW*259O*mw%m*d2j%&w0MJmxJq_c9>{9dbgloMfAG#4f#+_ zoP53(rYT^FeBWW#pe)}3LgX%^2ym}=0@xyjv4M9eLBVX;PLa!?Vei&DVxIU@h(S02 z?sS_xa=kESZWRmxO>DH>_k@3qg+PWkbY!XNlN`HT&F5y<>{$cW-0ex{Gubu6g4@y8 zYQ_$cA1_)JtogiP&Cfj?YO^)wkeZzd#>}x|bLf|N54UdV>q{E1g}}B!8RiI;`6S-5 zl^nMa9+DXz5~$VX8o?LfPAQr?0VjmM!-k9Aq|`nJ`j{^m3`9PA%FGfT<%Nl`V+cl` zDh?!KB|%|?t_=>O(Iv&viFOc-jiGGnJ)d>&L!oz0LJ#~g#3#SY2&=4WO@Aw(S_{b! zkhg%LZG`d&oz7hS20>eGu2T|G>0<;-b`~%_B$%kfzv#(V8X!`ssCo0AK`tx=B7ArK z_47NlQSsbHEPP$b&{|z1yf%~49U^-yn1uAvCv%Kw7hT4nzWOa4mYeSh=*luR3_;wU z+BWB{IMlK_nKa0NsXEqe87xN2@9!NVD~|FWjUuR&40xe*bQ{|dKhBUh*_n25cqLD! zZ~J2A=scLS?8jUg4xM^^VpqUAkw4<&PuVZlUdu!a@a=p6`vd@b`A$zZh9chMwHV(2 zptqMJMR8_5e&v8Zz(foBO9hZ89z37-8~^eF&gXC4SNC7w{UyJCYccRkxDa08&-V}I zJjc&*yhi40@I^g|+oK2(GsK?s6vx&ox_OTg-Tq)pBGM~?7(eLH?68_u=5!TG zYe$GiZwPJ(4w@T&M~oaX@}T>5HoEdW=!%2rS_PdW%=HJck|2d9;qPKKWTIQo`LOdJ z$^!la4))M4%V@$b?Tpd!|3I&DHu;b}R@I;2X{kkqYljmosZ@TgFobZck@$fTgZ6pt ztJ-}Lb#~3OJMSE*b|;Xh7}&bow`3ulY`rX5d?3Vmwn~VIYU5gS)&nXBaKv%X7wcic zGX9d#XQYe+M>*&&V}YE}$8dce8@^)i)TIS*Jj3zLwfd`zLgT9Me+128TxtzCT%zm^D#5v&^W_~F_U;_(_g#szR9AJCNB<5thcIk`>4 zBe$G_6z1<|ZF_((ATyu8Uzhr1x!K+}L3IH3ube=G?AkyQAH;Mcmbcp0;szUeK_`3Y zn-^H3Y31*1fLFNuVuz~@{GAPORRG}9!0!q9hT`V~BkgMZ4vZgdwH4cSJtR)u>HFc| zbvI@$ujV8(+DOQ z!;8J$l3rwQ!q^)ysC*o1DzZD*_LHX~9PE-d%J&*e>9WJIoI|+iBS*yNOsu%TOX!6g zZ}Wg`ydXn)46`3aqHRl924(MHn93cbXW2*I?I4}zfX;2H3lc3`W}?i@k7iE$S_nbF z!;LV*b7vW05h`&RodKw`tY&dF>`ZwOCA=D@^{n559k2@$`1;0pGGFPQo50aArlAi| zQ5`SlzEAB!MTOdPz*gpavmi`>#OuWbNaj#2%c%&RA%CO4Y1;`c;r>jVMPcdCXVZ;n z!$eNu8_^Egu(qyHnUaK7f@yYUU1`2YrG=<5g5d}nTi!?$JsI9kJX~Mt5=z`O{tK1z zd`f~xMA#nw@%IAxrN2oo|Cmns^N%CkWcOpb{!ph#ehb4=YSCc&zdp))IODWRk`zxQ z+xz1|&%RXHtS6@a_-*zKyZi`5-~kmLzrX~JPxu8SPS6%mEj%e-R00(50 znap1?{+iBTV4*_+%;vF7MtBGIixIZsMFfnrUOq0W36JEdT)YU47b5w9F^^2+>0&&o zntTn1r(a6oQz+Z3CzaIWy3tOC)hnXO-;rthL6gtw{U986oQ`+fZ$?Ia^pP<|bwfAS z&KXmrq%yPkx=9K2EcCWSa>uFs{E2IYv`1Qj_V}%ETH*6OPQKd#M0iG7dTYDNv(_i6 z&q*BQH)UI1<;O|(*I;i6C{O-{^ws*ul{-X#THc%q08*mpS-&&!VbMFOLj|f5>$?-Z z?Rga750|NF6v0D#eEKO@@SuT9VN|1W(Hl9^uIyXF3MrdJ3WraA|FIg;2<1G=9zkiY zDB}rsL|Hc~#wi|P<1wq@>-c%LS!(0(Rmr;46LrHo__Y*10P0@(9L0ye8|zc6>Z@1J z=*u^0RXIX>29TJk*~JF9sUZj|4-(YKN+CDieZ#ZnhKs~Ac^j-yULBtnzEVwclfmd`|5 zr-{ERdQh!F9|`ix|2=Cz#%J3PDgysV7CN5ek+lSFnju0o1(KmCJD)pilejM zFeKViA)ZI#G+F*0C}obw`7K&PzQtKQjW zdLt0O0eyu>#O4Jgg0crHOUYPJ0&<|F6VYsZJ&kJU6fi^#k4yk@nHecN#g-W90(73t zj8{a2*J*Hy1Qdw(7m_Ewm+=nAA9FC~facXW{^1>Pvlu+@)FN5%`wBdU4%v*1KZWN_ z_m&1}TZU~v4wup#zqkK_O_h^IBXP@iE}-&+XLK6wz8d5G5D zmBpg=Ull^MOcn%7f-Hi6&=s$gt>dIU#g`?oOWvk@L-M*vsMn@r06_#_z*lLN*8t9h3&`u_w>){__+R4LNhP#Zk51nKt)Ou?^B3cyH}tvt zy<^bP;OQ4_sgfVDdHkphe2{L|2iP*xexi3fMFvEB`~qH>f8;YuUmn|L>&L~)y!8)a z{qS%e@-9^KLzA}SqSh*!W<8xtGROZWn@kooE35U6M_G?GGiq$`Zx%gA?TMbbkL0IE zxc-UhIsTKmxBY46IbgmsH{0*b>IXAV$kVyi{&6i29GCL=oKJR_ zx;GnDc|lZn=0z3gRTpOCYJY!p0V{Y;eq4UX+BX|l`Hn)k`sByu_pOefWwWawu1B~b zm&2|JqO^{MU8hxcL!mq{^rJ+wgp&fWcS4y=vCOvPav?Al69PjJCShhx9taG{guqZt zi2DfPx|FZKZao0^@wY;0cpsncQGtH7{EynNlZVD*PNCC(LB$wQ;2Schl-UTcTMts zK1WramEz66=Ie_uVzAO9*=BK6AOKJ~nGT&~O_r>s6|7HDMe*xBJPHNm@f_rFnnI!) zFU1pWuEkurDgiT?r$9vSLE=ii4_RjJ#B~tjPVS7%_<{vm!B{kT2uW)jbbtDY3ETR@ z0l{CG<|LTo0X^Lm+PCLXHsVjhjU4azwvue>G94|zf*M5$R^rb*?}LM7fOIcB~H zuZ%_feACJzwiRdCJZVJ}?$@IQpXDWC+}o8FG#!VBIA<5(b6~if7hBmX?+S4*ma@fT zy4uV?+l*qDVS1kxZ*r#w??`|W!M}k1v{saH=|tXFyaO<%=nbgQ%TOVCD+sTC8Kh>3 zwHbbPSg)4qYEyRNs(fV|bIQt8C%bGV<(i!++tS&IiCjo`d`Pu-qo=)p7@q*a=MN3j8NJc0`aSY^{^yKwA)?p4e3 zMv&c!r7L2`&!S8fl{0%YbAKk<)#1JJ0jv$IFL&U#T?`Y9-(X%g#(1E>$b0}F2iBOk z<2Psv`~~_`ZN)t8Ok|?@;}&a=w%As;&f{$?9;Jo~i(nI`^sYri6F4(yj` zbC@MdwR?sWn{$j>GxR+SvsCpyJJFC&;Y8Pql(qUK9J~1lb^$PN6^oFoX^a^j;}1kG z7@u&AS33dlg#vCFFV%ss(ue2R9Q0v_)$$%Tj(r#v%&`?<`2vd|HiCrV64Z{H!643&|flkY?WjXntH9-jV5Bq)=RmuFQ+xCxDY(;)yeM-3m`aGKj zX0Tb-go*yT1_~Rc6)JnDrgmOWt?G5f}fibgyG z{RBa1tbK9m{btDl;2RJuBm>?j%VA>H5ZT@x`w-GK)g^9U2J_V zeAkelC9iY-R<-lD`1MtMmGy(7sh@Lsd=!0lQRO`4X1y^MD<%~E#TByO0SSx*S-`t|(Id{=+= z@0o2T%1`p_A`~{4SfETF%fT%E?b@8hzp3C~4(rqmQ60d#3R18;*0ovIRj;~Xy2rEE znJB6bo;~C7tUmReYTRNZS-wS+_aGAH-HTWx=a)3FpSHsFvNICNUD2i!g%%t{D#nM0 zWlC1P>iRhz3!8FT_&wGxEIehEW#OOd@Cn4?_Qd)vPE14U&{+9EK}beDcbUCip_fc= z7t52`HDva7FM0r@uSyh;8PP99o${B(|EphAd%{Z>SoDX175$rWE?PA#zTefbgI3R~ zp{Uwa9Kxa~&`l3R8YqXdKrVYDlB-gpNzK2<#C$*0uWEIGnEs~{$+s~0;2VQPwSr!; z)CE+(XGFf;?AP@Zr16=jS!P*?Bj%CDhs-tI+SM@-odsTCOkyCXFk807>>R0%zkU0ti-TfY( zhmhb&m=Em;9{F&03%+jE8%=Ga(p!6Ro+$gcczwF4jzYnZKQ4~r66AMkGZ~sk^5l(Ezj&wLhk6Pp;lHZ!>tq^j9SbWpKTr|-ZxT9d+;Q=G~ zsR{=#5GL3M7FS*HBB#u>@~CqdIE3t1{|T}a1ev?6rjrFwVdq?~QhZNHkOts#L5|!r z$bekZK)SFS__EqLpQpFI?82ly%qBoK*v%=&2(s6V<3pu#2~Dy9hPZP2TCP;{>O7@H zA~}Th6~bhqL8|-)$OOyh*=K#iaCvvr=L26Kv;ac2C{8mO6gX-tL?2{0ymc743nlr{5=4{t*~k zFoz3okb0#m0jiExVcx+`m7i^oumISWu!Kn|3NxE9#gQY-<3Ax`=lFzG3A;qgc0<@; zOPCzxftE?BEG_dGvU`!<_MXR-IO^`VM-Bfa8wIAsEmNeFG9_SQ0=kja^@g%Sa4-zK zQKSG4ni^qRC_i1$UOmez4l2?HQ2$L;v_hy~XVoCR!ICaTplHB9PKLg)ArL9&2=$w+ zvSm3fd?$$3zpU|g#?yAbfkRGHVGFw2WhFqKE=}Q(3D+oaV|*b)Z|VK-Z!J#M5==>QCikj_?d#C#GzC2XmVdhbi&46 zRF2{J(0R0V8*ZtotA$~C6C!Z6!UMRE@Q=LF<`DjZk^DpW6pWBUNBT6p#1DEp%%JoH zH<(Y*wDb|fSHOuQF<7tQ2tGzf@G+&@tiI7U_i8I_EgLi}SpWX6e%%)C_-IIKlMdn9 zu#C(S$R9N9Ih`eh8isjS9Sn>Ru!c{y3P0{)F)4Ffs0@7xcrz%#&zR1=f=%pd2T0Lw zB#=P9$FPx%{Ga|GO-DoEc%^UVbvF);E zHdNQlG$_%a4}p9;Y8&x4)y`Y7P;6E#_sY!|G`wm&hS9@VRV$s+=v?ssp3o&#h%?#R4zU%`-4UCd3rrJa0R`=Zzi`!KgHnL+5yx@f$xwb~M{b zMG9l8SK7KFf?o!;vHSpR8`k$7oFdDCJ5u20D^D#-{fvr$3IaP)JLF|%F|Q)Dxf29R zM}rV+@hgEjBTii1B5}Kb z@UZnjxIZ%98y9|xR2dg=3}gLk{^^o-zdUqowAAMif>2Z?GoS??frnUzFOWLf79rNc zDJ40r|CO`~I_tPb23VAWzsSS?vp1B%4%94sD=T3!mZsoMM!<^EIA%TV+T_mSX%i6} z$(NTd!;ew?aS`>u+;$TFcHhI1i8wzpB@P~QoJzy)Lf35$miy=1-p8HaYv~8IET=KT zoAToC%#bZLCDby1xbv2d2r_vind~*_1zrh4LV180@gOq_F!39fGwqJ^Dje4@%!A-d zqD`U@OMrM?d2kIjHwEELolxUS<;r_FMF(WcFqL=Q(+j1Aiu)?D2H?zg+72A@(1N&G zgb5R5ZM8*aCkt$=%S@8ryRuw8jm%NRma9*ac6b$uwnf4en&MUW-4 zr)}%BUuj*AwOO4S?`aAn9H`kqD-z%ge|uv@8eJLfjG32c%CewbUyT52lt3-EP!2gu zcqZAyb!#3d*VTPo6D*Xc?Z7qO_8dYfU1RbDoUeudZZ$ojmU89kC_Kv34@x6)<$XB zyf&(iT!b0R0a;Mwq|=Y|2PiNH`d$a3Ts61lZG3D_L`!b|D z!`|^);56(qTN<|d79s^%aZx`o#$&P7n|7}SmkSSDEvUx_kKhVRutR0!`-@g>+mY?urbA>O>;1A;x1?SQOjd2-kz#N;U3MDKbc3!>6iq$cd2^+usw{|VUV+KPt)lh@>5&=Q_s=W(ohFjN*=aT&fF@kIJ|J&auF zoY*Hht!I^U8ZK#K6$h(!Q)K|M8X{vBG{hc2ai>&H4Z?hhkpPU{GL8jdxSSM#u{JQB zNH5jXxM*37Akg+QglF?BxpH|OubS6YXQFM~CC4e%qwBG-+Q19^XC->O5-I=SBEZM% z;vqlXT%V%O$)!CUD&pnWGDgvFa7)o_!(NkKSMBQPPsZY=A}`aQCHw42?w#Y4P*|$L zSE10S@HwKu=|yzEMz5zWq!>8#kn-&|BJTfA8xi-vh|~kDl3;GFyo!--3pR=oV7qYFW=6;pyFD=WdvHWUQ=J$x3@82t(p-(2m6{Cq7>z7%~*rgJy zNfl*U5k;}U{x|%U@t(hO5MFtd{aLl0`8NpCU9VB z^M`f|W(OdlO(eeMMT)c49%m2O)tMw;6cJb)e3@z5l!X@{GI;_G)@b{{rxO^+tEAO? zMt-m$4|rRZQjqPrpJOVTI^H!^aWZS3%_DABuy zIvhz|n6!8~zPibS25^ z7zAEo-%$cUW5>F=qM>N2NVh?{H#;N_1EMdQFD%igKVTWTf1X_4=zaO`XIgFh>`oe2R)(}ROK?Z-AUu| zRfp=iOSA5}wofdCYW1J;p$gpRO=aVXkII89hQ^!g^W*aG^PZfIYe7L=$K=Q5-{*bj zlB_m%=ex5kbiMv?-ZqxQ@l_Fkg5gbBP%vX}z&id+(87E+52KZZY7UV-t%<%Ne@U8W!HFdnGfPs#O{>z&Nf>ylvbu4y~QLGt9 zX~8tpb0ouBfxt%&ISxwY1`P5)txh{etd-8*Eg)O0{ji77)QA zSxi@%*-^um>>k{7CjbNoC^tM@LlIJ6XWQK8E`w0hcWpaX|5PsI4kRrr(bGm1w99uS#+X8^(aGp5c3a_I8Thn2MN7d_V2O#to=hHI2**m5Jq6A^axy~X{Yax zNkFu92^CV7=LSTRe-Z7JJLq~RCfa%uRy1_s2l-z_#4QbZ_oJe%ycXcW>;Mjd;XNsL zuzFLlmKCm+BZ{BH!0KRr6NLGZgE_Ec>tGM$x**869LN!J0(*#CP8=}pfJCaaf)5Lu zQM5O_P~x?BSP;ej4h1e#$Q>ZPi{!P10?yOk6-f4Ae(zv{?fo$lJ+8JeA}fx8_Tqc* z%Jrs;BoFPx9R)emKDE|mjnrcHgt?qQw{n}EK+95i#*S-N1ERA|N7U^7W0^Abl>lab ziP?F(tUwg^+-A1fpP9>{lI9f`8_C#ujrEheNTyR`{WH%J>7N{AlCj^o*m;co%*DzX zOS>5FMw=NL>z8>PF>oN;e;fRpPo$szsvGpL7K$b;@#Xb)Q1>r< zp}a6IxA*c&qp~qM8=0;GdwXC)urP1V_^Y4nd}DkiKbD0ZrXdbfSjmfnFx#B^g_L|< zP($TXndnYoB|jf0g~CdHLlDITSBuZIuOP`&;FA$?N*-X^kRZ%H4kjPd-f;Sj3M|vs zBFU@Z&xjOc+W&n|q5cJW%2Fz4_pQ=XHc22oz7%`SgXeRXTHzabq;bkV~sAhlT=*fVk;S|cd?rp`?AE$2`+Io6NhW8UuJK_ zLiWCN$vkk`B<>M^E&1j+PKw9VpRzZD@pOs2&yvP!X=<~MOER)*LPyVF#4zVaHWq{i z;tEkY?P?EZ&>BFg5BbMU#k0u8q2imd%qx99dingshwXI{@Asi=GBzon5 zeIri60`MPv4Ms0`fl{0m29B629V+-Ma&wg~3&oFo6t2M~%9=2;%kv>adm6PpAm$_= zljCj}#eoG-_$=8fFVgS{o8q--Ziro7E^nWX%;0d=y)G+j7~DTPdvgRFO562z6==^P z5YAX8(vgKM$C7u0MUbIn$B(|61^JFGUL$4cJjf~T5QUAbi-rnUuRx)QVilGNA&S$H zl_QE!;lZx(J}p=i?j4ePs`sgmw}$jS6>jR=*tcLEx-lcF)7}>+Q@8A`dZ*Qjemw@z z>^ikT36HWK5CBaV1no!M2L%;EaGzhWK!4)KQZrjGphI^9`kwla0q8gT6(Ty4TGP8` z=z9U!KNo~05nIY~IMNa-pht0)BS4N-p8)Q2cLS1V`jLMnIzU>lFj)F%!mop2YKj%-L-v3v1Gqv_*EmZ=Yb{e~Fdz zIxtP$ioFBvmw{coh}U9$ejwWV0Lp?P;>;y~hDdhfy(*^(@z!7YrmIryf}^T72qH5` z;d;=6aG)I6)ri5pl6&|7Rmltph~s$}3!#W7AbGFVm4Adb-uXOtGa^-q1#>X1K1|b8 z$p^J?c7=yiFSW&+&e5VlXP45NOHWe_)m7!`tIB~H;i@>!nlbCtRCGx_tX?L+dG4=-+<1_WC}RXM%08Zw+eM^>&LWR<_xl~>yt z^=)T%O>qkuG@rDFTlUE@ar@<|S+!y>8jGO${2MeVn@9x}L!{<28qlR*6)YfzsDA)- z%5Fe&4Uy-_2Cnv6Rn9S=d+!D_IC4l1NBA&;-^`%-gh2|M&jq^y%{KZ?*Z4?-rgK2h zbT;8sC(TO0Z0?=aqNYP~@Fd&&WX{8;zj^OQadzL-;57|i*5CyV)@ksB2Fo;fRD*{# zctC?+Yw!yV?$F>?4SuLWQiEmEhf0LXOD7>qQD`V&x%*1nkZHoBLEkza+u6M7IaGAr>*l|9SFM6 zVPsrF$Uz35$oD8^AjlX_}s|xbr5P&R31e_9UBhMM3OuzyoVKSiu9fH*+fP zG@2!?qB_6V;I|swqrrR)eyqXG8r-D8Obx!L!4wT9XmGg(muT=c4bIgdp+SuXCu(r4 z21jZzOaidapZ{RJwGpOVm#qKv6HI}4pIz1;aau^$Q?XXc36idB?vG!1t1^9P`fz>! zMIQx6{HhYZXD)BT=-phVMQj>!`OZS!`tG{ugC@ZRFganJcB}b%6uTL zePA$wXaaai&MJ$hJcMRY4mlyj#1p0%FCGB1&-8Ufdr=7-01q$OHz=E$5LzM$&`a{T zF@bH{ARbm8rjO-9hz8~&>J~($K}0MTB8bHTcv!!YVzFQ`LWS!ulX8CJw@aac!9oNH z)J4=g1*$9vH7FN~+j7|8^`TglE8yvi=xn*35Tjwl0X$u|=ML(_+MVF8M7V?6)uDar zUULNxapB-LO311-$gqC}`s+bI3ia2AwZEd@s^glk-yW9LZx3U??RX96RvvsQJqew( z4-~8@pf7iTgfyTcA*f(iPEUdYWfxmui_nk zFgwtFvMCbt26mK(DGGE&Wk;AqvLnPX(i5hT^n^G@a>4|%H-|V@o=czD$xFpfdh$|3 zna!Xug(N7v1|h3jW^VV1DEFafMD$P(5kCjL?}@m_tz9%?R;hpQv< zP;-epSQ~N6NN}l)1Ridp3b%!*!pMm$*cRfF@#0b$FFaf<8KRQ~gQ!?ghLB5T2=NLM zE=UC7WK_9SMimRk)c;^)DdjEDz{nCBPh!6RH`k6QlR0R?@1yZAyq`^dD3pt1ONFwQ zRxI6Z!KsA{ia#3K{SWTGmyqg$x%Ior4Ll~34%`qm&&uN@1#%N@E(5Fc=0f`(5zfH8 z;^(}qFI#+%%XhM8+{j;+=)}GE`jFW8#}aYGd^5XBNj)oHDkpKMj=z-4f6(54O0bIkHygO?^0T>RtI#ed5kl|96;tzZ>u8VI!?K9w`nh~) z1MiZ`^%POilp}H&E5@ml;LAdhX1Sgc0wm*5GYPp{9$<1OM{*_iw2%QtF!9z6yGvF5$H5{-z)gM(aG)T>oc$=ldVwSdq?@>ziA|(&Ce0E zn+Aen#cw4KU4s$j3ptfxk5Czu`!etfO0PM{))9Q2%gP`GNX%kdL?v$VF~@<~YFem( zd33u{AAA+bYFY>|plPFgw0u~qM5PphHkVtp!564XR7xR060BXFta#b>w-AUaBQC&& zQ~Tsg4Hy!6A1bHRllkuFn@94chIQdI>5=p0(+i1|3RDTQ0@Z%WR+JI6WjTkQ&Q$-* zT&(-1`euH>pnv87jTLKb8m^xp?{WtHGn=u8kJxGk{WIkni)!pvKKju&Gn0>g1pfT- zPtHR>FdO3@F7UjG^FID5A30DGZ9SgjhFhi|#fU5@>bEl70i5O_P@@MFIJ6RNJu?U+ zScxcfenCFP;p*DULlfM6z>$@}A)O!beuo~?vEdAp0xY!8pGhFRr-9+;Z7kiMguejI@#GHt; zS!jTNiQ@tT>_l-u=7z$7I9;O2t%ycI^9_vydPj(LOjbMEn zTz%oAE`JKb{L;ZtRf^yBsG1c7n&g18wz7lDa>d4MWf>7fG1#F%+Yj|>p^xe{i_d}P zYdg=ZctAX}5@>srTV9rtKMleqJ-9$Oaj%RIu&<2sY?s&O-JkBVnpXuq2xy)>PITlo zqItt45Y0Q({hVi__Gji>)U{$4lQS#tO=3a39`pfq?KKw@b$-FczRSEPT&$L{M_udy z#vX7ndF}NVE_NTR8F+xdEPWl^@@e$dmsvr5<%MP^i~sla^^xa3vA!PSHLIY$2HXDs zy1q6~6n&j0f#~a1?&m!74f|8|^(!tW`g)p+iM}4^Vxq5KbTQG_LtISsbsrZKecgrY zg`)MMuW!3pK7GY5zkIKyzgcoUl$PK7;?$a_r^*V=#hP)ts^Bz@%YB7%oAv!6=k?z2 z{NLYluG+erf=er&+)XaeMbkHd7ptqZoQG}7zL6+deW?wry4ASB? zC)n(mdG{Hu#sifWKWSeM2&D!ZdohUv`?ydcObHVw3}$0TN+T@i%-1+&MyZ{Yjct7z&R#c#yT#?%ryJ(hO$~w zint@@xAs*Vmt}^-ez2YB7mRaz9^fTUvSSaK5 zQoZV0us@9_RDs;)ia~|5;)Sx7>Zjcc;LP{EAlqT3n~vTsJ(m}*RJMl;R=NnRDO|R7 zH!jwL~)%Hj(Qwyk)L6t=-R@p)^vur&{3_eHTUob)|*a3Q< z$^wz*Z?ZScMP8%@NVGEBE#^qgL~yCla&g7wjt~%U2~p>oK-EHs1Co5Hy~Wlp0<>** z~-J_ zOpJnhCTMJlMw}ScVoSls)Py@Tw3veWQ3mFEw!K8po*jlwnh3!!CWyy1#<^-npz+? zY_1w*cFX?L{*tP*h{kqU9uifndAH=cZVt8dUPNOT&@$BY!>xG{3M>|{4w^8BGG@N9 zS}XKG#XePAGD4}W!?%$upUhJ*OvXI|axuoi?3RS#eqf){3RXlL;ds|(rNSR_f~6D}NjTS%;29@iclJn(lQVuXQz2A1D-LQ|krHsF z5a32pHpE$QOE#gyHfzG z<91dv?jtCgp;!aWaQusz8>Qmif?P%ryuk(1I4-z9e|(Vj)vG7VdPcgrB8ID!xERc5 zMqqZZmO0}Rd%bY#6uW@b^etID!s?rTh3#CNN+e{{DROELr>OC=)_Zti#U6r&(#Xo3 z+}y@V&k?)6q2*(-F6M>tp%-B^*BBq zsZU?d`>ghHj&iY>UAz^PsNOl_$of=IoxCkCS3ung;IG-Ou}tWHimiHQ^Rqccx6~y+ z##K_jLFFx=eLZi{8lo?%Nq!iMVgsnCs5Z5scEo$Bje*bRB)f}yapfJKBJ3n}_0=!W zxFV6hnA6*T;XX-G^u`a6oc`?4&id3grTG;k;D$W*lyHcB4I=*0$N_pqFZn@nbk=W? zlfZYS@ZgN#OLms9n_@Q!-!6Q)`Oa{qUkg@x-BnuQYi#M%3v6XgXXLAB%Hg}IKqr417%rH$p%qEvqWahwkG5h&o zCnJugX6eJ)tDQdJtpcYH^}-0~wCck$)rWNfefXnvSi5Ze3r52Fu+Hj3u&C7s9SCgE zv7fBy<~qKf(0W*~*1hu<<-_|$$q%4NE%=pMRXakS$@f0LWcBEox-KEDzWSLNxN`fv zcM+I3F47rX?f`~6@jEeL+eA6j$&0|yBe_G#CGw!A@xFzAJPZ(LBa)*4y~|Kj^G^~Z zf)!5+RvZmf{4rJ1R-EjF6|j}R#B{H6(Yk2sUyZbrjY3QiZs{LS(j5iR&y7bp0ocS1Zsl4oGfXR9K+CnHP5f<{%pd;#(Ns%f^AD z7ICo2{`vg@{(c-Z=y~CLuR_1zdEq$ZQlFkHzSpD3?uBhga8d4IASmQuHdjn6lodR= zSOOF{aU5Ff+qfIFODjY(@_V&RU8y~F`-~AB@e?3j4{035qZ!V8AHqnuyKZlOTIdaz zZ}7^$0!qE|YZ&@Tom@dYS;f%O|+LsD=L=noO8_)>^S z4TxX_v&|LD9RR}%2R>M(IczIm_fu(d)EkGFzv`(8Y(9<+L~r^*UqrfA4q@8x=M%*% zq3(4ZrmuZXCEEH30C0^Dl-`S9XSNOMi|1D`q`#9$zS`e=E3qcE8Cbqi5X(0`EDgKG z@*=SOq9B%156efehJ|QJyf`W<74$23tjguC2N|gbBBk0`s7qaN)UNu6EGey%aklm*FK7o?U$9Ezx$3J}FGTUB!Rk|6c z&+?BwyL+JNVw6fzQ@tmc0(6Msc5J}x$@RsHE6U9*NSmdkxLM8%?O=e+q4BPtV8aVp zizHp1#*}ut!&t2q3(y+0Yr3|JZR4LWPmK37xlN<*zkkb)_eBwo_qSI>B%E6jld!d- z3?Ya8L9`hKxzJcBYiY$psJw9Q+}-BNmQI06msUKx+p_FIS}$D-x*NQ*!Pdw}-0E=` zJ<+yE-)v2;fI;TH4UEA6#UW0>R(i09WWy#`z;uP++py5U3X`1^@jo1;BdvXUg%6Yk z5PJ_n#G-9_?!=Z9HwE7Jz5Rg3dEeBZto-W(`QjvtR%Zd77XpG)OJ4z3z&k!Vh5pQN zeC4|*vHl~U0Ux2}gQd`B`2EP9$iZU|1zx5{H9-pqOYrV`pb%{8xB^xEJX8|&O~ml@ zJz2(QA-$~bNr%K;9w?DI66}}z>>-d710a?h^qO3_eL`?jxjd9F0(4>!*UyQ8W+qz> zi|MZgCoAZ?IY8+UkjSBuyKj0g-_rahMi_TpR>o4jZ zoNC(dzV9opq@8Mh0ADG~ZOu1Jl{fREt(}B+9`l2rtf+l8{CmNo-_BdqO(gIX8$W0r zkG2h#LiN~U=VC_dbLfBdxV+9cz9W3I8xMEm<#tBP8Lc#9UqQRAol3x?rJdrUm)I$k z47_g3l8izpS@O_NU9$V-Ph01&r6ik&Gdj}w*7`l7YlV8-FHs4q#M*GS|9QHE$z5=? z58yAnT^N1jh?J4zF#P7>N5#?EZ^70iyK#?vz8dC~4m6GGRw7lbuJn3OZ=uBCgLs7I zt+&u3{~Fkq5y-mIPQ@ag?daTUAe@)Tv2)U z2t1>Nci`HRpe2z$7pw1Qz~j1rC*+HwH=hXP-n4d@L{?DZibtcm1fR58a$0VWS zdaRDitAkU&U7zynZ)ynCecfn2`(*2tQ3|DMfemHadv5^&0~0a(4~RYN#niX4v2%dC5@ zE7bD>$PD_Qq7Q?|S$&9mPYM69pQjIe^4dL*+a$^2=<-cj$f=4(9lC($WYND8=?O6K zSi&_Qj8c8UcX{QT4l<<7y#tlgcFI72ha+WWXm+=xs#*o4_%(dyhDcEbtOBv?LXs?& zql=cqFk`Lrc9uqiRsAC72CrtTsgSfFp*>r65^-`Ef_mT{3rD`9Xq(*8_rVA0d%j`; zC&yhwy!<>mzxoWN6`bIup(LINHwV{R({L_U>|D1AXv=jI-ssJI7I}gBfXHLlS4AGt zM@oj>ykSzw%$-G3_no=3&$QxBbDrQ_sTsv)%NMuxnlBw?dQED4rq?F-fqKJqCM-iT zlg0#00hk4Lp{G>2AC>YWRAT-a;Synd=hTIBfiG10OK0vOf9&q_AJ56pvR_v#f0A!j zC2L~n-qg?$+Y;41)6Rk-3@aacLJ53+bk4UESQNS!|50L-nF{+9PG0xb<0Khs>!8hJ zL%OkCtaz1)agT!Jm8g*>gj{ofUT#9{ zBv?t}QwyOzPa{Virb3v?ZjVM@8ERyM4o|2REwGIo&tGthWTirUBAJZCAu=D?hQr0@ zl`%AYI$unliS~JIL)%dkIxgD&BinErcraGJYXQlAZ?npC6q;!ke#Odj6dDz0 zqfnPNO7uvqsIXl$O4u&U7Pgn0QLr+s9{jMQLL+r+ve!27H;yKcLX*8Tt-pcwSGxKe zQ2#jAk1Di&sX^)oN-ONip0FWF>j2LL9!5Zdzphnf?h?wzLLwj!ErS=DNZoE1T<7W~ zTqwf=l=cV%vEx8&Ltgm|CaIKvB}j!z1%@b*x{wO)QT{bB{;U_QqCW!7L*-Z&4c1hJ znks_^#mfxHC(`gKR~i)6l38_vxh zA6`BuJKt|_TWy8W#jrW}4xpTOr_az*6I+0Qa+Pq8*1r9dTl=REQA6{vqNc4mfdd7) zGFO%Om2<2@St;w;WslyLE0wO6<)o69V+BHAjnrPebdKmt%bPQiho;Oy;Hl`RZA$kq za|ebJuPIUmoAOm>HUlm37dRV9hB{@im8SM`YpkZvQAP(FDkxi)vkh$MZxFga4=my2 zSGq)u%K2xb<@{dSe^ZDL9gsU@?_HKH#Axemke9dh3z>o5DXn)?)yZVV5}Pxfk#>pb zdbPRo+w8}4D^zx^p7mHIK&^6i*JDGDT4biu&GY^|K=Ny+>iepCtM9AI(9{&|4p-*(lXJI=KFLzaVeQUR!t@YAv`pZEETfsS>8n))*>ul_6m zAs*YLJ=7nH(=l|qnT44byVXp>f-U3~^=XNOtJ&Se5z1Xp)`d>ueW*x%RS8tK6FLhz$EWfXwD6 znQrEsVfmTuANnj5ezLJ1{VGN{zb13K5(eUZN91;EW9Qm0v}Bo4&tvpRwd3jOAcg*y zd}62%DtvU^j+0ARYs9Sk@MFEQjb!&n8AiH_ia$T*JCCLAU;B2dvE;FT|Lre#q#7e# z@zU$Y9s@-220|ko$1v!PW$~lG+2-oU;zmhD(T=JTbJ31h#m$Sz(neRYU)7bisw*R1 zHMXi6TUCuzl}MKiYafNr2eFfysZnBp8%ZacZXv5E|8PVJeX>aR`Bm~G#scQK+q$Jv z(b2M=l_XsLWF;(ypSBqikNfcuKkZPxaEz7jWNv!Q129+ir9VPq(-U3lAtN13Y88tt zzh$f7aR`AvH8mws{FQNu^o3Xi!2HG+sY{by;r0nm zd!8z(#rQ5GW@E{Z;?d;AL@l5GgVxVPd7f9TUKdSr!;Ys->Z6bJt(`Ll=O>Aw`ElL6 z_>550jILY!y#`B8eA@Swx%leWC>VUXDxSoIFqTN^`W05XI)tFEb_t+SmztRs+d_sZY--yy<0bY z88^rD-9|}Heuy<^z0Zx$+*&~-x3nixFV@@1OMPk`Nhzm2n@Mj_oKPemu8Kf4n# z?n@Vu?czP$!e5v+jMr&HDF8TaXuFsxI3qA!@~JrhYVcQ^2!UnhiJWe`6)2`5YDWfC z)6VL;y4a<)wnIhS53Ah-V62`N%|^&nRguv7w@DpZRby%!@>&u_2a~b zy*jLf^66#<>dXgL}u{`;tPup3`)SrGq=nFqa1jWrOg9J%p|wMCCz$Z0{!Dr7mpPR-fvK&#_1N zBU3uU%|Oi}T4=0CZdV8SP?+SKMc49^eA@>c_7_=wxkLtqsb8kbwQu|a7B+EUuT0lv zp%G5~&5>;w*uY+F^aq!5O~o+watbKU=JR`+&`BX!9&Or1I@^vW0D9O*Jng~NU!K@+ z=V=le&+3)Ywmb1VjrY!RTyh!Qh8=h#5#RY>pOZ7!4+@$=N6dkRS}S?_EV|83*=(FU z+!i4#El_fWkECfl+I9pXVj+mWUNucvWKf7Q5eE+XuZ+&Uf?EYbN!ubjfpA>G=3_f* z?lg}dA+~O@1`la)p9FZIhnr2#+FgO)a4RzX5Sp75LQQ7o4qCupNfPTD&n~ur4TG8o z6nQ$6RFS`Xej@dWlz8gUL^{7VwBn+C=0wzN3G8{^3>6YkOYkq`pTOT5E&d+&L*`}e zhny93Y1s{b8ry&KA2lUiPrdZ{M$R88uI+H}8~)cTqcPn_D;S~UGvSG`a(bW_cU z^|k5KOKOW(b+q@#bLhnzYesB3we9vkUt8Q|YKC?I8u^jh;?*6?N^4S^ikH=l=s2}) zZt>>He{}5~px^R;RBrt@ zpZ2|9d-adbt$%3b;W}4;zd-erHnkx2OwGR_sMexy4Lj_gHA7znEV9bR3|I{_~=*T)fR*0@uA8mNUqpPA2U9Ycwb*M+zs6uo--~WV8kFL@} zbltS?bMJd}l^3FG+rW#)cyx^{MAu%KE%$kJMGDci^Paaq_UIZ^h^|e2uKA8fS5+ap zepr8ao1;sG9TX#F3r(Viom%~2FQVnJ3^W%sHBiA##T%(uE&sgsCaM(70&NBD46e6y z6fdJbeeRn-zZ#jNP>hC(MkYohB6?Ih>a|_SEI~0^DO#A%(1NXDowZvZ{}nQ0dF#CI z>6gz!=AgWFjz8&P6Px6Yl-cjJ?pr$_SE`R%VQS}rZg z;w;ntjB&je^$C|hH~jsY0gw&YzY5p}X>Lb5n1G>#^8IP=;iuIM03HZ_H9$sLkY#%# zNu~Uo&)d{I#7`qM(1LVCk)*P&Uht!jYX(3=pag3GQe{Cp4?>bkyz|1Ze>+G^ zX)Z0dJz087ke13^T4ucec5jfDl3ZHWU(z}|NK1JxE$3dp@R}ekqjPELe*MUQ2WctG zrDfo0#rFhh8JSDVFZYj}6Qm`UOUtb5&;M7DmLqd%IquyP9}ChF$))AdXI?lwNJ~X7 zEw^sCu_r)_)szk^qT1r_+Txzt;&*C`KTIT7V%q%g=&VcOMd9O)sY^;yXGc5^$)@hGXq~bq-=&wrRI+7Jt)k<{y7^;>Ewv(hkxe(qu_rVt->gbcW1+ z&fo+Ei!1ym`pA*P9$k2H34K{f=<2|<0Oi^x0HC*!(q`ui^O&E~iN+oBn-fpCjtguA z-kM!*DdRdpIoB^L%@D&mqusZ~!d?}pvC+1-r4S}P++jtwAgS(%&f>S)iB+p3LO6n0 z#DOmhe3*7{A*XHRu&R$o%1H~06qkzHvRaoXK5I&BcK2gg~?fc z^;1ow*#u0-dROvpPW6Y)xI2cmqwRIo?@qznbU0=}F=ClWig0HyxjfNnmLDeEYLh@( zrvLc!i#GqhrCkSIP=&_w{U$>=AT(yaf|IXSQ|xje zl|?sMRC*Q-BBR(=!GlPg5v|^>BcdYkR7@Kf2ClhnS*RpAHklj~_8>CdMo`zFVKZ%{ z(hMcLJoe1KivmSU64GjIiEt8VBFq>k8FqU{+e`i<$2AxgSVB>z(kvi1)ppnxRSLJp zqD5$Wf>e*U{F59sQ}Ny&RvUW{&D$kQAE|AEN{Y=HZbW*+Bb1lFlO}nfXeL_*+!CS( zcgL}9anIk_Z=1=xW^_+kM0pj<*}D9Ng<>v$$!g7Ftk!S`0!c+?{zPs(2oq$%^AfPz z)u236p;(>?2_pStOR1b#PD`|rYcyJ|S8@5g4Tpfc+-bc4M}(=^NSId3Zbm-wkF_O4 z5KdX<+dH{VU!0(Im7`)d_e%tk9QNrZT-so&zA7&BNv)%E6ouwhzjm8DL(Ri;L{ZK0M2IK#JH@Z-G zF*dNqyi=GSJkjO4k>q&YXs+!>t!h0yRj}3=gU2}OICpa8)MJX}r^i=v-+2q>Z$SkS zz6Xq$lf-;o)rK;cOZUc7=keI(gT*Qn)m@e7*m+8#!+beW%%6P{6WaUc8CtjB!7gfT zM4Q)ZUIUK$wm5F%c-`jSM0&KXV{}ELtr4rI(zA6D6uFKfdt6S*xR|4~TTX{^o8AFC zQQ_^@C~+?miW8>_tC!LG-xqE(??|D0Rk0T7QU6=vo?4lxUKO1sy@lTd!WgV5ZJ1)( zndONT05J}WR%4M6Zpy=Ukg;l0OshI&B0W3pExDeZy@&!Ps^U>q#@az#zc+za!IQE5 z%{5Vs4wSdd$71I{UpF$l7V#9b{@n;`joiAj-}#R@)>tjN&{7wS}zO!R`;+I zicvutpL$o6yGK-Tk@YyAP7H_EJf9f8(s`$@4R$}pYm3_susc66KpWZZQo&nc=Ijiu zj94Cr#~;%jSKK)>>zSilER+uHY5>pH=1#|^Ct!;I+>pMQ@vtdi2!WkwBx09fyk zbgf}Qum&MPMy8+b<+b5r9#UZ+K?YpPPekBFEZ#-}+a|Ik7wvap#uiB=yKv;c1Ga_R zfggKgDbT99nh=u<6RZ(VtcjYV z(%keSIXKt)$#y7czBBIy(93cH+cU}QZ zt>cikBJ2&Adj$m~Ad^~ex&~TnL2Gr# z4WRI;`r@bfqEz+2rd*b&ergK7h`g-6cy*%sg(>woDKO=Xy3{*$!=I?f9C!E{0mmVS z^)l=INM;Oxex^RPs=oS(8Q4r)r868cj+{1Lek4>TiBs_A(EUYU50n5#iI+?p>WkMT zs@IT?)u>eHc!6}RCLJq58tDQZD@n(Cj}BPEvy0cc*>_$#>Qg1oNRy7g9pUJ>EhcoN zB|wA3M6OO0zsuS|6INheh|c2m0FV)#^+S;#6nZM;U%Z1Gj@55ZnVhIzF=axKBx%7j zVUo~*=R>R+2$E!HoFvtOBr6^6SaIDUOGI_U*C&eCXP)NZusJGZKPy3w{v7o=k++^d zrWZfzFm`HAOfpXJ5%uaTlzP7I1b2RSb4fpX~Q1W+Y|GmNF?OekYYqq}bg zgFS)oLR@k3VZ}|?TygTeqG)oC$ObQYEWj{K!^C;z9MWOpn7n;le^{P+Ka z^0(!K^5@cAjuZR8l7DjNVNDlOAXt%fBF5?FK}W3YyO&7*3iN!;&id?SzIf7qB55F= z@|*mU{!*z(`il}k8X^=(;|(i~oc{RIVU!17J;XqQzG0ubgUfL?R>wv>QD41j#>weQ zyf09K9yayx#APqlrH`zr!ypnl8x}i8U$1(7(-1sUA3%^q9?io z31;?$ZfsF$3G4iXj%!To%j)alM6?6vnAGOl)JAnpS0SFbY$M-Ss@@cx^;enP!DD4I zbR7e?{ERLx9oGHk$tCd6|AB!13DfH?>%j>^j-SLEO@5EX@jYsE%G7BkwW-a$Yig@E z%;+~J^w4S11~m;A6edgBh#oLmt}V>w=omY3NldgFS{jA>?Vpkz_>#s`pzjCxG& zq_u+XRwULX+aopU#**S5vBl_b4T;N)o=v%m7$XA(54$pt9zntn>n}l*dt}4$-gpj z!Zu}(P5YGq;xh5ESZbCrDvgwMV+2Qra}Zpa2f;ZOLF!metpvkJBsn41U-nd8_4;V? z5Tu>kRPECmPCSvJvF&>zmy%rKomqCA{vt^^iQtdJQT1r@{_R_wl8jA-ZYpXX; z4fWgdpPrP{Z`Xcj_x<*d!e|LG5r$pP_X9D z)r78PASb|XtGT>S>e!vy1kPOl_0$UNRA8l9&JZV=f7v#wR#OvIG>r%C)-rGE`1;Fu zdq39HAkRJG8vgK?Qa$yl=jyOJUj1RyF_N6R1ZRMk^{xWy8}8*H*^Sh7Y_D{aNQ}>h zalEpQpwmq6Ckk_|1o#Hbd~=2UnYj*HX~t>(S2Q?Nf^-$MLbdWOp>vScN=UI5mK-Nm zR-`7B_I70Y^LW)kQm7`iss^j==&TKA+h%;`>x);UFAVl960165EUpf;Wg3RV>hQ@PbFta7)>H2!b^e!O4S$yhwACBx0h^ z0x;(kAs$%3q;D%{0dUQ^_a-a$c+?25=0US!<^p&rwNRju-jIT!g$5oY9$Zt~!m8e< zLJ~O8N}%hs7`jwZ<_~;mV}1$Q2%-KEM?j}gntzcLlhk052GcZ{q``MI7_Y&F8l0!W zSsK)8aIyx+YjCs%<0JqH_zU@8c3&xRFveNVC#REN4*`m27Z*rq?@yt<;zFXW;vJ@S z<>KrSc*YUR1yHb4ZljFltc{CGaKkHc@jcr10%eS(hIC(VB@L%7^&R1cy7gPGpnb+S zthn!hM=hhRv@T+w^nL3!7$SgtP+~X^0HU*78Zi_vWW5}w#U4SP+|+zergwnjyN3{} zZAvi?U2>8PO2#KrTt=wpL|J4lyL6liY=cniql-ZfO-GzB^UY)(nB<^jE!}!7hT!24 zwieT7Of~ANO|s4_G_rK;;7d9aK>}XDs~vp(FCr!rfjdT{9;BBor0AEI-Q8YwFS$mZ1(* zb!DZkqv<=qk4eF?b-kT<@xvo|?%7a2E{X^bFPjMVLbxLQ;Tfz@PO0>iAcd_>E}Ed} zzF6lD=b+2?q->>~ z_Hpi)LL>n>5a!)P>VrBSg^0TZ?~YokV?E*|(VQ45!Cobemibn94d%Dynxh9VFsL z3oPw-%e@4HZE@HgGgty?dLpHLAYuCeJ1*1|-&eJiPZtPsiA?|@oPFb$kONrEm8}`T z&vJ7NUa}0VF{zfydLip^tIq5R|xdp>(OYJY1F9ieD|qZ3ui6}Cfr zH^|;>3~wjEm@O~s)Jj75`kS8`GKW-EfMSWV42b%o!KQAdE_GDEpe!j#ELETb0n77=rnQUpr}nwE2x_BsL2(&G0kvun z7u2ewh`t!nxG#wO&$;)WmzkS4=IO!q_xpctKA*fhckX=eIrrRi&RypY_5L9ncx-I> z+qFILG0@*V$0ScGT#-5C8|*G+_LqSzgWW}-WTNr=V2QF%cu%IV9~xz5kB4z|Jrf}Z=d+iFLm%q4U`30k$mH)x-Tz-MbmfxE7JCRK`Bt?;EoK>3 zE$;?R1HL*2Z%u*=Xph4@MvdH9rG zS-U4v-Nhml_Vwof9J*f6L4kys@8Aa`>PuF_ra-{pzzErdJwJo7CLFj0^OLYu125pw zZD$XuOumt5XxSFt;{*;ZloE6$@y()5I1#XR12(5FIu{pqpd~jZ7u!Xag}v8>56CyV z#C(fl9^QJaOpb>!QTdz2SMqAvpcf7 zY6T`>O~Kiw!Z~@5Vh=}j*leu=^q=(93XXThs%L<6s&Zd%{D2{mO-N z@c_c;aysTKXcspefbBJGt%Fy7M8zFCr7$sPGfvbNH@x2!(x6R*wrWp!JGEj?fW8mj zUFvVaW1&g9k@Z!2!t01UwBwKt4jsbLf?4sd@eqx zvKT7~+guo%ER?I2*|guPw94e36$L9`oKgY3LDGxMGceRe?Uq^&%hw?-hq=Muz9&G_MSFGK?1a1LrNvu?^-3)K(q4mR& zg|Pmm>V08f98G{$)E%2xcs^9>$10_^0(uPBTFF_UqA;O?C)fiwFfI9oQ#&NFc0Kfg z69q8GE7fP=%VJRRl~sRV65dz~XEgoZjQgoL-eJ%ytt%67#3JN_T_mB3_Xw>%zX&w? zT9_(6+8PDNU?x&mqoTm%ZuyE|bu`h`)xxagLy6R4)TU9XOlA42&=0#{BdnUiMEH*? zQ>RO(zWkeQr2{E{zj)zb;IlFb+`}Hw*J=-j`dE@YQk78nAyvvRo!afQrEGmT0lc?m zuKGmu%6=z;WS15=9cv3z+{l){Vz2cgnOZA@$ugKAgI~ztXClDY=WfS2g@lMgM$<5M z1jQc3ZZtfz8E4h;ER4ev;W2IZ}F&}tU; zTNb=KT)M=}F8iQPz;bH>*5s{Ya5K^(UqBA(UnHZeF)AM!2ZT0th4)J#lgw9pV$Mh$ z7a?T-1lXv9HLXUGMRI|JF2$Ht=Zj2|Rx8X-uNaeZ>`@It!6@A6I!~-U4%+A}Sc0sl zs_iu!lht-AVK=#lJ*)i)?(JNZL4M)j zgyf<&yh2w00k2-SKHKnRm--1Jz7P6C!8+81@DX*1%7q^C8S?fGlJWY#h{}2l`c5)$ zaQSl{8wW}oCQ%6_S|)=+K>_bdq;}|EJpzP@=Qp&}?S{kHL~?^g#Qp*z?5kaFiOFM*~)UwT&vNHb&@(GNAhl<5jeg7Ztz z1;chrD2bRDPF=MQWrMTJm$yL%*zma6NZMGL)fk0d)uLv62-=CEiPQoCNG%G)Etq0m zqgL;sdykLXi6nGc;R1R|qOHYQoj;4cow&6ga)p)^Y+-gH^^nLTb-Bn9XKU9?KO5X# z#Q-11@Hmr%&mEsgT_?!H!4HrjaDZ$iZ^wI;$x9^ma>>of&<%r4AD)y1bW!A1SB!$r zRpF^HcVwPyL#u+xzl(*(R7!ae_Ge~@CsR`KVOG;aU}}-jUWhKhDCUE@lSnl-p$Jkq z5Y0+;{$g1#H)iW4QXkzjuXa)P3KiN*8XCw7#%j0$dyb&jAk-t35@gGp>qiT6(4zvc zF7|VhMNWooKt0X`{lGoSHX8bFSc;*Li|C#?;-Uc$3LzR`l&K{me_5MLWZ7^?iO<1T zkX}!AZJ7a*K`j2Y^S^LRKXv|EZ!83UZ(MAif?2CHJP30k=oNOXEk}McZ|#P+C`t6f zk$If&h2=Rl>je|>O$b$IqzOacCoyNaJh1}zpUn9ZeZuV1G)scHGMJTtIuUTnPG$2g z=Je25G^cj1dbi#q{7N@;Gvn-r_4|lz^q^0p>WKS=$_?#^Z!N%30SpC2hz-*N z?V{*fJ3@%!rCm`J;;DAZMQ93A9?fy`fHt9j&<}c(;saYd7dNbj{m`8Pa+5!gs<<2v25$fD9tRE=+bGSO&Pzd_J>XDuC znN`b0ARJVaSoxJ@BV&XO&>lPo&`U(B8g5BXgYv{dZ)U+qSPms?GLHJKr9&4T-$94a zzQDJlXM*)qSf~ev#-X()@Fwgbez$nx?ZCFQWZd@x2gejaDei(X7oLq$RF?TCwqu|Z z03j`@g8~5_{OU~btGM0|&GxNw!Wd@N!=?ki5kKI-wyzzLITI6LF<9NIQGxBr3 z8UY4X+<+^O&@+4$Zr0=4Sd`n#PE@LZ7AOF}{Tg7Qs(S;YqUvBCb=7iwMpDL&>qNO@ zwf$M7=B~CiZCGtM4N7$e=kTD^gkWK2wx9)9h=`%1F)LUwojXkBnHCa;l0X9_^=ns5 znN!$LG}6$ZtXd)X#P?O!C1CDUAcX7PAm}U+^6JR-GLfnp1huRYI*eSxY&RyNwgzPzh zi=$1R-+lHj@Ab?0!x%a@9z=15Yqc=g$itv zN}t4tQ2G=s2t##2=LT9W@Pcll{Nvh$aMuU)#6hiiWeo2}O%eypV2$9o!5Tr;a$6&~ zT%4x>5^#*jH+FHuwh&vpVaro}TPq4+b#(=J;%wU6@Zj2wNjM#SKuxLi7clFL`x{%g zTD!OMn2u7z%|wqEFFZv|_CtRiHm_vm2IsJ3eMRjkB{DHw5ew;JFA-pOSJ?VTlUbVw z!PGwjJI>lOnEr5Pzjsi>U@WvV=pF=Zs8Bt{P28Mzx>Pw_Gyr+^tnaI75o#26ZE7I2 zTEth+8@|~|JO*2svdRWcPUx||m>cx0(;a%&HP|J`wspSTxCCC6cJXAsJ{lz@=1Q-T zo>ugoU}7)qZpknl7^l(oRJnz^0t00?He6>8cw1N(6!T5oU2U~IfxD}FiMyE|*~DXH z;vty$`38hwVMF~d@xJA(FW!*jJ?Kiq1e|opIOc1^mL#PHCZMI6bBpl?J|j9B(Ep%z z1bWqbp|#ZQoJcmw&frqf4{UgJ+zJ@Bv_K<)vsbfbh^MB)=XEann15`*}8XWzu1NEYpQ`hrBIZj<9I^2rMR(J-js(9hvIKznA+WHO1OAZpC3C3xOOT;EzVdA*9 zUB0%~K{hhS_Q2xcEh!+}S}Uy@Wb@3o%BJ14VWsdZFzu^AIi+bQ3dE>K8n;TV#Z+nB zRnR@gn)*510+F_%0L0;&#q&SI##r{ByTSS*vUn4WBNcaIRE>QBC{o=z;!cgNn<6zQ z`>?p`u4Wjqo={2+m&x{iFPs=a-}iF1gNx&7`1HkBg~bcS`%2Ikfcl5ZoqhJVn~%Fd zt^$P3=fTlnJ}{UTj?5LhvTNnS`KV>#5jEC3RQ3ib5wZOT<|`J#Q!tFFhZh5+{=iPX z6SbayjxjV0UB-zS-k34;*U^IaX|PPBc7{X$A*?>4$pZCxLQ|ip;kPTdXt!!lP;J(>(Kf4g zaC>_NEgW?0X;KlU+j`=3+m;pBfF)mUxdS@~FzNR0ppC6h!2j(yA@*Z%2brDUKp%%} zgJTiK0EH^belO3>;kJtBog(@g-{QKUa?(&)K;#k`oQ+jC=c^v*&-O+)u?D`H+u9u~ z8QOnXWfeQpTAsp|Y|dA>VR_a*_!#azn$y}>_!jvbK&+OV<#W4)p6d$FO%Ss{@;Pj* zT4u@Tb`L!Vivq1ZgqF$YAZx2dw7zq`+AH*2H+b&aecSm1$8NP8jQQcl3*mw4FppHDa_U0!2f)6~udG?!VJ|tFzO+lRoji4w zun;jtB#stLEf6=9iLP2Ho*(d9qWr_zT~Sx*&I|2#R*7d+f?(lY;FuZ|sCNekL=HH| zmEu0Fe8Pe^OnQi6kes=MN5R|R+ko(6<7jUv{*-2hh!0U>6x@25)O>gu1ucDgqF{k2 z>VOF2vTdq|SxRV^nzQZF4q!sC3A`G=*&qFKy=8@HfSguYX7#=+22 zDn*YD6#)~rV&6fgyYlkdA$-WP1A{@-YPX(s{Qb?0 z7_fT?gswNV9-9=9XYy0Mc+r ztp{O+m?VO&J(Y4GUX@5rf`(pf8G=1v_;P3a#)kel-a-`4#bMV-&ch|;JRI(`g4wYa zA(R>r3fN-%R4rzcIp;`hW&|nR>d*vdiPmDj2O2gZ&fRln6d=#K+3J{ zDL4h%(6(hFESf++tJ4`|sQVe;*7`kp1hS>-9@y*Mx(p>%584x10oWNQY(!p3X(y1J z*;~j1%dUE~!%_9s^|RoNL;AZgdtUvzjiAIhKPYBQfp(+F20K4uO)u3b4F`H?mybi0 z6E5Lcydtl%TzVB~cW^$Sd=0u5=u%-8xFAf=K_jF57(55VH`G7X>HKXAY8&j8o*Uo= zDYM9872fHn)@376RG1Oydk5XFguFpTL|F!`0sWRNHp{u&DVSwyiRdANm#RUXuK{i= z#C^O0jS9{gh(V_qN{L+zP$AL=ZhReW082{(lZH@-?o1g%wKRlpz-nP=T0HMolq-}> z7{W(aM+_keX=n(@Z^#f}+#t?nkcLnV7NHvg7@sO78Unm_6fp!ku)ix*Fv>KyEu1=3 z+5%8RTeuBup$2VX0K6|Jow2HD8X z%Dg`bJU$C*0?pfMY){MEaD@f(6ROfnEUrMB@W?RNlsV#KtastXp|yh^sc0i*dl`{( z{qBiXVt9rnRtrhaf<@Tt77gXj&>)M3GPx)%?!hJ<91g<&Vp!b7H_<@o$3u|09SK-QK>ahOf#0usZ zlxrOr816nwY#9wL&|0VXo(~eK<6vm^rCr;1?S^e(8m3`%DZG~rPfIzC=~pE#5CuKh zS1{84rUDs;|WsH8g_>DsUWN=K82i$xFpRHCv+8VtE^lCAC5q2XESr3L!HiCECT$B;@=_5Q2QqO(>>l%`rR8V3v>lrr0&AUtN!!?VLPhd_}dLA zNPHa_D?*&B@H7lLgwFt9DA00pS)Ek_*zY^V!40s#YZxqL!TR7X%o%uv$i- zOQ>C|9Pmddw(Or~9~(Dh{R338^YkHLpI9%#oxv4oId0B6yj)f@6r&QPj8JbO`j;N7Oee(uAE7G}=B68*7o&*;SAwtf13g_)DGw?U$y zq}O^_b(rcv>JUA3fv8x)t1O-93B&jp^&Er({tdW7I*=C(qrpNUFXs%%tL68yBLGfC zaPb#xU{ou3OOwdAu)o_b6A)@83Lcz|a4(pVKU|5!>Y{e?A|Nxn48?&}LNbBwKI91R z2;4KK-*%M)mKWdiIP9N>k$l6KB`~3m(-oPC;hk~C_ilu_*8?ZwhPdc%xUt3e`eH{M zq`_;evY$K=^k zV#jt0U#bL)!Q?7PejHbj8Xkt^pQu;v;8T&OcgUf3lt4qt&V)`CYKw(uw7*)3zQv#c_}F+gp_a#Ur|N*>e{2?N{J0sNk#d$mvfZl;D`tZ8vWsK zDElu0qb}?}U!7Ue6Te}KBio`CnM(y84yeGyg3OYK;oOQ-C%?HRbNxf_ZOJ^)3STts z{^|NHnZXaEC4g}x`}AKu1eCMy^7b3ea6@GQA7Y1WW8^WG_#sn*{J{8&V2lA;qFeY);s8L-ZxSSQK(+c6e6pF313bG}UIcV~o6_9^z|5T%xWR~AQZN7a7jOVc(p#=|I z2l3MKdvVZMhi{i0hz|>AMYl5#E`A+n?ZDogL<+vsa*S|0LRzp}+70gu$CnMjv8dtA z$qz`U1g44aCP0GlIFXMXqWjS|q-*6{__``z=u=6Zmd`Gi>pWWdnw*a1d-WD7A2cwq z7;p#*0NBOP{b5zB&;1E!>}Gk(ekKWa7~vabp}*`i^7}*^U;7^Q6T^R74*vJb@(;oU z{*R&Bj<7FUS@7Xv%Q`fznG62~rh~0)8N5z2F3WTFD@#zWdt{-qX|g;$s61PtKANX? ztdFsaBK1)`F90@j)k!5Tbio81Zs~?oMsdIlKcJ*oePClMim&uMC47FP$Vk5JBVP7- zS3O%7e)cgKe$}20M$(GoKgda>;)G>#vp8zu!`fleX)4nZn^GUEEMEs_dH@Pu1=<MWfbG9GO%w^rpWh=bKAE) zKrYm1`k%|bU;Ueuw~*g~3FwbzPE%8>(5~V@4J;Q558dc2XHcf0V7cF@X=c2=d(!UmEo>|$cf7SSzLi~UqQtN*SRkM3w z(+rNbXk~W`ii5l6@CCOT=xJeVd148?lvxk_7J~Q0B{>iTNCSqgnFT|zSA^=39ezS4 zID=fef-)182|pS?2fwW3Q?hKvk)O>?!i26^4Fk~tg+Beu92mhiz=UrMepVI_Ep+cW zUt%WpxE;FxjOTC{Y@dG1%FcqbDnQEc{j(e2!xmF!3U_Rg^PDg3hNTXeO+5ZNj5R>jvUtm;~1Lf#NMm!im3Pp%TVkGw+tK z#-W@t%T@{#>fZX)noR4xy1d5{e_+bt;sUe5)i9fU+iztvRfJQ7P;#hb&=k=I;*1$g zUK|M$!WKt-j%^H1P@_Sh`eTW`ZiCe@Vndm@C_zBxnEtZg40%DPuvLvE1O*&wV9TOv z7<(TjNSop)`&C`>QE^A~#2^!32HRH9IvcB}6lRQ3ws3wjY9Y*dzYj8m9m<0~t-w8( z{o&@uiiLe{N$n}VO*5z!WG~N4ZU)hRyaj5vYz2&ZTVFs@?SESRj$KFo2T4299i9wr zIdD^jg&T*{GeT?2KdA4QJS<`?Q1;B8&{+V6Z6N3hv59A9qJq%|K6Ed3W+!lgShDPc zf~g2UYJYRli@+4_Z-z?68UYcy_%L2n<3*|z92smG1sX6iL3x1-L%#!83A_^CsS2;` z%yvk33|2chK~OV#W?aX71^-B({SO~6N*xGvq|N5ycian#Ul*UQhAMe=c`JSd{ODxs z@>YDK^;o97_oH5Br(~Dg0U3XM0ec$^DKN-ztK`p?xV3_`06Bf2{aI zk#-Zf7GIGPxzdxzsPo@J;PeS@^^rN)1}t_GH$3X<=g~d&Jn0)4;ZWtXvF`{qROJop zzZAv@R$V`=-jGv9J-ZT&2jU%&x9@d!E~7<^!2LFV+o!Kh`M;!n0LLpPfQ2md&}4+4~cgFeFJW_|{| zLVkVvE$Aakq`)|GY4`k6$25Kx526S9f*%Ne3$V{ zYLCe|_GJ-hU>X^!PD+9<6&_uaAm{wrzuFo8#tW zaj*V8@kp^b_X5~TABpB#Qlw@nk&qrRCZvK12BYkNj6wB%Cikt-&~}{(HpqiQILj= zt%ieT6PA4w1+&OB>>X*s?m~WDBwL+BNSGHEG2Gvw^}!vMj)VJ|lh%Nc@q392Ach`o z5r#srYOfs_BFMJ=%iATHpTOi-CA2Rn&Pq6pLWmQNN|Em&Tqd{ZL2ba8Q*>a#?ID{9 z^czY#xQA*OZol<`9RA_;YI!NHo9P-)3Bq*P;~8M6mX4%w%RiWPCe{METrnU7Zjmg| zF3Frc5?`p)StS+)Pl8Xi)Rt|>(K)7(9KNXg3clv*;K^@r`2OVwLd)4MC>WWnE^gQn z-+ENQwYDc3%H$EV51H+BEyOsnveo`c<315 zdejw5krCV|*{+1uq=YqDCH(d5kP^BmpX!8ELQv`sN|>kc)d{`uYDa)fknrR6bN!xD zKY;o627+o_i!dQ@)~j?qIw~!SP6t8ypT%F<^Bil6o?cd?rxU&&GKqQSfeM(yuIEu3nxRM$H#={xXxGJEN-(j%Xb`5~m7Jg^~I$-lqy_6doE{ z0IyLkFTUb=T>TVYp#1&()V&ha9M!!tc~ey4SwX=}>W9;v1e_;@=7R66psAojV$o4= zeGI{zFdzKG>p)z=wW`6)@yo=xcZ>{%iy$9+jAalsxBi!KAYvCN`K-LOD>f@QmJK$N zQXHMWZ_n35(@p4INV6Q z*PLY!UUF~9bU`l1bl?)-fd96Vl;A7yP?C#bb6e)4rJ^LQGI&b_P@s{;^UuJ|a1DO9 zty~}w&{M??SE97YqbgNEz8f-Ku~0P~3e{=Ju~eOvytgX(9DMQji+e@MKa|0{GFUHz ze~SR!{CpfmZXLbvpnSy*;?)@v!}3kg6*rnEbIz9=-XY)r|^-hT9}gUb0F<( z!56^sqv4xtOU5oNghQC_DHUUnm92i}j(da{7mI-7VlwB+oLm|FTm;^xF2(bOC*1n> zFHEaCtA!|jI6N$u1$3|eLA@BkM4QSsad z@i}OEp*JCq2p8W+f_$JegzdiSnu_;}=)Ey)T2)T~Cmxc$#OOlwBti1nCphI9IdF%{ z!1Z_-QANI#>|zIPA9Q-KGk6=gD z#tA|g5s9Hb4!_`p9~e~3o+LJMw!p0Rm)6W0_$``seg(|z7QxPYc>Nz5S|2*0umOJ) z4DzAPS-!p-F4>^jLFb_1Nq8S(GaNTldx&U67GTE=zH0XvcK6}*y`Jba;V?(hE}~7Y z$SiIWLb*`{g7{a??C!9h=RgS%-0&C#0*wnju;}p=ekD)Zc^9X8a)055!fUQc%o%{m`cnXAnE@|27N@Jga<*p{9u>ZoNr!(_8&GMFPzs8bt*BS zEit?e4)*y~&&1Li2*&{;^YceQ#;aiDjCbUbix^%5!vY9lPOxExU2)%%#p3S(V6@`% z7B~&JV)+-asbcfUiUFBQI7|T!5bx4Ogft03Fy$z5Cm{01Jn=v5_$z}O2nyx|K+S9}EJ5kt*+m*N!+ zZ6pDiX(bHGoXTWdW%-B2bA9o^t&%6@TE!_5&}osOve8VkND}oN~KR!V^SLv1(Os@t`j%dAQ|(?)QR^X3Q?G*zyc~?5PWQ zHMlqPy#yTWHBKJvg*WhEFEArGRTB!0{sD%w3vU7ksZ>-I6LyinnMa_TD`C0}9(umG zVTbln|AELnN~0nPgV3kMnbU8>e4)_&;(J2Lu=)Z$F4#VUTlw{5TwwqkfaAX#t_~$v zB;OmGTst-i-{klZHdnqns`#E(*vYePD_p$0d_&2$t#J4K~8nak!luN?zQszaWAytiuk+#1{DW$YT{-9;-~k5C|5! zi!WO*!~h=~`IvTqFKotJ*{YXCc?s{KmBYYl%+U44^Op$Rr|3fHQ54wX$aAk0&u`E& zYj_MsY4G4hkq6;u?$cC;puCA}mJN@|dN?}r^pnN&55gPetBU76Z^>B+p?08tXjRGp zJ{$|jYt7x%1xth97ezf3D^D;{52sPSP&{`Xrs3hJ&xnVlm58Yb_@2`lFy75x)dDw@9>lM!p8vy&rbNkC^y*>tq$!Z=^GA-S)oClH~5kAO(dIQGu zojl@Eq92hNCW9d|I79}YFB0CeO$NKmn>&dB>b~V093-!miT{$pV={P12KS0!&?_x> z;Y7kM^5zXP_#YYkK?LFUSM2Y-_I~WYz)~V^IxXx!Pha1$S7hE5NLZr5#DdJSMbNV0 zh-orzGQxGJ>}DzNceoQ3SK-8xKynAU4gh<=aN=6!fQvl#3aDZE*WMpkIHunsd06CC z$P~U$gA;3LUV#X&kstfQE%s`EHVj}KND}TLfh}JZ8li(@h6IcmW`S+uqD2TH;teaH zwZ{b5k6hm;0cTAEB!ru}8fNd1HrT^&%+dRV&ScF#$A>ePNRfJ#0IH5#ke?i zshl9ZTCfeLhI^2X{S&Y&Sm~ctDY_p|^oM~a4TNyUUo_ZYZ*tiZOxVi&Y5;ahsNAY6 zB60)imZ5Zq;#*U=Hc2_D5PB5iIk1-tJ}XTWe4bdSPA?C!OV8YoY*!}d3bvDT1>4#F z@-=eW6B=Y-@io}nc5|j|JM1h=wr~$6949Omz-L1D1`N;z6#`zx8^pMm9J^{wKmj`! zOGS81KOe(}FA9t2v@D&#sao7%Pbl0uo<8wd6co4XfZ@eDf1hRxl6b2$8Vt=}2SE*MMRk9@U!B;KLf z3`E3Xi^;i*klW<_Scn!e#oVxY8#ND=f{rFm{HKls*5K6&(4XoAbQrG^5aCO)&QBEs zke6kh%e0s}Z`dDa!IeB+5;Nvon$0&``#9Ey6+@_fnWqY~@u%Qrh7#x|R>FFI@?zld zR`nooJss+EbV*A$S=jEy^EaWhPMx2?IS-Lt>Nv2O(c{{)7iG(qsj9t9>eFwKV`S}J zDDj>9eM^B5*r7BkH%Jjz9SVW+P9mSvtDp$uT1F$|4V$+uzT$dWu|;ZzDs{d~wF8-r zuHo0thW_7D7?M8O=J&20WP3W4adb_~L^0oN>4C1Eea=eixe%ZWBEI`zwP@iW!Y-xqxip5`b5Ec%iegt%%A@%`d5uI zNXlTY3@#P{lv4gh`XlS)$H81k%3OH|bV_jjUNj2Oq={A&dk|3Bw1Q9He5FPFYvi;B zr2CKu`tc(4RPf;)h|0H^u|ELKD7a9Z_v~S#pvFVf3O*1_LwSE`>3@(-GSP-y*FiS8 zTn^ZT==D_K(Q8j3t<-j)gYX6+E}=sIzhOlQ_Ibv^eqB6Mcm_<~U>Zy}$ezR4@|WSz z6lCs#jnHps#U>-beBiuaxXg%4m=}lZHhC?M7#DMEau9*+&;I6h(4)zaJuv6Nb7~3q zWEj{kgdR6Ga1IWc%hwe*>;}}}{Nz$NKN&un2%U*ls-pqN7H11{*`Y9}gdDrLHvqi3 znz@Atxb=3q3)O`V$5Lbt?)w%M?lY zoDovXn;joYlIXxrW0;+*!tA88?CkSHu!A<(k)5V6J4?gt_*r%uv5nu_(rL@dPEDAd z8DVz3EIS211Uo{jJ5*L%n4K@e>{uhERympJ*k#z-(y>v~I%!6rRK&@g{N328Mnd9Do4161%mh~oGpkGR3y`95$KA;=BkaOD z0Xzy$!xsUJVny2n2a#e3FaN$KSiVbrvRmFx;JZ)p_6rR>g1}b@2PiUx2)GlRYKOL~ z6um}SxYR?#rFOEV{)OnLU13AjG)Z%q!aD`QvqnNgbaBGyhB&>S9 z!>VUzRj(S4y!o!Gr<{A%u`34;aakEEobzZJs+C^YYv~QGExqk54%=4qIpTc=)gyrh zqM->uiPV*{wO!(43_g>+9sJbygc;fkcTftn05_(B%v&16V5&T zMa@0+z;`1HR%E9C37bHeHNu2~%*R)~yCrkNZ{FFGnKb(w{GK=74u8)Z=8qQ0`J)+_ zDb62Z!#HPDiCA@jRuFv={$YzK-Z@a$z3Dy(M?4#P!>;M=A=)%o0w%wjj>o%`aoUt- zzwoxZM!r}GN=>&j7f+XO7^#LHUs8h)Ez5bcRm<^p6PQBE^cRXvGd`E8nXY-Nuk{Dn zIe=S-4CobxCa7?1tF4np~teF)!AQu_f`|4qn8oR40KtKvV04bZrM z@)Mkw#&t_Loc^+xF_PRtEX|LjU64hYBd>WIlo1!KAQ}3n61wnKd^(%atZ+u>=FaG& z|G|v184Sm#pp%xq23||q^%U6&gI=-hoCs=QuAqC+i6w4IGPm6?GXY;BdLr3Gc#-Rk z+hv+uSA_!B^?(my2sZ|EkX54lEvPLzIYJGc0+E8jxbRx)eT3ebKDWtCp^C9@P7F`b zvw-fS;ugkRkVWRuD-ej&e91zXG{reb_|eO=@K5q70KrpGR^g;T4A{GFyIjj+Xs#@d z6ItMi0YD9iU_Nl@4GimKHVODH9YlI(dJ6eq*Bm-$Ly?#$R61wU!BR{q0YGg&jrp^!soPx~~2r_S8Ld z=8eLC(fs*k%7K6u&2k-zxEY zqWC>o{GKX)$BEz5#P1p6_ZQ;V6~E_*-|^yiqWG;AzvqkJ$>Mja_^lDY)5UL{_`Oj4 z&Je#BiQk#xceeQT#P3}3J5T&xB7PT$-%G{sW#ad8_=Umd!oBu7^muF3Nn85&fUvO| z>#XH%sQ&6+c=d0*D#fd3@oG3;t;Va9@aiGFnt)e#;nhWWwHU8(u-B5ttDErZPk41d zUR{P)`2KUtT)cV}uV&!YM!drBzEy7ne!68mUiHGO)9|VvURB{0?xk)y2Cqiq)iAs| z8LtN8)wy_8idQr6YHz&45xO|gy85qph3{@v--%ZiUSZd*vPnbAy z`h;H(Ja5{-+Ue&GJa1B6b^SSqoI7pGz-i~yo?AbC!qkD;tPX~U4rz}HKsND^b1g|@ z@`S1O@Zt8f$>ZV5%BJVyV@mzx$O90s+gglGno=`);DmEA%R{QI($dnY0|wap*@Ffk zbA#Xp#zzdd4=yboWDgr=!xKXW3^;fY+&vhcQV$Fp4hi3q9?f9TVV&dxYW|gU+=3BDd!W;}~R}cY4{GQWK+`o;RWHtaBz! zwZL``79v4uOpjU;mZ(-ecQ%^a2*_Amz_W)RhFC;pxjA64HNAdn-J~fK2A+G~v?J`A zy6Wi@&K`f(x$s*z!Jc^bq{$P;A7S^e-7fcY=r|(JYR{cJt$y-&d+M}0d)hg5XHS}% zB>+IkbKAP99QzlHAHvQK&;1plAb!ShngVR-`e`Rylb}1+* zwCQeo&it}DbKzFmLECgc;F84C!wU+!^hIwT_XlqA>w#t46c$*81>Fn#cKP)~6K8+< z?`5~1l0N5;PycrN?p^-p>sJnby7Z-=e>CUxUBB4vs*bsRbN}uCe)}JZ^pOug`-{t( z4<9uO$Y0;D>%Lam+=87W+*ww7&dp_WZutKEjVkPnzr+zQ|7yP*ADwXKO`E>nv1ieu z&AZ)|_}l!GcfaP?<|{UpJhwDY{>OA3jWX4w)}g3eZcaM)wo3nuvf$?Z`gB>a)A-YN zI%MB>?Ku-?yx!$cGxz+_gVQf+Isd>3GrN~e9e?a~w;py_%QbBk^*eo<{NwWS$)&&i zW5N4nmpt3|@6TQERAzGHTfd*zy31Qf&3>U^#|5R+PX5g;+dcf&ih^EGRDHha&5u9( z+47Qw*N%AxXBWeNTKU3Jp%~$3|1Vyb?5}ZcN8_ST7rHeQIvnA@Lfn)Q`fG&lPx!AY z9D!@yK!<7RGqm_0G*cEq;O)zebBsgsx%uZ^v*1uJ!oPPSQ`-(idrQ z_^L$Y@3cq^BT)gjY5ZBRjWhh`!=9AzpQGs~&Oe3!yl@1r9W8EaaXsDB(o3|stHpgS zUZnBAKud=M-XnjyKI{}pwXDfnyiUviDlHwqj}`ta3P<3&v$$SfO}v&?9hR=|X^kEZ zB*TBYf2h{#e|Gp`xSprQmuhj`7asn@VPp93%Wwp)eJ$Qwi`yDr*T)V5)as){x|ZK+ zjov|8`dym9CTjw}LBr#OX!vhYI0D!EY5DJ^rJtdt>&4OaL67VDq~oL3Zdp2B*B`w; z@PzU3-(BGdT(`js?%_Y2XbAt|w+teGUL+=8%?aJIL)UoeYw=R8z|U&wH)-@rwfJk= z^SXU&)!o6qG;^_Zf6-6NUl%yd>Cu*BKzf7yYgvMW^ z7T4=D(DKvMVc&A(?|?|mvQF0Gwnop>_|yHxc3QgD9qQ0PYwBq^8vXxty06jKqqcU# z(c(J4x_-FY^Ji%BBQ*IrTD($=pQy!kebV(!Yfh}gHTs%*cW^h=+Vi@<)61{NOEtXi zZ}jIoi+4uf)986x0c|Z^_fM{tUZ^>6oxf`Bc|AYjB3^2;Q^iA){b`| zsNK-Z*I9k(&)ZslI{#X7hp3*Pj@RSg^?4otUE`WMb+9+R{5pS~#dUrhwFSfBktqu2-<0uE#s0r?IbR-(h&vS$?{_^bB&QE9Qx_tEUkFFp3^E!VWDnz@XKd;Ai{&jxz=k<7J<<;}o@tvjX&-d2K*O`2D zd1`RW(EAFA~ab^i6Z&aXZnp+B$3HTF9AOTBzLUguv=*W>#0uEs!( z7T5bTdR)&>uiwd?s00YjHilMlD_EPtRYshtA?UzO#5| z^tZOZ)$3Ou@9Fxe$My1S;$&m2YF*5E?mHgFAQz6Msg=Kx^bAbwVeA(VAU4?qOf3f0gW^VqxS@M3F zDyNRGIkJx^zdcNbl-{QJ^NyBsFH`lPr?<_Oa!ohnman%&-Y--2&;j3fM?pWmuMG9{ zw5s>2MDF_cZrx4b%WjjQj&IsW%FnfBsHfLFA@$RKQighZFh%Nhx-S)o3r9X(l zE4yjzm)m~QZ%JI$hTM32|2;(cnpLRtSGK3p4;AX^>3dcFOLOPnw97Uke|J|I>iCit ziSt#cr?<7r^z?hV^KaZy=Ia#4`q@|dmGqBt z`$2Bxy$d&k^0}JLOuVga#?@Y5xMm z-X%Y#`Ny`OO1kM2bJO?MNx7H3lw1DpL-Kyf!@1LIE|&FU&&=(=%D(C$>?2U2&cAh( zEMJof_4KCQWxct3Vp`KpT z&{w9ZaV~uS!X}X%*^t>uQFFQK`(;COr&|eG{zet*^n(hS-gKM{^>q6uDqV$?PW_k05w?)OJ5q*} z-lpoeX}G*^sps@`f3(!ks-tqZf5G|6?k>n}f6ddBeb(eoFR7OI(<;>Imv|~&g?f6M zvU_KC?)-xp@_y5=bEl_o>nh~abh`{Y`dxck_&R=7ZOt)1&dV0;N(m(ksq;%3B%a-kKvkED_P3cd1 zZ<$`UPww{F8z%3U43DN${^=W4|L^A9{Xch+yx*ikoqov;GCfeCp5An)On3g7JAdy= zdB5rpxzkH-m-k&2QvSrhJ!>zaA2k#zxlp=$tF-$z6%xKpJ?AWz=_N~Y`-k+M>i$1- zr`P;L-uIhwr?)*T?|W-=r#C+*@26kLonG>?N`EDHdazF2e<^o*)m!p@ph7A?$;TTZ z<=3o2N+7PeRo0b^rmWg-yre^hOox>CKnRboYwf`Bz=0(ig_0Pf+O-W75x)_X8E`^t~FHUh>P__$GDV znVvg6I9J^tpF6#*R^Es2q)0ngcH5@HnsZb-<)fvS)ys5Wg*yM~3uSuQuX5*KGDF@E zRH)-iE|TeK73%5U#WKBWX72o*S@M3f3Uz$bY?$sp{eQ^&epBxB=0)YgwIp}CdzZR@ckc9> z$#VSSPl*{HeJ01h?&mVp`A_d7$8}|P?(tn&H+kPzp^k6dBJ;Ja+<0qydB0JGI=;C? zrn^0J;~Vc+`7g`Of7PxM7pPFr-}+MG8da#L2Q)7;N{)y1bpK#^zxj~d>DHktU4=S6 zI83IO4atr7)qVTNxzjy0uhe*C?)2uN^1iL+p@=^9f6~JgZg_5d*$6rRVU5f^KWjVc zK83pdj*{tBDkS=C>bZdKkItQc^PaNb<@U+l|0>x_-cPGg&)-|F{LdrG&uIL4BV@U& z)I6MyuR22YPgSU=H}+EFCpFKir&s-4j-LV*c1Ty_oeDwwedm@qS-9ZmUxBuzGs4@*A#N2hh{Y21)z0 z2IsbKdvE1;Db(xFmgyyZbNlDUU#arX$UXmNpD6D)sZi(7JxQgjkkZM1XuVKh_oH<- zlP)D;X1&C;Shc{zLQkL+AfP z%O@`X(jQp=sQ%;RM|u}$-zHsFkdY60q-bdL!{`S}z}QFBE+}T~LrTKv2Wdn!H2Pum z10`VWBWf2EGxi}RVf2GEA{rX~F#3TKF!m9(3yK;0kdiR^K^hSajeZ#YKnWQ8h}s3k zjD1K+82uoPh=xW#jDDa5jD1Ayf?~!#q$G@fkVZs9qaQ{;Py)t2qIN+sV;@oyMn6a+ zqM^|bqaP>%V;@nwpqQ}_DG8$=q!H23=!ek{lz_31s9jLZ*oTya(GSvyXlV4q=m$!` z*hkbZC}!+KO2X&|X+$(M`eF0~C1C6$Y8MnU_8}!<^n)}a8XEmD`hgNK_7SxUiW&Qm zk}&!~8W9bRei;2g2^jl`+6BdoeMm_d{UD8qhDJY(exL-5eMIeoV#YqCB#eHLMnprS zA4We=0>(a~c0n;?A5s!VKS(2@q0tYcA1DE1A5puYn6VEj38NpR5z)}-htUs|fU%FL zT~N%}hm?fT57LNeX!OJA2TH)$N7ODTX6!>s!srKSL^L$|Ve|tfVC*Am7Zfx0Athn- zgES%<8vQW(ff6wG5w#178T*iuF#16n5ev5%--P|Vnel!Va_(uini^uy=}O2F7h)GjDy>_bYz=m%*; zG&K5Q^aCYe>?3Ly6f^cAC1Lb~G$I-r{V@805-|1=wF`%V;@nwpqQ}_DG8$=q!H23=!ek{ zlz_31s9jLZ*oTya(GSvyXlV4q=m$!`*hkbZC}!+KO2X&|X+$(M`eF0~C1C6$Y8MnU z_8}!<^n)}a8XEmD`hgNK_7SxUiW&Qmk}&!~8W9bRei;2g2^jl`+6BdoeMm_d{UD8q zhDJY(exL-5eMIeoV#YqCB#eHLMnprSA4We=0>(a~c0n;?A5s!VKS(2@q0tYcA1DE1 zA5puYn6VEj38NpR5z)}-htUs|fU%FLT~N%}hm?fT57LNeX!OJA2TH)$N7ODTX6!>s z!srKSL^L$|Ve|tfVC*Am7Zfx0Athn-gES%<8vQW(ff6wG5w#178T*iuF#16n5ev5%--P|Vnel!Va_ z(uini^uy=}O2F7h)GjDy>_bYz=m%*;G&K5Q^aCYe>?3Ly6f^cAC1Lb~G$I-r{V@80 z5-|1=wF`%V;@nwpqQ}_DG8$=q!H23=!ek{lz_31s9jLZ*oTya(GSvyXlV4q=m$!`*hkbZ zC}!+KO2X&|X+$(M`eF0~C1C6$Y8MnU_8}!<^n)}a8XEmD`hgNK_7SxUiW&Qmk}&!~ z8W9bRei;2g2^jl`+6Bc*)Wx=RLklUryLO+Vl-?Qshfe>Y`TL>s|DomcL*?I@f92{& zXZdr}x%~bAj_<7uo%EmN{lCrre<=O_-%`KSe#OaOzyF`AAJUKiU*%t_1o{7K`8v~Y zy?%8)>kR+DC7t{i*#(7M{zyKZip4t3b$4|)jNfh|4?4)1@$#CPwiB}}}-#8)x#9use`@6VE-$HWIryz>^1e`^B| z?=tZ|6K`F?vpW|N)Z@2Ku?=kTK6Ysps<3G*BTdh3$ zE)(xF@%DQ>{yio>VB(#PJpR*6yi>&UUuh=ZdY@N*cUvC+E|b2`#HZVM<+ncM;k|2_ z@?+BXnRxpnX8D=;fQx6!-)ZFazpURe@z*l(f92sFCf-Uj>0i&p-@(M+%ftIinRw>- z&-s{Vzd;Mnf2En@$260F>pq_R9VXs-fJfhF;++S1^gSlt=i(pY@o)J&ywB9%fQh&E z)&P4_n7!J z6Yn$e!Opz;cY5*gX(ryoVnM_2IQ2Zr1}?{?B8!A3hUr zFXPpp^$xH7Ni+2?VCtXMYapxstmVA&yRS3l-;>vW@l%6Y<@cES<1yPmn`ys3lfK)^ ztiS)^_5U0u-e>yHU=2_IJSP7Rv;G67{rOD(?OmDra}7^_JSKf-*}*LT;WF#bW8xj= z_$ke$&#gZ${~4bB22B6wG0X3B@l5&o%=)+f%CmoW?V&9DbC~@XtBu$H37GyTNbS!m zf55Cik10QwS^wUL%>LV9y!jiS$-kZE>A!U?v;AYzcbN38y?EnKk4ZmZmOo&QKiv0t z_3tz7&no1N-yP=o*LsBKKdm!)_U|+G$GM(Ye-5+#@c%xD<^Qegc>W_ekk@~5nDy^5 z@o8rL1^e^LZ!`U$!^Hbc`B^J?_Umx*O#OA4^7FWOuK&D&=YP^n{(UCiO zKaZ(@9#j8)Cf+%V*?v6AwEx|C^UprhegdZcT6^>QuU3X9KkGv#{u5sNZ!^muFz3%5 zCViKQ_n7!J6Yn$e&I3IE=QI7EwFl4sU8eq8f92_az?8qW56^$3neA7aIsUVm{5wp% z%fx$3e42^(nfQQ-w``vN*-X5{?LRQvKaWY@{g~%J9j5$TCf?)XnetCF>DvQ&`fD-w zKL-C`o}a~R|D5f3?WfOdKZApK^B)eg|7(BBYrj1veXEIC|4jN0v;X2V{h#$1Z~Wo6 z@bt&MjJN*fG3947>)&DGgHH}*&HuVg`Yv<+$!E&nVd|g9EWgL3pJvkcnRurgZ~ez- zmfuSA{C7~w^B+EU|Km!Y|MNcO*>AwCf9noj`xOk}$=~71kBRr0{a2eQKZmLR4wJsm zl%L1s-(&XQ0_ONDVAA)Q`-DA?XuIIHMF4KNICf;H4?{oWK zO!+(K@y4IlYM%bO3wiy2>mwe0hsl4MsXsmwA29JAv-}=Y|ARMp{SWsO-u#`<dRVoN0fb@#s5D`u1nM{=3h_drbb_%bEW3PTu&zX5t+t-euxFCO*x? z`%Jvm!m~eXdtUn=FyEhXnEuCS+E2ih|38`b!^AsGyvxLUOnjP&_nG*BiT9ZL>oD!t zW8z(A|0Q7Vf4A;p+7A=&GwaW~k=cJ?^6xOmKh_hx_QMT${ojDuf3a`m(RZ2h_n7!J z6Yn$e4zvCPCjEdpe)E|8J52lane^SydE*b~Bi{aBkLf?WU3mRRcO%b!eJ1}txBWYS zH-BN>&1?UxCwczcW9q-n_7L9r7Y|&caKTmVb;IToj+sJ_qcej z{(a2zA8984KC}L z`eW*!^)j#g)+ao?!=&#p>(ArT=a!$TKi22G{)^8nzx4{Q{;eh+{|=MB!=xWD=RaL$ z{d-J&nu+(Bc#mtp-1=kk?=$(gT6y;4Gt2KV>3dAP&%|5r@#JUS!Sp{&`W_Q+-Oua) zILz{UOuWtH-)GYInC-X6ZGV{McbRyPiBB`})}1{2^O^G}K9m1|iMN*V?AK@NpUtH2 zOyaFyyN5I9znJ{HOuY4PX8ZFXbN=lKp8R}f`{Odl9|3dx?{NJG*Z(v1$Jv#)|H5a= z-};oNzYY`cG4byEJo|B&_Um!+T>WLrFU{58J$UlBHZt{(iT8Kn?f>z(^qKPanfhbx z#`8bcXT19Jnf4Pf>wnoyy!$E7egdZdv;N8Je>+?}SAI;q$HZH&^7KE=q#rQ% zPdH5eJ!bv;-12kJPht9Rk10Q&i4U0aOEcSVpIQIbgFOFhz0b2h>op$UVYYwv7d-!K zGv((p$Di&8y!Oju%FkoU&wYc(f55~$?E2%`kI$7qlYi$)-uy+Hx&O-goM->mT|E1B zZsO^m^CfTpS(;gYZXe$GDPZ#NFze4_;(ez4ysvom7cj>U_9iBMrvLYu^wUiH37GX~ z?a8xWw~dMC(!YXt{)Eq@?=$VsVfNpwFPQ%SAzu4yGx46wTYqu5<-eJyzup7P@3%7P z`*V2br`dg&dq|l4t)elYftiPc!j86CW_~ zme13Fn~8Urc#qkBx=i~1Qr`TB$E5GA=h=_no!5V{{>7WW@|pPHO`iX8*Yoh{AM?uZ z4CUbiCjTDOe+Nvw^DtBXOuYLRkG|#e@GcV{F!jf0()Y@F`fDG-!~0CUdnAv(HH?Q( zGx5%F9{qrc_eSvO+aq~+pNV%J9(`*R51(e@?d3fGcOT-(-+6?me*v@obvN+n`^^5c+sIo#u-@YJ-%bCUr~jt^&9k4h>3_4n ze`osNJo`2MZ=U>2|C=d4X8+Ulzj^ZaO#hqJ{+RwZum7E9&foh?e89x}-0{Z-p8Omp z-dfIEzjD50uHP{Ex4HZ?@h%geX3Ecfn>qeq&OcaR@#^1a*1yZ7Z@ta4KcBgN>M`}l zx{oLS^mnAcjTQa#zoYzhyuFFXzq|HOR{PEUeto{*|Lv{Bwp~T?TO~Za$Hn*J(YJQt;l15>c&9fH?=kWI?o9goF!B9(c%O;) z4&c%Ee$2x=_7gmO)l)pY_cRahJj26VYnb@wczCCgSO4B0czFMhJiPZ89^P8S z!#j8I@cunKymK!PU&hs+Wjy-+15EtGJbWXw{Anh>iHY}__<)H|UzgwfO?COInREbcbND#9^Sexzxkgy`KPbv z$Ee=n~7 z9j5+S>v;O(+`*Gy8Iyhu6YsC$*{`*lhi_!^?=k6n*Yo_h&!q4ClczsE6Yu8v{p&dU z%lG@carnlUc=nfO;+vRwpNVf~;`9A}Z=C$yJimV$hxeZ2*}wlh58uX=U%ub3j4OY> z->;0rJ9&OTEDoRV_v7O5`F=kw4qx^%&wlg${!bkJe82w_htK!?`#8Lx=lRodcqh;E zH{e9w=Gqo42jF>&}NCjV}p=TF4Z_n7!J z6Yn$e0TXZKxqmZGel`>DF!A}GzY)j3%cP(0`5STc^F2Q!7XKBm|C;aq&p7%{p8Mb8 z@QtrA{TGvd8W*&W)iT9a!`x_qr9uprh@y-?=|7j-PvhrJh zi_<@siT9a!yMV{P$HWIrywiopf0~K6y7K6|OuWy;+l4&-JtjV2;+<~!@n5P8klsHi zQt^EEPgSe-uRw(qxLtYY-{p%hiJ|YknBVvz4xjJ)BXRxzeET19_hsboo*F{a*R){~&qm@(ZrxonLP)$xr^aVz`6-=ehqwFF%zh z_%uKIWpVVG_Mh+k!%#(^@-y)s z6Yn$e*58@sXW~63-e=-1X8+k?;yotbXX33}nDx)ZdrZ8~#9ND*-ryMMY=!>g#3FFtPkkT0J2)yHoZ_xs29^4`DT&L8B9k1M}-M}GAmC;$HxeJ=n1 zZG4>k?E888lkfR4-16)5FO(m<|CVR}rBpc#vR{&?lc)cu=k@sq_Wpb3{ENl>{$RfS zKfV6Q{{}bm=6~{~Px?ajNA#V~@>@Tl`q%3(U;h(V{(QfG9EazA|21EHoc`v!f4fWx z{QJr;j{f(RKk0*2lwbYp^3US)JpV2ZpYQo;ad>ABCjV7De7@&j#qn=l%cGy~`7yEd z@8i+8@;v_~mcGxUAMBmq`}1-1y*%Hajl<__|8aP$XIWn7Z`qpvAp6UA|He3lC;w0Q ze7~Pl6@$0(Jb$`(7ny-hKi~OpTcc0@FyHlqGKDAqOZa^K=K>91qvHAEx%6jf^xf}B zpUO+}FH!jKyZ)=-R=(x86@c`P@DwM0=)NA>>c+NO0>$&ich~R~?+jn6aP&N7lP~=; z4Nv7(W?@nNP`-Ld^yzsW-x>e5MxXMh^89bd>+<_=@lSFm`cxmC$&c!f^o8&g=i)ol zA6pTm`X>4m?~ML`8{b*|6Ms}LJ^a6pAF2vO^+n~QIO!MN*TesI`TyJe+e#oLFOm<% zJJWxXAK5G6Dc%{L>W7{uKSK2LwO_)2U;0Fk@D%Tie_H|QdBPJvo#82+{3YQjPV%7p zdT6T~I(>>${yL80W$J?Hk-UknO%KL|lurFedW_D0)bpiu3W*-ci|*_FvAFR7>5opI z`d=gmqC@#pNO+w-KluZ1RUQxc3 zPNAbN=s7AcmETtBl%I-bgEDnR&rdeTtjU zBEEF`?&0$M+V4uA_@w+Oe=FuZ7}CGa_$Pg)@=-|n6Fs^gd@9#p$o~>wlujYZ=lkNR z{s~X{>GX+DqDvt?Pk6fTcbD(KeP90l&*l8<_r<$c$nR%&hNt=?{;52kJ4nob65ghQ zX(7pl@RaO-A^9i0h^s$(|B#*|d{+MzkoqH(PGKzlhvfQkXZo+>iBDgBzl6$9av{1D z#^Eise(}BWzl+v?XY`2<@lW+ZxP1Kw;putGm-3-XHiMeT8>p@a~iH`(}i{@W?yX zhw;`5S$;1DpLU}7mKis^6UI9VAKaH){@#aC{6`ZWe;|za6yCl+H{R(I#rH3ABl7nZ zJ{`lqe|%K_d++<{=VAKRqq6+&u-x^RzBNjJ@#Jy+!gxpFy%@axV6^^z(KhY4Fy2%6 zbPPVYOZHEw{w_a$$a7)5PxxiI<>wtK`xk`&*?t?I4&$xIl>W!y?YpFZC;Xu2ulRi! z?3=Q-8s| zQU0IV-1Bc?ytPW{e+=F_BFg`aUEQn0ct_!_;koU{sffz|-LmPM!gx>N?HK>-z8j_g zz@MIp>c7JKG4%b5qxdyPJo{{zzO`EEe+=Gfit<17-0ERryrb|=O#KJyzKs{beU8h>#Z?<>6hU~cj_o< zzm(@}zx}hK__phR(iFx!3U9^KzkPL7el16oy%5HGL_ene^ZQ2i@8JjT+!)6D3U9~I zcb7)xfB7drsS4w*CuRB5G4zAwQU9}Hn`{0N#ybih#NfT*QTh+e_-iJN_Y~fZv487^ zX!*x(v&;+QeWD+uf7a&{cvvoWA7u!=j4C(`M_Tk#(N6y#^5~-|H-iVei(0UlIIVW#qjUgQTn@&x+!A+ zzM`Lwp`X_9U4MG`^AY+_OZf#cc&l%ee)+Oryd1_m3U7_b-G18pM)42beC|KPcw3d< zj=={S{f?hoS~g?D1`R=+6ygT~H#D2(?M|85N4?jObfv|#)F!+2leZ9ljESo=ru zCww*J<1pTOM#|rdq3>$=2PfZO8^${dZ{K@lPW|^ay#Lnq)5CaI$uAv4-!6^v|C9aR zkMuu1h4*9d-hom4$lpD(XPCaH_zz z%A)w!#!tO7jJFkiF9z>x_=YK~zYgQAX4U@0;H^WW^yify8tFedioPF%cQyR8$8{?Y z({~l#jj_MR zWB9kqqxkg5))T|{K;i8e`rZ*y{PxYWZwTY9%}W1b@Yb*>{;q*Nej3Kx3h&0?T@8O~ z!>-ZxSK+-FyfrdPfAEZbBJGE(@aY)5?L_fwE;;_1F#n#y`!RS=!(VXVgU5&Qj?#a3 zd2at7X!xIOnEF;2?;;^KXrg z(*JPBAx;?YD|}T<|Hakt4|iQOB#gJ#DE|?|zpvph9B@Z;{HE|h4Bk5`%Kxd!hChVq zdxVdv|3Jgf8PVlOVZ5*Kc8vU-F;V)H59u4Jf9qLUerr^2|B=@4)}pzuhv_>CZ^z)R zqoec_TfU0)UjtQtZVdmfhQH&g*{6r;Ti+=E5kueC@Pq!i_t-GrR(LlCpFTFq|L}o5 z8pC)`l|TLL5jp!mUPTmdpLu_z|LiFGUJQNbxF~+)PB%sTpR4fc7`$B>#Xo)b)5T%_ zeZ_we!+)URkNmnk(*N-keLseNdTf;b>D|Uh=I^YvQvZS&y!F#4e!_)QBlYhPK1P3h z4gY!Hr(472Pb>bd(Yf{CJ~2xF!VR~&VZ5*Kb`0J*DT?p2^W?vW@t)$}zB*?9zo?JzxC^@qw^on$@+6*%AeNoJ51as zI{&BeZVcY~S(N^??f>{dn14^&(-jop8s-081EDPxbcgIKYL5Tc454=Mfx8% zMt=6VDF0oq`=%+3w-w%tDSx2h`xo6hH;i`_J{^O1Pm9uD-E+HwFy2*oKL&4~9>xDE zedV|?-c$G>2Jf5^#dmK_o)gAf&#U(5sND9K*6^RK`t>ehd|J`BWAN^oQTi=A?|oPp z?;PZy~SZIGqz|a4_=_x*M!3+JLI*Z#s^zJI`{;x&-7yOR{ zzIXMWZ2m7r{TKM?Y;OOIF@1mZ{a4C8f0qipK8N$?ce;>W|EW2y{1PeuJvo2R7B5}v z+mFb;IxM^Wm~%N_|JprR{x#W;Ud!(PRd3Fx4SS#G+c)3^`*FbURoXZ5c}sjO*tY?H zf8CGUzvOY0{X99lj>aVu-c};vYE_?iz27I-B zsr?Z!Or+c)rEh+i^@^A)EY#;!kA73#mfKPdD1MP11G)i<2c zz_)La|JSqo4|5UcfBo{%3w%Bz`;m};eKF_Pe%XLuKM}75J|4{ZNnLN?{r5aq{;}l$ zC7l1hSyeXw8I%1);M0INkF@{7&%Yr)7W~&kxc&C6ul~vB6XK1)$Cq+`eC@H<_`HSx z0&gzkd{4b-fzNA-U-U+H`6oj;|KF)Kp7VJ_d@95*zMS*lZ#(m4pSQ$Y!G9a@O(%S~ zrO&67|5V`3Fm69S;w^UnMpdQf?~llCzlq`e>F4asuHPf#VA5;8OfsbzG{y%nWeb)bJvaf~m zGXcNvkw@_BFXB_-{GSGV?*}G!_5C-fe}etwHtzq!*FC`Qza_*Qfse;mh(;aKbXz`S@J&-{5JtVrdI{K|C>)Q`U=|6?it&-3*IlWN?@`hP=wD%dwKaQ^jn^|f!`5}ye6%^RHW^WAZ)eO@i1 z_9Kjc%v+q_{Gzq2|JKB(0&fHU$3{Q1@vk91x+{D9W!~oYt6jeOZQp-Od@R|2hx0c# zx#%jNSBqW#)sfl#zn#bV2S!!&_IXWwB=G7p&d(kY%s&vHO6B)C=Rd66yq|AhRdeUB za$){Zy~^9qk(V}R<6o0f`M;Ole$DoL{ZPy6r#$W3kH~&>RCfI0!2VXRJ;|=0%xBKN zIXaui_t~(1ro$<%+5EjFKAoBEKfaF!{@$i*`1#{=%D-SA-!}u_rpxI4{QPU;t-#~^ zX5cqzc_$k`7~-S%v;D{S&A?aGs9@L6miSb#kMDzlZ+_FvQ+@x{5|{s2u#fL!fuFP6 z1a|)_rt-JPWS5@}%D--(8SMOHh))GRdX3lLV{Yli*Z-3L(TUmi_51GmF8F`$4ZBqO z`L|?0S(qJvHGr@G8@}TYeEbQ1Q8up!a{luPXR+~>g|1I%KD1Y6U zuOGg->GNxSUag?~OMD|9zez*-vHnXFp9u9|eZcF_g(LoZt#98DuLb+*I`@4O)W2DW zEO^7`E%C9yn@XPl11g%c^H)suC;lM2{Nlbm|8E`sEE~V7FJ1i1vDx(}E#>x~s@Rjw z-)iC$f!F=G{o#!dJ<`v=`pVh20jU7QZ-Q1hZd*+MmG3 zzwr8dz}p?q@p<#L^FQq=#IF_i|D!&ONBO)ZKKeDg{G!#IKjPfO-}8CB(%FyB&9)z1 zz~kR{lP1slydgf`tTmfIvh-bXvxeJ$a^876`Mjn0B>|7e*G$lVe|ysrLw#OyaYt8t=<~Xg;=g$| zpA6vke_rxFyZ>!g5x+$?Z-f44Mzbf_`Y}skJl>bxPeZt01G4WAJcK+4HJbuG>uJed*KOsKdDx24@^Y+`}+hmykGRjaA~Z=D_gbUC;G z-H!HE-+qGp3%m*Z->iCr&OWcnek#P@9>(kc+WODkpJWo?*Aqy ze7D^9-w>Y&e7Zlk|IyV8+4Yl!eZhY-gxlX@;=_q=U;RS;pTMhi-2M|6H0ba1n)p=U z<4d{y123+}`cFfA)F3KAq0vH{|I~yD`}Wmu&VPHhQ2qz=_+K_)?2bNf zh>w2C9zVw``1#|`D-Y@E^OpEnn14MQ^PVpZv#IG&)zx!KD5Af}4;$wj~ zhw<`1qWk&m`o$2Re3YGkt9IWouE+J~W-S+t^zB>te|NV3aTU&YsXd~R&!;&5zMXA9 z4bH!7R+q5(dsUmpkHY+^ev6mi<2PT_%(rjWx%j7o{rC&c4|x8On|$69p9uENC4Bs{ z>jTHJ{@48B>?iMJ=U*Se%kSLrW3Tt^N0k5Q-E2PkgV&#(&N`L1U*+C^k_dcK%KaZU zsLo>FzN$jJ)c!QL->>=BZG2u6uZ8|c59jUw(Ub1w?XRk{uLfqfe|;qHzdJp40IUD1 zn&Tshug2@|uX~T^!Tblmt&e#DZ>4exF(O^udTItACd4>kd5s`d2E~Dm?%HSvQQ$pKAL4g$a1fUzm@1`x$UwJyw4V@rlIm zz~gt~@^$R|n{MLzZ!OHf$M5m{Z}r%zFZl6On>s!gcpLDiFKf&0f2&PgoQ%M$TD<&j zZ_|z4Kh(r00-pr@{pHBYpw*nt6<^AU|@6Ep0=PmK6!0X!F{~b%dV)GYjQ))jQ zdHq58s~x%hLuyn zI*Qldt@m7XrO!uHe^Pxc_5jpTx!=Y6};?MB+zq`)5AAij7}2@mAo|LwNn!zxKqv zeE$vcslc0Sx&79cA9A73TjHaSv+GZM9p{&xu-hp5K-i)U~1c}=`J zKD+$%a9;oFUe)JipI0T$ek$0HZs7j!ym?zTe$aKP{DkqhIf=hN<<>!mvGKP7KPx+a z>NoEHkyWl@?N`-v_M=a-`Sb`Lzq6yZZ2X|MB7U~O2mR0FYro**cWS?hz?+%;{BiuT zgSYqNZ^?cvl%EaqzsF&F@&2>E^FN-G?Z0ls$M5$}Jc7@EZS8m~*}svO|Hq5E+`;^( z{70W=+fRf1pWdYzzyCt^6M?rU^ZJvvD`V>?bOYyqGB?}4-HZ1>+a7xv<1O*2z?c{IM?E zeiGPk@$ks|eO?nEO~}4}Rv&QxKN~cjUH_@=DgIw&+t=%O{8s-yZhvN<_*CH4ADln( z@*eE^%@S`q^Y~%>5Y^`8e{7XLd;0cGBl7?2Z2zO1dHfr7`t)|6Pbhw=U_TDx_xl4A z*!l~L_^-^iuWsS?`#-xmzkj-;^FL0q%P-!P=l_Ybk1zH8S36PuPtT5D8rYxQ_e9?R zH*vfc)=$}p_rE99UiYSN-w+=Qyt$5-|M1zju=_uj_*7W`mF&drk9lP~=D%v{{5OJq z8`Qs7FRee>_g@pA2)y2km){|`_haKXL%bFEcrTv+y|%k?if`W%p9;Kb$nBT!(umbR zRmb%oiLn062K9H|d)-+6BjRIW{Z>@L`;Vpb=X~J%uXmyPC#?TSPUZdo(wb+m=Z6gO zslb~iy!`vD+JueYE%8dae%zVIujVnAviSqm%=sS)yxxWL*B>y6U;h#x3)kO9aemIk zC)xUc1N&bH{YNv--?yaoGk*Ln>HrktO>)$~u8 z|FHi@cKp)4dHHqQ<^5VduXd;S3-)bLfA?B?XIq~);061(GcUhedX2x@=k?|^eyT0Z zKiShia{E!8U&i|O4e_zS$EWlB zcYo#>)_+*=()__my!_9YdgCnLzS_(AZvn6MS z_AT)x)w17zm;~|P`i-9K{&`A#slcm`c=!_7w$}CS ztp8JcyZVy|d=l`>#zj+o`YvQ^@dt=eclou3%ogl`#+$~$Y*_C{g>LGz(?IU|Hp{U7y7&=J`s2u@DKmdyu{}X z@mAu4_%&R8?Y=&*_Hq8F0&lAE_|JZ6XicBj#4F+aA9v^ZU$DzScK$TPM*^>6&e!|9$ewqgelMT08%vbFz6|otNM7Gk;+5SM>c2+eP4a=Jtnn9?8mI9Z2@O zX7j2Bx4*Dm8+QF`h>r!{T)@XK$Je@z-M=#jIr~=Nbqj9)g*}HH;+LO2*zw63g8#d6 z{(}LJO!9f%*72#t|Cjq8opSFhK5vPSx^erqs(WtB)aQJg+d8oOS1IaWWp@2dgZel4 z(>q4__SKf|{28sv=JhOI|DSqkDx3d|h*#aY|Cs+t0{-_K8=dRh*Tlzyef0^q-*J-( z%zjLKBJgp*Kh$;@i@!dE>TkIIsG5tv?#1VC8(zBQCBFX#{)apTAU%V(pW%;w_qfli zL!Ess#cyj~{yly@Zn@7J;*G%D`JAs&uleOZuMczfRh(UZHfX;uO@8ih#5RZS4Wfo0v|8uk>)(jC0&fHUnG4E)@a>ypD1Ijk@vF)6-)oPS2l~7vJ`(u& zZ0>*GdPlSCSACqbAE(*ZPd^i|XQ zefyU9MBw$)-2X?Ge#F-A=~JBjNEp8-LHy5uq+K)LzB-lSw=CQLWGwGL*PVA**Pn9+%^T?3Hzn@;XUnqdj}6Wry=Gp}%jfm!&b|@m zkIV{Qen;-SxYFlU7so4M{hX@J^MB-fH>~h^LwqFgX+LiNg^F$Y_^Ye4p9=Zcqxt#c znzfhq@$IX+G=KAG_WWTqo1ed*==pd(pO1)->SfRWn1Els>#e;1fqj8b1AfoVI)3Zh zkBLtNUeDqFS8vs_iO(D2Q-Mzc{*Qk5v+D;-@lV3|)o|kvdlzp%@stsDeftUGCp^ET zKIQ&zG4C2Sel%ye^0&hEgS~~9|MlJfc)+)>>e2Xdb$0tr%Xs}8H+fh!pO1)-1wMI> z*Z-SdT*vw^Oa3PUAGPH1JFDk>KL6j1>c5cxXdM53%Fd^BWzWBu?!^C`o&Wd+?*HVu zwV&|wZ;6k7$>#NooWK6cwtW3a?Ci$^pZ4eRKjn;}to<0`web9D9Mqq<*XKw1{;M8j zU*L7h>(BYeUU0h4YvQ9d+4)ZgaQ|QYVPAIt#}J))f7c>L;gjM(@sM*S1)o5tM# zt}pC^%&0gd~jP<|IJyBw}Sn25Rcy>wHopH zU*unSepol=-`_E}zB<9rzdD=BUwD34pUm6e_+OUa;PaYzBk*=dp8pyxdJXq^Lwq9e z(Z}3=pDI-+`n)CH3Va%I`wf?kJJ#pbIWGUHz^iGz{$2R`Q!Lzh7lbK7J-%^%BNE)4BhpAGYB0hdo{Xli#xIuX>u_Kfn0ZT1))=YvQB8 zzM=D<8O`h8%Qb3s^Le$EJO8ADeRDf6zsviUedhCq?CZcj<}d7LoPYSu3(oR+3;%!5 z&VPClFF$kJ;Lbj;&ZYJv@fUM`P;|-FKCi(G{_7>&|5NvTgpEHUik}hqBq+ZvkGq0h zKO3^22)v%j%kP?1H*fFzZ;7`8Z};TwSH0L}vCpesRR4tdB`@>(JLH3{$NRh{K9%e* z#eO&%im3{pYHRbj{p3#nt9}+6RxJovk4&m+h<`3_9nE6lk z6M>IsaR0wKy#X6Psq>uw6~g^T8;sv-fBqT2{yU%APt|PyZE*crvj1&2`Tm=}#6OUI z{b$bS8&XG?s1ejE1w8}y$x;KvQy_7>m1>hJQOO6C71 zw?CokCRKc16L0s;wy)me{3n<0{qV(|?`t{_lk+CcokHmUuHan@{KR_FH}G z$PqrT22lBbmd)FFoWFbyzyGd@*Ux41$$ZYw{BOJNAZ^0jv z&BqHlUva_H6+W*9y8P=U*}PuF`Od?3JK5(o@p0d5K3dHAFXyhT>hp&9=&WpBrJT2y zo^hYgTi8D(n@e09R{u|=$ zQ`x*(!ueH;KYYvQE%EBgY(8Gf`Lhl@ySC4(3tj$g>ug>x<9wCn)e6pcef6FJzI{u4dQUc=2K+^XMjh(&>LQo_v}ZPNzu@+t9DN&G z|EP(#?`HGKmz@9o+M26<`-b>K`1tK&D*sEe zdA*YJr#{nbjBj5PA9c>=qi;C>z_=T`_`D%L?w!r6Z#jR}!`HL%pN0RgXY*;mmknFa z`VTeO#5m%yoU3i+I+~+m%(KXq8 z^eg8-8$Ph9&l}>CBeQw+8|U}jc`K*|32A# zIQ~AO!5!@UtA@G!#~rfyaQtlsoV}TEUlX5p%;v-K_mMT@ z{%*2#(<6NUE&P8zn-9m|OSYN7?*FPQT>jGm*?c(uuJQgve*HsybXPVXj=vin{X46F zhWPmGY(5-++i&Kv@tY;yzLm{~B8)*ThGcX7l0r zyZO|os{6blUR|8chvV;u2b8k;V@rH;YBnE^zth|I81CCw!>RncX7l0rdq|a6dH+wm zeI=U@$KU(ze9(oyeM7vSnazje?~zA;dYI2!@YA#TaQxl%rLiygyt<0=zkfC#j=vY2 z+LS-PNPOHqn-9m|Lxw-k=I;&ocG-M5{=W14dYyd#E%8ySY(5-+U*6%4^L$=i?ecFw z%;v-Kck2gF9q;p+_~h7ZJ{*5{-`RHbc|&}AYcVTg|&%I3rIcheuF-HXn|^pWp0(EB*3Q*Sh@c-Lm;`{9X3S&20UV2A^c};rP33i}OzO?Hl6b)3f<- z{5|KyyC3s;b)EA+74AQpP5AXgjgdnK`@E(5U&(pd_m9)-`SX`uewciw&#SFz{e!^k zCj9>Uc~8H~#!nIWYT5Vy)T#Xbd$&QW*!WQsA63uh?P;94-s4u^NyzjbI%X~hDeSuHr@c3Q((3`LOydgdnc)JB(Khfxl zxvcy(`5)EH_TL8nUwO^@?EZDsfbM?__18SW?eEvUE1Un0iH~b#+fVB7_}{wE=clv$ z6Q4--=koQ#FWaYT`FsLiu%8C}Cp9m6+vm-Vbp8{*-(eo)_3!-7%@+8)C0_T-ZvSaH z&;RHNcd+|Ex}l4IEbwtlZh!Ea`6a&nnD|Oz{e_;#hj zly5&FzEt4Vd~W}jL3^_LXNm71@NvLTY&LhSZ$BlzEaYp_`t^YC_WBL%{)O6>&R@d! zKcWTP{~qV|V)IWC@v-pzk90II|5eL(e9re@6Q4-@&79xzy&GHld<_33{ua)++3)vm zKCebm{jZzde$!hyfB9~W+4C=k>?`5mHVNT-p53Zhud_w8q zOX&yvM7mz={6u;~`bP<+<2Z?r1Rm+&ThI^KK|1Wi|A_u!#=3mrILSVE=)!;ftgDyc zThk95hxCw-=pRVOasQV8+x`dfFCj+|C-`ONxO^fV^#|!V?%&$~|2H4TANfQ%pm*S@yyYmP9NBu>5SbivH_!HCjfsl@NhIH^@{E&`*3ic!V2jYt3+S3ml z2S0Hf(veT3gGYKTB+wT7$Pf0T;5h6fpZR}p=dMp-AN3-c?!HTa<0M|c=@K z6~`eR`GjAHOW6Lx_`^@|(1o8!haJQRc90G`NQW-cah%Bilzsj%6aQuZ8}wg)H-0Jk z1^*FO5h<=22;3v|di}a9(9i*Eb`S}BU@4o@2;E`U4kC$fKM|vS%*=!!^ zh4@(DkzR;Th5Cc^LcA61BfSuB_Rp@rNH4@k2W0a|FT`7cM|vSXJ}}!p(hKqGpllxL zh4@6^kzR<`ZL;kny%3)YJkksC=HP7mNH4@kZL@i#7vinJBfStG>umc-FT|^M**ww< z@rl4Ay$~PG$nJlTUWnI+Wc!cwLc9^|BfStGO>_4r!tn#r3-PI7AL#{oA^$0*7vjyK z+3`bqA>Io4M|vUN%oOZXdLcfZo*jRr7vl9R+4T?Uh4@rB|02B*A1}+ckMu&kUBbuD z5dlaq#K+}semJbZNH4^zrP=n84qhDpKazd@tSB8ku75DUfpqLcANvswpe@GlxK6;o zah-s4To)ice;oa&N?X{&^$Iv#|Ag0H9f*S+=whA)>Cizsj??r5`9nJPqu~F@FOJi} z|B+rS-|1iShzIH!?Bn_m`A0m%`1cCzBY%jurvGCf@rIr7c%o^l z`hfqV9B~}>!~ClT{Q4jHw?X}fe<5#g$ew>u(_Ft&$iD9F?r+wl17Sa@%6Z8?c=!dr zSpU^iuKkDhO?7S`<%jx;d|@B{A^s5#pzXiqp@)1zzS#R$|JHt3e-LN29q)e;2lF33 zebHm^1>jz^sSY5XO=*!W4jrSD1DGEW{xw9-1!yu=k4@CZvB0pH^i&&v)3QlcHDlAuiE9-ujhG7e6%W?H-~V(!6o&# z@p(1c<=<3t-jM%^cI(IBf2&W9%&q^=+th|3Je>R(yTmPNs4fuXMeyAU2 z6}MlzTeUBI-Vz^Okj?A5oPX-Wp?!T`-R$xoOMF$%KXUXt6MbG2p9JxP|H%Pve1`b- zJ?yP(ecljn1wJ0(u1~?=`P9t+`n)ARmG~jt{|i%eBe&+(kN=r};$xxw)Bs-oSAF#4 z);@2DPXt~M=6v;IkI6lMl(%n*PX*py#rY;Z8t2|WmFLy%F8{HV|0%ruuAX_*Z$7Vy zPo?s^J*YolE<4WW4e?QM{zU(&@8J9|PaT+he^cIn3tl*XngiVU9PRJA6KW6jd3A@& zzZUrTAkMdIy)?IeH*a4P9}B$c#Q7;pKgd15o#zelM&P3!oPTq-XL$Q3J`wozT+Y}3 zx{|eDbtkodiNA>R-G@|r#`j+np9;Jg%lYeO?8DE0;Dz$H&-3z6o9M{5Z;6jy&K`fL z>6}06fE|s`tFbQsiC|y9%=w3R8nUm?YvQAU+5NYAmGcMpU(&?q4e_N{X0P8iA9DVs z1HP!@^Okt^10TPk{n&Y&zq{kSnLe+^x%@{0Z_I3=AIw^GylY= z0-w@66#Acf0~_}Dc>`YXUk%{npVQ5cx#xfK_AU59+4WBkTW9k3psCT z{Gayb=fCkI?_lju6K{p`Ph0ZwU%e4^X886E@rjWCxG%TgulI^weclppR%h4$v=z5M z?b}1x^`pASWA6X>pB~G-KP6v&hWJFVuP)~N z9+gc7`n)ARx;)!|{W`C|U60t3jX%`ARQ|67{bzI6ZqmSh*)@;no?p-VuZfQXUW0GV z#ozc>C+r_3Yg9r}_99;v*ZxpE6*F@$%oa#ut-(-h#g*yZqCGdHyeI zdSmYS>AZb)AJu=se%hAvBioKR*5@_&p#QUo-^+abxVZ7zZ2WGBSHEPpA3dDszwNSB zXZ!Xo@sYqsS8@Kp)SNFU8Yk^mn@$##D`QsrzuZfR;%=SNikGH?lR{OE>w;|pL zybbs^SG=~1Z{HH12z>lKx4(O7kIQ^sji>St`hT>axUsvxi}u%a{MFz1ye2*o__QhK z<7UU4>hp&9Xxf47c^%kK8@uOwVE=};U$gO>B|a6-KdLD&|1qCUy2Q7yCb;}7A%00U zUjB_5Rb}&Un)pcI&9&VAS<#2N=jZb6&wv-s-_gmu{cJvaRHe^b;$wj~zw`d9Rpqbe z_`G_+GK-=McMt2-h{_*#ODv4;`4_1RN(C}&R6~Ugx7rD5+7Zh zZ9lr1$N$Hl-_5!5$`L7gs ze195z*)3o3`cJ$P>Oa0e4gUGdhp_XHAwCj#e194Ij2&7I^8L5q2WPkcbSgjpeev@r ztp8GvQ2Q5n`z+_%d^GZS-@XPfoPP{`KNbEj?$_shpEtxCfyeiI!5^}-;^SZ96M@$c z^7+4~T8?G*)uWVuA^!OOF6^(|dk(vP)x;ZtPtN82&q337na%P~d?N7XTHgOnoqgV~ zK5xMb<%jRj!v8V9-NpP@lU)8&fls^f@$Zo*PXEcbuZg#U|M>nX?5}$5sA@iMU|$$N z;ro@~C+s(H3!k^dM?(LL?@xkn)q1zHd|o}~@^6LyAK#w@f2ukC6`$9{rvi`fKZ0*I zvDcP9Z@>%j!}kxtFS>mJyZ>s5SHk%N-#-Mu%ZQfm`S#Uhm;XrM@%=XNFMTt0tRzuo@7u=b-Kr}{7O`2HIB z&Z8C{?AzDGM?f9!;$tCx`2HC9QLheQ^Ea0GMB?fDTi`pL@gSQ& zQd3<1W5IuXe+m3M`xwS+;uC?#_k+MUe7*BNEdRu(0&nU2LEzUuSNf38TjHZjv*Vv$ z!uzj_+qZA#^Xdu8zrf@BF|hyf#2?uG2drO8!}zyw^GEo84EWn`o&B(H-;n*N*I$3X z1$>RQ;~(&O3;!4W_4ixA|8l{_zxcd*lIs7$Y#!fl0sr}0 z?)`cB@uML=5qNyR1^fs-hm9XCcwznq-){l`=#9s*>ksu5@wsK-+xVf zB*Y)zZvlVimFqV5c>{h%_WT#V-vYkVhn>Ijc}sjO@c4cU_;M}c0zYod$$b1kd?N68{}T8k4qCCjZ{HH12E3v8 z?#g^|BA^zL{kNi&r{~P^}{8xg0^gr@n3GsnG z;{8wSe+R+;T>}5{{1GLqV#~Ko&~F~-|I_+kN;+Zv#6Idj;`Dd@FINAb`rp2Q|Npjq z{ayXP8y}1=5O45%(2sxXzb2hfANB9wmT$58|FnFI)&HmM>n#dI7@t-Yw|^V|zpGDX zi|!vf5D@xbgVO(P`4+4HPs?|30sq7J|K0d(Z2eg9AJ47++xV9W`iS@cuk>N>@5WyX z{^NXt?LR&L{(t%?k?gIZek=j zcxn5O^}lfQZ;~$3ThNcN{$U^fBYqJbZ&&?0eds|y{mIRz<2=?74i?zLf9T=xl-_@e zdW-yEzgYeDB#811bt3vd>SrnKqdm~BxWVyZzOf$>iTokI>gVF>KlG7rID&j2{?La# zyuTgCOI!E@9>=9M{|h}!7m&yZE+m*;J=;V>L2uw59}A~ zKgtQ?efSam%Jty~?6<&y1-2VoAN~y3s^MPi?;q4lA9e3vFr!@mXfDZK|BC0g5LYQ1 z&|h-mIam1lmh|HYGay_+Pj%~Siq-#U;=Q@`1AqGeyz@W3DO+DX?AEV^<1+4rQtVt6#V3)#bjvCjD6O zAMXb!R=?z&?r-?|2L6xEj!!b_@5O)dwimAQ^)37t^wn{${T1u~@RQO9eSP(!i+>`- zCw;@MzbRJ#xm$l;=Id+HPX&EE-(IZ#9|uO&eSHJ}rTEdW>*?F(DS3k>c2E&Q1A6~hcuWv~|x|z2xOYyNcy776j`uiR=>I7e3 zO>^-#g8x{5UabDPKVA8budhiz3HATu$~Qgn@72${cj>ub`F1bvKuiq(JZmC>zyeM9AE#pS^m3udl3&e{>7)-_&l@|5N-6=^GkAhH=FDfrv7U>m}qD-|xvj zx&0ZXUi356$NB;2h2vPewL8BQ(wF?l^$M<2;6FU8r0=8^(pMx9`j2^0Ngvmfh4jmW z_@LZyeS`QQU$`DFq+ePiIJQ$a$|L;1C#ABYFyga6w_u6-2p zUs1&f^)(5#pzS}cKNE=$^)b)zZ{zb%^@}ZE#3A&*HsuT3F#hr4;@a;&)mQhrey&jY z{!{&=!N&F9zE)iQ{HOk_WaGxiY;1k{4%fyi-}FWIeD}uE*Y|Ja_|MtM^=Hb)^&juQ z-dORs_1yS>W9gf=|HHTh+y8U_f!>c+$p3$;kN2Pbuk^$5 zm7cV5`)Bi5ar*5k?BV@KjF-`VQJzT0bqUgW>HWF)|8{*`zaS2XPYVhG(*KMI{}s`0 z7=P3k=;OPrNJqIKovZ%2hxp@q6!x%>a>RaXLb0#^l*;@C{m_5x!+-2Yq=J3e&lF#u zsOcYwD~>~4k&bvEy;%K-1QA#0#~-`-S?JUbj)OfM2QJ(qf4E-6|6vdDL3@?*11{WZ zN(l9_4}Ih#3XX?=l>C1-9Vi7n4uGE#B_QrdM?FG1xN!S->rV?3fIqMk>SDhKd=if+-gcddE)=rhySn>(E-?pf8fHc z4vxqF!AF#U{s4N|FBE^2FY*n2JdnRa`kDlBJoK@T_+USx1CT%D2VA(-lmH(8 z$G)VG{}<9neGcnSe3N_s9O8`ngX0jdczZX`0l&g+L?1$ehaGU?Hl>C5 z7{7u4U(N4D(#QNA z^q_AeZWne!UF<_2e!~Ay7uQ2b&+F2CR_KM>V)gBO=Xa=YK6dG$F7}}h4*ui%1o=XI za2)){anK95wW(sD{y<;Tfh}ko)}Ny9FAzU@$1A3-zrRyAru9YYjh!}Bz4%yue@EAJ z<8pi-M7`+tNk-gEZoX!UuU`WF1$_OIA$@$mz|wofMPd5KHlJQ_ny(*`z6tc9gZFdl z_lom>M)k7X`j*j%Pbuk_82`L3KD^95C`>#nq3H`6-{Kfm->_^4< ze{|Er!J>eJ%%=bh9h_kNUo{fS9G4fK(Jyx+&nElz*!cj?Ezei`XU z$MO0JeZ0R%(RJ>L&)82@)v9^@DWo3@ z@lWaf3zpUyLFfN$>HP+q-1zOox%g}9f9&T}&jo$FAHm=_dLKflU((#AOnj&Ix?Ftn z`s9BU#7EV3c5M(J=!E(zaw*Yg2e!|ZFZ3%&Ux)f6@PEozIMMf_3Shr;^JTeeU12h>c(xT|9$d`{KsW<0$je$e-F>q zAH=7U{7;4Q4eO7jU!BHp(`Q}(tg2o;udm*8=dbAa?EWF8_j@R+Kj(3`^LyoV!ruJh z{d4b6&+C_ve*9wg`cHg6K)vDO7@nVDpacD=+J4NQzJ5gdrNQ|HTzGzw^b-P3Y}tzWGhk-lE) z;u^gayuW%AmyY*$sRe%>f7l&<(ZhrN_Ek#pw}Jnf^uzuEIw&7(527E(U-D`zzy52| zPlEV^3+un6KbU~dPd$B(U;jIhek$n)^ng8siBG8Syd zl78I#rnSC)8R^GG>R%A(Vi)hnn6Pl}Nxr^8{EO5tgJ7_IlKda{?2?tfemUY_r2fD_ z7rUM4$3FI|-23nAqW?^&{-;6x1gGfxPu9BnkN3Ug|4%=5r)`hJS1<7WPso3@h>st@ zMsfN(|C}7Pp?*^PokIFipl{HA>HYim-M`ky`)z)E=hG3n_{5~ImN_m7`e#e} zc)y)m_}BV~+uE-_DfRmYOaAM?f3>O83;PG?Ab!{$LO;Iv>3~6g{3{Tj4#l-ENq;ug zPgV8aCw%>s^y4D+FM-3sb{Oqn_S{1s`|+uSei$F{v_4$D?&1X<{5!uT|Ia=Cu3dBW z$Dn-Qa_1Qn=xd5UzW;#wWAcK*57M7Lzwvc`|5-x%NuZynX?%$9G)ekMuldPw$N2Gy zNZ$tfMyNl~$=jzNSJ1Y$dFT&czm)XTKp%WKK70|xpH#6tf&*?{#-1AupJ)d9-ykAl+a`q&Bq))$m@RfdiVv3Ir{MYb5xPE~S z;(~2^`msZU-#_;IhcePnitHaG{c_UZ;-sx6`|Zn+ek$n);}c20gvRH4pZoMTzW?Q< z9|!S4zVUuWP1o1g;vc~l*G(r(exg^dd~yC&HQn`3bYgb@tmym2hSs5Ay>TF~{!0m6 zJH0j1k55AW8^M2kpFq*|oupqu`n9?oepSwYOZDI4{21sP)SsaKOZrHkwQtnRub)%M ze;epq=m+%^I$?Z{r-VDNEWgb!UyJe;;vbHmCH=cdzx@}VUFgTZg7gzfKd7IQeovaX zo%!kg%YFY-(oZG*VEjBf3=HjWLED#R{Mgoye%CpGx{c{gm{# zB>fLJo7%#UPY2SEg7_FAKF}e#{N{A})ot|i*ZJ{@p?^|#{R!hE=_`6cVTWthuS3GD)~RcF2T~mv+u{OTHK@nHfNmV>rWy5G|-2e z_&%nl`7uc!&$;ZjWJ>P++4=Id&=0QfppWlYsyF}Ie?!2|n;yH9uU|p>Wx@Cs`eFT% z{MQ65__o{betc5IKP=zPoxkDvUDC(+bLqGmpXSc*7=OkzJ~5#_`GfD%=vjXqpNNj{ zap7nDae+O-MsMjU;eZN1?FQi`{_WxVB{xalO zxBe9CLkj6%x9biY&R_7~kbWA(M{P;*KfpboZfX5VA^i__f4On4e4(FG{NvMj{n4b4 z?>FnWoV`N&k4=5@WM99M^rr;%$H4y&-TVR8he-P9S38XElKcKu-4xgF+q&hc?Gg%IQa>ujuInxX4!NgwgQy!Z0l{i)H0^h>Dz#6f&C>Ert>wtznD?zQhbwR8Qaq5dr* z{Uq?;kbc;ILWhbozrk}kAC2kN&p*GELO<{yV0e8h>0{pV^GVHb@Xzm>^ixSc7+*>H zXup@<``{C~@Gzy z-}lqBeh=Tv$P3dCd|#t&-$$R%)z1X|+j8n><_F(@tLM^Gj{^WDCre-+tjaPRc7 zetZ&&Pt=L`&+soSUrGNt0+x*!o_oK_XiNT2A$=XhN0a~fe!P0m`QHGBgYEUSzxLf% z*!l-c`f-u|OZxSxVYhAh={UcBR*-%o=?DFfq`!vz->TsmH~Q^2h5tc(ko|D}89Mks zww8V@x%&B0e*aTR`bN+X`yY%$po=Zi$5&iG)c0S#=f){Xpl?vV)PAvk5<1YuHlq0V zeW=v<@h>6$w8;2N`esLG>CVN6-=Aw=Db>%I-oFzq;O)zzeZ5ZYi`GB<28Y8f8D6+- zi;Hvm=pQW2FWDeId7RdL+SgqD$2?yC|M)@IchfH3_0U{=)aNel5#kf-Z{_sD`}?9k zogg1yzTINK{*;owTAJNIhu3$aKKcKB>!CgT^3|jt3HmDN|3!WBzt5(d<-WiD=lPfP zwV)r?e^H<6=RJ2%Ve1EC(vJmw8`OVE|1B!#ORs!6_kPj5|7E0a1pUzeZBbu>?e66N zr^lE7;>X`0{+)&XKj_~i{io@~|3|mGX8HQ%h>xT{n#Rx64mKe_1NYVWGywgkdiP=M z{6+eSq#w+W)f4pb{i)w3uR3W%`=$0}==_@m@z>P8!s`osuPXHaeoCl(cglwK;TRuI zA^+1N{g?Eyey`^Z!*kcCbv5~)lK;`^ynGG%hZ$~uz|i`Cd=D%1AL$1V-0X9||F`77 z4dP=FpP>FjC)A%v34<&4dB88<3e=y#fAHb>MAC0Y<$l}ikDTNCpCbN&|IiQHFLdyK zY#Y-Lb5qN`eEmw&SIdI_v%c$}Lw)E#7u&Anf9vlnNBiwd&7||M6rZ5|O8U4y?cHb4 zUAg*$`FVru_t1ZGOdsXuugo-;9~vgZ?fjOyf3^9==H*;`EL|U!kpFQPUO)5T#jbuT znqQLi%Lur*?X9`z3+l!=Kh~o4Col2!=Nj=JwwH75gTMB_l=Me5efO9R{R7Q!7}8IL z_^T6Ke00TM>m&YO>`-yxdi_7|k5GIn!uc`sKRo|R@qzxNkI&1^pXBvRNnZ=)i}$1I zkN(>Kh~l$*=Lxyzzv>!_zh3UfRrvJ}%Dx4xN^LnbWtVZ^{28(AT6N_WzRqn&R{6y7uSh^i$~5_%ja1pN91DeP~VN zPe~v3f3vOo*URZ+{29OC;u{C+|1Ig``^%cv*Gc*`yi)JAKJbuS|AYAxP4y=V+wV3m z-r@QaNgw?~^!_PF<@$g04;@I~2JxqGs__1)q>uFbulV(dT>q0${}Ypb8t7~CKkT2O z1N+#beck%dv$^N*^6jgP^wsj9|0fXN|J5}9k@PV?w%tBsF7(fjhV+v#{-htCA0>TU zHw|6gtF?cADMx%H{owo}>F+@PoKb7f=l%0zLi$kAPt%WYkMDcGAD=1E z@0xvn3F9N_SJI0Fw*Ka;7josRss32f*Ma|*{15x*gN5*{pcKh~YLZb!fVM5LceFZ1JHhVl*khkjVTl0LpKY=3FH z;r#%b;uBMR)QaHz+mQO7pnssppkY40#rlmkzun)|FJD9cN1;BEW-N_wX?-Bw2FdH< zM|=8lN2gCO*-*Z8eUZ}jg%0#J`Hy*3%pXenrKI0@;Rkbb`Z2}FQhee--;jRzd}|^7 zL+AEBB&TmkKl+mT=Rn^I@t5=wpNA%PXq(edNZ*it5{#eKw$v_WxcOT{_eTopH(N7& zbWY!reoFdrc>PHF$*ZJK&(BKwxPQ91|79)x`d?1%zb5G;{gvlCF7(e|Q%FAz^ey=xp5LL9w@*K?uIb~;?mFF%k41cn z>>nikoyks%Q=9ko<5L0uCHt^gr8C{}Y_wp%caj&u^Z5 z-KkId@u?*Js5|ff!H50l?)XQr1^wl2<8$Blshd*$*Izk5ld%4i|BC9rrux4}po`rt z=={>V-um@d-un&I2X1^77wNyG--5=6<*ORJ#|=eCnOuk`CrDe3D#-w5>wI-$O%g!cE}{fV!y5&u9Re0-2Q ze;HaokLz^&A6v{14Ef;OIXV3l>mLxG7&Qz8ZG-teNk5{)C-*sR_WJsnzy69zzcQE~ zgO%|5OVZZ_blCg5VY&LRmeRPN>c0u%V=4aO`LU3G-HP!?=kz1eS6@^63iQ?X)IS8{ zlS2Bd`<=Go{S}(@W71E9`mdqim*&T4eUYS3-J2RYwC;xaAIuMzQT%P_KMEi?zexHK z9e?Sg$M5f#uOae`bx6ZTx%z3TewLHI`jYq02Js2{XXqe%*kb;q`OSj| z`u#&f`ms>|!~R*)N4vgm>KOL?^%T-iB>kX&ll1qdjC|2yMNhwfu%sUa@v%aDpo6&N zx70zjt@YF!e*auS`a00hb3y%4(gYKw-@faPFZlkah<~WxNI3rr`fpL-7Wbc)`~Fnj znA(>``wiw-HS}rxY3Dn8t@0V;KcK(to6co9eM9=uO2?(a_|}kq^ahPTX?|GJKb!J( z=A<1v`SGu$_@qVFA4$KA%J=o>FW%5UV17VVxPH_G@weoEIR0!T#J@F#>!_x0-r<*T z3F#++zG|FZzR=;(SE`Z{9vQgHtPTA$o=>^ko&S;^+2=3&mAijr-*)!sHA|tqYC$RY z);ncWzkiF!|B@^C`|%(Up1&mh4g`GCbj9~M{}ZY|hU$+E;-e`(;rXkO{=gwsa_hV5 zTGCHZKLdS(_y^}NNq;c;-*?%Y?Q;4l>FaN({s-ev3;%=buR{6HZNPb7U>{-9p1xa1VSeU(!As;~I@1?3yoe@P$pXMDqwF6;fzkAF1j zM}mHMew6f){^6K!NBHfl1L^BPUsHT+aDIeNK7aHB^XgAMF|db!evIM2(7wX+qojWj z*?FbTj|2Spmyv!f=?CXWN&gqRKppY(dma7w8|Vk|LH@)0r`?7A4fTIglLlk__>_~r z5%k0B3&a8TvF%0I9m98=@w~5}kbWw~Czv0W^nWBn_qYCZnjiluq@M`>htF@~eZue? zTYO(^`Jiu;T>Fiv{p#ATe~!-N{j;I^nY>KTzsz;*S<-)w3V!0SGe&MGU(&ZI-yaWR zLnll6(WkUNfzI!e{udPgiT!6C@7JFS(zjB4sD0u7f}}r$^lSXSbX&iCQ}`dm2XPJC zS6loe*#1WQttSt-+t;r|`3m|`iCf>L>HUF{KECgkF6p~+L;2GAH=*)P!}#n-{qw0# zU(Is+I`BKcOYv#ga{B##{Zt>i^MLxgxc*tvM|!Pw-!$|4&l1v)0)0*Xhy5pX@_yq7 z%|EO;yWaxe|A_QcA^zd}8zueP)Gzfv{>EA!`r0{XZQ42)4NXYSyRPvwnPH(l0G? z{DyhpKwia^u;{an59aEBO#P4g*41kh#K%&6!ttA=-;ngp(8sRy>rWZtAI2vlyK`Ot ziuZ>|`bdAg>lv^6i`8t02mP0@EpN6cRbI%0m0D|7Y7Q29L&_Z%_ThaqkR# z+4tX)ess1_{{#Oe{c_SjXY$#X`}!569~Y^Atl&Sc%SQA+Gq=8LbVBh-5&s}QR)`P2 z#}JxHDdG2;H`n*uZzbs`g8zCGy1skgwFgOmBI$3};_5$g?HB8>)Fw1OS($x)iQXZ7 zT7Otb|APfvZsqI8q@RZV@8tXq*B?syi2tKKY;OKD-~X$R-1)IXk^P&bUq zeX^zUjj4ZAL3}j%ANFsB^cQb_>dahxQqs4iuLFHU`r-P$Li%L~?3;VOFJHdt0$09i z-!^P~NZD1E=4b4}zpg*9`^g8Nu;&X(DE@KazlHz7^%rztAKU-XkAZUrkM#S`i1ed# zg#IBI|4aHOlm1R8EPdPWA4=iBq#yJ@l72+}&+c1K-LQTS^GllaO%NZ|#Kk*2zd#3Z z!PZd!{K}bE)bZ z+Ath!HSLe;Kl#MoUVGIIQ`>>*X!l$8`4+bWcSbJ5c0oB{gr*| zoaO7Mq#uX#OO#*T-s#&S^_TzAW|*(9H*@icduGQ+*QNF6FBTV{2D96(^z{?cPXzsV z1l>P+sW|-~u4>!S*H?9@|CIEHkpD&MpK#)BJNf!C=|_To`iwjOs%gdfKdI_|Gkkpu z|Aqb`t>)ezqKnjT(6I4~zJ9d1i;orbVJ3Uo4Ki)eETw_9|`qe$1W~r zdU5e7dwWnPUq6NZx!LtorLKI{%f;!x_~oIwM_}{*>n*7M3;L!F#lJ}X*LEG9JC)`2 zqwkzwvDCkHq35TH)IVY8P(V zu=9n!|1s%DLVWC1PG1+PfAM3lAMfiMioX`>XZZg1Lg$w{d#rlW*SCm|;J?1Z#YN5d z>-gZlHHfD{-@`<^3ksp(5H;m-+KM{!TWwkIq4fo|01Vv3h3MQLD}%P zXWNSP+x+-8Dsg-woWB(H3;NZ+_TM^nwRN4Hp7!+(>BqwPT~oa`Me2XD`B@vzU%38C zNk5hRCtX{l{(IG5`quYf*QNLf@yC0M6g}T9)lbA{+Br`R@bweYw}L*tE2E3l|9bZA zd;0pSp7TEy^uzU~lK)5_IDVhpBf|OhKMB>(GU57B1@E_q&Uy{@r)h6Vo6kD0|C#Tf zWAZFP%s ztlyyQsFU-xgYduv^ldqg`Q|CHhr1@VEtYU<*z3+QVCK02z;DLH-ApGuUk zP(P!SX?#xeSMW1$pMD^{?v{@|lhaRWeU$pxU8hDu{Nq!czA2!u>H2h3)0->T>*vci zUg-Lt=)COm)hlUyPS4N6&(MEO31ja3BzGq-ADf9B&KZRO%0 z3-M2ezuT)=ki6lJLP$OL;8uJZ=ZGgrhvX7|DS9>=YpJmOz}~xT)Rxd`q|W_ zD|-G#(ep2&|8)PT*;h$PPT!Eeq4hs$psz_k?dAGsQ$Qd7zczm4wK@HS^keeh1m$Z; zKN{z*kIbCE?tk!Jk!@bzDfg8C;bE&Lxu_fP5mxD+3|UNrZ&`=y;~<>tpy z(l15-aDLE!cXs}U^H-9-*`Th}DJP9Qc>T}1Y6bN>-&6Sp@zJCo&fiMF%CK7O#|zY5k*O7YR8zv#nmYuEqG_n$G!H_)fURUE8Oko1v$@S4)6{r_eBsKH?Me3iKSL8oBl75$6)@|eKr=*`0 zsh^wt&H8IkiF;oA75n~aCFxfP&NF~dhKH6`n54|YxpLUCm5A0JmfGab{y`Kl^@H=eqWVbkrkF-ycSLdjgOS z9^06H;CRFf$0NOvzInx!7j&_O9^!y>lo!(T@d?Tu@xk%nvF$`Z;3srK|06msj9Y6; z$MLkA-)wCEW3mMQVL0@&Q2ZtTkw3&4`iLjek-XVL1mGT5pRtQAIOrf z3*?pLe=^<02X>(!rb9pdDSNyk`5)?p`l0{n8k)}yGVs6hKfcM$M+fpMq6EYN|2HqW z`BS9Bf9N0`@rfVUxbcz7H}oHVsz$ti!cVh3Pe*+9b}k+H$M%1vZ~pW5^i5;#C;Yc> z@pSlaC>?%dEBfDx>p(w#hPMmos}6t9e|>zmz9t>iAL!d@e@{Q6_s>8F{@We6UFfSF zv-QLFi~6IVb;o0z41MfF7yF1a;*KrS;V1N?J>Bl2b zS4(^5)(_|XH}HQVpZ`R@v3>*hX_NVMzfjQsXonA``T7?A7tqhob1ZQBae21?ryUmE zcJLWlld4^hY+BP|epjq#r#ZlrP=?!aCn*xzpFT zXZ!y~{9O}Y-;#bJ)Xx<6zpxHvh0{+3{a#J?y2IC36)yhKquKr=E?5VhlD@ek+yC1a zzmt2uEMLAF`UhvXU+80y(o(oxT z8@|4UzEHk-eOjk%zH<8U*lhnt+<)2^zP|d<#Xl*ak9ErN*G^xJ%hn%td&k>-eNFml zA$_b34fKWjiTGfhZ}g4R*LP+6fBdW!ulo9y^y32c2kU&*w@yD5 z^y}Adx7^oPA5s5bp#EbWWlH+y?ri@jj9B-gudhizDNsML4$*$+{EzO**1z|`S=agc z2Kt5kr*())rPH^9{`eLxpYruB^b5ov>jcdzryt*&?SJ#T57xfE`k4Cv0{U1d7=Q2d zRg$eA-8q=GUrqW^+rRFAFh0>gIQ>M>U-fad?R@_Y^n>$@?c&adsQ(y$Mn5`zeP6c! zjXr-g_kOK>|7H=N0`&*$1l3PYKNa*RUsL&#udilN{Vxz7tb#nqEzmz;osnMa z^b;p-dHj|%vYbw<&zPG3Km?SJR{R`B>EK85Nh#{a)L{Z!Du_qFC%`Tncf z)c+LHr*$GJ>6?eL{U3hyk9+(28u~(fu>J(k@z~#;|Ix&3{a!zh$bJ7S-#-}AkA>@_ zygoh0ldN<4R?xqx|J&#L`WE^^`+`3DH}i+nj~~wVzf*Eu?)xBl{}tV5i5|;tU(m-o z%2?6-@FUs!pY&hS)7RIepA?7>)-mZSPCp6s%cw&M?>}N*r#1Z_^R?)IFdvEgoDuya zoNVbt={OEN^f2!OJOj}70>HiOJZyvZq_5S})Wowhtq9{`lsq|`5 zBn(Pun`n`!qfMKl4T&acqolNmVp?dilP$@#646jGtxo%<9jg`(N0u2K@n_kuPi)(BJLraL}I2)u56VH_@OS9Q7s|KWjkmjM@6fTI-UKy&K{+A)$1WeAQ9eHV z*7vc$_Rw!|5Mrzd;g>V$K}iaQu$o} z3SR&3Fpjw}^FZ|b`I?55ajtGGw+S~B+>NnpyzZxjLsj|VTE#874Czi<1x<-bqyKtkpBr1E_# zrxR@-QTfnOPUI-RN3%D}*Y_*sXV{18`6w|!U4NKO+Xu9+gnyTM?p>@<`H@WdsNWCX zA9ujk`n?DBI|b#BRr#s$mhvAQqw*6)N=Nwt{T+S~k)L7rwk|(^Deb?vf}UR;s`kGR zZJ$v2{zGd2d(!^Lj`AyAx~6>nqEh+QsC@qcRepx;k5&6GW3znk?c(}P8t<^PUcOJ| zN7Gdv8q@Xxl`oz#%NLIFpB?-04SM-y$Pbl2g0_#S{A8+Ge&Q(KuYCJqdiepBFDO5o zX#0f9k55$3r6d3Tg5vxf5*%}nUVe!Er}8^t`$j7N;v}>D2!BVzp@{Z5wZr@`^!6E{ z{9)AoY5RoAk2ab4kxcn$pIw?9@T9)~F_j-}QRUQFNbSEF?f)>P$J9Op`n$FJrFr-x zgNB`@kDpVp|5Sb-+CHN4hc#5=8_JKF^0EI5I($&3?|-$Gs(&RjRQt@Z|FkYl&_L;H zY5%=xd1@`q9R z3FW6TZ7(OQ^1bKH^6`7~R`DL@)9*KbeahDNJMNDtKQWbGZL%5%Mo{@dYt_G?qdZ(k z$7e+B|K{7CZn$;-OYL(Cm0w2XZ=&)eDjzz^@t5Scf7I{G^=hrr>o@jQ{mQATe|4hm z<2%%IeLmH%Pvb+xl#lUY;%%lA?K^Q!zlDF0MdelSiQUj*%c z%#@Gzv(H`=Zr$2`?o2R$rt;XKK9Umhq-+M2=ezE^E=X}0d-~W)x_g_)h zR~ysz0m_e*FO)Bs^3gue|7hOLTiZ`*{uWXBaR=3pM$q=r>1zMiK266*+W*8+{w)(` zm9Gz9Dt`)+jlhcBWeF7{*H!85&M7d+vCcAKd3amRipPW#I>sY z8q1XbgvuY*L+yXHOda0?`ny%Uhw|6XKJ_Vm{{@vV$EfoA(DuUF~Ov{X0*U54}|0^8EV6^_!*9hpV@~zcwhQ{uR^y_oVV0)Aj+C4;|%~ z)^mqI5&d`jmJ{dd{dWqLKa9#BLFGqOK6Dg^^``L|5&8dTREtNq=BG6ONvQlORQ@I^ zKcVuWqa3_Xi_eG{AL=EQ-rYJr+!0ZJQYt^C@;kjx`K9;oprf1!e}_O3`#<{HszbN# z|9v?AuBGz5?Wp}@`!1?}d)`X@i`tLG->veo|2;oD_%?lf^FOBZ(^J&=S>pq>|Ivl2 zd~ur^-z3^U{oN|QH2)tvWqSGeU&>Dzm7iQp?Vq+!sQj45XOtf^<)i%!eD{$X^!5`_ z`I5@du>D19|1tifeDA~j_K*AwTw3*BJwGAJr~EXg?E@-5w(=vG^0EIzR$p8G{{CPb zzXX-zOOK+b7)2{9kJwFkZ zFR1*+w0%V7`&RjaDIfd4>oJpuZ{7d>Fuuj})O!&AK-CUM(DunyYX8d?sPU~QwV%@S zK-T_ae*RLIf6CAAO6Om=kC<++@~{c}f1@fNI*RjYy?cB{#Qw)Un#|Z*erbHJ_L*w` z{!J?Xov>d1R5kyP_f)taP*+e4mS0AI0XQytcFai14_><`Mf-$#Z&Tlc8|=qQhi zZRroFM|=;Go{%6MAF%9(4N1 zhK&9K4!(%;kpEhIW3@UfrJkx!ieqC74p^apH@JfmFf7kK!51#O4VvGsWheRhSA zzJT!t-^b@_B!J`7XXFR_h4-UzJVZU9JTAfqc=#SZbA0?AeB|$coB#TjpDOfO9+3Zj zW<>9i!awRO@zrxl@bANjBX**{qr4LTOEsQhTt*)7cSLLlOtM+MNB*CVzrz^5`0D>3 zel;=xAMhnDen|U?za#IcclbxY`A_|GeDSsE|3Bu_^Ns&0pUb~=@R0}P4gTd^HNXGA z<%@5M{d4@_>Hp>YgK2+wUK0MQ(f4e z{S2u9d>`d;5qZ4(tv`R*I=|c-=by5c8h-@cU-!RL^%2qib$O8bEC;CTV0ccTEq#yU z**f~sVK07i|5pA!g6@9>wBAm9mOB56sobQgs$YrEbJY1$ME9{5{vYyxYWCK4Iv?x( z_)n|%oBi*VU++Z4Pi~{<>1V6`1HUc4XB%Zc!~b3vO97oar(C>Wu z0>*jhjV&GJ3DUXX(;v`(@jc8Rp`)MLI`+@jkyq#_*N$cXWj^u&emt7`jSZ&HS5U-u z_?n$xpZ;L$$h)NH)lg1|@6$RODA$gCNWgaZyUp?G54H}zt#_jD<2oD4wPQpA_^4;h z-=TAyl25wcfbS!(*e{!l&+w1-3LWL3eI>M>6Lhp2oTp)X_{L}K2g-i%ZWFMdC?8)y{eh3qK79dvaL~>%UJ3dh=1cT(n}F>x-r@`RT!jRD z_N~wLtD{^Y#sT*`6tS$K?ULaDA$hm{(^)3NBMTSzO{as zPX&v$YP`kv@Mm-Jnd5^8zI{Flf5{Q~=bis4ANvO${3CDBu^+aM{RmD}`+@HxAIZl` zhhIDXzvlZdt8v8U;xqhicxB**t@EGi_|l$n0-rv|(bckBI$8eWHBCp7bA-4;{x1 z>{m7V1NI9%_-;#oN1jn0@`3VDJ|gxH?FSruw*C7I2YHE~Rs9is>?hhOxQO^WzF&p@ zfOdra_)qssPE+Fz%ENx4Ja7?F?gw99xZBq8r?h^yUz48Sd|aJhm2ISP<_Oi^N}o{> zMLCns$LYPCPT0=+9zKHqUE`MJ=ieoMKzx5Bo!?P80r96W<%-!RKV!ZJzEA&o@8SAy zY`wo(`h5qV&L`v&b$(yAN%>EXRQ_?lG?MBw>McG~eP6;qZ3mtm`;ai^`LWk-^>LDyqCG2g>>sQ(LYA9jXO|8)I3qW2f3P&rYc{NppqK}>H@$4k7|kU99M zx8e1Fp1GA@I{wOfbp30NYJVu-j^UrwFRVX6M?XZ2j!@Sx@OAL3&T246=X>=PKX&j_ zh7TQFM6tlUF9!ZS&mUC2ep<=DPkfoF`o#X)G2G1fCmmcw@tpeIQIrGz`YYC!|9(P= zAHe_1#raPeK6G#qy{7cLS+oP-zw*lT^5<_#d;$Lse)t#TpLB2$Bm6G2#h=(G`c>yg z;LmjUXZR_{|24n-+@#Sq}dUKV|s% z-DkV~{hS;-M(0c73zz@D8ULiiH=@@m-~U}3j(thzdxz5aGGJNRZB4WKeyZ$R5R-t_To|1n- ze1CRv`wPANb*-U;izsM4Jez<1=rO13{0RAXw7-<$LkAZz*gn7hpXom06P+IuU%32l z$M`25T*ROT{jRb#{(Ujyf%5wgrTizTf0uuTpE7(ojo#0)_`i-C-9+b0)S;2?-zUERv19z-f$>i|xQKFk ze*Vw<;qmhGk5c^y#1{^J%J89si|D_UKmJ@+<74CaD~KOE_+bUcKk48idS}r2gVp{z zR^9n3-G7AqyXJokKjrv)<{y9V>%6?P&X0*NUH&UF{z->##GqOJ{P&4ItIOXXEY*Jk zzRN$uPdR?OeE&1&&n|yIxWt#p|FP=+C;F=$!%B>Q(%~Bs>y@G$%s)F{^-THuEhWBp znCk!jC&m3QW%$s+Mf6V3&;KrOesZtQ_rZ6~e=9ToNe36Pv@W~V{<9iYAJO>%@rBDj z!%rE$*eCz^_s9u@FV^`2e3$yuDBSQY?7SBIYh7TQF#N^NX z@n@%ABg)rbEVaKF{vG^qN5((t;3A3>&G{nQe~UL;8pq#+__2eZGJNRZBF3lW^M9Os z?cch8Nqp(xhdVL;Ne34(I6t31=B+zk)%o7x)c;>`)IY;d8NTS6&#yjs{KGomC%$m- z!<`xbq{BC2^m2ato4j#|k^g}Bv8(?x{FLL*&F7z8?fvrg(M#=Lfba6Z3*(=3_(n_^ z{?LUFH`VzO@uh>GGJNRZA||iq`=9&NlJfP>Oa5cx`}2z1U$`sdpLB2$lQ;AElWyO4 zna)p;e+NHh_|U;cjM9AmPCwpL{`-b-l@lQIqh~Dyi{-^b3m#>dh;(JHX z{NLrD;in8gVfcH!F#brL?-O4*_~CAhf70O_F?m1Vf1@q?37sDh-+#5Z{iO^aI=G0* z%6$I7uQq?6^9B67>c1M}pLB2$vEH~n|J!@XL*>uEmFho2{kz6LhMzKgZ&kkkX%`-~ zlg^KcAG!SR&iE%Cz7YeuUt#imTGv4fv7eCXgJVm)@7U;XUGeRRG={vG^q z55_;~;38r@W1Bzn=yk^Y+iR%$f9z`i3_oS~_Bwf(f7N~K7*F@_6JLB*eEtzuXZ({6 z--t=8{Q38BjaHTazD=q92k`%zqyIDfl;I2O`C$0()v#|HoiD(DvzQ<5$@nK7z7ga3 z>iKxP{vTd+rg8ok5nnp^DZ_^jE@F`6^T*EkXAj+fOnm<>hyT48|D=P9C>j1Q{Z9Hq z=O@G$4t~n;p@WMUoRYu3cehOg%I`my+Mh)IJNV(=jDOO>MU)@pU;jFL@+G5nzDK{$ zCLR2g;X?-(F}f`O{PT%{E6U&BF8Rmr!+DLY>mO~*<43p;EI%If93bTo4bE)p8pd+ zcKK)cDZ`g-^8Md9t!erCl_mcY`FHu>kMU1Bd?O})KEM64M~(LHmC^aX%Rj?U8Gdw7 zKEL{Y7aHS_5B_||_+OLpPda=f26gkVKRz?)@Kn!#Kz!-)&+t=*A9?xwy;h%RT>lX8 z@0$PAV*Ha1--yY&{PB0pUk^{z{YT)t=06NSW%yC2{Nw*oE3Y>0|Hk0I;i&)p8ULii zH==)jKL5#EzdW$qKYl+nA--_5zm(xa2NzLx%y0kS+|{IfeU$&{|KPjE{{tBRq=SoS zuVaSs|AOa-_0sv?QL6t(4t~n;p@WO)(K=r^jDr8xoc_Mf_lX}n_+f3vKk48i+UuZ! z-|f~1%YR?7l>dPEiG!aqeCXgJ+Uul&-+jpqzvz5HeCgnaKI5Nsa1rfw)WARZrCP@L zAA#>`{|rB6`0=Rx>%TX2dD86v#P<_N|38rNPda=f$}ai+f6(wN%HMx1)qg^K;ozqX zA3C^*;-Y+hv$=<_*7=h7iR=9TAjUuG;35X&^6$T&*LH_LbiQ}A>i^zx*8CeC7xQ0+ zpE7)}V*c^3`x(PCo$nLhcksi58ULiiH)7m9|Nd*eZdpB@9}quw)jz{e8NT;azW>gDT~mD+y<|E~Ve@Kc5#FU`OHGH~Fcu{u8{ zzHnTB2Ejq%qfzHsovdW?V4!A11xcZ)HM z;rMs-u`|r$Kk;J+KV|sP!9|RJ&L4kAUiwJ+@4J=ypCG<;@Wc9yf6~E4wATTI|EGH_ zK0xP3#19HUB@9@lQIqh|!Muy>G%cFj>i)gviZ6dG=7(jBf70O_ zQI5}_e_nOvq~pu^IRB8~d-=a#i}F&2pE3NTS-$_{FS+$Y-G9`Q>i<)R|DzcHq+>r3 zx%c0OjKAw+o$t4z`v0t$pECT6;dAf5^_ahSg28V?^}nY0{!4f?`;9R81G{F4sfh{2Kh`~f|d)z|sn8Pxt9{FLEm z3_sbNpZ`(ej^_10;`^%|{u?p=Nr!Jlu_d4X^??2jbpOGbRR6yf^HYYOG5lm={_$tr z*^}4n{I~=0*A?@_;~4*>!*?k%@1Ne-@!LZT{&|WYJNPNX&lrC4Prm7wG(0kpJ(C`6EM*& zh7cT$J82_ZhH)0&*^FQg<+c^J{cPqYh`DgeU!;hHt z4{n+B@FLy6H(2rG^^WnsIpd#n_(tT`Kd7~At@-}NeN_J&iuozS<WpE&upi<+QJj z`Ij6@{H4Y1FKog1Cmp^KgEsl|zeA@bz4iRZ4=BEH@Kc7LG5pxe_rH6;Yw3f44+$n;_v+yjM4f2aH{`J#r&`(F|x1RLJlD&t37P@%&jln)06&x4)F(XAD1{kk5Z4In=oR zmBiHkJ}TyiZ5aQg!#5(g{>D4A-x#3h-+z|;JNPNX&loF``w){@#N5q#7es~Jw zpLF;}lrQB!e_88`+n?0=lKB3|#raPee#Y>lQ}X8@$vv}b>-=CW)&CyF*WbgojDOPM z8!>8{fBi2!zRMP!FNiN4{FLEm44+&7Bzf`a3Oe5(NB$l858E;RNr!L5xPN~C8@pqj zz6Sp}YX1&?%J4IWpR~=d|7hSP=Jh|~i@hB6-=6VLI((O6`+R-_vrpS#r4`QB7&|8>>xuh`|_bIR~DhA*Rh{w%-eU=`TiWmj~&lngl94SNiX@P|M<=G z=RYH>e({;k7sQtie#-DOh95M}Z+}+~n`g{FyqBr{Ep{CLIxzl8xBbhR`R(twN==RX z-;(&k!A}`}#_+us`T5`R=&H}^`H$x+|FUNB_#1X){F83`_rA~1|GRx&yhZ1WSE&8h zD(0sQKV$g*OZoh?#p5sNd~Y7{s}}da@NC9E>9+r5@BH!i+pC)z*MAe@#}0nV@H2)l zy5;jLFTc2_?mv2!>fgZ+&td$NZu=K)^7);|Z#1s|Ci5x(uJeC}pD}#zg#7y7{M&Nl z`JW^q|E~KV=Q93DxBUmq`h$lrc*uPI{dL9nR~3&xDZ|egezb3X{;ywD-+2E!cti2y zZ;Scid5nM3xA9*qpa0kVE>G$0Pb?t+Cl~j>l;LL#KYAel_;>krKfa^$qs8QZjl+K@ z#y{z{e}7QE{|j&IIz{J;cZq+R!#~5%7`}IA{_*F~ReKrF-%8?32R}TY@lU$#KM3>r z!w&q)xc?n2QU0YP|0%=I7=AQ5KmT8TJ;QkaAy`WJKfgHtVQ0oa>9+s4W&ZK^uW8Re zt=E49{`%tfmoof};RjRl{U5w)VO5>)EmQvecZ>Pq1&n{vZU0fl{PB0=LC+fZ-+~XR z{$0<1GW?9;$8+-A-=P~$JzMvm5Z`x=|6LgWq}%?v^p;(LvY-#-X1Wc-tE`A6uyX zIryPq{F83`_hi2Rv7;NB&!23se#c3yaMVA;&lrAkU_QUqzLS>g`S&X*zI5=zZj67@ zZU51^`TcLzzMq@dU%=nV(f=8K#_;2F^N+u~^z5{~?%%6O`CnO_|L|hQKk2rAF*|?! zJG9<__jSIgO!?p0;h*7W3|}tDAAjDs@)4u`dsP%acKN@A@lU$#KWdimzw#^Z8_$0w z#Fq|!%J4Iee`$XEKdR2wcA>q074NG2`)eKbe<|aiblbo8bUy#Q)h(y#{A4d`f3Ei* z7=Fg_W&Zg8+QGAG>U`l-{X6*KWsHB)ZT~^%{Qh72jGYGS{HP)2{}jjdABLYXe0f2B z|G)N^XU^353Grpi;{F$2&iE(Y_Mddg=dYQw;0>Mc9ZCLM74uVupE3NnYd(M3urL0- z|A*(V1L6zE`zK*{#y{!X`0ttj{?o{1O^x#pL44_W{v>7i8N-j?%x`}+F23=0J^%4> zl>eU{{r?KaKk2sr=z@Iym`%?9+r1YX1Cl z^c#)M_s@tQJNPNX&lrAkNq+sGcKY;Nb^o$4)xU!uUd{L?-S!_}n$O>{`;UL*8Tg$j~PCEg*_Pmq~m*~$o&4nmObYi*WUx;%ZnVxKZc(%{D|RS z@ZhD!^>4o=wLjPS|Fw*N(o4SaA7=giAs_eM!N`9r#Sa|(l;LL#pId+axqd&-()oh; z!od%(WBij2+okwL{_+3#wtpDUKS!r4|A~X2GW?9=zmdQG#Ly>)8t)$^XDEK`Ii7#- z$@nL|-oDlg#{4G<6<<2|DZ|egepEAm{1xL~F@FC+5?@?Z-2cK}jDON? z|H8}9|EH5XZqVDGcNXP;yW;$(3_oM|-1_$uD@5%L{sqLp+~NOv#y{!X_^*&(|9!sv zz&QRU7b$*pV)6CIl;LL#-yf7;{}=32&$$2NT}{?~0@W6b{&@UJQEe<{PyIDVPhU+fp&e|_k? z8pic!34X=m@h7~Q@lQH9h@we8|JmQSn9sjlM*VMxVt&f-Glm~+$zOl{!+yiB*XuvH zT=D&?#r&{0G%<@5jCy~hK(|M&{Zzk?t4 zVf>R0-=%nF{`Eh@z1@%&$WHRZo|asLbZGX6;~ z`KJH)59af4eyQFl!+#ITzk{DL{EXozSLO2$eD@IJ{6k(#`FG4e!dn>sq}%?3>iNgt zyAN2syY4@_j`$Ud`(MiNGln0PU+32TVf_1IY%}BillTV8f30GE*pKl~x`z7qzoK*g z`R|}_f32bWPlzv0a2)>`e#Y>*_1C{!G0Ir~A?d69#}0mYE90MZ+dsGd`ff)yFs}bg z;!6iVW%wDx=hk08@Y_EBuD{_=xc1-nk@Qpky{5(a5BoFzNw@uT>#xr|sm>C;{-gfX z{vG_3;b#n=TYvqon}+VE^JC)2yExka0LDM*wtsH@^@VfdPjr5AoAMvH{4@NF;dAS+ zcdmSa@%%#)DZX&;b$D5S^xUdR`;~g`Q9k<@8E}bF#bum{fp!C>%Z5< z^A6Yf{u5OH1B=^V%J4IWA2rBt{}<1{%Q*iN#Fq|!IEe92y6rzWET4ZxtB3z>|2Y1} z@bAcf%J4IWFW=42|EE7xF`oYmo>cjl4t{tiUDH}Fpm1)KE?enyo>Qqy6rzXJiq?yJoR@=ogY7^_=(Fu!_OE#xBmD) zo5duZAB8qWlNLRQ|D!dO-K{c7UNL)%O$PccSg^XFKjf!lDOzA7%JoMgCtPKU7XM zLh(!Iv2;Hb{BX3Y|F!V%;D^MoZ0#8CuUCUUMzve$$eU;BW%PaVt@{2>^tmz0S)qL4 zV_W*qju0q<1Ag*@YIo4Vk5<{qa#(y_nTKa^Xafbsx(uY^7iqYdyq@Wn8-pQ!(kzK_4RrO(KF zX+NlcLx(@)-L8L>cgc0N2kP?=>C^iUSD$EaLSz-f2hDuqkI<11M67>|2!8zihNE=8 zcObq0@vYjp@lQIqh**Ec=64ynxcvBA z`u&dpe3yTQpE7)`e_``qyLw7xoiB**FL(GK&iE%Cz7g^MGa~Z8&l|O_()khbg@d0m zeCXgJf@}M~(tpfYelYIV5{?bQuen9-#(f(3~4;@^@h~9s({qL~vPcQ3y0lv%s zV~l^&!A11W%*{A)~n>EMSW82_Y$ zix_>N=3zF!)sUZ!=N}T{`yUjyzm(xa2Nw~~f7<-BAMR+bKZE+8mjC>5={Wy5$-%ug9UbZ`+%&;MEZzvQ8%#_zvG;Ah3{FC4}ACmmcw@rRn1+x|!2 z|N8~H{}_B%`)Bwm!w>FI&p+Ax{o0?tQRgSb7b_k9pJ4ox4&R9KEOj1l^Itl&(v>=2 z!oP!`GJNRZB8r3a`M-ShfU*9hSBLtagC9Q0_$M7)#N-fl{oD4xckdaCb^ku`g`@qY z3?DkUhckok&4;@@Y@a^{h!OPu;>--q`pWzt)$1?s&2Nw~1`}ou7zF&>&f0FpZ!A}`J zbZ`;DN5t``*14yDto!%tss0x`_~AIlKk48imhL}W_22xkuXfh?0r91SpE7*t;39%= z*Z<@Nt&HnG5%GP;`A7I1-|Cso~!A}`JbZ`;DxBc()K+B5^ zej}Ry{!o1U4WC#3as3{#6QkqzpKbm%Lu>D?^AqCxKNj;-hLbTm_;&vr*r%Ft{X0IM zjz125_yXgf(eeA!w*Nm~U2IlW(y4;oYdclm!&`A7Rg z6r|%iNh#9rZ(|;a@u&UuUrg8e3GtYm2YHr^G?KLzJYK+8zEw^^f;}QU6O9bTqDi3GiM1Co=7ybYM%7_;&vP z`1tGDy8i_Azq+{nrNlwIN6Z)R&kcDZ|MaJ!wYcuQmT#zO0Hl{u4iT@WUC5e?|x29)D+kbCOa2g80%^ z|HQ#@4^fhCk3Zn!J|K>NE3de`rJnzo_{p7)=bvUO|KK7D(mB2;Q`>>xeOCV&IzI}i z{&yxAHj4l?a@yF(W5xn`c&KJa&4t~mTGDZg<5&pYX z_SWhA2z=M?KfTQOXLNAw{&(=BR~o;+6%*gDS=|3p;-KCUCFyqkgKy{m=34u_s{0RG zQ~!7H!@0^oxQK#uj*tC7{+EneV?2KlgYWqLfs{BH_YgBimyfFP56@wM|9$lj&FfF# zuPvT`hOaR7&*-m?cf0uva zz&D~KeH;J8xBXAN>vH4zOK>u^f5-2yg$d)I(Sxz-{L}7#4-H%Xf$m>`pE~A0#DQ-_ zNxJPH{G_3J4iV$e?XPa`q4R?_H2$wIZhzrx%0IY>f^?e?uATp*2kmWK{}jZJ9pi6G z9E|&j8Ka9E^2eVW7amqm_a6~oI{4x1O#L%@(j@=KA{uy0v$mb6k_q2Kcy{+;uZ!A9lOc_qb=z@GB!he%}78}Q~N)~ ztp8S<-#JkC9}quw{QgABa56?O@t2wWeJY_t=Kl;QV|4jMKL3ffWybH{1ZPwGcllq& z_-AzaWIliBsa4GLU*by#KV>)>qs!6x{LL-iGUngjIm*9(uA}~!GyWM}j>+fmRH6M# zdi@LH#}0nVa56@haX!D}F)KFf`~?2bDL(#$?=$`x-8(9O{(1FrwQA~oc`n*tF+XKE z8KcXm^8HsisLm{%ADpN7(&hgH#y_Jc&GW~f?}vP6KL1O6|6GTEhLbUR@{c<1VI0Kx z|9Af*m+Af`@r8pQe#rP|bnxxt-*cO;|48S1ov8jD{FFEt_Yo!O_V^FJ?Z5HW4Vvlv zg!t0I4_7e$8C^cD+Mn%zdi(jt`*)J~{&|l2XE+(7gKr=IU)%lTA-aF>e3gH3o@4x5 z$@ph<`AmNQ>o{=fLpooS_zwRJCu4N^Y(9V1jn8#7_?@Z$yZmR2e@2&+ssCBe-=yEp zH17XK#P>TD=RajQ8KZ-5x4&_3XQ%7_6XFX8Km3UC&**Y&e*Qmvx#iP3-@kzRzk{DL zoQ%=sxO{%ok6Qox{wda9jfn4`U!4E&W5z$D%jfd>uP?4{u7BBu{JZ);!^s$3KA+DY z)1i;S7sQv2`FHpUg|{5wZXH|{@3 z@GmGHf5J~0|BN2ARLB41P4oWSnl(S1sQdT2QvG)+Zht9paNI+bq}#_o@T1So^WPu8 zA2~|r$HW&d|DQ4b868~v`HNlZ{(hUzPvGCdPZ>_e=-}Jq-<~zQUaa%|izxpG7oUHH zpELd$J-8|V`ftmlCUw{O0r91SpE8_`(Ivw_e!+C({R=^S(Y3h!g{v6)>qx-${`5$g-(n{yY#P{ns>R&Sc89ib6$1j?3fX+{le+NHhI2ogh zKKcF+*kiIW|MG=u|9)df{eQvuXY{zQ;@kbN<_q;&>iz}sg@d0moQ%=qW9a+TV#}F&{{3z={(bK_{(Z&NKcmZA^4njxo2wb;9|8C-{|qN%^r&Ax|H`EHbltxs zzI6Hjn(@!*SohM-f8SXr8tV^w7gPWHp*a63!^s#Oe7paRslU#cfBD3hj{Jw;F#Z`G ze0%)>qf1HW-^D?yZq_xzSjAY_`<uxjqKk@zVi`!qy@TG%qk3U~Dyvca}*6U8k9|u4Dnek6L=ieTG zruQ3lx1N8W__2eZGJNUa+v88G-xjXa`2q2zqy2@yF#bvB{M+sC&F8>T) zy7(WP$G=ALJ;w775%GQ3`ZsGB|D<#N?eTBa?dKZjpE2=;gP$^d>EPSr-yP%H8smRL z{Mf+{*E0S|=lt8_U-f~n8Rx$e`CsE0|A>QmA7aMnNw56**Np3j|Dw0Qgas$Dw=<8a9saqI2ogt_}2ZmcT@j$o$rJ1^8Y*IpV7g$&%aN-;fyId zKOnwz`DZv8ql0gsf6f{8v+?|yB);fc-2TG#%0K2kh=O!``~x5BP^16F?VmS}|MF_; ze~$d83|~6<_Vb^w)c)ihJ^#@)itoGpZ(#hB&iS{;|DV2`X8itQOnf1V$KRAV7+_UdL^&9l^&wBmG#1|Wj$DeQ$Q~#vf^&bTJ{0Y0B(L?7a;CFM>KXFj+h#8{? zx2fZf{6O6YM*jEo=NtFmB=KVhKm3EKe?}LL)b;1!6txaJ_~#sU*qge4?^>$=y2bZj zQihW;I{49LsvUyA>xi8j=zO2}{)LY5?@z`*ql0gc|5HxtJyGWe#1{^J%5XA9msJ1u z^|$FyHTg&93*yHPez=+O&*)L4+Mmtu_s5st>--4y?`VH1!^s%kzdfIS-09VS)cG;$ z|Kj5Q7yiZgXY_>O&j{bHq4WLgsQo+gpE8_`(Sz!0{%5zpmIv;4h0YI%AG^lCEsTFg z2j8B5oHKQ%G5+~I>G->;c>GO?gLwy{Bz>Flm;BrOAF~IS>;5C~FLLz%zm)Hyh_)3G(l%e}^>ZKgzuSIN*v= zyXyRe_|m~oiGz6;q9om(e{uX{SM@zs=XrbtA zIny})`rt2f%>Nm_bnxx_FJ~O_`nS4&L44uhhr2TVN$33A^UtymYa91}6XM4Xe#-Er zgD>7S+h4<1SERasNqp(xhgBK>q;vigi{JOhJzv)Oq93)t<&OGi_|nCSynzG4w{vhtJ{7VNvW%!ce`=`+LFU$W^vb%Zzo%sIy#rY4b zG5$%n{ey2m|8l^<*Npz>4

)ipQUn;Y$bKKL7Z9_|E6*?Jv4b@kPaAez-g1pLE;5 zoT83@_V}~%#3zR7d=U}fk^hu9IPXQw7(JetfBmy!=XU4m{D}CmgCFjp{DX_wiP1}Z ztNp#U@)*N^Onm9!rwk`!bnxxt|H4`wy6gVE+g1L3*ZODGnffQ)u7B|D@!vc5U1R(g z#1{^J%J8LwZ(slZYQpPtb^j6gl^pGVPsTs#od0CGdHi2n%iB@s%YiEYvCBWhmoC0F z{*L*!vN8XVcPPGetUny?#k7A$_ZqADpWXguJrmxc`}YSC-?9E=%5XA94+iC5e?Dqt zW8?a}Ain=w@%d-CH{+kt#bWyXPg(~Z*Z-a!vWxNlT?GHG^$!_N#^~V7v(yZjRe=N*WWbbI^(KRMOpzxG~-sXE^$e(dtU zuksHrq9C2+e{Aw^3O<^p^9B4n_$kAe4nBSd81>&f6({KYi1_|S$N0Y= zFCF<$iGzNJC`q^5ANcm~KRh?!>HGEkNAU09hx;?_pLC9Ix4)B@%_`IR{@tqm`M*2b zKXK6R5i>^j{-OI{*7}3(e&6)4&JTz$UH$(6#y{z{fAGZ$bsmELU#IOC#`AX({BJ5A ze^Q1o9en%zOYAoE4c)(Y5A}ZsKdjBPe@2gfRpU>vyLtR?@b$p$biPmg*uhU3PR8gZ zehoAKZymYQV>&+|zI4rhe8xYcgCET`$G_UQ{$|cU!FTy*I2ogZpIGDX#;Jc8_kSYP zzoY+!2QvN{9elg}9rE+=1$zEt)W3tDGMtRjOML73?@ed!lIZ*d`FHTcgBbse4!(W- zIcde3+jYJqzW+h-{5xeh8KZ+QPgd7qF#ePs)A3cE@7+t|?;pkEPk1onpV7g$uRjeu z;l6`)z7PI-$N0~1GDZjAKK`y-G`Y6U4~Q=u`48(T|2Xa<3exTIAN*i@bNpNP`BY>5 zO#!|m|0%JeaKNt}|cKNT%_$Qt7?^)wt@93RB_58=gmkxf)@TG%qkH7nU zTmK%NpCJE^_7@()_$Qt9Z_PjI25pYg`Tk%!{(k7_|HQ$(2Qg!GocE(0qW|}rckW9% zKOlbW;D_}X|D@agIlkAwEYtZB_^$TP@TG%q&%c^~eN!i$FNUc6O9wx!ulytLh@BWc zX`;^i?Bn0MTHQwI{D}DepT*;EN*s(kh>~mg_YbnUH(##%m&pH$;{F#lVEi*W__B?8{O$MKrN;f2 zn=Z_@urOSUq#y_LSp6Y*g{lC56$s=|D-Y{x^8y)pe9JD(`NxI$s zIDY4Ob(-q@fcUW^|KX90e@4f+gNXUZq>;7jyJ^zyU{$Iu8Z_4ncgOB|HfBeeEM*Ei!s{R-CFMj_pJesM0M#p_G z%!9%IeAjP`>yO?;)c-#!&VR~qGDZh~8~<+~^^Kl?pZLPT507E$pLDza!MD#p9v%48 z3Y{;B9}g(bf6DNsgKwXIH`tW!uJeQ8D*v&||FKN{Gdj3|b^bm5*Sg00X99dz`)4>A zql0hHzaH4{;hl8<5%HyiA2wqAGkS?{U4OfBuO{Xo+cZccu4~Q=u z`45k0`akI$-)?{P4*c9$e?Ni$PaOV|WRcksi;jDON? z|KOt@F#fOp^`one{69kDkAt5weCgl|&wT!Jz%zCC*ZC3nuKI7nw0}nT@5-Nl@9@Ij z<8{9GD7F8;9sQr-WQ?BNq~_oLJoEm~sp%o@b-qu0;oyfSF#Z`G{KUHcdF01cE9?A# z__2eZGMtRj!MFS0`PJH;rSm27|4(uL!={XXMvsnD`M3SQcxRnzI^TOt)xU7?Q-+f< zI{3E##XtO>>in4aa#Qj7S9l`R|4Fy|znGeT|9QrrC)U*Y-Uw>{e-!gm;$YlE%osgB zA^-a0yzb9ms`Gu~OD6x|gv}WLq}%?JY0AHS|M9YDm$P+#0RNvk#(#z{9sFpEdHt_) z!)za&AA#=`^TXy$`)71yys_GqO0 zm&A`9{ICV%pV3Qv+7IwMesr8M{&*-OUyd)`R$@8GAz!MqPql5Y1u@a_AbFLWAZ+~=>{=v8B|GlgKWnO;)fBRy7*jo7q7g3PT@$KX94%b(_OV7VQijMydeo7o1 zj}S9Phi^pm|CUd*HQv7tz<1<7Jc+4)Mh90;Gw=VrF<^2x-M=8d|EJ^l&u}tE2j9N_ z{M?NlPuKYo@nc8+!;=~Rj1Ini{NLZ}e3Qw|0#@rMlbQL>(Aag zf0fSniSO@FJpQB%Cu8&y|0*>PL;pXx|Bc4`{{i@$i~C>LmhsQ%;M?Q>@^e=k$A3Y5 z;ozqXCu4N*?e&irg{^z)`HzSnJNRKc#y_KjZ?Av3f5Tel`S+7F{;zV>Kf}ow9pf(c z1NGm2#7X^i{{i@p_7}Ei{4+ZE_WW<~otM0?^9Au^2R~&v8KZ-5_x}ND*L`(Gtv8yC?tp&*%w};Xfh1?^^$hI5_SjW{e&){JHB}7}x*3(bWD{7r%cH zp2pNaqbC*A`Invl(SOV^u7CT)_gfcVe@Tghydz4|?fippAODuM{oxF~{uAQIyA|`p z(;5Ga9#2sIZT?w%957YqOX5ohKV>)>ql0f>|L^t9X~z7=8>8yqujcT72IHU6!ME%G znn5*N>i&J=$F&{fA8}Cch>~=>{!4tS2aJCgA5rsKogWcjxcr~V^ncPhzFq$pG<%?} z&i7-L|JcD#8NPJ!t@+o_bt_$_^JC&m2R{rM|D<#N?fMV;zIwgR51yj-cc7#GiGy(u zF=KRG_m{}!++)&|2r`L86AB4_-UGAiC+3l=ZmN5`1^Zt`%8&~aSu_FZudX%?e=$K-+9LKN69ma zFJ1o6X8J$r9N(UQ*X}U*E#1HOEcO3A9POVt==X>jqX+lW^=B*pAFt|uiO%=OQvTN$ z=RZ7$@lU$#KRQKS|BsrQ@4qfz|4DV79}z!x`6mv1BW8^5zeM+6tnvTts^)pFjUwBv%^azaW0>;HL~HWAqZ=s{hH=Z(XnFKO(+#@WW1we?|x29)I6ywv%!H zJ0ZTmr=$LfgL+4lq}%n+@khlY&F5cH{|7nx|M^V+C!OVYHm|=-f1~qsJ^$Ww)c#!l z8NOur662rs`x9p_IQ|En9}quw@Wakb{WE&fR`q*({x_=iFUIpnlKB2!j{0Xf8KZmc z72m%8^v$HmIQ~V?Q~ozN>i+`9KcmYTYTg-n=J@}>Z!@pa^B)sGcKK&G8KZ-5`>%e{ zUmJD4B))X{@4~cy((U#yPRzgm{^P=#U+H}B1(kn)V{!gdhA$obsE(Qc@7~_Yc>Y)r zUpn$1c4g|H(W4o3{I%Zy`R&3Bp40tD@V~dC{WF}5(ZRRt|Ec!^J@ENdfCu8&y-uQF{{8W){YwWw zW%$y;x9h*g3g3ACJ|KSVXn*0wjDONO|3NL&f81sBEZx6=e}<3qoRr~92j9N`x@2X8 z?{&T;zQ0fL_#0lr_$Qt7Z;yW!cc^-V&JQN2`j0mik3T7KkPpO+(b4Yg`akCMZi95b zAiiIxm>*us^nXSN-|qhne-3_l z8B_nHbA0>wd(*lGU+ew_@%_5R`A-?Xbnxx=ci0hi|JL~u{$1_=a;E+n9mhTU_m>|% z=tlGThsi4cevRV(mol7;(WBOC+_BF;?!D-iWxD@__`<;tyEFb79eg|g8+U4VtIn6i zmw!6ypEzjuh?4Ye+8_DHc@XA5HU3y^JpbcQrSZqn{=zF5|BNo9{QNI};P9rp|A6@Z zW`}=vw0Ob1{xDtfg@Yen#neBegKy`*{Turk_dk8&M0-V8iI=GTyZm3x_-FLs!uKW^A#^5{h zA6~<>f70#zgKy`5!70z0>)*|!_FvD@{u#bx_(^Z|+%t|t82={x8W`_i__L_}?^}HQ z341X0&*;IabpCH$f9;fXyGXBpLHyXkPZ>_e=>CxW=TD9t_nz_oO$`2);{1o#GX5DI z^Uk1|dHve*bh%kHN3&{0RJC9M3=YV*Hc7jsM1K{IT0#ue*Q0 zPUpwSzsoK!p- zbU8DB{5`G0kGtyr1MnUB4{u=nlWzM59})ep&eAXM(D{P+{+i>3L+CS-b`v+fG z_kU~FnQh$vj)?Eqa@0R@(C!d3M)zOJum7swPy1B&AA`TPm>>3G>YvfUx9fj)=Y5Ch zd`W!qU~&Fa;^4dwQIc-wzr?rlf6?SB#{AQtNAn*?{=>eEe@0LCR_A~A^Pk86^4L?l z|A6??!A}`Z#^@!!b^h_>jK_@kPXzJ({T=mx3*(>B!ME%GuYGIpru&bPe@FXEiGzAa zl%(7BU*cQ!zx(@-RnqyA_`>DCALF0VMYsI=|F!FQbN>A*wLb?xWjGn5m-trwzyI90 z*1CV6_|m}-Z)N;5I{0?|kG}O{&~P zYX*K{w7>b({$2G?9Mn6aBz>Fur~KQ;-%7i0cu405#FsArw=w=1UEG&{{pH(e#}9SB zmni?f>-`UglQFt?f;#@&`G0oP+0}KvPkiCvhmrD+ydw(I?fipppZ^{)X0J!Iv^N*C_ zWQ-o|n?L?cdS{C9{!>JJxqmS~9LV@*^b+41e_BkPH$cySOnm=!x|93F$pLDzZm-yE4XXNSlg{1XT59x-F|`2PIyXX~$T z7}x&=@%=^)|AUzNXLLOG5vAt)FLy5bWti?i0{>e_|7SQEql0gcKQ(q9)K2He#Fviz zhj%jm86Et@H=qA{>ZV7V>->cH!jb=!;be>sesqw@uX_3_%V{0tZdAGB>2ZU#=m=&e{c~6=^Wp_{(124=JTiCTh#s??Js5c z(!sae-$z}>Ez#>gAijT6ar+AgGxg8tlIq`n{^`XrKQ`9+G4X|ipE8_`(UZRU^WU3$ z&$vqGC*Zep)c+91Kcj>1pKp#oZ&#~gT>p{8k6r#5PR8iq+xed|IJr{y@4Zd!&%qDx zWBfBZ`1bP$yRIMJM(0Q1JMy10oQ%=MkNNe#;J{wpb-pCN-`-LG_cQ&Ubi4n9Z|A@6 zqzcCUCvO4GKOOv(;Y$ZUm|?E}dCJ2(Kd<|b!9Us2|A#X5&*fkDZ93d!Cy@M|J36Ar^LZ|A7aMn{-FHx|5~e? z8U7RE#}0n@5L5q*UgBHl|6RAc_+;I`B))X;Q-+f4r?mzhNQvW-xIRD{r zrv6E{>!0KQ@!X%r^^bt~@fnW(&+w&-Z(V=rb;sYv^G^}+h0FiLO#L&uccz+u+x>6k zg_8}ww?yS%y8IId^KL{*x}E>2~`A z-}XQ7w%;e|e4qHStNo8)+CS+m-x_~zn7gc=&KJb@4=T=o%J3z_k6WtiANKv96=!xo zPvd&>mBnShLbTm`1bgF^NzEO>yO@hbo}e= z@IR9A&*0 zsOJB6{zpExzj6Evi0`j;JpagWGDZjAv-1D?z>|#YKi+cXU+n5=|4%ah8C}j+*WK;$ zx53~lSLpc{#E%{Pl;LEIF6ZR)`(AOcasMYFzI5=z(TsmakItg!AD5fwzYV@#Y&?Gy zy-)qmvHn;}9Q1ocNxI$tlMae+=l}NWck8X^-}`|0RUP#|hVjqnqBR|Vto2v^*?eLL zogWZid{*55QihW;y0}{%f9(GE~=O5S6t7f@o+0J}OZ` zK~x3>MO0kDf(?Te`>I#~(by0xYj3ErV~-7DW$f5j1q=0kf8<>InHh6(Zg~DV-k1CM zz0Nr^lS#RAH*0TQe^SJcw-EA=nfw_Ye0TkCu3x#@%s)o`+ZL~X*ypCiLEjNI>2CiU z`0v~IAI}_ohxPuI1o;c~4{yu!2NzM1&hg#)>+tQtX8ztswEhb9PZ_=z_-_5zt!`<( ze@hYH-%{xR?M(j}J${Pj|0j0+zdmZ=CRYA)X#Qzo{bx8CqvO5r?)#6Qdg~SI{<9DM ztL5`Ayo1S~(ZNT={m1#6S6knI2#Bww{25Nh=-?(F*!BNo;4KTx`YZ6I{O@G)XLRu0 z>tEw1pHXM>BjU#bKV>)>ql53xzZNe%Vm*H!6JHDb@Gd5QMh8D}j(>5BHJX|EC&c$( zD<6L;!^s%EfuGsO-}m1+$2$IM^k3kI)0zAk9enrt$EY`YerV?J&87MOr7-`AgLM~C zlm4IecTRr)!TtTuV?OxWdjE@0d?oP1yYu|PMO37-eCPKsf4pqRN6h@=k7@lE_$kBJ z0zYwn|L)h$Z~SEPgHMSs^?wG_e@550Q9%WjGn5gC9(H?tfiy zvGx3CM0|gC`TPs-Ve)5m@ZIC@rsG>#*FR$7D}kRfoQ%=I4?eNyf8$OsKWX+q{vz*x zysL2hzn96M(f$4N{ik}%=AXV>=VwiRLVPXoQ-+fEiGDZjAegDeWZKhiHAAI5~fgj$_PO{?hZ$#6jMO8KVc+72p5g;*oyV z^Y8wbwEheHu#TDkjP9>peEh{*10>6<>ea?(9B8Ouiz%68I^@$rv4ccmDVMXr}f2oksqx%GaOpVJ3e@*U#kF zAKm9a-&nHI>1O`k*LnSwz)u-Y#^~U?{l9XDhphJ>`^1k0e)tHJKcnke#rfa!(21v* z`3J<;!uJnShLbTm_-_6$&guHA$yeY@`9I3!&*=Ku;`|4z8zPe*5#RUA$6v~DGDZjA z&HvE*F15b@853U#{O~a*e@55)=EooR`8&1taUIP3HSyzl!v2rpWQ-n7%GZB4{{ufb z%^LsSH?;ms`9IF&&*=X3#r#>_##+yx2E^A={tPE$^!PHm|LQz{Fr@d}f1CAJ#P@Z1 z{lh1i{23km__*8$uK!)T`{Aj{kHBv&jDLocF*^9(ZTUC^zuVkXwlMiI@s*VSlT7}M z4!%477PWck50meIOXE-Arwk`!^rUgV|8S2#-AA>ZZ1Mx*Yk?m=#pKWE;JfF4z0W<_ z`u?v1U+O=@$rv4cZ%w=ZGddl3v6+8Fe1Gfm@fSYLXOr&}UkUt_;be>szMFr)$2V)q5k1> zO#Y0nlj8h4?66*D@)hx8Vf>{GCu4N*-TZr8w%r{jKSKTjKYX6apV1R$|8wn2FMn?G zW8(W?3F{xj$rxR&Q+)iJnJu)wf0z(o3H&f&@@I7L-Q(W_JwNSe=C6_eHs$M2%5XA9 z2j5-)1{|7M`ycNITK@%p_yUtZql52`zn5FjwD#YM__0v`l;LEIuHG#^{+&H*`nhKP zBk-mCUu5!UbnxBd-`3AHS!D8K;%kAQGMtRj!FT&Vvehta|E+(_`yX#xKK{a&nEV;t zTd(-~*QnDU_{_}T`zhyZfuAy*jM2e&^IvCHH~abn_`>)LUuN=W^mzT^_2;l}Tg)`` zSH$MJ-7pnjE<>N19I2oe{8x+sK^;LS+zpVX_CcYN<;pP?=YRcrs(-uk`iE~a`7^q%Dn9;?8*}SaGyj12@y_MvpDDx17#(~!|3B18hnxI} z_*&qHZ!!5Zx_+Vf{IBJCe_GEU#;AV>A%BLGF*^9}{2PAabnE;#A-)&qu7oW7L_573fdp`bRfuAy*jM0;4^ZSqP`g_n__gT+>Ma0+A`u`4-KcjoCir1g+ zb*tIOAL9Gp2>U;VlQBB@?)ua9q3-XS<39m^2Vwrd%jD1K;Jf|bsp-iJO@8zT^mP%^hH(G?Jtluf5B^uoU)G|l_5774zQ1NUKV>)>qx<_8^M7wz zXT5*GUy%1-3HDsd~~A>zMUd#P@e8AAc#s$rxSJxO4e?9rX1tCO=00 z0zdqK$)C}a1B>hb!d9o;W%4!gW1;>j!^s#u?qAHmHayz8|KTsB`7h=FA(KC&M`1Dl zgWk)3GxJx(*8)FfI2og>gNpglBimP*{FwOuuI1w|{D{e)(Sw7F`To4ry8feyuLOR| za56^s4=LtfvB$O6`=|ZCsQ&^#oWtbL=-z;0{!YJ*KHIFnBEA;*DZ|MaT{HY8$4>my zelYzzgpLAu{{w7}&UrGBPhLbV6|9pP@ckh2c)bjXxlOO+0{TKLQ z#^lfF-T}q$f9g1Pmi7MMg!o$Erwk`!bnxB%|J&1l*wV`X-#mZaUfBPA%;eAL`pV+{ z@2dw7x9)!=#P@eB=cf!OV|4J{{qMZ$)9y3#_ZCtA1%CKRoU6xo_j^i7(G}!ufLoB*#{nCeg9t(UrYIa%JiSn!FTun`#-;-_5I5T zd?|m1lQBB@?)ZP#^2lE~=V{|pOxc(RK z*mbd4e{WgNR~wb{!+A{q8Qs(Q`jb3ofB$yG^2GlBA@O6O{wc%B7#)1~_&;RaneUnT z2gKI`Kh#YAj1IoL{w_G(Kh@+b;`{3ezDKWhui;0A35h`v;GPA!uSinW%6fq{Yo)^zawW@>yNhv zjsMMr{u2j%N7SUd{pa|%UiOQ1{v8lM7WmnA#Ej9S!}9ZQxBoXByte)Q$2F<`0zdqo=|7{ZC-ZeTS!5soC%n0EKXd#= z#P{cxuRkfn$rv4c_xOL<`D3pz`3dr$Uq1fA`Aq(du3yOe?;d|%+wnZ>{RbNPUm;xo zW;hw6gYPf1>p%O!mxq}7du!49CyoCfnEV+Xe0TqG--0>5$q$I{H!rV$%5XA9SA&Yj z|93-U>-twjd?oP1ADQ`2x;y`aY5Dr^e`fDLM&EnRU^D-O_^~kmQsQ9VBW8@QU(MHF z_xQWxj81D?{I&D``z^}rAO6JjpV5QC#r6NG#Y>Nxe7`aA*Av!1hLbTm=AAqLTdw}c zAd|0%ucZ8cX7Xor|M24c>n=FWdjF2sB+ow<_$kB57(E(J=U>kH`}yeGt?xhj#8*Q7 z!(W*E86AAL{vW)0$ron*1LA8be}s zzB~TUzV$lm{3j-UEam?@lRu+_?;ij6J)nnm{VM@q%AYvccOz=j|1&`_wOt|{|npi^O)IxpZHpM|8z3*=ukC1;@KL5f$nfw_&Ve+5!*)FS@{Ge%GeUrhdt4z7Fs`|(}h z-Pf$YLj9%u8BWIN;Je4a?dD$4+2lvWS5p3eGx;+*_`z@aI)wTkIyPKx@?+FrdjC1Y z$rv4c_xQ7Sd%OOc__37#KY9LGcM%oo?)uxncdq~LePH$GX8u7H%|C&k5(oP}#EjAP z>-qlA&HuUY9&cgt74d!P{r~?m{b%&xrQ+kyoQ+#fHTeSdYjE?``m#@F!A|`)Ek9H}3{^NwFR^Qaj-zUBj_$kB57#)1K|D(H%Xl?QX;>Q9% zT+HOp=-|7*|Ml!~pG-3O(S|hs1%AqKGDi0X=i|>^{~jAQ^G%Z<6JK=@*8e3;{)`U3 zzlXj4?fu}aF(yADek|})hLbTm_-_A4jh*(I$=9gAzz>%)`7?TOck%vXtrws8+T?p1 z(fq3}uYbyLGDg=7f3K&f%ryBv@s+?2mofP>dNiXr|Dz`VXr2EB$X|H>X3B6fM)&W@ z`R@7Wt#|xseg8ute}Nw^XYyzCWRraV<<7simOgG>e~O473-wPKPR8iqyYGMd_?UC5 z%>Kv3*8)HE+O4=xjN>liAVvp2o@!tJ8S{KU>-v9!{_i4;e}}}jL{RC|8D)4wHR%k|3=7P;D@U- z{bzJ_Z}Ix~+OdldH|rl0UrYUGI2ohsH;VVaLtk0bGx-|z7v8@duEF%5bhrNveCPLf z-Z*37Fq7|Xl8=A2M0o!@anN_fjM4R*#rdDG%axCt{DAnezz^4C@+bX2`GfD|f5dCa znI>N$|2@j*UrHS0jhHdIcVF@NTlVi*d;f|21%9{|GyWMpX88R--p*eCHl_Wqz)u-Y z#^|2T&p(2}_VH(vF%w6b_4kSIcPy`exHgkNql51`zdv*Gf{)iR`2q6ZQ&|5PPR8iq zCv)xl-|?)W@0)x@d?n@In8}~f!FPZE|Cro(mUaC- zM*RhT*o4WS(ZNp~{yu(h>-mp__HZiU*L!9F!?h& z`0nxl?cK*lCg0nP_CEqYWjGn5gYWKtn|}H1>n7hPzTc&M{)Ou@`7=8B?*4bnpSHEm zKLg?`fuAy*jL{qTqw?bbu0J;2p#Q68{tERM_~Cj?{)`U3KQ+G(0e;`rpSP}mN5t0x zKV>)>qk|v+V*ma}eBXzUn)%1*e^;UZ>ofT?I{3=D|8#qcHmjTb1o=zjpW$ST4!*np zo$X&_)n6n3&gJV**p$hi(ZP3r|L2WgXC7_l?=`3WpTJKUPR8iqyVu_iY4w41{UsoN zEbzk(^89h$gQ!S%_kZBK$Ny~Jwv)~LBjRg;pE7(c@tx-{hi`hh_5RnG`2LkXJlOjFmqz`C`Ij<$E%4pr@53E;v!4I+ThREE@^8lEPdb;s`};Eo{Ivfj zR{x0~3;dMfYk}_`e?MKk&OavK+nn~_0zcf4$)9vKf9Lnl);eU1b|ya{e!N%t`kOL* zE%0OK_&4^97p&)BBIGad!;P5yN$2u+k3a9VYGYl0_qWLF?{_Jme<{P)0^eQ#gAwmq z&ws?kR{}rWn8}}XE`N9Z|F^{vZ=3zs;CB=H&+xUtk3O@{|F-?Ai}n6DZ_B*?vA_>E z$@9l~H{u{h*Y_8ne=q4cbXPNfpZHqfrwk`!bZ;=7|BkcwKi@4nZ;8ndi0?NkfBrh$ zl*ymb!B?Bv&;Ne^%Ms_Be1-Z8<1b}68KZ;mUVm?tU1&Xj6QTYBKirJTpV7g0*WV4^ z)&tD^W8y2J{wc%B7#)1iS^sVwp7b*L3HrZx`TPr;Gx;+*`0o1q_?`W&?>}nfFYr@_ zlQBB@?)k?Ntpe-*lh=~g->&8BZ`gv#pV7g0*Wbyz)K zJ%1Z)MaO@EA8yX%&*;I>;`L|voPVwLR}o*WQ@;MB3@2lB@ZI(2v^#z})Exg2_)`D3 zVDe{l@ZI&N!%oi}Y4T&@#{xfPI2ogZ@2)>BY7eV7`3dp;eT4bHC6hm+gYT|Cf6iXZ zdjEz-{RMu?a56>*-(7#sJ^M}T{;SuDj{gEbY{}%$=-|8S&n9pEYkmLBC%%^Y&u}tE z2j5+Pc6_=0cV_)%#P{)`U3yZ$`#!saz5Kk{k)5$c~ZoQ%(1 ze1E<2@s~23jM2e&*WaC=*=h|l{}}m8{cpqM&*+e^$bhnN_3G(k=zW$^PCu4N* z-Szja+KsH|PxaO`{{()x4U<2kCnprIKMyQ;W;?U~UK?8frT#OVjM2e&*PoGVykLF* z(I>u=j(^)S`7=8B?)uaB^E&JJ7Z5)d_$kB57#)0f{poT1Dc1cb1-{h(?U?)-9ej8F z=`eS~ShN2T`Y-TPhLbTm`0o0%;Pu~*F!?d@{T}7>FWjEVpV7g0*PrLEK5?YUPmsUV ze}Y+O*Otkj(ZP4upS`ylXRZI)=}+W#ox#{xgx zfytlI!FSi6{=0qu zm-v3q^7SWWI2ogZ@2)?6e_8OnnZHK-pb^__4rG8BWIN;JfS3srMaqr&<3Pe5wB( znEV+Xe0Tk6{K4`EO@2arE$~x@lQBB@?)q~=vpsv7d`*16SNZxARx|lCI{5DTGxd(! zw>9}*TiX9i{bx8Cql53RKg*k4UT5-s;`{rQuRq}~O#X}xzPtWxe$q?U`}cx&l)q5_ zl;LEI9*r;F|D4zTXzTs=iukIkeEkV`W%6fq@ZI%iqp4r4Z`MBoU#Ne|a56>*-(7z$ zxoUzn{$t|D0zcf1$)C}|ch{dGGf%qN%s&BNsDH|EGDZjAU4O!>T3u%HHSzu4!u;Qz z$)C}|ch{f877x7F1u0QXmXO1@c3GtP{PZ>_e=-|8S&&Ov@3rxO7 z{u>JY@66=S=-|8S&)qk4eB0!EJJRt_8vhI@V|4J{^{3aL(~mOwKJop1h4pVwCVxf; z-(7!}wS4OKE0aH?gX_+}ru{qaZ04U3Ukmk58BWIN z;Jf|5Y>z{%=TH5e>G<1SSpW87@@I7YR`K`mI?i}zv6+8B{8-?p3@2lB@ZItE#xL!C zlOGe`-?)7Ih25C^8C}!&U)}m&GV|nzOuk0_`;@OgDZ|MaJvk!({;kVD>xT=EG5LN6 zI{pj%aBn7mMvspy=I_4nsU;>qBEA;Bf1EO$jM3wl>Hfd-{=qKib+LZ`+^f#>_xBaX z|2|Cqj2=Bu{QT$t{+ct~%-<)z68I^@$rwHPIe+d_Ip6&`fot|Sm1{NlRu+_ z?~cFUTI|!-%wG{-3;dMfWQ-2J`~2}o%jTSH@?-SBkI?__dH#6r15uIgKK}u}yZ%pJ zf9b6zU!(s5KV|q@;Jf(`?lius$yd8z{tNl{VEWJK$$9zs3qG-*zrJ?tclP&>z~8KV z{Y{C3x+7}R|5JbB>ofD?5RU&ROz3!%nSZitp1&6AANFMOXY}Z4ntyBUxZ=GT;Ggly z@V+Kr6W{M!UjLNgWQ-2JJN~v?v)=ywpWSKwJD~jd6ZT@pKk07${Re6NbH4xn=+|Fb z-+$G6=dG`Ac8vSv>XJ-BZ@%=~2*PpN-lRu+J4;S;p=1m?j`HJ{@({3w{ z6Ye;|=ak`OjP5^D%pZ31an}3yBI3tV|Mz3YKk4v^m=NC`|N8hbH<63|}*R z^=O{I%YXIdf!mn;1pRLz^#6ZM{~6tTthoMHjGSnH|8mcK{`va}^Pk~lj2;g!KL1*L z{6802`4e9W{BVCJe@2f+5a0R!=S_Ef(%s~%E_wd3^!{UplQFt_EnolL@84cIsP+t# z9}!;*{O|xKe@1WMJNe)8>lxPZFDAa$r!zX@4SCt$;>m`oB3nEZtJaeevzJ3NTVpV1rm&ifC>4*c2r{+mYr0zYLq z8KZ;m9{-*^djtFZzuoBg^ShA$!A$;)4!-;ToyLznXgz=K6JH7Zl;LEI-oSU(zb5Y; z9Gd+PkpDr#_&R1tv>=k9LVI)=<3*f|Kpy2 zEjoKYYyJ23q2u4d<>N19I2ohIPZzJhi>Ln4!^%IP{QnW=|DjC&j2^w0pLeP>|LEy8t?lP;_owkcT-g6Gd@b?@!*xENv&gJ}g#3m2rwm^Ue0TkM;O%v+-yhJ(f2pwkAIs!VI?`^4l)pRw ze`xok_5Ew_fV}@o;HL~<3w(F}U-s6A*8LBk__4qbk7M#Dy&-S>1Lg0||8*W2Z9V_3 z!SCFu{QfU-aNi#>V|47h5V8Neevj3x`R^S_^MAR}|B-qA;35uUba37M*RqFyvVMOm zCcg57-~S*E)*VDmI?CP<>AJgn{=dfqv#jUeg8sDr952lOC?ldPCpoAHa9}zuyG!ag(oz?>7?iKY^M5q`Q3o<@~uPm)~;0Kfjp#2=zZj zIQ|m{^A0g%bZ=?<73+z+{;RtdSkK?b#E%7jcp}q(Mvoc(;>XhbXE+(7gRc*<&p-E{ zx&H1ZUx6>>Kbpy((ZP4?KlqHhw8@W9e_{WXGMtRjgJs3z|FIAIbu#%e@wHI@@MI=` zMvs;k^FP>rP3!oZApc#;pFc_&PR8iT1@!#u-S+jj$AACeAv6Ez5IX(|{IG_}pV7VB ziuv<~oO+eX4+hZu+f~S);be>+?3!QqR8Icio!{5G|Evb){8-?Jr!e_5y8e^N|M)Av zHuH}TrTotkj{giNV|3rkpF4Ng|0ct4nrQN4@LLGSzcEbyjPA9}uRFQ>pJ|tj>R|E{ z;>Q9%WjGn5gYV{Fb!62}CO9{{L(D!eu635nl`Zl;LEI z4!*ahef@8bG|$NeU(|? zKhVUF1%7xslRu*e@9kW;|LpPSI_H@AdxNR}*OiaIl;LEIu0JTwf8o-^I{yraA75F% z{|?V!@@I7K{o?$Oo%@ot{wU-x)IVi78KWl*f8I;4Tlb$M@TL66G5Irk)FGdL?)ck$ zK!+-`{~Gl_ue|;#!^s$3e@w^U@9poO?6!Zrv&jz*r}bahe}-o=`7?SjJkKB3fpPwO z;^V*9oBW9Q{wN`ThLbV6_k4cc-#!0+dVJLqlb;Y@3H_T@{^RyP9kZV`{v+ZmDSw8OF*^9} z{-d>8{E6BBnD|=C{~RWNMhD-W|KE=})q4ISz99;K7)TF!DU%+>dzwOr^Zk>Pn zN7C`d0r6wu`eVv)GDc4>%GW=){+q1*v~~U8KPu1P zKUv6sJd;18CzllScY1%Z{r;({kcapF(c~-QYk{9KoQ%=I zM+Co3-A?^XevJI3{$If4&*``rEix$AYb zj=ur%{ng9sA70G#pV7fb#QawT{CUSv{{?`SHi)2N&JFv6cVuJb&*E;rbVGFzyjEM%UZs^UfWAUEaQSy2KZ6AqDehhw1`T0k9C6hntZvG8?`W_UHf5VnE-P`0R;GbGP z{!-!~Z^Vqzlj?lm?LL1t?11*x^(Rey|Fm*`coj4L89i7=d}sgn&iA_F|0@@M{H2+{BEDX~{P>#^ z2YpA(7(F?*`2N?uJJ0HA@)P36UCNKYVJ*{tMvq42{K&KKKR$fhOV;~WH1ZefpE8_` z(ZP4u-^&`dgAGYPgADetdd@b<98<_qxI{0q=PdL4+ z_549Zd@mK&KjL8DiKt0;>kqzL|5Fax#Crc_asti&v&-ur-pJ(7=>9du_4l&(&ob+; zi60C6l;LEI4!&Fe=&9AM>#yF4l)q5_@Fr&blkV0Ze7F9+POGx6zXm7eeE*#C`lrOf zxJS$wJsDM8|GTGr^{QEaMSLaj!^uql86AAL{zIoezlF(kqzL z|33Sz_m0VrM^pXBm9M|y6efR0_YN&S{|di2`#O{Fot*Py;ruIQI2ogRC*|v|d;C3Y zi=C|R|0cxurTyPjCVxiPbMpP4%WtvCj|W)!*HHdvm)AdKI2ofygNo~aOwF*7Cf^6Y zS^54eyqU?L(RG@i|GU?JZr$wy>-}p1@wLEDiGy*Es7ZIne=wT%pU(cT-xc5YHS<@* zSHkm0;j}z|a1j;h96#8|-hW^IbUXX`YvTJGme)UJ_*&q*`>&bp2mkhe`Q!dWg8VNi zAAjL3O#c~OA5?t)yWWKJt^L1u3XOk(pE8_`(fz^22s4G5nl=XFlO>+bnxBZ-x$)d*&QZ7 z7@PNBZ7Ga@hLbTm-h1FV-~ayR$uZXZ_afrQ0zbTs$)C}^Dfzs2?>~$g`GR%-O`n?Q zuZ8}VoyT?p^MEpeHhj%jhGdlS0_#fTrjWH%aCcYBJU&?SYMh8Fn(?0*cX|G)`G5HDc zwUqx|O#X}xJ|f27NmJ{$Gx?hMUKe5fGn|ak!A+d^p9NRE_^`?MPN(%(8voOo{23j5 z_x&r&nr&w7e|_S|QvVrF#^~TD*V+A_KKDE8`_}>SwZISWX7Xor@ZI+h&fISAntw6z{k6;2-<08G zj1IoL|GDp}UVoeUC*TY7FT97zpV7g0fB)vU5|i}`_Ivt)c+I{PI{1hff7AM3 zu;TegpPqkAi0`jcKK@dMlQBBD?)rb{@QtrA^Vh^z0zaI|jDOPI@ejVYmVN$p+`td_ zvHE{@KK^x0`TCnOd@bhjmQ<89kwWr~CfPJv+Z~g2@kv zuLOR|a56>*|3CA8>OohVd`0|N;D-+}`7=8B?)>ld?6kz>N5t0xKV>)>ql1r#`8WOj z&#do1Cg}fqLjNCT#y{!q_y<=x=O6#v{^5%EFJt`)&ZY4;Mi~DLUkiM9{LguDq@6$U z^%>>&pTb9&{xdqb(N6aD-w&7d8D{oh6F(OCDZ|Ma9enrt%Pvb*Ta)jNr{k~G|3{hp z86A9g{*Cx}d(Y(i;7k2yI2ogZ@6NyRS3PRo{|ty93;gggCVxf;9})9!H?`goR{rPF z`Y-TP;$Yv6s7ZI{AGq%P8@Aa=@0yPmKUHAl(KcnNlkM8)pt2;gfm(7Orq9K1-&mSbj*TVZJQ-+f>(3k0?mO1xE8;7GA3nq6&*;J`Oi^r&OOu2KPJ8}z5jC-lRu+_?_U3UpvC#t^N+zL zwEmu3zW+)YPR8g#J9__z^ZfPcZO^xkKZ^KD;D^sL`7=8B*axHk-O_JvGwZLx7oNXK ziGy_)QIqbjzj*HxBKWOOpJv_v4JK0kHxTy!&oTKkdN8c`{`-7=ZC5jYMf_OGpW$ST z?(LdC|L>0fr(bIFiOG+NucZ8+XYyzC__+MKySx8=`O{4XnEV9!3;dMfWQ-0zBKqHR z=KQ9%e38kY z(ZP4~Z-4l`HD>-A^*>AKKf}owT@TLpU+(-t*+zLfuKO#X}xzB~Tjy=I#A`+M;fdHv%Ph4qi&WQ-oalka~KvHo}2_#Er{ zyMHCEe*!<8o#&5zC!!+V-G74X=6}tCsn+@v5nt^leE);tYlffD`sZo;`G+2TM$9(H zUyS_63hUqNO#Y<1`6s{R^Uwb*?*r;z^TU=GnSB4My#DIca(+r2-1kJx7~LD0^WFK^ zZBDD9Cf~c7=Kt>H^$*`*#y_L`f8}*gp0n?N{W0|}`~B<0*HZorCu4N*-Q)kE!;gK? z%s)W>rpV6b^ ziqC(SZnxa}{fU71zV!ZEhLbV6KeCv={t@%`HuG2DOV2;Q!{pEC!EeR&-*uy}-Z1$Q z@nb1};^4T0s7ZInAII@9c|Oo@erX;%k8)rcC~f4!*no-S+V&2buf;d};s3a56>*9}&mj*Iszk zdjE+czAwCgKYWkLpV7f}*Prhe486x-{m<_+ z`7^pYzIgpv+U-c|{#Qc$Sg3!>a56^sMiukVJNd$n|5yKp>rdCw{%0fM`p*YU{)`?I z-<^N2TzRB*{_hiCOZhXLjM2e&$KSwfhT6{`6F-*n|B%U_(S3UE*v)@~ny+SA;~({p zgz?XCGDZjAeg62|wr787^1Vsa|8vXFzrv50{23kGU~qmP4(m^!HcPiL`9ATLz)u-Y z#^~VVci_SQ-(`PW&p!p=3-u4@F!?h&`0nqIPjBD*QZs)={8-AL;be>szI*@qpzHQ} z-Q-8a*8)GB%jD1K4SeVOH&1jPeW1yYiSLguAAc#s$rv5{#NnUNc(2t>euDlB{4itk zXY>aCTlVaR8*ntYA=3+qqHa56>*-@X2I;pelh?;m^D)Ba1!|6?Y9MhD-$|2O%~ zcD>B}eei|(mol7;(ZR=aK$!pCZk;sB*^v*+KO z-FLCRf0>~F()j<3$)C}|clRI1?GvPC{u=#1PgwsLPR8iqyU+jBPMK@Hf5W>WpZ`kW zho3X~GdlS0_n+6@^XS;jKO%lC@KfU8ycbcE?wsk`f2^eGoH7_wS+mKbzV2pW630$h!Wl zk-xwXzsd6l7jY1y2OW#~myUeo8?*oZ)V%*n>OaHD7+rPB`M3^(@&8ok#n$`}z`wA3 z{)OK%{U_b+KgVBi@^ycj`77f49}4{^4(g7WF}nVku0K2dzkaLx+L-(Z{Ggm4e#i8m z(Ubb({_lL&#v@FAjQR`wl;LEIu0JWxf7b`Lu-2c1__4qbzi0AibhVV8KXvNg_26-r zoB34u90-N5t0xKm38opV5Q%#r#_~9%#LPB0>Fy_fMq^Cu4N|7Oj8p z*~g!Q=iNKj%-_3}_CFVuAAiFinfw_Yb@z6$@BhDY@j)Aye4qIKCgs=PQ-+f=~t3@V1Aifg#;ZIEdj1Ing{rj>WlkDps#E%7j%5XA92j9K_*5c@at<3x*^k3kI zKQs9=I{5DXfAtyttnc5&=>Ns#<1b}68KXDwo&E0tOJ-Q_KS{vfw0!)9zcBeTI{1j# ze=K|~u=ammO#2@ue;nsi;^4d+QIqcOKfq0#-yb;ck`KQ!`yUWLX88E;hQH?dgNvw0 z$KN4x{LybV{h!6Zjq;yZzW+)Yz83i2>-PG$=4bn-)~I*q$6)cH+!`Bjjczz!g{8^(H9cJQ9%tY`8k9eE=ne{Y1%U)Xx` z4<A z{ipq&`O?1sPyATmrwk`!bnt`6?CYQPFE8t9<{u&d&4m5m-%S3Du0|I>f7IcT;AN8^ z&&bDLe1*_|hLbTm^7f9(=OM=5@Y8>`p8rk2m-7FI$)C|1_|E;8V70@qGV|BO*8)Ff zI2ogZ@6P|f+TCM4f9&0p*WYh0^#5Nbe?|x2J^uDt(%(A&@rkble#&q%MhD-$|MAk4 zOYbx59}qtl_~9ZZe@1WMJM;hFeHL2Zzfr{3()edM8KZ-bbpYePW0Tjd_a8*)|CQzQ zFI>#z&*Ti3GcAEW;QKV>)>ql1qK{${7WY+Zj#(0_p+E@AR#ba1_s?fw6d z%O-DPjz5k53*#?kI2ogZ@817evS-UXOuo98=6?%e{x8k*$9XTJA|2;Fh~T^X&)1vx zYhv=f`*Oazs(k#V#KH9d#Ej8VcbEU`&YkS%zlpEAmcM^ET*maD(ed5~M2x>l*|jU? zU&H>F`0>?3{tPE$^!Stfyx-p{KMw)_{6UFz{15J@`fo1ue>sysqhs8;@4wsNf9tJy z{utlCRK(W;KV>)>ql546zYn_jUF-U51in!J(A#0f?^R>mAr4}6@Z;8Y{ZEefvYtPP ziSO46{bx8Cql1s%p+Ntee!kUr=KM>D9}D#lS7Y*Lbnx*W6!34kW8FhczW)HNKUxOx@+A6&gTqx+6dAK7pd{hM{1zX;~FUf~Zqc(otfdSCkgxqq)1eVn7yM>dS4 ze}i#{KU|ys0d+$ief+_U{QeL0wvLXx(4Y9Zd^|RxzZ-J!Khz8D|1Nw($9#hC)#?A}Q;aXp z|BLwl;qUR^U$HpgLrKK{|Ix#$Rx^)(UYo5~{3q0h!tt+hJ`P+&N;-Ta;(H%h|FI6c z|9^ajzg}}^Rhj;xZE}D5k@ENB)if#g2OYi;ab3WT@Z(1K`}(2VzcBs9@F&!-YMo+# z(BTUazHt74I=a5_8U7x+f93?!Uqb%;kIMU7$M}N|Ux@IB^J{#DA2-6^TBj_t_TQTP zDZyX3ZgKsf!xy5W>#p!s>Gjxda5Hao=>WBRt3^@`0E|_)you)r;``lmrefj>j zdi`R5(BTUa*Ojo(MRaU6e1yN5xBhsq=}(bAE%-|rf6(CzvB3}h4ritF_oOFxv)|8( z`U&H&rfG5gpu-m;z89fC&W}%(&X41M+Ixmszi1EY?{DS(t=b^>hvOq+bJB5KL&Usr z_wfx4b^ZbUt^4*qd;E1If3KI%-#YSv`XJ6G-NAYAhvOXHH|+i$KEvORU7A_%KlM80 z{Vv3AM?DeYZ)NLOwcD@O_j4lhr|Qf5ThI9Thw<&*L+_`db*0kr_xoLK zH#Ntf*O~e&_^WM}*AIO~oIyJJ)DX$v%J%oJPR}kd{Y87`{`{ZI*XQaDi~Adpj=my# zyXE_Dtk0FMFT+Qj|C8x2?vndcznAwnW&CNzAKtsPvg2>g?q^x+v)7g8hv2VfqvG{t z9O;-Zi2CPM8-IU&|DpB$B~AYPKg#P@wQ+HOebUiaMEGmyFMW@zVSGCOfc53qH^y4m zSG>Jwe*98C{^}TiNrnCzd^*1H5&m|(`vB|tHw}M6{lZO(>!(OZ-4Ic~l^uT{9zXJG zbAI^UX#W0L-rsu0$3Kj3|BihAuB^Yse{TQ0=}+xV{oSbi`K8)Ti|ZGYj=CZ0`{=wJ z;|>uGbt3w^S~B(m(_gX=`TMf`_*=bM@%-&fI_526bV`0-3*)ZR}Acn*90e zl>18=ADZzEfB5~=O4sM<>$Mqg`tyUlep;wsP4nXZMx>*!h*4+iFFl`%`_xWb8$P1H z?XH~qmgz4be~H(v^io7si`*ZMyNGQ`ZvfFhxc;J7^XrK2-{CX--L~7SyO{nI`SZUj z?{6LBZ+3d6^cR!ASnwBaUR=MCq`N$QeSY5u^8?ZSJA8(}esA`v zGyQ3dzpC>3)sqj5FT{UH$Gk-h9-#AIdOo4j`P*pWlxt0YUUyobo0a>k-J*DXxruc6 zLWDnWCHJR87OnTI=}(crxN-UMqk7BY`5TaqdLlOXqvv}ntzZA!=3DzeuSZ@#Z%X;` zBW3()#vgun$&DCqZp8Ro_u!`1{x2ba@v`#%*0e0HUqm|UhNxc4_kSzvugwX&k1_kJ z$)6VdRc%%5&nF$e5M6(GkBD10d`A72zOlqQKlggl{8(OIzdG`Pbs2Fs>EIx`{!mB! zdpE-0Wp^I;j9EWL{*>S^Y*k!8MLOz+2!E(srT%Jm{ivnsFX)xmPt7l%zxCt;bwh0I z=f2%~=o{(zZ0xHL-9Mzys9*J%?TqF!3z4G}{$M~Dg_|sEXZTz)+@pS9=r_}zrKP~KE!fo>UVSj?C zNXNQ|82z(q^_#ZcqM>Gg{R60e?aJ#{&-nAU&3(fcqQ7X>{O$hcMtx0x5&Z30?yr`7 zU|m6+LApEs)Xw?$M{xbGA-aD^pRqoFzwMgV`(>j8slR>7{Z(&Q+~0t7)D1CNylVA( ztl6mHX8rvBxj(;exxbY0rx|~0>8klV;iBWanf_Fm`-`^}*1zqG>lcxZx*;YH(E3N` zANZa$(_Rn#z2U2=i%owq{2g3gzpA#y^PoBDn9qnoll*%V*uPY|zi)ket@VEM_#mp^ zA?5z+7#|7a8~(hO`8=uA-(TM>w(hSc z(PsS;_-iSwe>)b}FCravLxex9FO^=O{LtU^ThpI6Ag`Ym{8jB#?9V41z7X}zt5&}Q z$91sk=aawqiSqi@G5!+4-^$jn|=L&)=%tU$}E|{S@h_8={`JYW17-#lyYK z{zl}_d$QbLJ>$>oko$%&MEG0T`mH~$%P*$Cg#0O?ezoKS>mFjv`MYJ+>UVSR%v%36 z{0a4|t}gCxKsxG%sL9{T*01BXw^`Ru{eiUp9V)DUj6co!yLHv-ch+ugt@ncjF|Z9<5jEQy=(OzV$P44{3XKp zt7H5ng1?om-~nrTc?tH*Ge@^cNpW^P`op z{xSZ%-E-gYg&1{PwezDFI^TbU>CZcij=#eEttB5=_Yh;opT2F?#$UV66RqFZ@X22+ z)USGv;{FDtqi%@sx3c4J|7SjZ%B){JD6gM?n6UmaJ~GC)zCEuWp7X49{B4q4XV~NAShfD1v)@^R&H4rK_f+}(sOnVg&nF$e5aDlS`+M&EK@XVz zBJvjt{jFpCC7i!ISFL^zjXB-A{t}Zv-!HFU*txiVigeTsQIo%wtzYxzv+d*W;k5n< z{^}VY|1iGw%>4Qb&O0idAD>R>GQjMwCV#QuuXfMk`o*N9ZixD>RqOBSS1+@kFY$)t z^$VUZ?{9UNVt)bY@P!C}E8E{so*G+k)-ND`dXTXGG5$2?Z~Cg$Z{(qk_cr}0_!IhD z)3vyM5$UKKq9%VUTfe`iKE93VFD8F}>+=3q?N#j0Cmp^J_1&vhzd@5XXl(jR$X_gs zzdFWWBKTX``km0P>qyg|CVxt(U)U|LAL@fRh;-~{5cLeZewD5-;VwV7G5z^R(E2yH ze16n3KD@n)eY^g!4ocUDx{L|;H~j_VFBa-oOFmE^#8~jRvi;p{mi>O8;7HoP98q4s z>V1mmM?gCIjTm%y_RkewUwizQ{wu!!jPL(z@~7IA&)<~srx}0I7y0oGvC{q?(0=wl zW`Dh-sD87`{nZ4;^@~VH-4NjmvC{d`ZSt6QroVvvMS{Po?#2Fm(%}mczTz|U`{-P=3p?UrMBg@BM9pf(%{H^Tu@p)_QWj(*E$)Db`{Q1eSNAWr`h;+aU{utzAC;>KPwi&tl)`E3V&HIzL8Ues6cvpC*6mi}L5&Ysm-d zgBUaZqTTcB2Y7B0QCgoDEWxDxMz!>6jOY!CCZt$@3H|T>tJ^ zZ|Nwrei8W#x|WZ>l<|>qzMJOvF9Rn^^}D>+Ro3vcB7Cjv z^Y^>d);wX>FFrc&Z~Q~~^{c9Vi~H-7j=mzoU&FYo@cEo~ci-b-(_cdVwBWCf@t0KS zufZqNVBA0Nce=Ko&rXh^_2tL%`h|Up>!(OZ-4Ic~mF;i;oxZZ}A9=&6zk zcw8pC)A=v;6~_^#d=1YZ)c0&T-R!SV{tPFvwj-&`=xyRrHnt#`8(O}FW!d*KW>D- zKMuandj8KFLG$C+a(^}Z71u8!9d$!Y9DjJu-Svgf@Hg}Fw(FSn^U0qQ{8jz0*q={2 zd?C92RE6I^zxc(Y)-e4A zKlnl%NjiKXy8bHdZG$y{VDS2&n_Q-HT{d{$3)UG?hxJjRXTrrpL(t`{Y4mmg1@S; z*k4=H;S16AS80E{Pk5`J=`Y6k6a3XN{$^L`uhRbh^VpVKoBo31X@7N8d4I!$^7>)? zBMu@R^BK{*JU{>NFQn&qD?C4{{_fN}O@E5~X~ADT!a5DlOyuy z3;t>kF0S8Aq@!+#s9(drw8Hw$zOq+n)-NW1O7K^GNU^`pq{A0tgFoyGD)cw!$k*GO z{?sTMf7_IwpQnru&G?4DXdhgM$@`4??MCdc_IUX0VWz)`{P{!6=SR(e;`L=B=`Iic zf?(zR?Y6MFb^X9Qf%d1{me;RpVD1n7L-a|P~h1PoZ-G{hj{cXD^xlV)Ca2f8n9U^;4vyZiuKKuHRQ$zrWwS^kUOr za3b|rm5;xA#-Dds@w|pVtS^=NyZVOtTbTYd`HO||S4%!H?hs?fU;JP`?pAjEb(%ZF zdcTEt64h^5dHt#f756tF9eqWFzm+|HoH8nT)2yFQ{$ioODdSHI{#JJUO?!OSU#34r z{Ru_H%%4-S8Rp+icui>-S;2n%ti{ro4Xjj6d&)+&6q7!XNgh zm9BqH-@W)$vwr?5R6oIAE&0H@hZqa~FfR~MFE^roO|Lo9K7NqDcxd_ctLh_*`x}ss zx*?)|$x6PTq1DX~zi8G^kv}brzm)N(8Gi}w2QY6d?eD7_>|stY18q=7->~YG`qPebUiaMEG0T_2s>To@i$J^G?nE z#Y@YtKi4t-62Tw#f0fRU1FE|pWcmxppBCyDs^a=7(or|WhWgR>8}U1=?!3ik%-#o7HOu|g zk`Ii3#F%u{4KeDG@BiSh()n@sW=pL1mqg^xU#r|-_0h%s4M>MCM14>GeACMMyXMaQ zt^3oO{KbO5l<}uIfA_AMza^vFTHg-{&Y<;g?ehB798+Ash;-BqQQx;}{tg;?$V_wo z#^f&+{8bGv_UDrhUx@ntRr7axvynBXKW`k>uW@<(>KK0s=kI}4^LO$GS6T08P~!(OZ-4OMItLE>PpO!~v{Swr#NqPP18Gqifxo`MF)H7Gj-*ZoWXx+aI&ZPdX zR=&TgB_CM#5M#z)(vz;c(0jBiUH@7(y0wd0zli)P!C&=p#r+LPN8J$NZ)Nv?v#S?& zHvI)>(ea~EdHquIf#VwDeA1o6m8TD;{nbj|-=8?;J?s6V5&W%NKK^P(=JkUw#EGPH z{t~)wTIu`ix=jhK^S7A%#e%=8
ZC7tu<>)TR)5dV`x^`W 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