Coder Social home page Coder Social logo

fisco-bcos / fisco-bcos-browser Goto Github PK

View Code? Open in Web Editor NEW
174.0 14.0 117.0 65.63 MB

A broswer to show the detail infomation of a running FISCO BCOS chain

Home Page: https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/browser/browser.html

License: GNU General Public License v3.0

Java 26.77% JavaScript 11.49% CSS 4.13% Shell 0.88% HTML 12.15% Vue 40.90% Python 3.69%
fisco-bcos blockchain-explorer explorer

fisco-bcos-browser's Introduction

FISCO-BCOS 2.0区块链浏览器

CodeFactor Code Lines license GitHub (pre-)release

全新适配FISCO-BCOS 2+版本,如果使用FISCO-BCOS 1.2或1.3版本请用v1.2.1版本

区块链浏览器将区块链中的数据可视化,并进行实时展示。方便用户以Web页面的方式,获取当前区块链中的信息。觉得不错的话,就给个Star⭐️吧~~~

详细了解,请阅读技术文档

社区相关项目

  • 基于python-sdk开发的纯Python区块链浏览器 FiscoBcos-PyConsole

    FiscoBcos-PyConsole 是基于 python-sdk 开发的纯Python区块链浏览器。 对现有的浏览器进行了改进,本工程只需要Python3.5+ 即可,不再需要Python2.7, Java, 以及MySQL。

    并且对区块链数据及参数进行了Restful 的接口封装,可以直接进行HTTP请求。

    详情点击这里

  • 基于 Docker 部署的区块链浏览器

    方便一键部署,仅依赖 Docker 和 docker-compose,适配 FISCO BCOS 2.0。

    详情点击这里

fisco-bcos-browser's People

Contributors

gongdaxia avatar jimmyshi22 avatar mingzhenliu avatar sayou1989 avatar tiantiandas avatar wall-ee avatar xyzshen avatar youngwilliamz 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

fisco-bcos-browser's Issues

server 启动后log报错3065 - Expression #1 of ORDER BY clause is not in SELECT list

3065 - Expression #1 of ORDER BY clause is not in SELECT list, references column 'db_browser_test.t.block_height' which is not in SELECT list; this is incompatible with DISTINCT

路径:src/main/resources/mapper/TransactionMapper.xml
SELECT DISTINCT t.from as transFrom FROM tx_raw_data_#{groupId} t WHERE NOT EXISTS ( SELECT 1 FROM tb_chain_user WHERE group_id = #{groupId} AND address = t.from ) ORDER BY t.block_height DESC,t.tx_index DESC

Chrome/Chromium 无法编译合约,FireFox 可以

在 Chromium(75.0.3770.100 Arch Linux) 和 Chrome(75.0.3770.100) 下,此处的代码 catch 到的错误如下:

                    try {
                        o = JSON.parse(i.compileStandard(r()(s), this.findImports))
                    } catch(t) {
                        console.log(t);
                        e.errorInfo = "string" != typeof t ? r()(t) : t
                    }
RangeError: Maximum call stack size exceeded
    at Object.$db [as dynCall_viiiiii] (soljson-v0.4.25+commit.59dbf8f1.js:12)
    at invoke_viiiiii (soljson-v0.4.25+commit.59dbf8f1.js:1)
    at Array.pva (soljson-v0.4.25+commit.59dbf8f1.js:13)
    at Object.M9a [as dynCall_vi] (soljson-v0.4.25+commit.59dbf8f1.js:12)
    at invoke_vi (soljson-v0.4.25+commit.59dbf8f1.js:1)
    at Array.xta (soljson-v0.4.25+commit.59dbf8f1.js:10)
    at Object.Dfb [as dynCall_iii] (soljson-v0.4.25+commit.59dbf8f1.js:12)
    at invoke_iii (soljson-v0.4.25+commit.59dbf8f1.js:1)
    at Array.vta (soljson-v0.4.25+commit.59dbf8f1.js:10)
    at Object.Yfb [as dynCall_iiiiii] (soljson-v0.4.25+commit.59dbf8f1.js:12)

server 启动后log报错3065 - Expression #1 of ORDER BY clause is not in SELECT list

3065 - Expression #1 of ORDER BY clause is not in SELECT list, references column 'db_browser_test.t.block_height' which is not in SELECT list; this is incompatible with DISTINCT

路径:src/main/resources/mapper/TransactionMapper.xml
SELECT DISTINCT t.from as transFrom FROM tx_raw_data_#{groupId} t WHERE NOT EXISTS ( SELECT 1 FROM tb_chain_user WHERE group_id = #{groupId} AND address = t.from ) ORDER BY t.block_height DESC,t.tx_index DESC

修改sql后正常启动 但是没有定时从链上获取交易数据保存到数据库

无法启动

$ python deploy.py startAll
  File "deploy.py", line 52
    print helpMsg
                ^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(helpMsg)?

$ python -V
Python 3.7.3

GovernService.java里面异常处理太随意了,全都是throws Throwable

比如说如下几个方法

