Merge branch 'master' of github.com:tomochain/tomochain

This commit is contained in:
Nguyen Sy Thanh Son 2019-01-02 11:37:48 +00:00
commit b1c5475f4f
17 changed files with 116 additions and 129 deletions

View file

@ -7,35 +7,28 @@
TomoChain is an innovative solution to the scalability problem with the Ethereum blockchain.
Our mission is to be a leading force in building the Internet of Value, and its infrastructure.
We are working to create an alternative, scalable financial system which is more secure, transparent, efficient, inclusive and equitable for everyone.
We are working to create an alternative, scalable financial system which is more secure, transparent, efficient, inclusive, and equitable for everyone.
TomoChain relies on a system of 150 Masternodes with Proof of Stake Voting consensus that can support near-zero fee, and 2-second transaction confirmation time.
Security, stability and chain finality are guaranteed via novel techniques such as double validation, staking via smart-contracts and "true" randomization processes.
TomoChain relies on a system of 150 Masternodes with a Proof of Stake Voting consensus that can support near-zero fee, and 2-second transaction confirmation times.
Security, stability, and chain finality are guaranteed via novel techniques such as double validation, staking via smart-contracts, and "true" randomization processes.
Tomochain supports all EVM-compatible smart-contracts, protocols, and atomic cross-chain token transfers.
New scaling techniques such as sharding, private-chain generation, hardware integration will be continuously researched and incorporated into Tomochain's masternode architecture which will be an ideal scalable smart-contract public blockchain for decentralized apps, token issuances and token integrations for small and big businesses.
New scaling techniques such as sharding, private-chain generation, and hardware integration will be continuously researched and incorporated into Tomochain's masternode architecture. This architecture will be an ideal scalable smart-contract public blockchain for decentralized apps, token issuances, and token integrations for small and big businesses.
More details can be found at our [technical white paper](https://tomochain.com/docs/technical-whitepaper---1.0.pdf)
Reading more about us on:
Read more about us on:
- our website: http://tomochain.com
- our blogs and announcements: https://medium.com/tomochain
- our documentation site: https://docs.tomochain.com
## Tomochain vs Giants
Tomochain is built by the mindset of standing on the giants shoulder.
We have learned from all advanced technical design concept of many well-known public blockchains on the market and shaped up the platform with our own ingredients.
See below the overall technical comparison table that we try to make clear the position of Tomochain comparing to some popular blockchains at the top-tier.
![Tomochain](https://s3-ap-southeast-1.amazonaws.com/tomochain/tomochainvsgiants.png)
- our documentation portal: https://docs.tomochain.com
## Building the source
Tomochain provides client binary called `tomo` for both running a masternode and running a full-node.
Building `tomo` requires both a Go (1.7+) and a C compiler.
Install them by your own way. Once the dependencies are installed, just run below commands:
Tomochain provides a client binary called `tomo` for both running a masternode and running a full-node.
Building `tomo` requires both a Go (1.7+) and C compiler; install both of these.
Once the dependencies are installed, just run the below commands:
```bash
$ git clone https://github.com/tomochain/tomochain tomochain
@ -43,19 +36,19 @@ $ cd tomochain
$ make tomo
```
Alternatively, you could quickly download pre-complied binary on our [github release page](https://github.com/tomochain/tomochain/releases)
Alternatively, you could quickly download our pre-complied binary from our [github release page](https://github.com/tomochain/tomochain/releases)
## Running tomo
### Running a tomo masternode
Please refer to the [official documentation](https://docs.tomochain.com/get-started/run-node/) on how to run a node if you goal is to run a masternode.
Please refer to the [official documentation](https://docs.tomochain.com/get-started/run-node/) on how to run a node if your goal is to run a masternode.
The recommanded ways of running a node and applying to become a masternode are explained in detail there.
### Attaching to the Tomochain test network
We published our test network 2.0 with full implementation of PoSV consensus at https://stats.testnet.tomochain.com.
If you'd like to experiment with smart contracts creation and DApps, you might be interested in giving it a try on our Testnet.
If you'd like to experiment with smart contract creation and DApps, you might be interested to give these a try on our Testnet.
In order to connect to one of the masternodes on the Testnet, just run the command below:
@ -154,22 +147,22 @@ The implementation of the following features is being studied by our research te
- Layer 2 scalability with state sharding
- DEX integration
- Spam filtering
- Multi-chains interoperabilty
- Multi-chain interoperabilty
## Contribution and technical discuss
## Contributing and technical discussion
Thank you for considering to try out our network and/or help out with the source code.
We would love to get your help, feel free to lend a hand.
Even the smallest bit of code, bug reporting or just discussing ideas are highly appreciated.
We would love to get your help; feel free to lend a hand.
Even the smallest bit of code, bug reporting, or just discussing ideas are highly appreciated.
If you would like to contribute to the tomochain source code, please refer to our Developer Guide for details on configuring development environment, managing dependencies, compiling, testing and submitting your code changes to our repo.
Please also make sure your contributions adhere to the base coding guidelines:
- Code must adhere the official Go [formatting](https://golang.org/doc/effective_go.html#formatting) guidelines (i.e uses [gofmt](https://golang.org/cmd/gofmt/)).
- Code must be documented adhering to the official Go [commentary](https://golang.org/doc/effective_go.html#commentary) guidelines.
- Code must adhere to official Go [formatting](https://golang.org/doc/effective_go.html#formatting) guidelines (i.e uses [gofmt](https://golang.org/cmd/gofmt/)).
- Code comments must adhere to the official Go [commentary](https://golang.org/doc/effective_go.html#commentary) guidelines.
- Pull requests need to be based on and opened against the `master` branch.
- Problem you are trying to contribute must be well-explained as an issue on our [github issue page](https://github.com/tomochain/tomochain/issues)
- Any code you are trying to contribute must be well-explained as an issue on our [github issue page](https://github.com/tomochain/tomochain/issues)
- Commit messages should be short but clear enough and should refer to the corresponding pre-logged issue mentioned above.
For technical discussion, feel free to join our chat at [Gitter](https://gitter.im/tomochain/tomochain).

View file

@ -1087,9 +1087,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
cfg.EnablePreimageRecording = ctx.GlobalBool(VMEnableDebugFlag.Name)
}
if ctx.GlobalIsSet(StoreRewardFlag.Name) {
cfg.StoreRewardFolder = filepath.Join(stack.DataDir(), "tomo", "rewards")
if _, err := os.Stat(cfg.StoreRewardFolder); os.IsNotExist(err) {
os.Mkdir(cfg.StoreRewardFolder, os.ModePerm)
common.StoreRewardFolder = filepath.Join(stack.DataDir(), "tomo", "rewards")
if _, err := os.Stat(common.StoreRewardFolder); os.IsNotExist(err) {
os.Mkdir(common.StoreRewardFolder, os.ModePerm)
}
}
// Override any default configs for hard coded networks.

View file

@ -18,3 +18,4 @@ const (
)
var IsTestnet bool = false
var StoreRewardFolder string

View file

@ -18,10 +18,13 @@ package posv
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"math/big"
"math/rand"
"path/filepath"
"strconv"
"sync"
"time"
@ -215,7 +218,6 @@ type Posv struct {
signatures *lru.ARCCache // Signatures of recent blocks to speed up mining
validatorSignatures *lru.ARCCache // Signatures of recent blocks to speed up mining
verifiedHeaders *lru.ARCCache
rewards *lru.ARCCache
proposals map[common.Address]bool // Current list of proposals we are pushing
signer common.Address // Ethereum address of the signing key
@ -241,7 +243,6 @@ func New(config *params.PosvConfig, db ethdb.Database) *Posv {
signatures, _ := lru.NewARC(inmemorySnapshots)
validatorSignatures, _ := lru.NewARC(inmemorySnapshots)
verifiedHeaders, _ := lru.NewARC(inmemorySnapshots)
rewards, _ := lru.NewARC(inmemorySnapshots)
return &Posv{
config: &conf,
db: db,
@ -249,7 +250,6 @@ func New(config *params.PosvConfig, db ethdb.Database) *Posv {
signatures: signatures,
verifiedHeaders: verifiedHeaders,
validatorSignatures: validatorSignatures,
rewards: rewards,
proposals: make(map[common.Address]bool),
}
}
@ -850,11 +850,19 @@ func (c *Posv) Finalize(chain consensus.ChainReader, header *types.Header, state
rCheckpoint := chain.Config().Posv.RewardCheckpoint
if c.HookReward != nil && number%rCheckpoint == 0 {
err, rewardResults := c.HookReward(chain, state, header)
err, rewards := c.HookReward(chain, state, header)
if err != nil {
return nil, err
}
c.rewards.Add(header.Hash(), rewardResults)
if len(common.StoreRewardFolder) > 0 {
data, err := json.Marshal(rewards)
if err == nil {
err = ioutil.WriteFile(filepath.Join(common.StoreRewardFolder, header.Number.String()+"."+header.Hash().Hex()), data, 0644)
}
if err != nil {
log.Error("Error when save reward info ", "number", header.Number, "hash", header.Hash().Hex(), "err", err)
}
}
}
// the state remains as is and uncles are dropped
@ -1084,15 +1092,3 @@ func Hop(len, pre, cur int) int {
return len - 1
}
}
func (c *Posv) GetRewards(hash common.Hash) map[string]interface{} {
rewards, ok := c.rewards.Get(hash)
if !ok {
return nil
}
return rewards.(map[string]interface{})
}
func (c *Posv) InsertRewards(hash common.Hash, rewards map[string]interface{}) {
c.rewards.Add(hash, rewards)
}

View file

@ -86,7 +86,8 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
// Add tx signed to local tx pool.
err = pool.AddLocal(txSigned)
if err != nil {
log.Warn("Fail to add tx sign to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce)
log.Error("Fail to add tx sign to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce)
return err
}
// Create secret tx.
@ -115,6 +116,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
err = pool.AddLocal(txSigned)
if err != nil {
log.Error("Fail to add tx secret to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce)
return err
}
// Put randomize key into chainDb.
@ -126,6 +128,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
randomizeKeyValue, err := chainDb.Get(randomizeKeyName)
if err != nil {
log.Error("Fail to get randomize key from state db.", "error", err)
return err
}
tx, err := BuildTxOpeningRandomize(nonce+1, common.HexToAddress(common.RandomizeSMC), randomizeKeyValue)
@ -142,6 +145,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
err = pool.AddLocal(txSigned)
if err != nil {
log.Error("Fail to add tx opening to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce)
return err
}
// Clear randomize key in state db.
@ -217,15 +221,18 @@ func GetRandomizeFromContract(client bind.ContractBackend, addrMasternode common
randomize, err := randomizeContract.NewTomoRandomize(common.HexToAddress(common.RandomizeSMC), client)
if err != nil {
log.Error("Fail to get instance of randomize", "error", err)
return -1, err
}
opts := new(bind.CallOpts)
secrets, err := randomize.GetSecret(opts, addrMasternode)
if err != nil {
log.Error("Fail get secrets from randomize", "error", err)
return -1, err
}
opening, err := randomize.GetOpening(opts, addrMasternode)
if err != nil {
log.Error("Fail get opening from randomize", "error", err)
return -1, err
}
return DecryptRandomizeFromSecretsAndOpening(secrets, opening)
@ -290,6 +297,7 @@ func DecryptRandomizeFromSecretsAndOpening(secrets [][32]byte, opening [32]byte)
intNumber, err := strconv.Atoi(decryptSecret)
if err != nil {
log.Error("Can not convert string to integer", "error", err)
return -1, err
}
random = int64(intNumber)
}

View file

@ -141,10 +141,9 @@ type BlockChain struct {
validator Validator // block and state validator interface
vmConfig vm.Config
badBlocks *lru.Cache // Bad block cache
IPCEndpoint string
Client *ethclient.Client // Global ipc client instance.
HookWriteRewards func(header *types.Header)
badBlocks *lru.Cache // Bad block cache
IPCEndpoint string
Client *ethclient.Client // Global ipc client instance.
}
// NewBlockChain returns a fully initialised block chain using information
@ -1218,14 +1217,10 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty
if (chain[i].NumberU64() % bc.chainConfig.Posv.Epoch) == (bc.chainConfig.Posv.Epoch - bc.chainConfig.Posv.Gap) {
err := bc.UpdateM1()
if err != nil {
log.Error("Error when update masternodes set. Stopping node", "err", err)
os.Exit(1)
log.Crit("Error when update masternodes set. Stopping node", "err", err)
}
}
}
if bc.HookWriteRewards != nil {
bc.HookWriteRewards(block.Header())
}
}
// Append a single chain head event if we've progressed the chain
if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() {
@ -1432,9 +1427,6 @@ func (bc *BlockChain) insertBlock(block *types.Block) ([]interface{}, []*types.L
events = append(events, ChainHeadEvent{block})
log.Debug("New ChainHeadEvent from fetcher ", "number", block.NumberU64(), "hash", block.Hash())
}
if bc.HookWriteRewards != nil {
bc.HookWriteRewards(block.Header())
}
return events, coalescedLogs, nil
}

View file

@ -366,7 +366,7 @@ func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis {
common.BytesToAddress([]byte{6}): {Balance: big.NewInt(1)}, // ECAdd
common.BytesToAddress([]byte{7}): {Balance: big.NewInt(1)}, // ECScalarMul
common.BytesToAddress([]byte{8}): {Balance: big.NewInt(1)}, // ECPairing
faucet: {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))},
faucet: {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))},
},
}
}

View file

@ -18,8 +18,10 @@ package eth
import (
"context"
"github.com/ethereum/go-ethereum/consensus/posv"
"encoding/json"
"io/ioutil"
"math/big"
"path/filepath"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
@ -236,10 +238,24 @@ func (b *EthApiBackend) GetEngine() consensus.Engine {
}
func (s *EthApiBackend) GetRewardByHash(hash common.Hash) map[string]interface{} {
if c, ok := s.eth.Engine().(*posv.Posv); ok {
rewards := c.GetRewards(hash)
if rewards != nil {
return rewards
header := s.eth.blockchain.GetHeaderByHash(hash)
if header != nil {
data, err := ioutil.ReadFile(filepath.Join(common.StoreRewardFolder, header.Number.String()+"."+header.Hash().Hex()))
if err == nil {
rewards := make(map[string]interface{})
err = json.Unmarshal(data, &rewards)
if err == nil {
return rewards
}
} else {
data, err = ioutil.ReadFile(filepath.Join(common.StoreRewardFolder, header.Number.String()+"."+header.HashNoValidator().Hex()))
if err == nil {
rewards := make(map[string]interface{})
err = json.Unmarshal(data, &rewards)
if err == nil {
return rewards
}
}
}
}
return make(map[string]interface{})

View file

@ -18,12 +18,9 @@
package eth
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"math/big"
"path/filepath"
"runtime"
"sync"
"sync/atomic"
@ -292,8 +289,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
c.HookReward = func(chain consensus.ChainReader, state *state.StateDB, header *types.Header) (error, map[string]interface{}) {
client, err := eth.blockchain.GetClient()
if err != nil {
log.Error("Fail to connect IPC client for blockSigner", "error", err)
return err, nil
log.Crit("Fail to connect IPC client for blockSigner", "error", err)
}
number := header.Number.Uint64()
rCheckpoint := chain.Config().Posv.RewardCheckpoint
@ -314,20 +310,17 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
signers, err := contracts.GetRewardForCheckpoint(chain, addr, number, rCheckpoint, client, totalSigner)
fmt.Println("Time Get Signers", "block", header.Number.Uint64(), "time", common.PrettyDuration(time.Since(start)))
if err != nil {
log.Error("Fail to get signers for reward checkpoint", "error", err)
return err, nil
log.Crit("Fail to get signers for reward checkpoint", "error", err)
}
rewards["signers"] = signers
rewardSigners, err := contracts.CalculateRewardForSigner(chainReward, signers, *totalSigner)
if err != nil {
log.Error("Fail to calculate reward for signers", "error", err)
return err, nil
log.Crit("Fail to calculate reward for signers", "error", err)
}
// Get validator.
validator, err := contract.NewTomoValidator(common.HexToAddress(common.MasternodeVotingSMC), client)
if err != nil {
log.Error("Fail get instance of Tomo Validator", "error", err)
return err, nil
log.Crit("Fail get instance of Tomo Validator", "error", err)
}
// Add reward for coin holders.
voterResults := make(map[common.Address]interface{})
@ -337,8 +330,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
err, rewards := contracts.CalculateRewardForHolders(foudationWalletAddr, validator, state, signer, calcReward)
// err, rewards := contracts.CalculateRewardForHolders2(foudationWalletAddr, vmenv, state, signer, calcReward)
if err != nil {
log.Error("Fail to calculate reward for holders.", "error", err)
return err, nil
log.Crit("Fail to calculate reward for holders.", "error", err)
}
voterResults[signer] = rewards
}
@ -378,27 +370,6 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
}
return false
}
eth.blockchain.HookWriteRewards = func(header *types.Header) {
if len(config.StoreRewardFolder) > 0 {
rewards := c.GetRewards(header.Hash())
if rewards == nil {
rewards = c.GetRewards(header.HashNoValidator())
if rewards != nil {
c.InsertRewards(header.Hash(), rewards)
}
}
if rewards == nil {
return
}
data, err := json.Marshal(rewards)
if err == nil {
err = ioutil.WriteFile(filepath.Join(config.StoreRewardFolder, header.Number.String()+"."+header.Hash().Hex()), data, 0644)
}
if err != nil {
log.Error("Error when save reward info ", "number", header.Number, "hash", header.Hash().Hex(), "err", err)
}
}
}
}
return eth, nil
}

View file

@ -114,8 +114,6 @@ type Config struct {
// Miscellaneous options
DocRoot string `toml:"-"`
StoreRewardFolder string
}
type configMarshaling struct {

View file

@ -40,8 +40,8 @@ type PublicDownloaderAPI struct {
// installSyncSubscription channel.
func NewPublicDownloaderAPI(d *Downloader, m *event.TypeMux) *PublicDownloaderAPI {
api := &PublicDownloaderAPI{
d: d,
mux: m,
d: d,
mux: m,
installSyncSubscription: make(chan chan interface{}),
uninstallSyncSubscription: make(chan *uninstallSyncSubscriptionRequest),
}

View file

@ -242,10 +242,10 @@ func testGetBlockBodies(t *testing.T, protocol int) {
available []bool // Availability of explicitly requested blocks
expected int // Total number of existing blocks to expect
}{
{1, nil, nil, 1}, // A single random block should be retrievable
{10, nil, nil, 10}, // Multiple random blocks should be retrievable
{limit, nil, nil, limit}, // The maximum possible blocks should be retrievable
{limit + 1, nil, nil, limit}, // No more than the possible block count should be returned
{1, nil, nil, 1}, // A single random block should be retrievable
{10, nil, nil, 10}, // Multiple random blocks should be retrievable
{limit, nil, nil, limit}, // The maximum possible blocks should be retrievable
{limit + 1, nil, nil, limit}, // No more than the possible block count should be returned
{0, []common.Hash{pm.blockchain.Genesis().Hash()}, []bool{true}, 1}, // The genesis block should be retrievable
{0, []common.Hash{pm.blockchain.CurrentBlock().Hash()}, []bool{true}, 1}, // The chains head block should be retrievable
{0, []common.Hash{{}}, []bool{false}, 0}, // A non existent block should not be returned

View file

@ -494,13 +494,7 @@ func (s *PublicBlockChainAPI) BlockNumber() *big.Int {
// BlockNumber returns the block number of the chain head.
func (s *PublicBlockChainAPI) GetRewardByHash(hash common.Hash) map[string]interface{} {
if c, ok := s.b.GetEngine().(*posv.Posv); ok {
rewards := c.GetRewards(hash)
if rewards != nil {
return rewards
}
}
return make(map[string]interface{})
return s.b.GetRewardByHash(hash)
}
// GetBalance returns the amount of wei for the given address in the state of the
@ -865,6 +859,7 @@ func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx
client, err := s.b.GetIPCClient()
if err != nil {
log.Error("Fail to connect IPC client for block status", "error", err)
return nil, err
}
var signers []common.Address
var filterSigners []common.Address
@ -874,6 +869,7 @@ func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx
signers, err = contracts.GetSignersFromContract(addrBlockSigner, client, b.Hash())
if err != nil {
log.Error("Fail to get signers from block signer SC.", "error", err)
return nil, err
}
// Get block epoc latest.
if s.b.ChainConfig().Posv != nil {

View file

@ -18,8 +18,10 @@ package les
import (
"context"
"github.com/ethereum/go-ethereum/consensus/posv"
"encoding/json"
"io/ioutil"
"math/big"
"path/filepath"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
@ -202,10 +204,24 @@ func (b *LesApiBackend) GetEngine() consensus.Engine {
return b.eth.engine
}
func (s *LesApiBackend) GetRewardByHash(hash common.Hash) map[string]interface{} {
if c, ok := s.eth.Engine().(*posv.Posv); ok {
rewards := c.GetRewards(hash)
if rewards != nil {
return rewards
header := s.eth.blockchain.GetHeaderByHash(hash)
if header != nil {
data, err := ioutil.ReadFile(filepath.Join(common.StoreRewardFolder, header.Number.String()+"."+header.Hash().Hex()))
if err == nil {
rewards := make(map[string]interface{})
err = json.Unmarshal(data, &rewards)
if err == nil {
return rewards
}
} else {
data, err = ioutil.ReadFile(filepath.Join(common.StoreRewardFolder, header.Number.String()+"."+header.HashNoValidator().Hex()))
if err == nil {
rewards := make(map[string]interface{})
err = json.Unmarshal(data, &rewards)
if err == nil {
return rewards
}
}
}
}
return make(map[string]interface{})

View file

@ -612,12 +612,12 @@ func (self *worker) commitNewWork() {
delete(self.possibleUncles, hash)
}
}
// Create the new block to seal with the consensus engine
if work.Block, err = self.engine.Finalize(self.chain, header, work.state, work.txs, uncles, work.receipts); err != nil {
log.Error("Failed to finalize block for sealing", "err", err)
return
}
if atomic.LoadInt32(&self.mining) == 1 {
// Create the new block to seal with the consensus engine
if work.Block, err = self.engine.Finalize(self.chain, header, work.state, work.txs, uncles, work.receipts); err != nil {
log.Error("Failed to finalize block for sealing", "err", err)
return
}
log.Info("Committing new block", "number", work.Block.Number(), "txs", work.tcount, "special txs", len(specialTxs), "uncles", len(uncles), "elapsed", common.PrettyDuration(time.Since(tstart)))
self.unconfirmed.Shift(work.Block.NumberU64() - 1)
self.lastParentBlockCommit = parent.Hash().Hex()

View file

@ -133,7 +133,7 @@ func (s *Server) serveRequest(codec ServerCodec, singleShot bool, options CodecO
const size = 64 << 10
buf := make([]byte, size)
buf = buf[:runtime.Stack(buf, false)]
log.Error(string(buf))
log.Error(fmt.Sprintf("RPC serveRequest %s\n", string(buf)))
}
s.codecsMu.Lock()
s.codecs.Remove(codec)
@ -344,7 +344,7 @@ func (s *Server) exec(ctx context.Context, codec ServerCodec, req *serverRequest
}
if err := codec.Write(response); err != nil {
log.Error(fmt.Sprintf("%v\n", err))
log.Error(fmt.Sprintf("RPC exec %v\n", err))
codec.Close()
}
@ -371,7 +371,7 @@ func (s *Server) execBatch(ctx context.Context, codec ServerCodec, requests []*s
}
if err := codec.Write(responses); err != nil {
log.Error(fmt.Sprintf("%v\n", err))
log.Error(fmt.Sprintf("RPC execBacth %v\n", err))
codec.Close()
}

View file

@ -71,7 +71,7 @@ func initErrHandling() {
multipleChoicesPage := GetMultipleChoicesErrorPage()
//map the codes to the available pages
tnames := map[int]string{
0: genErrPage, //default
0: genErrPage, //default
http.StatusBadRequest: genErrPage,
http.StatusNotFound: notFoundPage,
http.StatusMultipleChoices: multipleChoicesPage,