Code Monkey home page Code Monkey logo

chain33's People

Contributors

33cn avatar andyyuanfzm avatar bysomeone avatar caopingcp avatar chain33-shg avatar developerren avatar harrylee2015 avatar helpylee avatar hugo-huang avatar hxzqlh avatar jixingwei avatar jpeng-go avatar leowei1234567 avatar libangzhu avatar linj-disanbo avatar linjingljlj avatar ljh88hjl avatar lyh169 avatar lynazrael avatar mdj33 avatar qiantangriver avatar quakertlist avatar suyanlong avatar vipwzw avatar xiaoyaoyishen avatar yingqm avatar yuanchain avatar zhengjunhe avatar zjb0807 avatar zzh33cn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

chain33's Issues

CreateTx接口note字段解码失败

Describe the bug
CreateTx中的note被改成byte之后有个问题,如果note信息里面包含空格,调jrpc接口时json.unmarshal会报错"illegal base64 data at input byte 8"

To Reproduce

  1. 构造CreteTx参数,note字段直接给字符串
  2. 调用jrpc接口Chain33.CreateRawTransaction

Expected behavior
返回交易码流

Screenshots
a816f106a3dd27b8695783e4f60ee88

Int overflow in ProcSendToAddress

Describe the bug
我在看代码的时候,发现在 ProcSendToAddress 函数中存在一个溢出,当设置 amount 足够大时,可以造成溢出

	if !SendToAddress.IsToken {
		if Balance < amount+wallet.FeeAmount {
			return nil, types.ErrInsufficientBalance
		}
	} 

To Reproduce
执行下面的脚本可以触发

sendTrans = "{\"method\": \"Chain33.SendToAddress\",\"params\": [{\"From\": \"1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs\",\"To\": \"1GhMZ7vpEEGLUmxcf8KRNedjpKZYFus9dJ\",\"amount\": 9223372036854775807}],\"id\": 0}"
print sendTrans
req2 = requests.post("http://localhost:8801",data=sendTrans)
print 'sendTrans',req2.text

Expected behavior
应该抛出 amountErr 异常,而不是交易哈希

Sniffing traffic for replay attacks

Describe the bug
when I sniffing the traffic, and send it again to the server, the server return me as follow:

{"id":0,"result":null,"error":"ErrTxExist"}

the traffic contains two method: SignRawTx and Chain33.SendTransaction, but i notice that the SignRawTx method contains my -k arg as addr:

./chain33-cli send bty transfer -a 1000 -t 1GhMZ7vpEEGLUmxcf8KRNedjpKZYFus9dJ -n \"test for transfer bty\" -k 1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs

"addr": "1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs",
"txHex": ",
"expire": "120s"

So i think that it is signed in server side and I can modify something to replay the transaction.
Then i modify the expire to 121s to invoke SignRawTx, it send me a result which is different from before.
After that I invoke the SendTransaction and it return me a transaction hash, state is ExecOK !
To Reproduce

from scapy.all import *
import json,os,threading,requests

class myThread1(threading.Thread):
    def run(self):
        os.system(
            "./chain33-cli send bty transfer -a 1000 -t 1GhMZ7vpEEGLUmxcf8KRNedjpKZYFus9dJ -n \"test for transfer bty\" -k 1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs")


class myThread2(threading.Thread):
    def run(self):
        dpkt = sniff(iface='lo0', count=25, filter="tcp and ( port 8801)")
        obj = []
        for item in dpkt:
            if 'method' in str(item):
                obj.append(str(item[TCP])[181:])

        req1 = requests.post("http://localhost:8801",data=obj[0].replace("120s","121s"))
        print 'sign',obj[0]
        hs = json.loads(req1.text)['result']
        print 'result',hs
        sendTrans = "{\"method\": \"Chain33.SendTransaction\",\"params\": [{\"token\": \"BTY\",\"data\": \""+ hs +"\"}],\"id\": 0}"
        print sendTrans
        req2 = requests.post("http://localhost:8801",data=sendTrans.replace("120s","121s"))
        print 'sendTrans',req2.text