public Object getInfoByMethod(String methodName, Object[] params) throws Throwable {

public void handlePendingTransInfo() throws Throwable {

public void handleTransReceiptInfo(String hash) throws Throwable {

public Map<String, Object> handleTransInfo(JSONObject json) throws Throwable {

public void handleBlockInfo(int blockHeight) throws Throwable {

public void handleBlockInfo() throws Throwable {

public void handleBlockChainInfo() throws Throwable {

public void start() throws Throwable {

无法添加节点

安装好区块链浏览器后,添加节点提示 节点信息有误或未激活,但是rpc端口20200和p2p端口30300本地telnet都是通的,ip确认没错,groupid为1也没错,但就是无法添加,请问应该如何排查解决
image

数据库

数据库表里没有数据,页面是空白的怎么解决?

怎么停止呀?

python deploy.py run 启动后,我要修改配置文件,重启停止没有命令么?

server端sh start.sh失败

[root@localhost fisco-bcos-browser]# gradle clean
:clean

BUILD SUCCESSFUL

Total time: 4.176 secs

This build could be faster, please consider using the Gradle Daemon: https://docs.gradle.org/2.14/userguide/gradle_daemon.html
[root@localhost fisco-bcos-browser]#
[root@localhost fisco-bcos-browser]#
[root@localhost fisco-bcos-browser]# ls
build.gradle libs README.md serverStatus.sh start.sh
fisco-bcos-server mysql.sock script src stop.sh
[root@localhost fisco-bcos-browser]#
[root@localhost fisco-bcos-browser]#
[root@localhost fisco-bcos-browser]# gradle build
:compileJava
:processResources
:classes
:jar UP-TO-DATE
:assemble UP-TO-DATE
:compileTestJava
:processTestResources UP-TO-DATE
:testClasses
:test
:check
:build

BUILD SUCCESSFUL
Total time: 6.991 secs
This build could be faster, please consider using the Gradle Daemon: https://docs.gradle.org/2.14/userguide/gradle_daemon.html
[root@localhost fisco-bcos-browser]# ls
build fisco-bcos-server mysql.sock script src stop.sh
build.gradle libs README.md serverStatus.sh start.sh
[root@localhost fisco-bcos-browser]# sh start.sh

Starting org.bcos.browser.service.Main ...Error: Could not find or load main class org.bcos.browser.service.Main
[Failed]

db建表脚本注释格式有误

-- 查询块高索引
ALTER TABLE tb_block ADD INDEX index_number (number);
-- 交易表的联合索引
ALTER TABLE tb_transaction ADD INDEX index_number(blockNumber,transactionIndex);

#原注释横杠后缺少空格导致执行失败

建议增加合约事件浏览功能

目前在区块浏览器里看不到合约事件,不知道合约里面发生了什么,对开发调试和问题排查有很大的障碍,所以希望能有这样的功能。
希望能通过搜索合约,来浏览该合约上发生的事情,包括:

  1. emit Transfer(_from, _to, _value); 合约事件
  2. require(msg.sender == admin, 'only admin can do this'); 异常信息

如果能开放JSON-RPC API接口来获取以上数据,那就更好了

Error occurs in ReportAgent.py

After I run sh start_Agent.sh, an error found in agentOut.txt:

[root@iZwz90zd30oi79xmeuayxnZ report]# cat agentOut.txt 
Traceback (most recent call last):
  File "/root/fisco-bcos-browser/report/ReportAgent.py", line 855, in <module>
    main()
  File "/root/fisco-bcos-browser/report/ReportAgent.py", line 847, in main
    nodes_state[node[0]] = NodeState(node) # init node state
  File "/root/fisco-bcos-browser/report/ReportAgent.py", line 456, in __init__
    ret = parseLogConf(logconf, node[0])
  File "/root/fisco-bcos-browser/report/ReportAgent.py", line 437, in parseLogConf
    print "file:" + logconf + " not exist or other error: " + e + " for node:" + nodename
TypeError: cannot concatenate 'str' and 'exceptions.IOError' objects

I only change first few lines , my changed ReportAgent.py:

#!/usr/bin/env python 
# -*- coding: utf-8 -*-


# @file: AgentBROWSER_SERVER.py
# @author: fisco <[email protected]>
#
# @date: 2017


import requests
import threading
import socket
import json
import time
import sys
import os
import re
import datetime
from copy import deepcopy
# reload(sys)
# sys.setdefaultencoding( "utf-8" )
######################  参数配置  ######################
ACCESS_NODE_INTERVAL = 60 #60s 多久询问、上报一次node的信息

HOST_IP = "****" #本机器的外网IP,仅作为浏览器端区分是哪台机器上报的数据
BROWSER_SERVER_IP = "localhost" #上报server端的IP
BROWSER_SERVER_PORT = "8080" #上报server端的端口

node0 = ["node0", "~/wujie/build/node0/log.conf", 8545] #node的名字, log.conf的路径, RPC端口号, node的log目录(可选)
node1 = ["node1", "~/wujie/build/node1/log.conf", 8546] #node的名字, log.conf的路径, RPC端口号, log.conf的路径(可选)

#nodes = [node0]
nodes = [node0, node1]
BROWSER_SERVER_URL = "http://"+ BROWSER_SERVER_IP + ":" + BROWSER_SERVER_PORT + "/fisco-bcos-server/browserFacade" 
ALERT_URL = "http://"+ BROWSER_SERVER_IP + ":" + BROWSER_SERVER_PORT + "/fisco-bcos-server/browserFacade" #保留功能,目前未实现
###################### 参数配置结束 ###################### 

##################  保留字段 无需配置  ###################
ALERT_WAY = "1,2,3" 
ALERT_RECIVER = "bcosorg"
USER_AUTH_KEY = "fisco-bcos" #保留的字段,可以任意设置
INTERFACE_NAME = "test_chain0" #链的标识,任意设置
#########################################################
def getHostIp():
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect((BROWSER_SERVER_IP, int(BROWSER_SERVER_PORT)))
        ip = s.getsockname()[0]
    except:
        print "Could not connect to BROWSER_SERVER" + BROWSER_SERVER_IP + ":" + BROWSER_SERVER_PORT
    finally:
        s.close()
 
    return ip

#HOST_IP = getHostIp() #本机器的IP地址
########################################################
# cpp 定义
STAT_PBFT_VIEWCHANGE_TAG = "PBFT ViewChange"

STAT_DB_GET = "DB get"
STAT_DB_SET = "DB set"
STAT_DB_GET_SIZE = "DB get size"
STAT_DB_SET_SIZE = "DB set size"
STAT_DB_HIT_MEM = "DB hit mem"

STAT_TX_EXEC = "TX Exec"
STAT_TX_TRACE = "Tx Trace Time"
STAT_BLOCK_PBFT_SEAL = "PBFT Seal Time"
STAT_BLOCK_PBFT_EXEC = "PBFT Exec Time"
STAT_BLOCK_PBFT_SIGN = "PBFT Sign Time"
STAT_BLOCK_PBFT_COMMIT = "PBFT Commit Time"
STAT_BLOCK_PBFT_CHAIN = "PBFT BlkToChain Time"
STAT_BLOCK_PBFT_VIEWCHANGE = "PBFT viewchange time"

REPORT_CAT_MAX = "max"
REPORT_CAT_MIN = "min"
REPORT_CAT_AVG = "avg"
REPORT_CAT_CNT = "cnt"
REPORT_CAT_SUC_CNT = "suc_cnt"
REPORT_CAT_SUC_PER = "suc_per"

### 其他
BLOCK_HEIGHT = "Block Height"
PBFT_VIEW = "PBFT View"
UNV_BLOCK_Q_SIZE = "Unverified Block Queue Size"
V_BLOCK_Q_SIZE = "Verified Block Queue Size"
UNV_TX_Q_SIZE = "Unverified Transactions Queue Size"
V_TX_Q_SIZE = "Verified Transactions Queue Size"

TX_FLOW = "tx_flow"
BLOCK_FLOW = "block_flow"

ENLARGE_FACTOR = 10000
SEP_SYMBLE = "|"
NORMAL_SEP_SYMBLE = "_"

__report_real_name = {
    STAT_DB_GET : u"数据库读",
    STAT_DB_SET : u"数据库写",
    STAT_DB_GET_SIZE : u"读数据大小(B)",
    STAT_DB_SET_SIZE : u"写数据大小(B)",
    STAT_DB_HIT_MEM : u"命中缓存",
    STAT_TX_EXEC : u"交易执行耗时(毫秒)",
    STAT_TX_TRACE : u"交易上链总耗时(毫秒)",
    STAT_BLOCK_PBFT_SEAL : u"PBFT打包耗时(毫秒)",
    STAT_BLOCK_PBFT_EXEC : u"PBFT执行耗时(毫秒)",
    STAT_BLOCK_PBFT_SIGN : u"PBFT签名耗时(毫秒)",
    STAT_BLOCK_PBFT_COMMIT : u"PBFT提交耗时(毫秒)",
    STAT_BLOCK_PBFT_CHAIN : u"PBFT区块落盘耗时(毫秒)",
    STAT_BLOCK_PBFT_VIEWCHANGE : u"PBFT_View共识耗时(毫秒)",
    REPORT_CAT_MAX : u"最大", 
    REPORT_CAT_MIN : u"最小",
    REPORT_CAT_AVG : u"平均",
    REPORT_CAT_CNT : u"总数",
    REPORT_CAT_SUC_CNT : u"成功次数", 
    REPORT_CAT_SUC_PER : u"成功百分比",
    BLOCK_HEIGHT : u"区块高度",
    PBFT_VIEW : u"PBFT view大小",
    UNV_BLOCK_Q_SIZE : u"未确认块队列大小",
    V_BLOCK_Q_SIZE : u"确认块队列大小",
    UNV_TX_Q_SIZE : u"未确认交易队列大小",
    V_TX_Q_SIZE : u"确认交易队列大小",
    TX_FLOW : u"交易流程跟踪",
    BLOCK_FLOW : u"出块流程跟踪",
}


def enlargeValue(value):
    return float(value) * ENLARGE_FACTOR


def doNothing(value): return value

ATTR_NAME = "attr"
__report_key_rule = {
    # for db
    STAT_DB_GET : {
        ATTR_NAME : "db_get",
        REPORT_CAT_MAX : doNothing,
        REPORT_CAT_MIN : doNothing,
        REPORT_CAT_AVG : doNothing,
        REPORT_CAT_CNT : doNothing,
    },
    STAT_DB_SET : {
        ATTR_NAME : "db_set",
        REPORT_CAT_MAX : doNothing,
        REPORT_CAT_MIN : doNothing,
        REPORT_CAT_AVG : doNothing,
        REPORT_CAT_CNT : doNothing,
    },
    STAT_DB_GET_SIZE : {
        ATTR_NAME : "db_get_size",
        REPORT_CAT_MAX : doNothing,
        REPORT_CAT_MIN : doNothing,
        REPORT_CAT_AVG : doNothing,
    },
    STAT_DB_SET_SIZE : {
        ATTR_NAME : "db_set_size",
        REPORT_CAT_MAX : doNothing,
        REPORT_CAT_MIN : doNothing,
        REPORT_CAT_AVG : doNothing,
    },
    STAT_DB_HIT_MEM : {
        ATTR_NAME : "db_hit_mem",
        REPORT_CAT_CNT : doNothing,
        REPORT_CAT_SUC_CNT : doNothing,
        REPORT_CAT_SUC_PER : doNothing,
    },
    # for tx
    STAT_TX_EXEC : {
        ATTR_NAME : "tx_exec",
        REPORT_CAT_MAX : doNothing,
        REPORT_CAT_MIN : doNothing,
        REPORT_CAT_AVG : doNothing,
        REPORT_CAT_CNT : doNothing,
    },
    STAT_TX_TRACE : {
        ATTR_NAME : "tx_trace",
        REPORT_CAT_MAX : doNothing,
        REPORT_CAT_MIN : doNothing,
        REPORT_CAT_AVG : doNothing,
    },
    # PBFT
    STAT_BLOCK_PBFT_SEAL : {
        ATTR_NAME : "pbft_seal",
        REPORT_CAT_MAX : doNothing,
        REPORT_CAT_MIN : doNothing,
        REPORT_CAT_AVG : doNothing,
    },
    STAT_BLOCK_PBFT_EXEC : {
        ATTR_NAME : "pbft_exec",
        REPORT_CAT_MAX : doNothing,
        REPORT_CAT_MIN : doNothing,
        REPORT_CAT_AVG : doNothing,
    },
    STAT_BLOCK_PBFT_SIGN : {
        ATTR_NAME : "pbft_sign",
        REPORT_CAT_MAX : doNothing,
        REPORT_CAT_MIN : doNothing,
        REPORT_CAT_AVG : doNothing,
    },
    STAT_BLOCK_PBFT_COMMIT : {
        ATTR_NAME : "pbft_commit",
        REPORT_CAT_MAX : doNothing,
        REPORT_CAT_MIN : doNothing,
        REPORT_CAT_AVG : doNothing,
    },
    STAT_BLOCK_PBFT_CHAIN : {
        ATTR_NAME : "pbft_chain",
        REPORT_CAT_MAX : doNothing,
        REPORT_CAT_MIN : doNothing,
        REPORT_CAT_AVG : doNothing,
    },
    STAT_BLOCK_PBFT_VIEWCHANGE : {
        ATTR_NAME : "pbft_viewchange",
        REPORT_CAT_MAX : doNothing,
        REPORT_CAT_MIN : doNothing,
        REPORT_CAT_AVG : doNothing,
    },
}
__alert_key = { STAT_PBFT_VIEWCHANGE_TAG : "timeout and viewchange" }

def statFilename(log_filename_format, less_time=0):
    # find log file
    # 按log.conf中的文件名格式进行文件名生成,减少的时间为格式最后一位的时间单位
    # 如配置为 "%Y%M%d%H" 日志为 YYYYMMDDHH , 那么就减少HH个单位对应的less_time时间生成文件名
    flag = log_filename_format[-1]
    t = datetime.timedelta(hours=int(less_time))
    if flag == "H":
        pass
    elif flag == "m":
        t = datetime.timedelta(minutes=int(less_time))
    elif flag == "d":
        t = datetime.timedelta(days=int(less_time))
    elif flag == "s":
        t = datetime.timedelta(seconds=int(less_time))
    logtime = (datetime.datetime.now() - t).strftime(log_filename_format)
    # logtime = (datetime.datetime.now() - datetime.timedelta(hours=int(less_hour))).strftime("%Y%m%d%H")
    suffix = logtime + '.log'
    return "stat_log_" + suffix
    
#######################################################
#### global var
nodes_state = dict()
TAIL_LINE_NUM = 1000
TAIL_TIME_GAP = ACCESS_NODE_INTERVAL  # 1 min
####################################################### 

def currentMs():
    return int(time.time()*1000)

# tail 工具
PAGE = 4096
class Tail(object):
    def __init__(self, filename, callback=sys.stdout.write):
        self.filename = filename
        self.callback = callback

    def n(self, n=10, node=-1):
        with open(self.filename, 'rb') as f:
            f.seek(0, 2)
            f_len = f.tell()
            rem = f_len % PAGE
            page_n = f_len // PAGE
            r_len = rem if rem else PAGE
            while True:
                if r_len >= f_len:
                    f.seek(0)
                    lines = f.readlines()[::-1]
                    break

                f.seek(-r_len, 2)
                # print('f_len: {}, rem: {}, page_n: {}, r_len: {}'.format(f_len, rem, page_n, r_len))
                lines = f.readlines()[::-1]
                count = len(lines) -1   # 末行可能不完整,减一行,加大读取量

                if count >= n:
                    break
                else:
                    r_len += PAGE
                    page_n -= 1
            output_line = lines[:n]
            output_line.reverse()
            if node == -1:
                for line in output_line:
                    self.callback(line)
            else:
                for line in output_line:
                    self.callback(line, node)
            pass
        pass

__tx_flow_pattern = re.compile(r'\[tx\](.+)')
__block_flow_pattern = re.compile(r'\[block\](\[Leader\])?(.+)')
__common_pattern = re.compile(r'([\w\s]+)\[(.+)\]:([\d:\s]+)')

__tx_flow_template = {
    "hash" : None,
    "start" : None,
    "onChain" : None
}
__block_flow_template = {
    "hash": None,
    "leader": False,
    "empty" : True,
    "height": 0,
    "start": None,
    "sealed": None,
    "execed": None,
    "signed": None,
    "commited": None,
    "onChain": None,
    "viewchange_start": None,
    "viewchanged": None,
}

def parseTxFlowLog(logstr):
    ret = __tx_flow_pattern.match(logstr)
    if ret is None or len(ret.groups()) != 1:
        return None
    
    s = ret.group(1)
    ret = s.split("|")
    m = deepcopy(__tx_flow_template)

    for item in ret:
        tmp = __common_pattern.match(item.strip())
        if tmp is None or len(tmp.groups()) != 3:
            continue
        tmp = tmp.groups()
        if tmp[0] == "start":
            m["hash"] = "0x" + tmp[1]
            m["start"] = { "msg" : None, "time" : tmp[2].strip() }
        else:
            m[tmp[0]] = { "msg" : tmp[1].strip(), "time" : tmp[2].strip() }
    return m


def parseBlockFlowLog(logstr):
    ret = __block_flow_pattern.match(logstr)
    if ret is None:
        return None

    if len(ret.groups()) != 2:
        return

    m = deepcopy(__block_flow_template)
    if ret.group(1):
        m['leader'] = True

    s = ret.group(2)
    isLeader = True
    ret = s.split("|")

    for item in ret:
        tmp = __common_pattern.match(item.strip())
        if tmp is None or len(tmp.groups()) != 3:
            continue
        tmp = tmp.groups()
        if tmp[0] == "execed":
            if tmp[1].startswith("#empty"):
                m["empty"] = True
                m["execed"] = { "msg" : tmp[1].strip(), "time" : tmp[2].strip() }               
            else:
                m["empty"] = False
                msg = ""
                for i in tmp[1].split(" "):
                    t=i.split(":")
                    if len(t) == 2:
                        if t[0] == "hash":
                            m["hash"] = "0x" + t[1]
                        elif t[0] == "height":
                            m["height"] = int(t[1])
                        elif t[0] == "unexected_hash":
                            msg += i
                            msg += " "
                        elif t[0] == "txnum":
                            msg += i
                            msg += " "
                m["execed"] = { "msg" : msg if msg else None, "time" : tmp[2].strip() }
        else:
            msg = tmp[1].strip()
            m[tmp[0]] = { "msg" : msg if msg else None, "time" : tmp[2].strip() }
    if m["empty"] == True:
        return None #若需要不上报空块则return None
    return m


def timeStrToStand(s):
    d = {
        r'%M':r'%m',
        r'%m':r'%M',
        r'%s':r'%S',
        r'%g':r'%f',
    }
    # p = r'\b(' + '|'.join(d.keys()) + r')\b'
    p = '|'.join(d.keys())
    pattern = re.compile(p)
    return pattern.sub(lambda x: d[x.group()], s)


def parseLogConf(logconf, nodename):
    try:
        time_format = ""
        file_format = ""
        dir_path = ""
        with open(logconf) as f:
            for line in f:
                line = line.strip()
                if line.startswith("*"):
                    if line.find("GLOBAL"): # only pickup GLOBAL block
                        for i in f:
                            line = i.strip()
                            if line.startswith("*"):
                                break # jump two level loop
                            # parse
                            if line.startswith("FORMAT"):
                                m = re.match(r'.*\{(.*)\}.*', line)
                                if m is not None and m.group(1): # pick up time format
                                    time_format = timeStrToStand(m.group(1))
                            elif line.startswith("FILENAME"):
                                m = re.match(r'(.*\"(.+)\/.*)?\{(.*)\}.*', line)
                                if m is not None and m.group(3): # pick up time format
                                    dir_path = m.group(2)
                                    file_format = timeStrToStand(m.group(3))
                        else: # pair with for
                            continue
                break

        if time_format and file_format and dir_path:
            return (time_format, file_format, dir_path)
        print "Not found related value(FORMAT, FILENAME, DIR_PATH)[", time_format, file_format, dir_path, "] in GLOBAL block in log.conf for node:" + nodename
        return None
    except Exception, e:
        print "file:" + logconf + " not exist or other error: " + e + " for node:" + nodename
    return None


class NodeState(object):
    def __init__(self, node):
        self.node_name = node[0]
        self.last_alert = dict()
        self.filter_time = 0
        self.flow_filter_time = 0
        self.tx_flow_log = []
        self.block_flow_log = []
        self.lock = threading.Lock()

        self.log_time_format = '%Y-%m-%d %H:%M:%S'
        self.log_filename_format = "%Y%M%d%H"
        self.dir_path = ""

        logconf = node[1]
        ret = parseLogConf(logconf, node[0])
        if ret is None:
            print "node:" + node[0] + ", some thing wrong for parsing log.conf"
            exit(1)
        self.log_time_format = ret[0]
        self.log_filename_format = ret[1]
        self.dir_path = ret[2]

        if len(node) >= 4: # [name, logconf, port, logpath]
            self.dir_path = node[3]
            
        if not self.dir_path.startswith("/"):
            print 'node:' + node[0] + ", "\
                'the dir_path is [' + self.dir_path + \
                '] in log.conf or parse log.conf error. We suggest to use absolute path for dir_path to find log file. ' + \
                'Add absolute path as the 4th params in node, e.g. ["node0", "/bcos-data/node0/log.conf", 8545, "/bcos-data/node0/log/"]'
            exit(1)

    def getLastReport(self, attr_name):
        return self.last_alert.get(attr_name, 0)

    def setLastReport(self, attr_name, report_time):
        self.last_alert[attr_name] = report_time

    def shouldReport(self, attr_name):
        now=currentMs() 
        last_time=self.getLastReport(attr_name)
        if now - last_time > 60000 : #相同的告警60s上报一次
            self.setLastReport(attr_name, now)
            return True
        return False

    def logTxFlow(self, logstr):
        tmp = parseTxFlowLog(logstr)
        if tmp:
            self.lock.acquire()
            self.tx_flow_log.append(tmp)
            self.lock.release()

    def logBlockFlow(self, logstr):
        tmp = parseBlockFlowLog(logstr)
        if tmp:
            self.lock.acquire()
            self.block_flow_log.append(tmp)
            self.lock.release()

    def popTxFlowLog(self):
        self.lock.acquire()
        arr = self.tx_flow_log
        self.tx_flow_log = [] # reset
        self.lock.release()
        return arr
    
    def popBlockFlowLog(self):
        self.lock.acquire()
        arr = self.block_flow_log
        self.block_flow_log = [] # reset
        self.lock.release()
        return arr

    pass


def thread_postToBrowserServer(node_name, attr, attr_name, value, timestamp):
    arguement = {
        "userAuthKey" : USER_AUTH_KEY,
        "metricDataList":[
            {
                "interfaceName": INTERFACE_NAME,
                "object" : HOST_IP + "_" + node_name,
                "attr": attr,
                "attrName": attr_name,
                "collectTimestamp": timestamp,
                "metricValue": value,
                "hostIp": HOST_IP
            }
        ]
    }
    print arguement
    try:
        rsp = requests.post(BROWSER_SERVER_URL, json=arguement)
    except:
        print "Could not post to BROWSER_SERVER"


def postToBrowserServer(node_name, attr, attr_name, value, timestamp):
    #开一个子线程发送
    t = threading.Thread(target = thread_postToBrowserServer, 
                      args = (node_name, attr, attr_name, value, timestamp), 
                     name = "thread_postToBrowserServer")
    t.start()


def thread_postAlert(node_name, attr_name, alert_level, alert_info, timestamp):
    arguement = {
        "alertList":[
            {
                "alert_title" : attr_name,
                "alert_level" : alert_level,
                "alert_obj" : HOST_IP + "_" + node_name,
                "alert_info" : "[timestamp:" + str(timestamp) + "] " + attr_name + ": " + alert_info,
                "alert_ip" : HOST_IP,
                "alert_way" : ALERT_WAY,
                "alert_reciver" : ALERT_RECIVER
            }
        ]   
    }
    print "##Alert:"
    print arguement
    try:
        rsp = requests.post(ALERT_URL, json=arguement)
        print rsp.text
    except:
        print "Could not report alert"


def postAlert(node_name, attr_name, alert_level, alert_info, timestamp):
    #alert_level: 数字  1:critical,2:major,3:minor,4:warning, 5:info。告警级别 critical > major > minor > warning > info
    return
    state = nodes_state.get(node_name, None)
    if state is not None:
        if state.shouldReport(attr_name):
            #开一个子线程发送
            t = threading.Thread(target = thread_postAlert, 
                            args = (node_name, attr_name, alert_level, alert_info, timestamp), 
                            name = "thread_postAlert")
            t.start()
    else:
        # todo add other alert
        pass

#########

__timeFilterPattern = re.compile(r'\w+\|((\w|-|:| |)+)\|(.+)')
__pattern = re.compile(r'.+\[\d+\]\[(.*)\]\[.*\](.+)')


def parser(line, node_state):
    if not line.startswith("##State"):
        return

    m = __pattern.match(line)
    if m is None or len(m.groups()) != 2:
        print "error in parser: \n" + line
        return
    name = m.group(1)
    s = m.group(2)
    item = s.split("|")
    
    if name in __alert_key: # 发警告信息    
        postAlert(node_state.node_name, name, 4, __alert_key[name], currentMs())
        return 

    # 正常上报
    if name in __report_key_rule:
        for i in item:
            ret = i.split(":")
            rawkey = ret[0].strip()
            if rawkey in __report_key_rule[name]:
                value = ret[1].strip()
                key = __report_key_rule[name][ATTR_NAME] + NORMAL_SEP_SYMBLE + rawkey
                report_key = __report_real_name[name] + " " + SEP_SYMBLE + " " + __report_real_name[rawkey]
                postToBrowserServer(node_state.node_name, key, report_key, __report_key_rule[name][rawkey](value), currentMs())
    pass


def parser2(line, node_state):
    if not line.startswith("##State Report"):       
        if line.startswith("[tx]"):
            node_state.logTxFlow(line)
        elif line.startswith("[block]"):
            node_state.logBlockFlow(line)


def logtimeparser(t, format):
    # return time.mktime(time.strptime(t, '%Y-%m-%d %H:%M:%S'))
    return time.mktime(time.strptime(t, format))


def timeCompare(t, node_state):
    now = 0
    try:
        now = logtimeparser(t, node_state.log_time_format)
    except:
        return True

    if now > node_state.filter_time:
        node_state.filter_time = now - TAIL_TIME_GAP
        return True 
    return False


def timeCompare2(t, node_state):
    now = 0
    try:
        now = logtimeparser(t, node_state.log_time_format)
    except:
        return True

    if now > node_state.flow_filter_time:
        node_state.flow_filter_time = now - 1 # TODO 修改成宏定义
        return True
    return False


def handleLine(line, node_state, compare, callback):  # filter time and line header 
    m = __timeFilterPattern.match(line)
    if m is None or len(m.groups()) != 3:
        print "error in handleLine parser: \n" + line
        return
    t = m.group(1)
    s = m.group(3)
    #print line
    if compare(t.strip(), node_state):
        # print line
        callback(s.strip(), node_state)
        pass


def handleFile(line, node_state):
    handleLine(line.strip(), node_state, timeCompare, parser)


def handleFile2(line, node_state):
    handleLine(line.strip(), node_state, timeCompare2, parser2)


def readFile(filename, node_state):
    py_tail = Tail(filename, handleFile)
    py_tail.n(TAIL_LINE_NUM, node_state)


def readFile2(filename, node_state):
    py_tail = Tail(filename, handleFile2)
    py_tail.n(500, node_state)


def accessFile(node_state, callback, recursive_deep=0):
    name = statFilename(node_state.log_filename_format, recursive_deep) # 每次递归减少1单位对应时间
    filename = node_state.dir_path + "/" + name
    
    if os.path.isfile(filename):
        callback(filename, node_state)
    else:
        if recursive_deep == 3: # 递归三次就出去,相当于向前找3个文件
            # todo can't find file
            print "can't find file for:" + filename
            postAlert(node_state.node_name, "logfile access ERROR", 5, "can't find file for:" + filename + ", try to find prev log file", currentMs())
        else:
            accessFile(node_state, callback, recursive_deep + 1)
    pass


def accessLog(node_state, interval=60):
    for sec in range(interval) :
        #流程统计上报interval次,每隔1s上报一次
        time.sleep(1)
        accessFile(node_state, readFile2)
        postToBrowserServer(node_state.node_name, TX_FLOW, __report_real_name[TX_FLOW], node_state.popTxFlowLog(), currentMs())
        postToBrowserServer(node_state.node_name, BLOCK_FLOW, __report_real_name[BLOCK_FLOW], node_state.popBlockFlowLog(), currentMs())        

    #单点统计在sleep了interal后再统一上报
    accessFile(node_state, readFile)
    # TODO 1秒一次

    pass
  
############# RPC 端口数据上报 #################
# last_report_time = 0
def accessNodeRpcPort(arguement, node_name, rpcPort):
    #print arguement
    try:
        rsp = requests.post("http://" + HOST_IP + ":" + str(rpcPort), json=arguement)
        print rsp.text
        info = json.loads(rsp.text) 
        return info #返回查询结果的json对象
    except:
        print "Could not access " + node_name + " RPC port " + str(rpcPort)

        #RPC端口错误,则告警
        # global last_report_time
        # if currentMs() - last_report_time > 60000 : #相同的告警60s上报一次
        postAlert(node_name, "RPC port not avaliable", 4, "AgentBROWSER_SERVER.py could not access RPC port. ", currentMs())
            # last_report_time = currentMs()
        raise Exception("Node RPC port access error")


def accessBlockNumber(node_name, rpcPort):
    arguement = {"jsonrpc":"2.0", "method":"eth_blockNumber", "params":[], "id":3424}

    info = []
    try:
        info = accessNodeRpcPort(arguement, node_name, rpcPort)
    except:
        return

    block_height = int(info["result"], 16)
    print "Block height " + str(block_height)
    # TODO fix postToBrowserServer attr
    postToBrowserServer(node_name, BLOCK_HEIGHT, __report_real_name[BLOCK_HEIGHT], block_height, currentMs()) 


def accessBlockView(node_name, rpcPort):
    arguement = {"jsonrpc": "2.0","method": "eth_pbftView", "params":[], "id":3424}
    info = []
    try:
        info = accessNodeRpcPort(arguement, node_name, rpcPort)
    except:
        return

    block_view = int(info["result"], 16)
    print "Block View " + str(block_view)
    # TODO fix postToBrowserServer attr
    postToBrowserServer(node_name, PBFT_VIEW, __report_real_name[PBFT_VIEW], block_view, currentMs())


def accessUnverifiedBlockQueueNumber(node_name, rpcPort):
    arguement = {"jsonrpc":"2.0", "method":"eth_unverifiedBlockQueueSize", "params":[], "id":3424}
    info = []
    try:
        info = accessNodeRpcPort(arguement, node_name, rpcPort)
    except:
        return

    num = int(info["result"], 16)
    print "UnverifiedBlockQueueSize " + str(num)
    # TODO fix postToBrowserServer attr
    postToBrowserServer(node_name, UNV_BLOCK_Q_SIZE, __report_real_name[UNV_BLOCK_Q_SIZE], num, currentMs())


def accessVerifiedBlockQueueNumber(node_name, rpcPort):
    arguement = {"jsonrpc":"2.0", "method":"eth_verifiedBlockQueueSize", "params":[], "id":3424}
    info = []
    try:
        info = accessNodeRpcPort(arguement, node_name, rpcPort)
    except:
        return

    num = int(info["result"], 16)
    print "VerifiedBlockQueueSize " + str(num)
    # TODO fix postToBrowserServer attr
    postToBrowserServer(node_name, V_BLOCK_Q_SIZE, __report_real_name[V_BLOCK_Q_SIZE] , num, currentMs())


def accessUnverifiedTxQueueNumber(node_name, rpcPort):
    arguement = {"jsonrpc":"2.0","method":"eth_unverifiedTransactionsQueueSize","params":[],"id":3424}
    info = []
    try:
        info = accessNodeRpcPort(arguement, node_name, rpcPort)
    except:
        return

    num = int(info["result"], 16)
    print "UnverifiedTransactionsQueueSize " + str(num)
    # TODO fix postToBrowserServer attr
    postToBrowserServer(node_name, UNV_TX_Q_SIZE, __report_real_name[UNV_TX_Q_SIZE], num, currentMs())


def accessVerifiedTxQueueNumber(node_name, rpcPort):
    arguement = {"jsonrpc":"2.0","method":"eth_verifiedTransactionsQueueSize","params":[],"id":3424}
    info = []
    try:
        info = accessNodeRpcPort(arguement, node_name, rpcPort)
    except:
        return

    num = int(info["result"], 16)
    print "VerifiedTransactionsQueueSize " + str(num)
    # TODO fix postToBrowserServer attr
    postToBrowserServer(node_name, V_TX_Q_SIZE, __report_real_name[V_TX_Q_SIZE], num, currentMs())

def accessRpc(node_name, rpcPort):
    accessBlockNumber(node_name, rpcPort)
    accessBlockView(node_name, rpcPort)
    accessUnverifiedBlockQueueNumber(node_name, rpcPort)
    accessVerifiedBlockQueueNumber(node_name, rpcPort)
    accessUnverifiedTxQueueNumber(node_name, rpcPort)
    accessVerifiedTxQueueNumber(node_name, rpcPort)

##############################

def accessNodeByTime(interval, node):
    #每隔interval,查询上报
    while True:
        print "accessNodeInfo " + node[0] + " " + node[1] + " " + str(node[2])
        accessRpc(node[0], node[2])
        # accessLog(node[0], node[1], interval) #与accessRpc不同,accessLog中,流程统计跑interval次,每1s上报一次,待interval后,将单点统计统一上报
        accessLog(nodes_state[node[0]], interval)

def main():
    for node in nodes:
        nodes_state[node[0]] = NodeState(node) # init node state
        #每个node一个Agent线程
        t = threading.Thread(target = accessNodeByTime,
                             args = (ACCESS_NODE_INTERVAL, node),
                             name = "thread_access_node")
        t.start()

if __name__ == "__main__":
    main()

dev2.0.0 gradle build error

Starting a Gradle Daemon, 13 busy Daemons could not be reused, use --status for details

FAILURE: Build failed with an exception.

  • Where:
    Build file '/home/app/fisco/fisco-bcos-browser/server/fisco-bcos-browser/build.gradle' line: 52

  • What went wrong:
    A problem occurred evaluating root project 'fisco-bcos-browser'.

Could not find method annotationProcessor() for arguments [org.projectlombok:lombok:1.18.2] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.

  • Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

  • Get more help at https://help.gradle.org

群组和节点配置希望重新修改

目前区块链浏览器默认是提供给普通用户查看使用,但是由于群组和节点是直接可以修改,经常会有用户上去修改,导致程序不能用。

区块链浏览器群组和节点配置希望做成后台配置、或者文件配置,如果只是在内网使用的区块链浏览器,没多大使用性,毕竟后台的sdk、webase等都可以实现相关技术对接。

在重启浏览器Tomcat服务以后,报主键冲突的错误,再也不能愉快的使用了

Caused by: org.springframework.dao.DuplicateKeyException:

Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '0x14182e0d8082c05bfbbb196eae807c2e01ee6f96efeed8021c6640e6d51954' for key 'PRIMARY'

The error may involve cn.bcos.browser.dao.GovernServiceDAO.insertTransactionInfo-Inline

The error occurred while setting parameters

SQL: insert into tb_transaction( pk_hash, blockHash, blockNumber, blockTimestamp, blockGasLimit, transactionIndex, transactionFrom, transactionTo, gas, gasPrice, cumulativeGas, randomId, contractName, version, method, params, inputText, gmt_create, gmt_modify ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW() )

Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '0x14182e0d8082c05bfbbb196eae807c2e01ee6f96efeed8021c6640e6d51954' for key 'PRIMARY'

; SQL []; Duplicate entry '0x14182e0d8082c05bfbbb196eae807c2e01ee6f96efeed8021c6640e6d51954' for key 'PRIMARY'; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '0x14182e0d8082c05bfbbb196eae807c2e01ee6f96efeed8021c6640e6d51954' for key 'PRIMARY'
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:239) ~[spring-jdbc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73) ~[spring-jdbc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:73) ~[mybatis-spring-1.2.2.jar:1.2.2]
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:371) ~[mybatis-spring-1.2.2.jar:1.2.2]
at com.sun.proxy.$Proxy30.insert(Unknown Source) ~[?:?]
at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:240) ~[mybatis-spring-1.2.2.jar:1.2.2]
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:51) ~[mybatis-3.2.8.jar:3.2.8]
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:52) ~[mybatis-3.2.8.jar:3.2.8]
at com.sun.proxy.$Proxy34.insertTransactionInfo(Unknown Source) ~[?:?]
at sun.reflect.GeneratedMethodAccessor207.invoke(Unknown Source) ~[?:?]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_131]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_131]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317) ~[spring-aop-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) ~[spring-aop-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) ~[spring-tx-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281) ~[spring-tx-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) ~[spring-tx-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) ~[spring-aop-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at com.sun.proxy.$Proxy35.insertTransactionInfo(Unknown Source) ~[?:?]
at cn.bcos.browser.service.GovernService.handleTransInfo(GovernService.java:231) ~[classes/:?]
at cn.bcos.browser.service.GovernService.handleBlockInfo(GovernService.java:153) ~[classes/:?]
at cn.bcos.browser.service.GovernService.handleBlockInfo(GovernService.java:129) ~[classes/:?]
at sun.reflect.GeneratedMethodAccessor204.invoke(Unknown Source) ~[?:?]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_131]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_131]
at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:269) ~[spring-core-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean$MethodInvokingJob.executeInternal(MethodInvokingJobDetailFactoryBean.java:257) ~[spring-context-support-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:75) ~[spring-context-support-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.quartz.core.JobRunShell.run(JobRunShell.java:202) ~[quartz-2.3.0.jar:?]

./start.sh报错,无法启动

Starting org.bcos.browser.Application [Failed]

01dac4987baf9415b7f23df2b2d18d8

日志如下
2020-08-30 14:56:36.977 [main] INFO Application() - Starting Application on TEST-WEB12345678 with PID 9289 (/www/wwwroot/bcos/browser/server/apps/fisco-bcos-browser.jar started by root in /www/wwwroot/bcos/browser/server)
2020-08-30 14:56:36.981 [main] INFO Application() - No active profile set, falling back to default profiles: default
2020-08-30 14:56:37.030 [main] INFO AnnotationConfigEmbeddedWebApplicationContext() - Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@6caf0677: startup date [Sun Aug 30 14:56:37 CST 2020]; root of context hierarchy
2020-08-30 14:56:37.315 [background-preinit] INFO Version() - HV000001: Hibernate Validator 5.3.6.Final
2020-08-30 14:56:37.968 [main] INFO PostProcessorRegistrationDelegate$BeanPostProcessorChecker() - Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$973a4bef] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-08-30 14:56:38.301 [main] INFO TomcatEmbeddedServletContainer() - Tomcat initialized with port(s): 5101 (http)
2020-08-30 14:56:38.396 [localhost-startStop-1] INFO ContextLoader() - Root WebApplicationContext: initialization completed in 1368 ms
2020-08-30 14:56:38.492 [localhost-startStop-1] INFO ServletRegistrationBean() - Mapping servlet: 'dispatcherServlet' to [/]
2020-08-30 14:56:38.495 [localhost-startStop-1] INFO FilterRegistrationBean() - Mapping filter: 'characterEncodingFilter' to: [/]
2020-08-30 14:56:38.495 [localhost-startStop-1] INFO FilterRegistrationBean() - Mapping filter: 'hiddenHttpMethodFilter' to: [/
]
2020-08-30 14:56:38.495 [localhost-startStop-1] INFO FilterRegistrationBean() - Mapping filter: 'httpPutFormContentFilter' to: [/]
2020-08-30 14:56:38.495 [localhost-startStop-1] INFO FilterRegistrationBean() - Mapping filter: 'requestContextFilter' to: [/
]
2020-08-30 14:56:39.364 [main] INFO XmlBeanDefinitionReader() - Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
2020-08-30 14:56:39.405 [main] WARN AnnotationConfigEmbeddedWebApplicationContext() - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'initTable' defined in URL [jar:file:/www/wwwroot/bcos/browser/server/apps/fisco-bcos-browser.jar!/org/bcos/browser/config/InitTable.class]: Invocation of init method failed; nested exception is org.springframework.dao.TransientDataAccessResourceException:

Error updating database. Cause: java.sql.SQLException: Could not retrieve transation read-only status server

The error may involve defaultParameterMap

The error occurred while setting parameters

SQL: CREATE TABLE IF NOT EXISTS tb_group ( group_id int(11) NOT NULL COMMENT '群组ID', group_name varchar(128) NOT NULL COMMENT '群组名称', group_desc varchar(1024) COMMENT '群组描述', gmt_create datetime COMMENT '创建时间', gmt_modify datetime COMMENT '修改时间', PRIMARY KEY (group_id) ) COMMENT='群组信息表' ENGINE=InnoDB CHARSET=utf8

Cause: java.sql.SQLException: Could not retrieve transation read-only status server

; SQL []; Could not retrieve transation read-only status server; nested exception is java.sql.SQLException: Could not retrieve transation read-only status server
2020-08-30 14:56:39.418 [main] INFO AutoConfigurationReportLoggingInitializer() -

Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2020-08-30 14:56:39.420 [main] ERROR SpringApplication() - Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'initTable' defined in URL [jar:file:/www/wwwroot/bcos/browser/server/apps/fisco-bcos-browser.jar!/org/bcos/browser/config/InitTable.class]: Invocation of init method failed; nested exception is org.springframework.dao.TransientDataAccessResourceException:

Error updating database. Cause: java.sql.SQLException: Could not retrieve transation read-only status server

The error may involve defaultParameterMap

The error occurred while setting parameters

SQL: CREATE TABLE IF NOT EXISTS tb_group ( group_id int(11) NOT NULL COMMENT '群组ID', group_name varchar(128) NOT NULL COMMENT '群组名称', group_desc varchar(1024) COMMENT '群组描述', gmt_create datetime COMMENT '创建时间', gmt_modify datetime COMMENT '修改时间', PRIMARY KEY (group_id) ) COMMENT='群组信息表' ENGINE=InnoDB CHARSET=utf8

Cause: java.sql.SQLException: Could not retrieve transation read-only status server

; SQL []; Could not retrieve transation read-only status server; nested exception is java.sql.SQLException: Could not retrieve transation read-only status server
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1630) ~[spring-beans-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) ~[spring-beans-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:481) ~[spring-beans-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312) ~[spring-beans-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308) ~[spring-beans-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:756) ~[spring-beans-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) ~[spring-context-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.bcos.browser.Application.main(Application.java:25) [fisco-bcos-browser.jar:?]
Caused by: org.springframework.dao.TransientDataAccessResourceException:

Error updating database. Cause: java.sql.SQLException: Could not retrieve transation read-only status server

The error may involve defaultParameterMap

The error occurred while setting parameters

SQL: CREATE TABLE IF NOT EXISTS tb_group ( group_id int(11) NOT NULL COMMENT '群组ID', group_name varchar(128) NOT NULL COMMENT '群组名称', group_desc varchar(1024) COMMENT '群组描述', gmt_create datetime COMMENT '创建时间', gmt_modify datetime COMMENT '修改时间', PRIMARY KEY (group_id) ) COMMENT='群组信息表' ENGINE=InnoDB CHARSET=utf8

Cause: java.sql.SQLException: Could not retrieve transation read-only status server

; SQL []; Could not retrieve transation read-only status server; nested exception is java.sql.SQLException: Could not retrieve transation read-only status server
at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:108) ~[spring-jdbc-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73) ~[spring-jdbc-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:82) ~[spring-jdbc-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:82) ~[spring-jdbc-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:73) ~[mybatis-spring-1.3.1.jar:1.3.1]
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:446) ~[mybatis-spring-1.3.1.jar:1.3.1]
at com.sun.proxy.$Proxy84.update(Unknown Source) ~[?:?]
at org.mybatis.spring.SqlSessionTemplate.update(SqlSessionTemplate.java:294) ~[mybatis-spring-1.3.1.jar:1.3.1]
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:62) ~[mybatis-3.4.5.jar:3.4.5]
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:59) ~[mybatis-3.4.5.jar:3.4.5]
at com.sun.proxy.$Proxy85.createTbGroup(Unknown Source) ~[?:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_121]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_121]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_121]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_121]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333) ~[spring-aop-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) ~[spring-aop-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) ~[spring-tx-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) ~[spring-aop-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at com.sun.proxy.$Proxy87.createTbGroup(Unknown Source) ~[?:?]
at org.bcos.browser.config.InitTable.afterPropertiesSet(InitTable.java:18) ~[fisco-bcos-browser.jar:?]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1688) ~[spring-beans-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1626) ~[spring-beans-4.3.25.RELEASE.jar:4.3.25.RELEASE]
... 16 more
Caused by: java.sql.SQLException: Could not retrieve transation read-only status server
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1084) ~[mysql-connector-java-5.1.30.jar:?]
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:987) ~[mysql-connector-java-5.1.30.jar:?]
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:973) ~[mysql-connector-java-5.1.30.jar:?]
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:918) ~[mysql-connector-java-5.1.30.jar:?]
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:949) ~[mysql-connector-java-5.1.30.jar:?]
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:939) ~[mysql-connector-java-5.1.30.jar:?]
at com.mysql.jdbc.ConnectionImpl.isReadOnly(ConnectionImpl.java:3976) ~[mysql-connector-java-5.1.30.jar:?]
at com.mysql.jdbc.ConnectionImpl.isReadOnly(ConnectionImpl.java:3947) ~[mysql-connector-java-5.1.30.jar:?]
at com.mysql.jdbc.PreparedStatement.checkReadOnlySafeStatement(PreparedStatement.java:1215) ~[mysql-connector-java-5.1.30.jar:?]
at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1235) ~[mysql-connector-java-5.1.30.jar:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_121]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_121]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_121]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_121]
at org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy.invoke(StatementFacade.java:114) ~[tomcat-jdbc-8.5.16.jar:?]
at com.sun.proxy.$Proxy90.execute(Unknown Source) ~[?:?]
at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:46) ~[mybatis-3.4.5.jar:3.4.5]
at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:74) ~[mybatis-3.4.5.jar:3.4.5]
at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:50) ~[mybatis-3.4.5.jar:3.4.5]
at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117) ~[mybatis-3.4.5.jar:3.4.5]
at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76) ~[mybatis-3.4.5.jar:3.4.5]
at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:198) ~[mybatis-3.4.5.jar:3.4.5]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_121]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_121]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_121]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_121]
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:433) ~[mybatis-spring-1.3.1.jar:1.3.1]
at com.sun.proxy.$Proxy84.update(Unknown Source) ~[?:?]
at org.mybatis.spring.SqlSessionTemplate.update(SqlSessionTemplate.java:294) ~[mybatis-spring-1.3.1.jar:1.3.1]
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:62) ~[mybatis-3.4.5.jar:3.4.5]
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:59) ~[mybatis-3.4.5.jar:3.4.5]
at com.sun.proxy.$Proxy85.createTbGroup(Unknown Source) ~[?:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_121]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_121]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_121]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_121]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333) ~[spring-aop-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) ~[spring-aop-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) ~[spring-tx-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) ~[spring-aop-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at com.sun.proxy.$Proxy87.createTbGroup(Unknown Source) ~[?:?]
at org.bcos.browser.config.InitTable.afterPropertiesSet(InitTable.java:18) ~[fisco-bcos-browser.jar:?]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1688) ~[spring-beans-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1626) ~[spring-beans-4.3.25.RELEASE.jar:4.3.25.RELEASE]
... 16 more
Caused by: java.sql.SQLException: Unknown system variable 'tx_read_only'
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1084) ~[mysql-connector-java-5.1.30.jar:?]
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4232) ~[mysql-connector-java-5.1.30.jar:?]
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4164) ~[mysql-connector-java-5.1.30.jar:?]
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2615) ~[mysql-connector-java-5.1.30.jar:?]
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2776) ~[mysql-connector-java-5.1.30.jar:?]
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2832) ~[mysql-connector-java-5.1.30.jar:?]
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2781) ~[mysql-connector-java-5.1.30.jar:?]
at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1569) ~[mysql-connector-java-5.1.30.jar:?]
at com.mysql.jdbc.ConnectionImpl.isReadOnly(ConnectionImpl.java:3970) ~[mysql-connector-java-5.1.30.jar:?]
at com.mysql.jdbc.ConnectionImpl.isReadOnly(ConnectionImpl.java:3947) ~[mysql-connector-java-5.1.30.jar:?]
at com.mysql.jdbc.PreparedStatement.checkReadOnlySafeStatement(PreparedStatement.java:1215) ~[mysql-connector-java-5.1.30.jar:?]
at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1235) ~[mysql-connector-java-5.1.30.jar:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_121]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_121]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_121]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_121]
at org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy.invoke(StatementFacade.java:114) ~[tomcat-jdbc-8.5.16.jar:?]
at com.sun.proxy.$Proxy90.execute(Unknown Source) ~[?:?]
at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:46) ~[mybatis-3.4.5.jar:3.4.5]
at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:74) ~[mybatis-3.4.5.jar:3.4.5]
at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:50) ~[mybatis-3.4.5.jar:3.4.5]
at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117) ~[mybatis-3.4.5.jar:3.4.5]
at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76) ~[mybatis-3.4.5.jar:3.4.5]
at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:198) ~[mybatis-3.4.5.jar:3.4.5]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_121]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_121]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_121]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_121]
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:433) ~[mybatis-spring-1.3.1.jar:1.3.1]
at com.sun.proxy.$Proxy84.update(Unknown Source) ~[?:?]
at org.mybatis.spring.SqlSessionTemplate.update(SqlSessionTemplate.java:294) ~[mybatis-spring-1.3.1.jar:1.3.1]
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:62) ~[mybatis-3.4.5.jar:3.4.5]
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:59) ~[mybatis-3.4.5.jar:3.4.5]
at com.sun.proxy.$Proxy85.createTbGroup(Unknown Source) ~[?:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_121]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_121]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_121]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_121]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333) ~[spring-aop-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) ~[spring-aop-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) ~[spring-tx-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) ~[spring-aop-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at com.sun.proxy.$Proxy87.createTbGroup(Unknown Source) ~[?:?]
at org.bcos.browser.config.InitTable.afterPropertiesSet(InitTable.java:18) ~[fisco-bcos-browser.jar:?]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1688) ~[spring-beans-4.3.25.RELEASE.jar:4.3.25.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1626) ~[spring-beans-4.3.25.RELEASE.jar:4.3.25.RELEASE]
... 16 more

report中监控脚本启动不正常

错误如下:
node:node0, the dir_path is [./log] in log.conf or parse log.conf error. We suggest to use absolute path for dir_path to find log file. Add absolute path as the 4th params in node, e.g. ["node0", "/bcos-data/node0/log.conf", 8545, "/bcos-data/node0/log/"]

原配置如下:
node0 = ["node0", "/bcos-data/node0/log.conf", 8545] #node的名字, log.conf的路径, RPC端口号, node的log目录(可选)
node1 = ["node1", "/bcos-data/node1/log.conf", 8546, "/bcos-data/node0/log/"] #node的名字, log.conf的路径, RPC端口号, log.conf的路径(可选)

解决问题:
原配置中说明,log.conf的路径(可选),但是在启动中node0没有配置log的路径就会出现如上问题,添加对应日志log路径,正常启动监控,相对路径不行,必须得绝对路径设置了才可以

区块链浏览器一键部署,缺少表 db_browser.tx_receipt_raw_data_1

  1. 在fisco v2.8.0 基础上部署browser v2.2.5,采用一键部署的方式,前端运行正常服务端启动正常,配置节点信息时,服务端日志提示: Table 'db_browser.tx_receipt_raw_data_1' doesn't exist
  2. 采用手动的方式,部署browser v2.2.4 遇到同样的问题
  3. 手动部署browser v2.2.3 遇到同样的问题
  4. 手动部署browser v2.2.2 缺少sql脚本,无法建表