thread1 = myThread1()
thread2 = myThread2()
thread2.start()
thread1.start()

Expected behavior
it should signed in client side.

Screenshots
two different result.
image
two transaction hash
image
image
image

通过系统配置文件修改localdb的version

localdb 的version 目前直接写死在代码里面,不够灵活,也不能支持不同的链不同的版本号。
代码在 common/version , 可以把localdb 的version 通过配置文件来配置,这样更加灵活。

chain33.GetAllExecBalance接口无法根据地址查询平行链上合约中的余额

调用接口查询返回null
{"id":11,"result":{"addr":"13TTVDo8hY7GDG5Lgv492hVypukGCQNQYf","execAccount":null},"error":null}
应该是client在构造执行器名称时,没有将平行链的前缀带进去。
for _, exec := range types.AllowUserExec {
execer := string(exec)
params := &types.ReqBalance{
Addresses: addrs,
Execer: execer,
}

同步区块链数据到mysql等外部环境处理

外部程序如何实时的处理区块链的数据

我们提供了一个 blockchain seq 的接口,可以通过轮询的方式,实时的获取数据。通过这个方式,可以把数据同步到mysql 中。这个程序可以完全独立于blockchain ,类似mysql 和 blockchain的一个桥梁。如果用go直接完成整个同步应该不会有问题,但是,个人认为我们应该运行 php, nodejs 之类的擅长网页开发的脚本来做这个事情,比较好的办法是,同步好一个快以后,通知 PHP ,Nodejs 的一个callback 接口,PHP 和 nodejs 通过这个callback 接口 进一步处理数据,处理完成后,返回ok,或者调用done接口,通知这个桥接程序,已经处理完成。通知总是按照 seq的顺序通知,如果客户端没有正确标记,就会一直通知这个seq。

添加多重签名地址

添加多重签名地址

普通地址不能直接转账给多重签名地址

必须在支持多重签名地址的合约转账到多重签名地址

is there an Int Overflow?

Describe the bug
If I send a transfer command and the amount with a big number, sometimes it will throw a AmountErr.
But when I review the code, I found that as follow.

	amountInt64 := int64(math.Trunc((amount+0.0000001)*1e4)) * 1e4

So I make the amount = 1844674407370956,and it return me a transaction hash, not AmountErr.

To Reproduce

./chain33-cli send bty transfer -a 1844674407370956 -t 1GhMZ7vpEEGLUmxcf8KRNedjpKZYFus9dJ -n "test for transfer bty" -k 1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs

Expected behavior

throw amountError

Screenshots
If applicable, add screenshots to help explain your problem.
image

本地solo测试时,余额被自动买成ticket

Describe the bug
本地solo测试时,余额被自动买成ticket

To Reproduce

  1. 配置本地solo测试环境;
  2. 启动一个全新的环境;
  3. 将创世地址导入钱包,这时查看余额是正确的;
  4. 等候10分钟左右;
  5. 再次查看此地址余额,发现coins下面仅剩余一点,其余全部被买成ticket;

Expected behavior
非ticket共识下,不应该启用ticket挖矿逻辑;

Screenshots

Desktop (please complete the following information):

  • OS: Linux 4.15.0-38-generic #41-Ubuntu SMP Wed Oct 10 10:59:38 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
  • Version Chain33主干最新版本

钱包中获取区块是否已经同步处理存在数据DataRace

在部分查询通过钱包接口调用钱包中client通道查询信息时,由于其他模块存在多线程调用的场景,所以可能在高频率调用的情况下出现数据竞争问题。

考虑在初始化时增加初始化是否完成的标记,只有初始化完成以后才允许执行一系列操作。

新增feature,关键修改列表

项目有一些新增feature和修改,一旦这些issue关闭,之前未关注的人便不感知。不可能每个人去翻git记录。有的新功能大家不会使用,还需要咨询相关开发人员。

将mempool插件化改造

目的是排队方式可以配置

目前的排队方式是按时间排队,不够灵活,将mempool的模式改成consensus和store那种可以配置的、可以在plugin修改排队方式的模式就比较灵活

具体设计中,考虑到只是修改排队方式的话,mempool当前的基本流程不变,只用对cache进行分离,插件可以修改cache里缓存池的数据结构,也可以通过对cache里的方法实现来控制排队方式的修改

新增随机数Hash插件

  1. 建立一个随机数插件,各执行器可以通过封装好的消息,像获取区块高度那样,简单的从随机数插件获取一个Hash值

  2. 随机数插件,能够支持多种算法,根据配置文件选择具体的,与共识相关的算法,第一期支持ticket数据

ticket共识,节点有票,高度无法增长,log日志出现ErrBlockHashNoMatch

故障描述:测试节点日志错误如下

日志:

t=2018-11-20T10:08:02+0800 lvl=info msg=EventAddBlockDetail module=blockchain height=32298 hash=2565eb1ebea289c65e11e0d15834766e6421de8af825ddf03b6e3378ecc9c7a9
t=2018-11-20T10:08:02+0800 lvl=eror msg="addBlockDetail parent hash no match" module=blockchain err=ErrBlockHashNoMatch bestHash=0xe74be80d69c0417ea0ca4d4838e0b4796afe69105bf84772249460f1094df89e blockHash=0x23a5f9e834488c0884ceb7fffed6ee4e6f14e35eb495db4c5f7c7e5aca109caa
addBlock=true height=32298
t=2018-11-20T10:08:02+0800 lvl=eror msg=addBlockDetail module=blockchain err=ErrBlockHashNoMatch


使用cli查询结果,blockHash和bestHash查询的节点block一致
root@ubuntu055-2:/home/lcj2# ./chain33-cli block view -s 0xe74be80d69c0417ea0ca4d4838e0b4796afe69105bf84772249460f1094df89e
{
"head":

{ "version": 0, "parentHash": "0xedf7213e03f98c69d700c10f3cc76b90417024d8d202c855b77add499a049188", "txHash": "0xf27e9046164a513467c48b609706d53d9a792d760fc36fc65b2a95adddc7c87d", "stateHash": "0x591874e1fda2e250f20a5a89897c23060e2e5fdf8170faab0376c16a5f01240b", "height": 32297, "blockTime": 1542620076, "txCount": 4, "hash": "0x23a5f9e834488c0884ceb7fffed6ee4e6f14e35eb495db4c5f7c7e5aca109caa", "difficulty": 505287814 }
,
"txCount": 4,
"txHashes": [
"0x35eccb79dcf12f940990621e401aaefc7a523e7eedee7b183032b7f55147d073",
"0xfcf014282ed95209393b943230e64483dd0906761a9e7f2b98754c2ce0fb4160",
"0xdc76081b95e5b27544927128864bbbb9b3cba92f6d15f6390f5eda6750859e3c",
"0x932de9bd54a49990ebfdc11b13ff13bcf25e53f2cbff5739a60af6d348c5e545"
]
}


root@ubuntu055-2:/home/lcj2# ./chain33-cli block view -s 0x23a5f9e834488c0884ceb7fffed6ee4e6f14e35eb495db4c5f7c7e5aca109caa
{
"head":

{ "version": 0, "parentHash": "0xedf7213e03f98c69d700c10f3cc76b90417024d8d202c855b77add499a049188", "txHash": "0xf27e9046164a513467c48b609706d53d9a792d760fc36fc65b2a95adddc7c87d", "stateHash": "0x591874e1fda2e250f20a5a89897c23060e2e5fdf8170faab0376c16a5f01240b", "height": 32297, "blockTime": 1542620076, "txCount": 4, "hash": "0x23a5f9e834488c0884ceb7fffed6ee4e6f14e35eb495db4c5f7c7e5aca109caa", "difficulty": 505287814 }
,
"txCount": 4,
"txHashes": [
"0x35eccb79dcf12f940990621e401aaefc7a523e7eedee7b183032b7f55147d073",
"0xfcf014282ed95209393b943230e64483dd0906761a9e7f2b98754c2ce0fb4160",
"0xdc76081b95e5b27544927128864bbbb9b3cba92f6d15f6390f5eda6750859e3c",
"0x932de9bd54a49990ebfdc11b13ff13bcf25e53f2cbff5739a60af6d348c5e545"
]
}

执行器测试范例

目前执行器单元测试还没有一个通用好到办法,可以考虑加一个范例,做一下单元测试。

  1. 可以测试 exec 和 local del local, 测试回滚状态的 数据库是否正确。

  2. 可以考虑用一个专门用于测试的 Localdb 和 statedb

Int overflow in parseExpire.

Describe the bug
我在看代码的时候,发现在 parseExpire 函数中存在一处溢出。

func (wallet *Wallet) parseExpire(expire string) (int64, error) {
	if len(expire) == 0 {
		return 0, errors.New("Expire string should not be empty")
	}

	if expire[0] == 'H' && expire[1] == ':' {
		txHeight, err := strconv.ParseInt(expire[2:], 10, 64)
		if err != nil {
			return 0, err
		}
		if txHeight <= 0 {
			fmt.Printf("txHeight should be grate to 0")
			return 0, errors.New("txHeight should be grate to 0")
		}

		return txHeight + types.TxHeightFlag, nil
	}

types.TxHeightFlag 是常量 1<<62,但是当 expireH:9223372036854775806 时会造成溢出
To Reproduce

./chain33-cli bty transfer -a 1000 -t 1GhMZ7vpEEGLUmxcf8KRNedjpKZYFus9dJ

./chain33-cli wallet sign -d  "tx"  -a 1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs // should throw here

./chain33-cli wallet send -d "signed_tx"

Expected behavior
这个 bug 看上去似乎没有什么危害,但是它通过了 sign 阶段的检查,在 sendTransaction 阶段抛出异常,正确应该是在 sign 阶段抛出异常
Screenshots
image

db 和 receipt 操作需求调研

背景

目前 写执行器的时候,需要手工构造交易,这个引起代码非常底层和冗长。

解决方案调研

1. eos table 的概念
2. 现有系统主要的代码冗余点
3. 提供什么样的封装比较合适
4. 现有行业中主要的解决方案有什么

Query the frozen and active balance in all exec address for specific address

1.the key store format int the Store DB is like this "mavl-coins-bty-exec-exec_addr-addr",eg:mavl-coins-bty-exec-16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp:1JmFaA6unrCFYEWPGRi7uuXY1KthTJxJEP
16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp is the exec address,1JmFaA6unrCFYEWPGRi7uuXY1KthTJxJEP is the specific address.

2.we can use command as following to query the result:
cli stat exec_balance -symbol bty -exec coins -addr 1JmFaA6unrCFYEWPGRi7uuXY1KthTJxJEP -exec_addr 16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp -height -1
the result is like this:

{
    "totalAmount":10,
    "frozenAmount":3,
    "activeAmount":7,
    "execBalances":[
        {
            "execAddr":"xxxx",
            "frozen":1,
            "active":2
        },
        ...
    ]
} 

Can not sync?

I build the code from the master branch, and change the .toml file, just singleMode=true to singleMode=false, and add seeds' IPs in p2p configuration.
I lauched 5 nodes, and use rpc request IsSyncto detect, but seems cannot sync? How should I change the .toml file or the bugs in code?

工具需要增加创建项目的功能

工具程序tools可以考虑加入创建简单的工程创建向导功能, 内含简单的设置、查询值的合约。类似于一键创建bityuan的项目。

./test.sh

{
"isOK": false,
"msg": "ErrSeedWordNum"
}
{
"isOK": false,
"msg": "ErrSaveSeedFirst"
}
ErrWalletIsLocked
ErrWalletIsLocked
ErrAccountNotExist

设置交易费用后执行 SendToAddress,发生区块污染

Describe the bug
我在阅读源码中的 api 时,注意到 set_fee 可以用来设置交易费用,于是我准备测试是否会有相关的溢出,结果在我设置费用为一个大数之后,再调用 SendToAddress 时,竟然执行了一百多次 procExecAddBlock 函数,并且区块高度增加了一百多(之后每次增加的不一样,但是都很多),其中都是无效交易。
To Reproduce*
首先设置交易费用

./chain33-cli wallet set_fee -a 92233720368

然后执行下面脚本调用 SendToAddress

    sendTrans = "{\"method\": \"Chain33.SendToAddress\",\"params\": [{\"From\": \"1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs\",\"To\": \"1GhMZ7vpEEGLUmxcf8KRNedjpKZYFus9dJ\",\"amount\": 100000000}],\"id\": 0}"
    print sendTrans
    req2 = requests.post("http://localhost:8801",data=sendTrans)

Expected behavior
仅增加一个区块高度
Screenshots
image

p2p 版本的配置

p2p的版本在不主动配置的时候,默认最小版本与当前版本持平,最大版本是最小版本+1

wasm或者evm合约LocalDB存储时存在跨合约操作的风险

chain33/executor/allow.go:isAllowLocalKey中的实现中
execer = types.GetRealExecName(execer)
当调用user.wasm.xxx合约时,通过上述调用获取到的execer为wasm,
这样就会存在用户自定义合约跨合约操作的风险,
这样的情况也会发生在user.evm.xxx的合约执行过程中。
@vipwzw 你认为呢?

Chain33.getBlocks 接口可否增加出参: 交易的hash

Is your feature request related to a problem? Please describe.
此接口可以获取到区块中的所有交易的详情,但是详情中缺少了交易hash,在做浏览器时,需要额外的接口查找交易hash

Describe the solution you'd like
出参中增加交易的hash:

{
    "id":int32,
    "result":
    {
        "items":
        [
            {
                "block":
                {
                    "version":int64,
                    "parentHash":"string",
                    "txHash":"string",
                    "stateHash":"string",
                    "height":int64,
                    "blockTime":int64,
                    "txs":
                    [
                        {
                            "txhash": "交易的hash",
                            "execer":"string",
                            "payload":"string",
                            "fee":int64,
                            "expire":int32,
                            "nonce":int32,
                            "to":"string",
                            "signature":{"ty":int32,"pubkey":"string","signature":"string"}
                        }
                    ]
                },
                "receipts":
                [
                    {
                        "ty":int32,
                        "logs":[{"ty":int32,"log":"string"}]
                    }
                ]
            }
        ]
    }
}

Describe alternatives you've considered
如果不增加,需要先请求 chain33.getBlockOverview,获取到此区块中的交易hash,然后chain33.GetTxByHashes 获取到交易详情

钱包密码明文传输

Describe the bug
我抓到一些流量,显示在解锁钱包时,密码使用明文传输,这里是不是应该用公私钥加密一下,或者使用MD5。
To Reproduce

./chain33-cli wallet unlock -p test

抓取流量显示密码为明文

{
	"method": "Chain33.UnLock",
	"params": [
		{
			"passwd": "test"
		}
	],
	"id": 0
}

Expected behavior
应该用公私钥加密一下,或者使用MD5。
Screenshots
image

Javascript VM 支持

Javascript VM 相对比较成熟,可以考虑确定性改造过的JavaScript VM 以避免分叉

I found that the password stored in the log which is plain text.

Describe the bug
When I review the code, I found that the code like follow will dump the password in plain text.

func (store *Store) VerifyPasswordHash(password string) bool {
	var WalletPwHash types.WalletPwHash
	pwhashbytes, err := store.Get(CalcPasswordHash())
	if pwhashbytes == nil || err != nil {
		return false
	}
	err = json.Unmarshal(pwhashbytes, &WalletPwHash)
	if err != nil {
		storelog.Error("VerifyPasswordHash unmarshal", "err", err)
		return false
	}
	pwhashstr := fmt.Sprintf("%s:%s", password, WalletPwHash.Randstr) // dump the password
	pwhash := sha256.Sum256([]byte(pwhashstr))
	Pwhash := pwhash[:]
	//通过新的密码计算pwhash最对比
	return bytes.Equal(WalletPwHash.GetPwHash(), Pwhash)
}

Expected behavior
This bug appeared in Twitter before.
https://techcrunch.com/2018/05/03/twitter-password-bug/
Screenshots
image

rpc 接口 构造token交易 打币失败

我是通过Chain33.CreateRawTransaction 这个RPC 接口构造一笔往平行链某个地址打币的交易,签名后,查询交易详情,显示 交易不成功。
下面是我构造的过程,tokenSymbol=TEST,execName=user.p.sto.token

var params = make(map[string]interface{})
params["to"] = txinfo.GetTo()
params["amount"] = int64((txinfo.GetAmount() + 0.0000001) * 1e8)
params["fee"] = 1e5
params["note"] = txinfo.GetNote()
params["isToken"] = true
params["tokenSymbol"] = txinfo.GetTokensymbol()
params["execName"] = BtyCfg.TokenExecer
parmbs, err := json.Marshal(params)
if err != nil {
return "", err
}
postdata := fmt.Sprintf({"jsonrpc":"2.0","id":2,"method":"Chain33.CreateRawTransaction","params":[%v]}, string(parmbs))

merkle tree 计算存在哈希碰撞

Describe the bug
当我阅读关于merkle tree 生成的相关代码时,经过调试,我发现在交易数为单数时,会将最后一份交易copy 一份来计算 merkle tree 的 merkleRoot,如果恶意节点接收到 [tx1,tx2,tx3] 的 block,并将 [tx1,tx2,tx3,tx3] 的交易广播出去,两者的 merkleRoot 相同,可能造成造成双花攻击。
To Reproduce
在 merkle.go 的 Computation 函数中,这段代码,交易数为单数时会将最后一个交易copy 一份来计算 hash

	for count != (1 << level) {
		if (flage&2) != 0 && matchh {
			branch = append(branch, h)
		}
		h = GetHashFromTwoHash(h, h) // Use two identical transactions to calculate the hash
		count += (1 << level)
		level++

Expected behavior

单数交易取本身哈希在merkle tree上一层计算哈希值

目前github上面的mavl裁剪中没有加入上次说的多级裁剪机制

目前github上面的mavl裁剪中没有加入上次说的类似于多级裁剪机制,在gitlab上面的有,我是不是将gitlab上面的同步到github上先。
//二级裁剪高度,达到此高度未裁剪则放入该处
secondLevelPruningHeight = 1000000
//三级裁剪高度,达到此高度还没有裁剪,则不进行裁剪
threeLevelPruningHeight = 1500000
onceScanCount = 100000
@vipwzw

建议chain33 主链增加地址相关的域名解析

用钱包打币,需要输入很长的地址,这些地址通常比较复杂,难以记忆,如果可以通过类似DNS域名的方式来隐藏地址,这样就可以很方便的进行交易发送,构建等。

每次清空datadir后重新同步数据,都会新生成一个node award地址

如果不删除wallet节点,只删除datadir,重新同步数据,每同步一次就会生成一个node award账户,操作多次后就会有一堆node award账户;

按照正常理解,账户应该是存在钱包中,如果钱包已经有了,应该只同步区块数据,不应该再生成新的node award地址

平行链切换主节点

平行链安全的切换主节点:
不同的主节点,有不同的seq id。分成两种情况讨论:

  1. 平行链最后seq对应的hash id 可以在 另一个主链上取到,然后更新新的seq id 并继续同步。
  2. 如果最后的seq 对应的hash id 取不到,还需要一个个回滚,然后处理。
  3. 对平行链节点同步到的数据做一个安全校验,检查 prevHash 是否能够连续匹配,如果不匹配,要考虑切换节点的可能性(对负载均衡节点的情况下)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.