浏览器tomcat日志过大问题

这个浏览器的跑在tomcat里面疯狂的输入日志,没两天catalina.out文件的容量就好几个G了。。。。大佬们有啥好的想法吗?

server端代码问题

image
如图,观察到代码已经从原来的org包迁到cn包,为何还保留org包,另外,代码为何要换包呢?

区块链浏览器交易状态的问题

区块链浏览器查看交易详情的时候,交易状态是一个状态码,不够直观。如图:
image
如果能够在区块交易的下方单开一列,显著的标识当前交易是什么状态(如:成功则绿色,失败则红色警告等),点开交易详情,交易状态显示状态,而不显示状态码,就更好了。

合约配置业务无法编译合约

c9298bb6-c158-448c-a8a7-ae9b54a3e265:1 Uncaught TypeError: Cannot use 'in' operator to search for '_solidity_version' in undefined
at e (c9298bb6-c158-448c-a8a7-ae9b54a3e265:1:6173)
at c9298bb6-c158-448c-a8a7-ae9b54a3e265:1:1023
e @ c9298bb6-c158-448c-a8a7-ae9b54a3e265:1
(匿名) @ c9298bb6-c158-448c-a8a7-ae9b54a3e265:1

v2.0 如何验证 server 端正常运行?

搭建起来之后只看到页面提示

服务器累了,请联系管理员

而后台只看到

xxx.xxx.xxx.xxx - - [25/Mar/2019:07:52:55 +0000] "GET /api/fisco-bcos-browser/group/groupList HTTP/1.1" 404 555 "http://example.com:8080/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"

执行sh start.sh后log日志异常

2018-03-08 20:49:56.078 [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-4] ERROR GovernService(359) - 请求RPC异常
java.net.ConnectException: 拒绝连接 (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method) ~[?:1.8.0_161]
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[?:1.8.0_161]
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[?:1.8.0_161]
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[?:1.8.0_161]
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[?:1.8.0_161]
at java.net.Socket.connect(Socket.java:589) ~[?:1.8.0_161]
at sun.net.NetworkClient.doConnect(NetworkClient.java:175) ~[?:1.8.0_161]
at sun.net.www.http.HttpClient.openServer(HttpClient.java:463) ~[?:1.8.0_161]
at sun.net.www.http.HttpClient.openServer(HttpClient.java:558) ~[?:1.8.0_161]
at sun.net.www.http.HttpClient.(HttpClient.java:242) ~[?:1.8.0_161]
at sun.net.www.http.HttpClient.New(HttpClient.java:339) ~[?:1.8.0_161]
at sun.net.www.http.HttpClient.New(HttpClient.java:357) ~[?:1.8.0_161]
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1220) ~[?:1.8.0_161]
at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1199) ~[?:1.8.0_161]
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1050) ~[?:1.8.0_161]
at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:984) ~[?:1.8.0_161]
at com.googlecode.jsonrpc4j.JsonRpcHttpClient.invoke(JsonRpcHttpClient.java:138) ~[jsonrpc4j-1.5.1.jar:1.5.1]
at com.googlecode.jsonrpc4j.JsonRpcHttpClient.invoke(JsonRpcHttpClient.java:118) ~[jsonrpc4j-1.5.1.jar:1.5.1]
at com.googlecode.jsonrpc4j.JsonRpcHttpClient.invoke(JsonRpcHttpClient.java:176) ~[jsonrpc4j-1.5.1.jar:1.5.1]
at org.bcos.browser.service.GovernService.getInfoByMethod(GovernService.java:356) [fisco-bcos-browser.jar:?]
at org.bcos.browser.service.GovernService.handlePendingTransInfo(GovernService.java:259) [fisco-bcos-browser.jar:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_161]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_161]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_161]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_161]
at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:269) [spring-core-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean$MethodInvokingJob.executeInternal(MethodInvokingJobDetailFactoryBean.java:257) [spring-context-support-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:75) [spring-context-support-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.quartz.core.JobRunShell.run(JobRunShell.java:202) [quartz-2.3.0.jar:?]
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [quartz-2.3.0.jar:?]
2018-03-08 20:49:56.079 [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-4] ERROR JobRunShell(211) - Job DEFAULT.handlePendingTransInfo threw an unhandled Exception:

我本地的rpc服务都是正常的(CentOS 7 环境),防火墙也是关着的,"RROR GovernService(359) - 请求RPC异常” 这样的问题如何解决呢?

打包失败

ERROR in ./src/util/ethAbi.js
Module not found: Error: Can't resolve 'underscore' in 'D:\xxx\fisco-bcos-browser\web\fisco-bcos-browser-front\src\util'
@ ./src/util/ethAbi.js 10:8-29
@ ./node_modules/babel-loader/lib!./node_modules/vue-loader/lib??vue-loader-options!./src/views/components/transactionDetail.vue?vue&type=script&lang=js&
@ ./src/views/components/transactionDetail.vue?vue&type=script&lang=js&
@ ./src/views/components/transactionDetail.vue
@ ./src/router/index.js
@ ./src/main.js

区块链浏览器参数说明

区块链浏览器启动后,可以看到区块有关的交易信息,有没有对区块信息各参数的解释说明文档?比如每个区块JSON的每个key代表什么意思,区块信息如下:
{
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000002000001000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000",
"totalDifficulty": "0x7f",
"receiptsRoot": "0x475eeb079cd7e851114f86a667b088959ae413b67cd022f5b315b0655b85b12c",
"extraData": "0xda8098312e302b2b363035612a524c696e75782f672b2b2f496e74",
"author": "0x0000000000000000000000000000000000000000",
"transactions": [
{
"blockHash": "0x2ec9865c785c5c73e2827a429259b34c2f36b8ab91ce998120834999ac8b0ba5",
"input": "0x66c9913900000000000000000000000000000000000000000000000000000000000003e7",
"randomId": "0x280ea27de0db196090c218018733bcd081bd237ea0ebaa07feda0c7f09d471b",
"blockNumber": "0x7f",
"gas": "0x1c9c380",
"from": "0x79f88c7389714d52b5f68bbca464fa04ffff018f",
"transactionIndex": "0x0",
"to": "0x306e04fa1e890dab60f2d54bdb4e1978f4ef47a6",
"nonce": "0x280ea27de0db196090c218018733bcd081bd237ea0ebaa07feda0c7f09d471b",
"value": "0x0",
"hash": "0x55a1eeb6e370022d6cfd34d446889b1e3e8a9009b6cc4ffbb4ae0bbb8344881b",
"gasPrice": "0x1c9c380"
}
],
"miner": "0x0000000000000000000000000000000000000000",
"difficulty": "0x1",
"gasLimit": "0x77359400",
"number": "0x7f",
"gasUsed": "0xe0e8",
"uncles": [],
"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"size": "0x25",
"transactionsRoot": "0xc2e45c268e9ad0beaf13fd4be093882544bdc0133e06808feb71f639a297a8d2",
"stateRoot": "0x19d16ea7c2b48e0f51bb813595c76e17dfe12f6dfae41f51bb69446f0ee1f758",
"genIndex": "0x1",
"parentHash": "0xce863fe4b0aae61507451c7e1c95fd61230447578cffb1a4072e45f813a86e21",
"hash": "0x2ec9865c785c5c73e2827a429259b34c2f36b8ab91ce998120834999ac8b0ba5",
"timestamp": "0x1624946caeb"
}

怎么配置我的节点地址呀?

我发现我启动了服务,浏览器让我加群组,我一直加不成功,一直报 系统异常。

我的common.properties文件配置如下

package.url=https://github.com/FISCO-BCOS/fisco-bcos-browser/releases/download/v2.0.0-rc2/fisco-bcos-browser.zip
mysql.ip=127.0.0.1
mysql.port=3306
mysql.user=root
mysql.password=mysql密码
mysql.database=testDB
deploy.ip=127.0.0.1
server.port=8088
web.port=8081

mac 上编译web失败

node version: v12.10.0

ERROR in ./node_modules/require-from-string/index.js
Module not found: Error: Can't resolve 'module' in '/Users/liaohua/fisco-bcos/fisco-bcos-browser/web/fisco-bcos-browser-front/node_modules/require-from-string'
 @ ./node_modules/require-from-string/index.js 3:13-30
 @ ./node_modules/solc/wrapper.js
 @ ./node_modules/babel-loader/lib!./node_modules/vue-loader/lib??vue-loader-options!./src/views/components/contractConfig.vue?vue&type=script&lang=js&
 @ ./src/views/components/contractConfig.vue?vue&type=script&lang=js&
 @ ./src/views/components/contractConfig.vue
 @ ./src/router/index.js
 @ ./src/main.js

query fail:System abnormality

请问mysql的ip地址设为多少啊?刚搭建的区块链浏览器怎么可能有记录呢?这个记录记录的是mysql中存储的数据吗?刚创建的mysql又怎么会有数据呢?

节点配置里配置多个节点时会产生重复数据?

节点配置里配置多个节点(同一个群组)时,tx_raw_data_1表里会插入重复数据.
跟踪代码发现每个配置的节点都会创建一个DataExportExecutor并且最终执行MysqlStoreService.storeBlockInfoBO()
而tx_raw_data_1的索引不是唯一索引,所以最终创建了多条同样数据.
请问这个是bug吗?

v2.2.4/fisco-bcos-browser.zip提供的start.sh脚本中含有换行符

执行区块链浏览器一键部署时,在输入python3 deploy.py installAll命令后报错。错误日志如下:
====== db script init success! ======
Traceback (most recent call last):
File "deploy.py", line 66, in
do()
File "deploy.py", line 14, in do
commBuild.do()
File "/home/huangmb/fisco/browser-deploy/comm/build.py", line 15, in do
installServer()
File "/home/huangmb/fisco/browser-deploy/comm/build.py", line 87, in installServer
startServer()
File "/home/huangmb/fisco/browser-deploy/comm/build.py", line 137, in startServer
result = doCmd("bash start.sh")
File "/home/huangmb/fisco/browser-deploy/comm/utils.py", line 91, in doCmd
raise Exception("execute cmd error ,cmd : {}, status is {} ,output is {}".format(cmd,status, output))
Exception: execute cmd error ,cmd : bash start.sh, status is 2 ,output is start.sh: line 2: $'\r': command not found
start.sh: line 7: $'\r': command not found
start.sh: line 13: syntax error near unexpected token $'{\r'' start.sh: line 13: getTradeProtalPID(){
'
查看/server/start.sh发现有windos换行符:
#!/bin/bash^M$
^M$
APP_MAIN=org.bcos.browser.Application^M$
CLASSPATH='conf/:apps/:lib/'^M$
CURRENT_DIR=pwd^M$
LOG_DIR=${CURRENT_DIR}/log^M$
^M$
if [ ! -d "log" ]; then^M$
mkdir -p log^M$
fi^M$
^M$
tradePortalPID=0^M$
getTradeProtalPID(){^M$
javaps=$JAVA_HOME/bin/jps -l | grep $APP_MAIN^M$
if [ -n "$javaps" ]; then^M$
tradePortalPID=echo $javaps | awk '{print $1}'^M$
else^M$
tradePortalPID=0^M$
fi^M$
}^M$
^M$
start(){^M$
^IgetTradeProtalPID^M$
^Iecho "==============================================================================================="^M$
^Iif [ $tradePortalPID -ne 0 ]; then^M$
^I echo "$APP_MAIN is already started(PID=$tradePortalPID)"^M$
^I echo "==============================================================================================="^M$
^Ielse^M$
^I echo -n "Starting $APP_MAIN "^M$
^I nohup $JAVA_HOME/bin/java -cp $CLASSPATH $APP_MAIN >> $LOG_DIR/browser.out 2&gt;&amp;1 &amp;^M$
^I sleep 5^M$
^I getTradeProtalPID^M$
^I if [ $tradePortalPID -ne 0 ]; then^M$
^I echo "(PID=$tradePortalPID)...[Success]"^M$
^I echo "==============================================================================================="^M$
^I else^M$
^I echo "[Failed]"^M$
^I echo "==============================================================================================="^M$
^I fi^M$
^Ifi^M$
}^M$
^M$
start^M$
此时需要自己替换脚本的换行符或者安装dos2unix后执行才能成功。

首页节点端口全部为0

fisco-bcos-browser搭建成功并且成功运行,但是首页的节点端口那一栏端口全部为0,我是在一台服务器起了很多节点,求帮助
tim 20180410180852

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.