From 678da8e84e6d02b7b3682d8f5ed3c58b232ef850 Mon Sep 17 00:00:00 2001 From: Steven Yuan Date: Tue, 11 Jan 2022 17:38:38 +0000 Subject: [PATCH 01/19] Only get block identifier for account balance calls (not full block response) --- helium/middleware.go | 42 +++++++++++++++++++++++++++++++++++++ services/account_service.go | 14 ++++--------- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/helium/middleware.go b/helium/middleware.go index 50de76a..55c5574 100644 --- a/helium/middleware.go +++ b/helium/middleware.go @@ -80,6 +80,48 @@ func GetCurrentHeight() (*int64, *types.Error) { return &result, nil } +func GetBlockIdentifier(blockIdentifier *types.PartialBlockIdentifier) (*types.BlockIdentifier, *types.Error) { + type request struct { + Height int64 `json:"height,omitempty"` + Hash string `json:"hash,omitempty"` + } + + var result Block + var req request + + if blockIdentifier.Index != nil && blockIdentifier.Hash != nil { + req = request{ + Height: *blockIdentifier.Index, + } + } else if blockIdentifier.Index == nil && blockIdentifier.Hash != nil { + req = request{ + Hash: *blockIdentifier.Hash, + } + } else if blockIdentifier.Index != nil && blockIdentifier.Hash == nil { + req = request{ + Height: *blockIdentifier.Index, + } + } + + callResult, err := utils.DecodeCallAsNumber(NodeClient.Call("block_get", req)) + jsonResult, _ := json.Marshal(callResult) + json.Unmarshal(jsonResult, &result) + + if err != nil { + return nil, WrapErr( + ErrFailed, + err, + ) + } + + identifier := &types.BlockIdentifier{ + Index: result.Height, + Hash: result.Hash, + } + + return identifier, nil +} + func GetBlock(blockIdentifier *types.PartialBlockIdentifier) (*types.Block, *types.Error) { type request struct { Height int64 `json:"height,omitempty"` diff --git a/services/account_service.go b/services/account_service.go index 1d10fe5..40490f2 100644 --- a/services/account_service.go +++ b/services/account_service.go @@ -81,29 +81,23 @@ func (s *AccountAPIService) AccountBalance( return nil, chErr } - currentBlock, cErr := helium.GetBlock(&types.PartialBlockIdentifier{ + currentBlock, cErr := helium.GetBlockIdentifier(&types.PartialBlockIdentifier{ Index: currentHeight, }) if cErr != nil { return nil, cErr } - blockId = types.BlockIdentifier{ - Index: currentBlock.BlockIdentifier.Index, - Hash: currentBlock.BlockIdentifier.Hash, - } + blockId = *currentBlock } else { - requestedBlock, rErr := helium.GetBlock(&types.PartialBlockIdentifier{ + requestedBlock, rErr := helium.GetBlockIdentifier(&types.PartialBlockIdentifier{ Index: request.BlockIdentifier.Index, }) if rErr != nil { return nil, rErr } - blockId = types.BlockIdentifier{ - Index: requestedBlock.BlockIdentifier.Index, - Hash: requestedBlock.BlockIdentifier.Hash, - } + blockId = *requestedBlock } return &types.AccountBalanceResponse{ From 80987ba4393810f17fcbeda0c9c86f84c58c2abb Mon Sep 17 00:00:00 2001 From: Steven Yuan Date: Tue, 11 Jan 2022 18:15:12 +0000 Subject: [PATCH 02/19] Optimize /network/status to not require full blocks --- helium/middleware.go | 39 +++++++++++++++++++++++++++++++++++++ helium/types.go | 4 ++++ services/network_service.go | 34 +++++++++++++++++--------------- 3 files changed, 61 insertions(+), 16 deletions(-) diff --git a/helium/middleware.go b/helium/middleware.go index 55c5574..f69da8c 100644 --- a/helium/middleware.go +++ b/helium/middleware.go @@ -80,6 +80,45 @@ func GetCurrentHeight() (*int64, *types.Error) { return &result, nil } +func GetBlockTimestamp(blockIdentifier *types.PartialBlockIdentifier) (*int64, *types.Error) { + type request struct { + Height int64 `json:"height,omitempty"` + Hash string `json:"hash,omitempty"` + } + + var result Block + var req request + + if blockIdentifier.Index != nil && blockIdentifier.Hash != nil { + req = request{ + Height: *blockIdentifier.Index, + } + } else if blockIdentifier.Index == nil && blockIdentifier.Hash != nil { + req = request{ + Hash: *blockIdentifier.Hash, + } + } else if blockIdentifier.Index != nil && blockIdentifier.Hash == nil { + req = request{ + Height: *blockIdentifier.Index, + } + } + + callResult, err := utils.DecodeCallAsNumber(NodeClient.Call("block_get", req)) + jsonResult, _ := json.Marshal(callResult) + json.Unmarshal(jsonResult, &result) + + if err != nil { + return nil, WrapErr( + ErrFailed, + err, + ) + } + + timestamp := result.Time + + return ×tamp, nil +} + func GetBlockIdentifier(blockIdentifier *types.PartialBlockIdentifier) (*types.BlockIdentifier, *types.Error) { type request struct { Height int64 `json:"height,omitempty"` diff --git a/helium/types.go b/helium/types.go index d2a74c2..4cfa00c 100644 --- a/helium/types.go +++ b/helium/types.go @@ -28,6 +28,10 @@ func readLBSfile() *int64 { lbs, err := strconv.ParseInt(s, 10, 64) + // Increment last blessed snapshot block in order to account + // for previous_block query in /network/status + lbs = lbs + 1 + if err != nil { log.Fatal(err) } diff --git a/services/network_service.go b/services/network_service.go index 14e06f8..0f3ea84 100644 --- a/services/network_service.go +++ b/services/network_service.go @@ -58,19 +58,27 @@ func (s *NetworkAPIService) NetworkStatus( return nil, chErr } - currentBlock, cbErr := helium.GetBlock(&types.PartialBlockIdentifier{ + currentBlockID, cbiErr := helium.GetBlockIdentifier(&types.PartialBlockIdentifier{ Index: currentHeight, }) - if cbErr != nil { - return nil, cbErr + if cbiErr != nil { + return nil, cbiErr } - if currentBlock.BlockIdentifier.Index < *helium.LBS { + currentBlockTimestamp, cbtErr := helium.GetBlockTimestamp(&types.PartialBlockIdentifier{ + Index: currentHeight, + }) + + if cbtErr != nil { + return nil, cbtErr + } + + if currentBlockID.Index < *helium.LBS { return nil, helium.WrapErr(helium.ErrNodeSync, errors.New("node is catching up to snapshot height")) } - lastBlessedBlock, lbErr := helium.GetBlock(&types.PartialBlockIdentifier{ + lastBlessedBlock, lbErr := helium.GetBlockIdentifier(&types.PartialBlockIdentifier{ Index: helium.LBS, }) @@ -97,21 +105,15 @@ func (s *NetworkAPIService) NetworkStatus( } return &types.NetworkStatusResponse{ - CurrentBlockIdentifier: &types.BlockIdentifier{ - Index: currentBlock.BlockIdentifier.Index, - Hash: currentBlock.BlockIdentifier.Hash, - }, - CurrentBlockTimestamp: currentBlock.Timestamp, + CurrentBlockIdentifier: currentBlockID, + CurrentBlockTimestamp: *currentBlockTimestamp, GenesisBlockIdentifier: &types.BlockIdentifier{ Index: genesisIndex, Hash: genesisHash, }, - OldestBlockIdentifier: &types.BlockIdentifier{ - Index: lastBlessedBlock.BlockIdentifier.Index, - Hash: lastBlessedBlock.BlockIdentifier.Hash, - }, - Peers: peers, - SyncStatus: syncStatus, + OldestBlockIdentifier: lastBlessedBlock, + Peers: peers, + SyncStatus: syncStatus, }, nil } From 3c695d2601043ad0cbc7e9f870c222770541c5a6 Mon Sep 17 00:00:00 2001 From: Steven Yuan Date: Tue, 11 Jan 2022 18:47:47 +0000 Subject: [PATCH 03/19] Timestamp bug --- helium/middleware.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helium/middleware.go b/helium/middleware.go index f69da8c..befb9da 100644 --- a/helium/middleware.go +++ b/helium/middleware.go @@ -114,7 +114,7 @@ func GetBlockTimestamp(blockIdentifier *types.PartialBlockIdentifier) (*int64, * ) } - timestamp := result.Time + timestamp := result.Time * 1000 return ×tamp, nil } From f43dcfefada60511b87849beeaab741d15b16d87 Mon Sep 17 00:00:00 2001 From: Steven Yuan Date: Wed, 12 Jan 2022 21:30:58 +0000 Subject: [PATCH 04/19] Change genesis blocks to be 60 seconds before block #2 --- helium/middleware.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helium/middleware.go b/helium/middleware.go index befb9da..96f8ce5 100644 --- a/helium/middleware.go +++ b/helium/middleware.go @@ -218,7 +218,7 @@ func GetBlock(blockIdentifier *types.PartialBlockIdentifier) (*types.Block, *typ var blockTime int64 if result.Time == 0 { - blockTime = 946684800 + blockTime = 1624398097 } else { blockTime = result.Time } From e534797f66a2427afecef58995cc14ee92554d8f Mon Sep 17 00:00:00 2001 From: Steven Yuan Date: Wed, 12 Jan 2022 21:38:41 +0000 Subject: [PATCH 05/19] Timestamp fixes + differentiate Mainnet / Testnet genesis timestamps --- helium/middleware.go | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/helium/middleware.go b/helium/middleware.go index 96f8ce5..6c37da5 100644 --- a/helium/middleware.go +++ b/helium/middleware.go @@ -114,9 +114,22 @@ func GetBlockTimestamp(blockIdentifier *types.PartialBlockIdentifier) (*int64, * ) } - timestamp := result.Time * 1000 + var blockTime int64 - return ×tamp, nil + if result.Time == 0 { + if CurrentNetwork.Network == MainnetNetwork { + blockTime = 1564436673 + } else { + // Assumed to be testnet + blockTime = 1624398097 + } + } else { + blockTime = result.Time + } + + blockTime = result.Time * 1000 + + return &blockTime, nil } func GetBlockIdentifier(blockIdentifier *types.PartialBlockIdentifier) (*types.BlockIdentifier, *types.Error) { @@ -218,7 +231,12 @@ func GetBlock(blockIdentifier *types.PartialBlockIdentifier) (*types.Block, *typ var blockTime int64 if result.Time == 0 { - blockTime = 1624398097 + if CurrentNetwork.Network == MainnetNetwork { + blockTime = 1564436673 + } else { + // Assumed to be testnet + blockTime = 1624398097 + } } else { blockTime = result.Time } From bc7066c57150d200077a31477cb21825b0b44975 Mon Sep 17 00:00:00 2001 From: Steven Yuan Date: Wed, 12 Jan 2022 21:43:30 +0000 Subject: [PATCH 06/19] Bump Dockerfile_quick, add Dockerfile todos --- Dockerfile | 2 ++ Dockerfile_quick | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 6fff3fb..0948886 100644 --- a/Dockerfile +++ b/Dockerfile @@ -84,6 +84,7 @@ ENV CC=gcc CXX=g++ CFLAGS="-U__sun__" \ WORKDIR /usr/src/ # Add our code +# TODO: git checkout specific release when ready RUN git clone https://github.com/helium/blockchain-node.git @@ -137,6 +138,7 @@ RUN apt update \ ENV PATH="/src/go/bin:$PATH" \ CGO_ENABLED=0 +# TODO: git clone from url instead of direct copy COPY . rosetta-helium RUN cd rosetta-helium && go build -o rosetta-helium diff --git a/Dockerfile_quick b/Dockerfile_quick index d3252b4..7abcdf9 100644 --- a/Dockerfile_quick +++ b/Dockerfile_quick @@ -1,6 +1,6 @@ ARG UBUNTU_BUILDER=ubuntu:20.04 -ARG MAINNET_RUNNER=quay.io/team-helium/blockchain-node:blockchain-node-ubuntu18-1.1.53 -ARG TESTNET_RUNNER=quay.io/team-helium/blockchain-node:blockchain-node-testnet-ubuntu18-1.1.53 +ARG MAINNET_RUNNER=quay.io/team-helium/blockchain-node:blockchain-node-ubuntu18-1.1.57 +ARG TESTNET_RUNNER=quay.io/team-helium/blockchain-node:blockchain-node-testnet-ubuntu18-1.1.57 ARG NETWORK=mainnet From 510427c28edc9ab9479047e93260b67d94daa1a3 Mon Sep 17 00:00:00 2001 From: Steven Yuan Date: Wed, 19 Jan 2022 18:56:36 +0000 Subject: [PATCH 07/19] Temp update to checkout alternate node code --- Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 0948886..40e48ac 100644 --- a/Dockerfile +++ b/Dockerfile @@ -85,7 +85,7 @@ WORKDIR /usr/src/ # Add our code # TODO: git checkout specific release when ready -RUN git clone https://github.com/helium/blockchain-node.git +RUN git clone https://github.com/syuan100/blockchain-node.git FROM node-builder AS node-mainnet @@ -94,6 +94,8 @@ ARG BUILD_TARGET=docker_rosetta WORKDIR /usr/src/blockchain-node +RUN git checkout commit-hooks-with-heights + RUN ./rebar3 as ${BUILD_TARGET} tar -n blockchain_node RUN mkdir -p /opt/blockchain_node \ From c0dd54606d621babbae6d3dbf34e36c56ca11eae Mon Sep 17 00:00:00 2001 From: Steven Yuan Date: Thu, 20 Jan 2022 21:47:49 +0000 Subject: [PATCH 08/19] Check construction configs for helium testnet --- rosetta-cli-config/mainnet/config.json | 9 --- rosetta-cli-config/mainnet/helium.ros | 94 -------------------------- rosetta-cli-config/testnet/config.json | 9 +++ 3 files changed, 9 insertions(+), 103 deletions(-) delete mode 100644 rosetta-cli-config/mainnet/helium.ros diff --git a/rosetta-cli-config/mainnet/config.json b/rosetta-cli-config/mainnet/config.json index 4df0281..fba3e65 100644 --- a/rosetta-cli-config/mainnet/config.json +++ b/rosetta-cli-config/mainnet/config.json @@ -8,15 +8,6 @@ "http_timeout": 2000, "tip_delay": 1200, "max_retries": 10, - "construction": { - "stale_depth": 3, - "broadcast_limit": 5, - "constructor_dsl_file": "helium.ros", - "end_conditions": { - "create_account": 1, - "transfer": 1 - } - }, "data": { "start_index": 1156322, "historical_balance_enabled": true, diff --git a/rosetta-cli-config/mainnet/helium.ros b/rosetta-cli-config/mainnet/helium.ros deleted file mode 100644 index a9a5463..0000000 --- a/rosetta-cli-config/mainnet/helium.ros +++ /dev/null @@ -1,94 +0,0 @@ -request_funds(1){ - find_account{ - currency = {"symbol":"HNT", "decimals":8}; - random_account = find_balance({ - "minimum_balance":{ - "value": "0", - "currency": {{currency}} - }, - "create_limit":1 - }); - }, - - // Create a separate scenario to request funds so that - // the address we are using to request funds does not - // get rolled back if funds do not yet exist. - request{ - loaded_account = find_balance({ - "account_identifier": {{random_account.account_identifier}}, - "minimum_balance":{ - "value": "10000000", - "currency": {{currency}} - } - }); - } -} - -create_account(1){ - create{ - network = {"network":"Mainnet", "blockchain":"Helium"}; - key = generate_key({"curve_type": "edwards25519"}); - account = derive({ - "network_identifier": {{network}}, - "public_key": {{key.public_key}} - }); - - // If the account is not saved, the key will be lost! - save_account({ - "account_identifier": {{account.account_identifier}}, - "keypair": {{key}} - }); - } -} - -transfer(10){ - transfer{ - transfer.network = {"network":"Mainnet", "blockchain":"Helium"}; - currency = {"symbol":"HNT", "decimals":8}; - sender = find_balance({ - "minimum_balance":{ - "value": "10000000", - "currency": {{currency}} - } - }); - - // Set the recipient_amount as some value <= sender.balance-max_fee - max_fee = "5000000"; - available_amount = {{sender.balance.value}} - {{max_fee}}; - recipient_amount = random_number({"minimum": "1", "maximum": {{available_amount}}}); - print_message({"recipient_amount":{{recipient_amount}}}); - - // Find recipient and construct operations - sender_amount = 0 - {{recipient_amount}}; - recipient = find_balance({ - "not_account_identifier":[{{sender.account_identifier}}], - "minimum_balance":{ - "value": "0", - "currency": {{currency}} - }, - "create_limit": 100, - "create_probability": 50 - }); - transfer.confirmation_depth = "1"; - transfer.operations = [ - { - "operation_identifier":{"index":0}, - "type":"debit_op", - "account":{{sender.account_identifier}}, - "amount":{ - "value":{{sender_amount}}, - "currency":{{currency}} - } - }, - { - "operation_identifier":{"index":1}, - "type":"credit_op", - "account":{{recipient.account_identifier}}, - "amount":{ - "value":{{recipient_amount}}, - "currency":{{currency}} - } - } - ]; - } -} \ No newline at end of file diff --git a/rosetta-cli-config/testnet/config.json b/rosetta-cli-config/testnet/config.json index e6d05fd..036233e 100644 --- a/rosetta-cli-config/testnet/config.json +++ b/rosetta-cli-config/testnet/config.json @@ -8,6 +8,15 @@ "http_timeout": 2000, "tip_delay": 1200, "max_retries": 10, + "construction": { + "stale_depth": 3, + "broadcast_limit": 5, + "constructor_dsl_file": "helium-testnet.ros", + "end_conditions": { + "create_account": 1, + "transfer": 1 + } + }, "data": { "historical_balance_enabled": true, "end_conditions": { From 275cd7992122268959038c239005af42846f589d Mon Sep 17 00:00:00 2001 From: Steven Yuan Date: Thu, 20 Jan 2022 21:49:28 +0000 Subject: [PATCH 09/19] Update mainnet config end conditions for rosetta-cli --- rosetta-cli-config/mainnet/config.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rosetta-cli-config/mainnet/config.json b/rosetta-cli-config/mainnet/config.json index fba3e65..8f90635 100644 --- a/rosetta-cli-config/mainnet/config.json +++ b/rosetta-cli-config/mainnet/config.json @@ -12,7 +12,10 @@ "start_index": 1156322, "historical_balance_enabled": true, "end_conditions": { - "tip": true + "reconciliation_coverage": { + "coverage": 0.95, + "from_tip": true + } } } } \ No newline at end of file From c94996c649b96476a0070678a5a75485a2674183 Mon Sep 17 00:00:00 2001 From: Steven Yuan Date: Thu, 20 Jan 2022 21:55:43 +0000 Subject: [PATCH 10/19] Split dockerfiles + update README --- Dockerfile | 19 +----- Dockerfile_testnet | 156 +++++++++++++++++++++++++++++++++++++++++++++ README.md | 6 +- 3 files changed, 160 insertions(+), 21 deletions(-) create mode 100644 Dockerfile_testnet diff --git a/Dockerfile b/Dockerfile index 40e48ac..a2c9498 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,3 @@ -ARG NETWORK=mainnet - FROM ubuntu:20.04 as node-builder ARG BUILD_VERSION="23.3.4.7" @@ -102,18 +100,6 @@ RUN mkdir -p /opt/blockchain_node \ && tar -zxvf _build/${BUILD_TARGET}/rel/*/*.tar.gz -C /opt/blockchain_node -FROM node-builder AS node-testnet - -ARG BUILD_TARGET=docker_rosetta_testnet - -WORKDIR /usr/src/blockchain-node - -RUN ./rebar3 as ${BUILD_TARGET} tar -n blockchain_node - -RUN mkdir -p /opt/blockchain_node \ - && tar -zxvf _build/${BUILD_TARGET}/rel/*/*.tar.gz -C /opt/blockchain_node - - FROM ubuntu:20.04 AS rosetta-builder RUN set -xe \ @@ -146,9 +132,8 @@ COPY . rosetta-helium RUN cd rosetta-helium && go build -o rosetta-helium -FROM node-${NETWORK} as rosetta-helium-final +FROM node-mainnet as rosetta-helium-final -ARG NETWORK ARG DEBIAN_FRONTEND=noninteractive EXPOSE 8080 @@ -162,7 +147,7 @@ WORKDIR /app COPY --from=rosetta-builder /src/rosetta-helium/rosetta-helium rosetta-helium COPY --from=rosetta-builder /src/rosetta-helium/ghost-transactions ghost-transactions -COPY --from=rosetta-builder /src/rosetta-helium/docker/${NETWORK}.sh start.sh +COPY --from=rosetta-builder /src/rosetta-helium/docker/mainnet.sh start.sh COPY --from=rosetta-builder /src/rosetta-helium/helium-constructor helium-constructor RUN cd helium-constructor \ diff --git a/Dockerfile_testnet b/Dockerfile_testnet new file mode 100644 index 0000000..3437e25 --- /dev/null +++ b/Dockerfile_testnet @@ -0,0 +1,156 @@ +FROM ubuntu:20.04 as node-builder + +ARG BUILD_VERSION="23.3.4.7" +ARG BUILD_SHA256="37e39a43c495861ce69de06e1a013a7eac81d15dc6eebd2d2022fd68791f4b2d" +ENV OTP_VERSION=$BUILD_VERSION \ + REBAR3_VERSION="3.16.1" + +LABEL org.opencontainers.image.version=$OTP_VERSION + +# We'll install the build dependencies, and purge them on the last step to make +# sure our final image contains only what we've just built: +RUN set -xe \ + && OTP_DOWNLOAD_URL="https://github.com/erlang/otp/releases/download/OTP-${BUILD_VERSION}/otp_src_${BUILD_VERSION}.tar.gz" \ + && OTP_DOWNLOAD_SHA256="${BUILD_SHA256}" \ + && fetchDeps=' \ + curl \ + ca-certificates' \ + && apt-get update \ + && apt-get install -y --no-install-recommends $fetchDeps \ + && curl -fSL -o otp-src.tar.gz "$OTP_DOWNLOAD_URL" \ + && echo "$OTP_DOWNLOAD_SHA256 otp-src.tar.gz" | sha256sum -c - \ + && runtimeDeps=' \ + libssl1.1 \ + ' \ + && buildDeps=' \ + autoconf \ + dpkg-dev \ + gcc \ + g++ \ + make \ + libncurses-dev \ + libssl-dev \ + ' \ + && apt-get install -y --no-install-recommends $runtimeDeps \ + && apt-get install -y --no-install-recommends $buildDeps \ + && export ERL_TOP="/usr/src/otp_src_${OTP_VERSION%%@*}" \ + && mkdir -vp $ERL_TOP \ + && tar -xzf otp-src.tar.gz -C $ERL_TOP --strip-components=1 \ + && rm otp-src.tar.gz \ + && ( cd $ERL_TOP \ + && ./otp_build autoconf \ + && gnuArch="$(dpkg-architecture --query DEB_HOST_GNU_TYPE)" \ + && ./configure --build="$gnuArch" \ + && make -j$(nproc) \ + && make install ) \ + && find /usr/local -name examples | xargs rm -rf \ + && REBAR3_DOWNLOAD_URL="https://github.com/erlang/rebar3/archive/${REBAR3_VERSION}.tar.gz" \ + && REBAR3_DOWNLOAD_SHA256="a14711b09f6e1fc1b080b79d78c304afebcbb7fafed9d0972eb739f0ed89121b" \ + && mkdir -p /usr/src/rebar3-src \ + && curl -fSL -o rebar3-src.tar.gz "$REBAR3_DOWNLOAD_URL" \ + && echo "$REBAR3_DOWNLOAD_SHA256 rebar3-src.tar.gz" | sha256sum -c - \ + && tar -xzf rebar3-src.tar.gz -C /usr/src/rebar3-src --strip-components=1 \ + && rm rebar3-src.tar.gz \ + && cd /usr/src/rebar3-src \ + && HOME=$PWD ./bootstrap \ + && install -v ./rebar3 /usr/local/bin/ \ + && rm -rf /usr/src/rebar3-src \ + && apt-get purge -y --auto-remove $buildDeps $fetchDeps \ + && rm -rf $ERL_TOP /var/lib/apt/lists/* + +RUN set -xe \ + && apt update \ + && apt-get install -y --no-install-recommends \ + libssl-dev make automake autoconf libncurses5-dev gcc \ + libdbus-1-dev libbz2-dev bison flex libgmp-dev liblz4-dev \ + libsodium-dev sed wget curl build-essential libtool git \ + ca-certificates \ + && mkdir -p /opt/cmake \ + && wget -O /opt/cmake/cmake.tgz \ + https://github.com/Kitware/CMake/releases/download/v3.21.3/cmake-3.21.3-linux-x86_64.tar.gz \ + && tar -zxf /opt/cmake/cmake.tgz -C /opt/cmake --strip-components=1 + +# Install Rust toolchain +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y + +ENV CC=gcc CXX=g++ CFLAGS="-U__sun__" \ + ERLANG_ROCKSDB_OPTS="-DWITH_BUNDLE_SNAPPY=ON -DWITH_BUNDLE_LZ4=ON" \ + ERL_COMPILER_OPTIONS="[deterministic]" \ + PATH="/root/.cargo/bin:/opt/cmake/bin:$PATH" \ + RUSTFLAGS="-C target-feature=-crt-static" + +WORKDIR /usr/src/ + +# Add our code +# TODO: git checkout specific release when ready +RUN git clone https://github.com/syuan100/blockchain-node.git + + +FROM node-builder AS node-testnet + +ARG BUILD_TARGET=docker_rosetta_testnet + +WORKDIR /usr/src/blockchain-node + +RUN ./rebar3 as ${BUILD_TARGET} tar -n blockchain_node + +RUN mkdir -p /opt/blockchain_node \ + && tar -zxvf _build/${BUILD_TARGET}/rel/*/*.tar.gz -C /opt/blockchain_node + + +FROM ubuntu:20.04 AS rosetta-builder + +RUN set -xe \ + && ulimit -n 100000 \ + && apt update \ + && apt install -y --no-install-recommends libdbus-1-3 libgmp10 libsodium23 \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /opt/blockchain_node + +ENV COOKIE=blockchain_node \ + # Write files generated during startup to /tmp + RELX_OUT_FILE_PATH=/tmp \ + # add to path, for easy exec interaction + PATH=/sbin:/bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH:/opt/blockchain_node/bin + +WORKDIR /src + +RUN apt update \ + && apt install -y --no-install-recommends \ + curl ca-certificates git \ + && curl -L https://golang.org/dl/go1.17.1.linux-amd64.tar.gz | tar xzf - + +ENV PATH="/src/go/bin:$PATH" \ + CGO_ENABLED=0 + +# TODO: git clone from url instead of direct copy +COPY . rosetta-helium + +RUN cd rosetta-helium && go build -o rosetta-helium + + +FROM node-testnet as rosetta-helium-final + +ARG DEBIAN_FRONTEND=noninteractive + +EXPOSE 8080 +EXPOSE 44158 + +RUN apt update \ + && apt install -y --no-install-recommends \ + ca-certificates git npm + +WORKDIR /app + +COPY --from=rosetta-builder /src/rosetta-helium/rosetta-helium rosetta-helium +COPY --from=rosetta-builder /src/rosetta-helium/ghost-transactions ghost-transactions +COPY --from=rosetta-builder /src/rosetta-helium/docker/testnet.sh start.sh +COPY --from=rosetta-builder /src/rosetta-helium/helium-constructor helium-constructor + +RUN cd helium-constructor \ + && npm install \ + && npm run build \ + && chmod +x /app/start.sh + +ENTRYPOINT ["/app/start.sh"] diff --git a/README.md b/README.md index 170f4c7..3e88336 100644 --- a/README.md +++ b/README.md @@ -18,12 +18,12 @@ This project was created by [@syuan100](https://github.com/syuan100) and support #### Build container from source Mainnet: ```text -DOCKER_BUILDKIT=1 docker build . -t rosetta-helium:latest +docker build . -t rosetta-helium:latest ``` Testnet: ```text -DOCKER_BUILDKIT=1 docker build . -t rosetta-helium:latest --build-arg NETWORK=testnet +docker build . -f Dockerfile_testnet -t rosetta-helium:latest ``` *Note: `DOCKER_BUILDKIT=1` is not necessary but including it may reduce the image size due to the nature of the conditional build.* @@ -63,8 +63,6 @@ docker run -d --rm --init --ulimit "nofile=1000000:1000000" -v "$(pwd)/helium-da Mainnet: ```text rosetta-cli check:data --configuration-file rosetta-cli-config/mainnet/config.json - -rosetta-cli check:construction --configuration-file rosetta-cli-config/mainnet/config.json ``` Testnet: From cc3bae9b086d9bebc9d661a79fd3e9ad785a4e0f Mon Sep 17 00:00:00 2001 From: Steven Yuan Date: Sat, 29 Jan 2022 18:46:57 +0000 Subject: [PATCH 11/19] Make sure testnet pulls from commit-hooks branch --- Dockerfile_testnet | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dockerfile_testnet b/Dockerfile_testnet index 3437e25..8789de9 100644 --- a/Dockerfile_testnet +++ b/Dockerfile_testnet @@ -92,6 +92,8 @@ ARG BUILD_TARGET=docker_rosetta_testnet WORKDIR /usr/src/blockchain-node +RUN git checkout commit-hooks-with-heights + RUN ./rebar3 as ${BUILD_TARGET} tar -n blockchain_node RUN mkdir -p /opt/blockchain_node \ From c358cef0f1c27abe060fa9bc54b8e76d1d2cfcd2 Mon Sep 17 00:00:00 2001 From: Steven Yuan Date: Tue, 1 Feb 2022 05:20:31 +0000 Subject: [PATCH 12/19] Remove syncStatus for now, reduce # of calls in network/status --- helium/middleware.go | 41 +++++++++++++++++++++++++++++++++++++ services/network_service.go | 32 +++++++++++++++-------------- 2 files changed, 58 insertions(+), 15 deletions(-) diff --git a/helium/middleware.go b/helium/middleware.go index 6c37da5..d45b215 100644 --- a/helium/middleware.go +++ b/helium/middleware.go @@ -174,6 +174,47 @@ func GetBlockIdentifier(blockIdentifier *types.PartialBlockIdentifier) (*types.B return identifier, nil } +func GetBlockMeta(blockIdentifier *types.PartialBlockIdentifier) (*Block, *types.Error) { + type request struct { + Height int64 `json:"height,omitempty"` + Hash string `json:"hash,omitempty"` + } + + var result Block + var req request + + if blockIdentifier.Index != nil && blockIdentifier.Hash != nil { + req = request{ + Height: *blockIdentifier.Index, + } + } else if blockIdentifier.Index == nil && blockIdentifier.Hash != nil { + req = request{ + Hash: *blockIdentifier.Hash, + } + } else if blockIdentifier.Index != nil && blockIdentifier.Hash == nil { + req = request{ + Height: *blockIdentifier.Index, + } + } + + callResult, err := utils.DecodeCallAsNumber(NodeClient.Call("block_get", req)) + jsonResult, _ := json.Marshal(callResult) + json.Unmarshal(jsonResult, &result) + + if err != nil { + return nil, WrapErr( + ErrFailed, + err, + ) + } + + // Must multiply time by 1000 since Helium response is + // in seconds not miliseconds + result.Time = result.Time * 1000 + + return &result, nil +} + func GetBlock(blockIdentifier *types.PartialBlockIdentifier) (*types.Block, *types.Error) { type request struct { Height int64 `json:"height,omitempty"` diff --git a/services/network_service.go b/services/network_service.go index 0f3ea84..7eb652d 100644 --- a/services/network_service.go +++ b/services/network_service.go @@ -58,22 +58,21 @@ func (s *NetworkAPIService) NetworkStatus( return nil, chErr } - currentBlockID, cbiErr := helium.GetBlockIdentifier(&types.PartialBlockIdentifier{ + currentBlock, cbErr := helium.GetBlockMeta(&types.PartialBlockIdentifier{ Index: currentHeight, }) - if cbiErr != nil { - return nil, cbiErr + if cbErr != nil { + return nil, cbErr } - currentBlockTimestamp, cbtErr := helium.GetBlockTimestamp(&types.PartialBlockIdentifier{ - Index: currentHeight, - }) - - if cbtErr != nil { - return nil, cbtErr + currentBlockID := &types.BlockIdentifier{ + Index: currentBlock.Height, + Hash: currentBlock.Hash, } + currentBlockTimestamp := currentBlock.Time + if currentBlockID.Index < *helium.LBS { return nil, helium.WrapErr(helium.ErrNodeSync, errors.New("node is catching up to snapshot height")) } @@ -91,10 +90,13 @@ func (s *NetworkAPIService) NetworkStatus( return nil, pErr } - syncStatus, sErr := helium.GetSyncStatus() - if sErr != nil { - return nil, sErr - } + // Removing syncStatus for now since currentBlock is + // retrieved from external API which is not ideal. + // + // syncStatus, sErr := helium.GetSyncStatus() + // if sErr != nil { + // return nil, sErr + // } genesisIndex := helium.MainnetGenesisBlockIndex genesisHash := helium.MainnetGenesisBlockHash @@ -106,14 +108,14 @@ func (s *NetworkAPIService) NetworkStatus( return &types.NetworkStatusResponse{ CurrentBlockIdentifier: currentBlockID, - CurrentBlockTimestamp: *currentBlockTimestamp, + CurrentBlockTimestamp: currentBlockTimestamp, GenesisBlockIdentifier: &types.BlockIdentifier{ Index: genesisIndex, Hash: genesisHash, }, OldestBlockIdentifier: lastBlessedBlock, Peers: peers, - SyncStatus: syncStatus, + // SyncStatus: syncStatus, }, nil } From e3f6fca4a91ed0676364ae160972cb77b59ee052 Mon Sep 17 00:00:00 2001 From: Steven Yuan Date: Wed, 23 Feb 2022 04:00:28 +0000 Subject: [PATCH 13/19] New start index closer to tip --- Dockerfile | 4 +- .../{1156322.json => 1236241.json} | 39 ++++++++++++++++++- rosetta-cli-config/mainnet/config.json | 2 +- 3 files changed, 40 insertions(+), 5 deletions(-) rename ghost-transactions/{1156322.json => 1236241.json} (72%) diff --git a/Dockerfile b/Dockerfile index a2c9498..e035528 100644 --- a/Dockerfile +++ b/Dockerfile @@ -83,7 +83,7 @@ WORKDIR /usr/src/ # Add our code # TODO: git checkout specific release when ready -RUN git clone https://github.com/syuan100/blockchain-node.git +RUN git clone https://github.com/syuan100/blockchain-node.git && echo '' FROM node-builder AS node-mainnet @@ -92,7 +92,7 @@ ARG BUILD_TARGET=docker_rosetta WORKDIR /usr/src/blockchain-node -RUN git checkout commit-hooks-with-heights +RUN git checkout bump_snap_sy RUN ./rebar3 as ${BUILD_TARGET} tar -n blockchain_node diff --git a/ghost-transactions/1156322.json b/ghost-transactions/1236241.json similarity index 72% rename from ghost-transactions/1156322.json rename to ghost-transactions/1236241.json index 3e9a8a6..8146ce2 100644 --- a/ghost-transactions/1156322.json +++ b/ghost-transactions/1236241.json @@ -10,6 +10,9 @@ {"Block":1103228,"Hash":"NpIO3cnUG0AF2kYh4kdCt34nkCD7JkxOM1RaoEf67u8","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"NpIO3cnUG0AF2kYh4kdCt34nkCD7JkxOM1RaoEf67u8\", \"type\": \"unstake_validator_v1\", \"owner\": \"149K7qgzFAD1Yy4vJJj5WrBLxziYmwqgCGCtUozXiooMRsKDbmA\", \"address\": \"11MS3mqmVTXKGwGddcuTH6B97WL6hzHc2NebgvQafNiuvw5WWgR\", \"stake_amount\": 1000000000000, \"owner_signature\": \"s_MnjBwwUf6lXuZ8VkKbbqZmwGbT3aSDM3rzvsMhHXGRtTJINfIzBu4b4Egv31U030xSO2naIh3azXZ6FhQvAA\", \"stake_release_height\": 1353280}","Time":"2021-11-18T23:35:20-05:00"}, {"Block":1128077,"Hash":"FoSM4rRMXEnx4c181LywlRljK3bPGlP0-TNp-vpYIlE","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"FoSM4rRMXEnx4c181LywlRljK3bPGlP0-TNp-vpYIlE\", \"type\": \"unstake_validator_v1\", \"owner\": \"13vs2tyGeoRpnRGgyRVZRKDhXdYYDRUCngJmQCUCfkZtq4TE7M9\", \"address\": \"11r5Xgma4zCVqfsSGNPD8Gb2ekiJRLxWmA4rXv4UFKTDXYXJcaH\", \"stake_amount\": 1000000000000, \"owner_signature\": \"jS9TCa-mxhC0VN-76Uvngc_CcVbouCpBPGBuK-zjka4sPL2nWLDADZq5aCmStaaEhuMAO98BY9tZPjKYJchABw\", \"stake_release_height\": 1378083}","Time":"2021-12-06T14:27:04-05:00"}, {"Block":1150629,"Hash":"G4VCOOzIJffBn3_ecEj5QzqWXSpmKzvPWVg5rob43oc","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"G4VCOOzIJffBn3_ecEj5QzqWXSpmKzvPWVg5rob43oc\", \"type\": \"unstake_validator_v1\", \"owner\": \"13vAncddhhsEgeHznUtfM5zYiGQozS11rMvp1ad3WsUYEyU7KoU\", \"address\": \"112eoqVMVuYRTFrT9yZyjw67eTWR8o1mdKxYvo9qn57uWx55kAin\", \"stake_amount\": 1000000000000, \"owner_signature\": \"BcI7MQxUhHv4XpfD4qgPhhFh2Oy05AWxrqLNh2DbDplMmpchv9R6DS7hPKupVJrlTYeYN2jDW4RscGtKdto0AA\", \"stake_release_height\": 1400635}","Time":"2021-12-23T07:07:10-05:00"}, +{"Block":1184435,"Hash":"RMXovClP05Jnb4iurKek78HMNsoO8Bj2f1ycFf_S6tw","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"RMXovClP05Jnb4iurKek78HMNsoO8Bj2f1ycFf_S6tw\", \"type\": \"unstake_validator_v1\", \"owner\": \"13YjqdzC1tPDyVE25YnjfzoaDnTjmroaqKVzciLPSGgMuT1VWNX\", \"address\": \"14X7JsJkH2pxntupHtap2SUyFBqw2R7JLNzqpNkkKXjmNft9ti5\", \"stake_amount\": 1000000000000, \"owner_signature\": \"YbPzqxeMEg_3dDYtCTwHe3BrFma66MV996hSo9rluinJSFuFpmH9qwkc-s-6hyjYxDCzNoipTJBywJraWPSKCw\", \"stake_release_height\": 1434454}","Time":"2022-01-16T16:50:46-05:00"}, +{"Block":1184436,"Hash":"fIVEuqz1JbQ1Bsfz2H-Lob0q4QzXvxq3Nj-LXxhCgKI","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"fIVEuqz1JbQ1Bsfz2H-Lob0q4QzXvxq3Nj-LXxhCgKI\", \"type\": \"unstake_validator_v1\", \"owner\": \"13YjqdzC1tPDyVE25YnjfzoaDnTjmroaqKVzciLPSGgMuT1VWNX\", \"address\": \"13EXp7rNBEWNnuXMt1LkZ8j8U4SQofT4vccuTnUDbW87XND5tRt\", \"stake_amount\": 1000000000000, \"owner_signature\": \"-i7OpsT3w06_ornclAF06Gjhig9gLDWo39tic99LjbjHCvQ65GJWSRpcMxVarr_iQ27WH7SLNF7ogur2KVCuBA\", \"stake_release_height\": 1434454}","Time":"2022-01-16T16:51:36-05:00"}, +{"Block":1228768,"Hash":"jZYijpnCgzivwoimAI2T-VN6O2yQEsInAJ3AbkPPAH8","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"jZYijpnCgzivwoimAI2T-VN6O2yQEsInAJ3AbkPPAH8\", \"type\": \"unstake_validator_v1\", \"owner\": \"14iFzQ429bvb8gFuwcwjdutbxQMGU1d18q1Wu6WFMegP7P1Ycu2\", \"address\": \"13Qx7G1dyvqp9ZoSFgSNmQCooTKzwt9hQVN4TST24fGW7PP4c6q\", \"stake_amount\": 1000000000000, \"owner_signature\": \"QFkXRCUrvsjgi8X4Df_q31zOh1RL8dBX2wqFBDEL-HTARy7ggeLAe-4a21L1WAt6HzNHyor8VhNWvfJKomIzAw\", \"stake_release_height\": 1478782}","Time":"2022-02-16T17:47:34-05:00"}, {"Block":960405,"Hash":"P4vjS7HDbBWQ1dUWDB36htTgBk9GmxPOH8SiqYvDxnQ","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"P4vjS7HDbBWQ1dUWDB36htTgBk9GmxPOH8SiqYvDxnQ\", \"type\": \"unstake_validator_v1\", \"owner\": \"12xoVMjaduyZm1bw1GEBXoQe6YHCfU5gghcuobQ5weopZ8as3qw\", \"address\": \"112LWrY91t5xEZ4ChoehMQBTVBZk8QKrnhZatKQbPTLM3c67R3CZ\", \"stake_amount\": 1000000000000, \"owner_signature\": \"blk_dAVf8XX_JcrvNXJ8Jjm_WqlU58ccrjZ431PMZIucq7jv76tlJbjzpJJ2qoEabXdYOqp2wHhKcGT9AhzRDQ\", \"stake_release_height\": 1210420}","Time":"2021-08-11T01:46:59-04:00"}, {"Block":980401,"Hash":"1MLDABvC7R_jyNUrDEmaB7U1pdyvQyUL9XQTERlSNg0","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"1MLDABvC7R_jyNUrDEmaB7U1pdyvQyUL9XQTERlSNg0\", \"type\": \"unstake_validator_v1\", \"owner\": \"13z7iDxBz6NuCDXBJm573kBqS7vDcKMzN3NscQndrvDLCCJKNMd\", \"address\": \"112cMXhHGQfyrc3mkfPvczg5qfSgGod2EgQCwEzMSxRDjouVQp3A\", \"stake_amount\": 1000000000000, \"owner_signature\": \"fJQbWBx8FE0jUfHN4pvQKvPDJe9YN_gI25Ox6pwWLdS8HGhMx8lbIkoBpkdp1qELSaZmLctVXe2L5LO9j0w5Dw\", \"stake_release_height\": 1230420}","Time":"2021-08-24T15:33:00-04:00"}, {"Block":1005224,"Hash":"nKn8B-2pHiLtL-EadB1niqd5gCQsQk5C0BUc4StXciI","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"nKn8B-2pHiLtL-EadB1niqd5gCQsQk5C0BUc4StXciI\", \"type\": \"unstake_validator_v1\", \"owner\": \"141WsikcrSo8tugixuLN5QTfzzLbm757UKd556iSx16sfq127ey\", \"address\": \"112E2kYMHdw6jqWFZ4Hc1CfJBx765B441ByLWAe7hQKDvzKwkV13\", \"stake_amount\": 1000000000000, \"owner_signature\": \"WKL3M-MDCLXLTduVN1wpWtGvFRImi16NXMmgmBue5r_3NOyD95RiPGytu6SUglZEChsaz1ey1vFyPVYTyo6oDA\", \"stake_release_height\": 1255236}","Time":"2021-09-10T11:38:38-04:00"}, @@ -19,6 +22,12 @@ {"Block":1128027,"Hash":"pi2XvDlBdpwRD5VoKkZqJask8EvsD_X1YBv_4XypYL0","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"pi2XvDlBdpwRD5VoKkZqJask8EvsD_X1YBv_4XypYL0\", \"type\": \"unstake_validator_v1\", \"owner\": \"13vs2tyGeoRpnRGgyRVZRKDhXdYYDRUCngJmQCUCfkZtq4TE7M9\", \"address\": \"11nvWaoLVnpzLNYYVEYbWyiYyiCK27489Ck74r3XnscXH4ohb7S\", \"stake_amount\": 1000000000000, \"owner_signature\": \"cGl8ztmhz2HGYgSBFx380DsiuIf6vgZgrX8mkyTGT2e-L-GwZxiuQ1JtrN0CsuYUy9teGqG1k-EBANj9GHZCBw\", \"stake_release_height\": 1378029}","Time":"2021-12-06T13:40:55-05:00"}, {"Block":1130063,"Hash":"F2jhlgz5JyuYSakoHb9B41Ka8MJhkjzgHruOspiQdtw","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"F2jhlgz5JyuYSakoHb9B41Ka8MJhkjzgHruOspiQdtw\", \"type\": \"unstake_validator_v1\", \"owner\": \"1365o2Bbm7vKtM96kjaM2kGxKJ4M6VfJooK9KUwHJM2j9H8thWd\", \"address\": \"13WyJBxEf7a9c71epworCGKoK2v2Xs1n87b2wRnj7E8Ui4SGRfJ\", \"stake_amount\": 1000000000000, \"owner_signature\": \"uHmfgn1-BNIoGD4oQjeev3oyJmnroV-QzqyExI-biXuLY5ciGWAPVQP2b_3SX73VqNmlfilWccwVjeFICqJhDA\", \"stake_release_height\": 1380088}","Time":"2021-12-07T22:11:54-05:00"}, {"Block":1143847,"Hash":"COXQqCkOBdd5GzIDb93dNZ0gg2bGxJw39CCh9EQBGBc","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"COXQqCkOBdd5GzIDb93dNZ0gg2bGxJw39CCh9EQBGBc\", \"type\": \"unstake_validator_v1\", \"owner\": \"13zo16SCZ1fZhaxuEFthg1QWjtoiHbDC1fUVjuKoGDCFXomMMmP\", \"address\": \"112ZFstLDFuaFrBd1c5WmiPY2juJYncGmDjHNEuQc6vzi8EPa6Tj\", \"stake_amount\": 1000000000000, \"owner_signature\": \"gjSCMvGMv8vQM_5Z4DJWZaXyg61Yj4-Gmbi6ynESN7A2Fj4KgT10v8qWnawyXuCCyuOVGnus3A6tkRkwt-uQBg\", \"stake_release_height\": 1393847}","Time":"2021-12-17T19:10:46-05:00"}, +{"Block":1159761,"Hash":"thR5VG60YZxFf7k0TvWjqsYlZbhVDwk0ma__D1dCFds","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"thR5VG60YZxFf7k0TvWjqsYlZbhVDwk0ma__D1dCFds\", \"type\": \"unstake_validator_v1\", \"owner\": \"134ktUDj1aMaJLnH4S4sGET5YeHYyKvYoc3m3zQficDofkCp25q\", \"address\": \"14H1AD8pFPAMxzxvoDLzmC5M4UcaCsQttsy124C6n31aZRwhhSm\", \"stake_amount\": 1000000000000, \"owner_signature\": \"SjIUdsW8BZlBhOHaGCygaSNiVUiM2xytPzXmClkQymz_ihTGP1p3eugXOrwFASXbl6U1_0uIZ-CAwjUMIAZFDw\", \"stake_release_height\": 1409764}","Time":"2021-12-30T16:38:25-05:00"}, +{"Block":1165163,"Hash":"kP-o62g5hENW3dGS9BCNKuaU9e5vM18wQNHl5kc5l7w","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"kP-o62g5hENW3dGS9BCNKuaU9e5vM18wQNHl5kc5l7w\", \"type\": \"unstake_validator_v1\", \"owner\": \"132s6X8Sh1EFxkL4p6wWBKnWnL1fqGjn6BpsCiPyzYfE4Nvqho6\", \"address\": \"11xxPWhKPmz362J53ENXtqqhZxAWdnabrST25AzmbNcBka3kRgw\", \"stake_amount\": 1000000000000, \"owner_signature\": \"fAderTSekO2udePBuhusQwPscFGfdXS-l1dv3kGx8pChuLv4mu_KFUT9S-i9BAr2DxiWzdzFubGSsCjm5d8RCA\", \"stake_release_height\": 1415173}","Time":"2022-01-03T23:53:54-05:00"}, +{"Block":1179316,"Hash":"U-bSHdqPrA0mlKwAHq2E8RrBpo6h4g0a3ICGNteJ8hE","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"U-bSHdqPrA0mlKwAHq2E8RrBpo6h4g0a3ICGNteJ8hE\", \"type\": \"unstake_validator_v1\", \"owner\": \"13CCaouFndqHYG882kJELoy7oY1Veo78qZ3ihGepTsCi6wYGNtM\", \"address\": \"112vq2u7JHaHCofSpQANqUDuCDjU9T2R6uZ9ELnw7ffpqHatp7KL\", \"stake_amount\": 1000000000000, \"owner_signature\": \"NJ-gni7PvVQNMEg5WuwtJRoPLgLgX9aFLEPRiyy9HL1uEag7VyKCwjKnpUfiwu4WFv2mJPFP-6kpNTq_RgKgCg\", \"stake_release_height\": 1429319}","Time":"2022-01-13T08:42:13-05:00"}, +{"Block":1187448,"Hash":"83Q8h-ERMwrhHRmlQc3GTftdB-I5lMuIkxoYKIANCUw","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"83Q8h-ERMwrhHRmlQc3GTftdB-I5lMuIkxoYKIANCUw\", \"type\": \"unstake_validator_v1\", \"owner\": \"14J6zntifsPAbiPxHYhyK7zV5ZdtKm3DiiZUVNRCe4NS9kEbGKT\", \"address\": \"116tGvUzhrF4de99R4WtSjEzC4KUYhmoDB3d3LBP1KWh4ywN8jr\", \"stake_amount\": 1000000000000, \"owner_signature\": \"QqzaLK0I6hgFAv-gR-hoq_002qCsizdOf8Bzzy1cVdogPVpaEr_q8MJ9GsqepTn99TQLkwOpKwXKdswSmR9-Aw\", \"stake_release_height\": 1437461}","Time":"2022-01-18T15:32:29-05:00"}, +{"Block":1204193,"Hash":"MMNRcZ6Cwz6i9JxzAt-3S-Muox6avUK2LhXPAVXq5Tk","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"MMNRcZ6Cwz6i9JxzAt-3S-Muox6avUK2LhXPAVXq5Tk\", \"type\": \"unstake_validator_v1\", \"owner\": \"13XwyG3nRs7u8BHjFHpfquNNmQi4EpuyhbMVTBP2yNzUvLKJNYi\", \"address\": \"112uXKVQwo2fxmcmp6zBMYiKHXyevUuBnjXjwFAZVYWofpLcBiza\", \"stake_amount\": 1000000000000, \"owner_signature\": \"0D1UphyulqwMYt4iKozLl_EsXm9YZY9W7YBllXqV8SheIuob34RO40RYXLPM84PJSqdcESyVlh3AAFF4X9gGCw\", \"stake_release_height\": 1454195}","Time":"2022-01-29T19:41:26-05:00"}, +{"Block":1205593,"Hash":"dDaHd1YJUUtyHhdea7Yp7b6zXQ0gEVIecnT_kpbkARw","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"dDaHd1YJUUtyHhdea7Yp7b6zXQ0gEVIecnT_kpbkARw\", \"type\": \"unstake_validator_v1\", \"owner\": \"14PNnDMq6EnG9kXGPeH3DiBKT5akZ89AmEGzUesTaX1SdLbNpfT\", \"address\": \"11CLUNS5fqLkFvbWHuxk1oRZx5o6xh68PcFjfTADkh3zWTmD2Ah\", \"stake_amount\": 1000000000000, \"owner_signature\": \"7WQHoMa3SJOUmcFnvcPii6rlelRcR3Ge7QXIRRLu57ceGJAdokE8Gm5zYUpu8kwkwblCeOtowCJ-8qvvbZPOCA\", \"stake_release_height\": 1455610}","Time":"2022-01-30T20:29:02-05:00"}, {"Block":912024,"Hash":"fMT-7_f2WQNKAYIQWX2-V258KsoI61HYbt_zAbN3A1I","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"fMT-7_f2WQNKAYIQWX2-V258KsoI61HYbt_zAbN3A1I\", \"type\": \"unstake_validator_v1\", \"owner\": \"13Yet3BKcwpanUMFE4botQp4ZQwkDJeNzKdCMMoMot4fsQLEN4n\", \"address\": \"11cY9Ly5H3hU4Ai2k7G9niHLAxsKb1ragQYGLJ7E9vh4Vnx6Efb\", \"stake_amount\": 1000000000000, \"owner_signature\": \"M17f8dT1YkLjZwZwayasX3wsZg8wPXoR3a7sGja0Ds6zEVBiRxfsTFE6Qo7gL7bbAizHDZC6N2s1rF5eO_mWCg\", \"stake_release_height\": 1162029}","Time":"2021-07-08T16:45:34-04:00"}, {"Block":968474,"Hash":"GtbPkm_o8CfXYRKHR3RbMdhi3QgqTTMC5eNcg0dpLy0","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"GtbPkm_o8CfXYRKHR3RbMdhi3QgqTTMC5eNcg0dpLy0\", \"type\": \"unstake_validator_v1\", \"owner\": \"13RtTjMaNpqEQBQqN9K1RezaHJS1cTmX9iMJch3tnGM2XVKz7k6\", \"address\": \"14rZ2HDVZpwbwKwr6XicHvEAZG1TupPGUBWmD6dCNPwma4ojVVE\", \"stake_amount\": 1000000000000, \"owner_signature\": \"Td86kJjiO5RZCAppJ7USl_B9wNkagHckeXJNz7mx25wAPfuN7X4CNNUjHI-1CJMf43QijXfgEo_ounAr0VFuDQ\", \"stake_release_height\": 1218500}","Time":"2021-08-16T18:56:17-04:00"}, {"Block":968474,"Hash":"KB6m3qpOJb603jlfONUj4lglHDP5fHpbCPjYX7DM8KU","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"KB6m3qpOJb603jlfONUj4lglHDP5fHpbCPjYX7DM8KU\", \"type\": \"unstake_validator_v1\", \"owner\": \"13RtTjMaNpqEQBQqN9K1RezaHJS1cTmX9iMJch3tnGM2XVKz7k6\", \"address\": \"13cvwDwy9uzPQhMDzLToXrSpANDBKEFvu6s45LbescLfqF92PPC\", \"stake_amount\": 1000000000000, \"owner_signature\": \"aB_aFkezJZ0CZfMKi-1G6ZQA9JEltA4Ij3N3Ao4-1yweH76PYAwyCVXmvqa0Ni028IduOPeuZPqViL8Dw87sAA\", \"stake_release_height\": 1218500}","Time":"2021-08-16T18:56:17-04:00"}, @@ -35,6 +44,9 @@ {"Block":1103224,"Hash":"Bca7GjNvo9TgBhiiWPdMtMxY_E2osuwFmwwPRUOo5Sg","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"Bca7GjNvo9TgBhiiWPdMtMxY_E2osuwFmwwPRUOo5Sg\", \"type\": \"unstake_validator_v1\", \"owner\": \"149K7qgzFAD1Yy4vJJj5WrBLxziYmwqgCGCtUozXiooMRsKDbmA\", \"address\": \"1122PAKuXrPtoTwEysHKuTBv9rR1h3EoEuA7cbtpnT1n8RmLnVPU\", \"stake_amount\": 1000000000000, \"owner_signature\": \"cNKj_-tV_aBcxu0sd1r_BWyYI_wnC9BYrlA0V3RWaZRrLLuFe6-1sn-SLd8jfLA8dINBsYNOrt0UZSxuD8C8Bw\", \"stake_release_height\": 1353280}","Time":"2021-11-18T23:31:45-05:00"}, {"Block":1103234,"Hash":"1qRwmphja0rrvw-IQ-tJmcIegC_a6kb-AvhplioNVRE","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"1qRwmphja0rrvw-IQ-tJmcIegC_a6kb-AvhplioNVRE\", \"type\": \"unstake_validator_v1\", \"owner\": \"149K7qgzFAD1Yy4vJJj5WrBLxziYmwqgCGCtUozXiooMRsKDbmA\", \"address\": \"11HFLaPyb2ytrtDuSWkJ2FA4p75b1mTJLMDw6PqBqsr6htp6vhH\", \"stake_amount\": 1000000000000, \"owner_signature\": \"hj7yF6pbJWjATCJH__fMTV9Fh1KLlDjPnzy5TCehcuPn91EssS68erF3NUzagyYoEYCABJzAXetFmDv-Uu-jDw\", \"stake_release_height\": 1353280}","Time":"2021-11-18T23:40:54-05:00"}, {"Block":1107597,"Hash":"zCf_iXptpWwGL0ip_wQSs0_n9m_3eF6YQsTa-FHNtlA","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"zCf_iXptpWwGL0ip_wQSs0_n9m_3eF6YQsTa-FHNtlA\", \"type\": \"unstake_validator_v1\", \"owner\": \"135bea4mPyYnYLhCa9xCSKxuRpPek4DdU6RtNXLUenx965FF2Qx\", \"address\": \"11ZsTPXrzZrZ79ipBtUVSaDdVWGhSuQ5NhAiZRVXPgaTFmdhHKv\", \"stake_amount\": 1000000000000, \"owner_signature\": \"Wcb9SxiS__apapVcbmznmWsQaFhp79MmzWDShDGkD8n2McbOGT7INunRy9akig_5NV52rbxHaawQ6YAB0eOBDA\", \"stake_release_height\": 1357611}","Time":"2021-11-22T12:26:02-05:00"}, +{"Block":1158384,"Hash":"x3Nhho7THmDJAPNeRiEbVVOXVOKpNJTtx_Y10-OCMbw","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"x3Nhho7THmDJAPNeRiEbVVOXVOKpNJTtx_Y10-OCMbw\", \"type\": \"unstake_validator_v1\", \"owner\": \"13PL7mqUNewGt4j5XTch2t3v8awB3YJkJJVLYtrsX7aVQcAWWy3\", \"address\": \"11LUtbdfzvEmvTxvuExubsVezsbjmkEtFHeV3gRUG4A8X12ESAZ\", \"stake_amount\": 1000000000000, \"owner_signature\": \"i6MoxnRUEbKvPgkX0FHTBMgsU4xemKIA-vtL-Y6vf-govNXU4TjDKJur7EKF_UEaCTMzjhFlCjbFforzQKcTDw\", \"stake_release_height\": 1408397}","Time":"2021-12-29T14:13:07-05:00"}, +{"Block":1191129,"Hash":"9K6ZRAZ3juua6cHQuL6WfOOx252VT51cYgMwtMLE71M","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"9K6ZRAZ3juua6cHQuL6WfOOx252VT51cYgMwtMLE71M\", \"type\": \"unstake_validator_v1\", \"owner\": \"13fAhjCGycJALqbsQCJ49d6JUQjQ5wgBUEZm7ZGytfGPNM4uzn9\", \"address\": \"14ko5Gg33HoeUGypDh2W9Cr2oj18foiRVagvyhdMcQbwgvrpm2S\", \"stake_amount\": 1000000000000, \"owner_signature\": \"VM9K6Ce59KMpC7S0yOOer3kZG0tIw3R6wjzpe0HTDk2TPM5nBIYO1F_SqxVKL1JAs1_YDvWthDFUyFY0xEE8BQ\", \"stake_release_height\": 1441129}","Time":"2022-01-21T00:11:54-05:00"}, +{"Block":1205599,"Hash":"bFyJt0uPq5GeJSI0os_EkS-ZZfsvOR0GnV66w4A4p34","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"bFyJt0uPq5GeJSI0os_EkS-ZZfsvOR0GnV66w4A4p34\", \"type\": \"unstake_validator_v1\", \"owner\": \"14PNnDMq6EnG9kXGPeH3DiBKT5akZ89AmEGzUesTaX1SdLbNpfT\", \"address\": \"112ssQr2qe3XLb6dBTNZVBdaiEU9bEb2XpFQkvN2wbLaB5xoshZh\", \"stake_amount\": 1000000000000, \"owner_signature\": \"D805VbtCTXHwwKBDf8ekpsg_jiHmJF76cxTmJGTqz0mou5bjFsI0q5-EygASKjlWzIiwoLOHsQ96RoRjJN-dCA\", \"stake_release_height\": 1455610}","Time":"2022-01-30T20:35:08-05:00"}, {"Block":993298,"Hash":"whK6XSNtJ7mFNCOG5DgZ020ZF3WNWwU0TuB8DBI6Z9U","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"whK6XSNtJ7mFNCOG5DgZ020ZF3WNWwU0TuB8DBI6Z9U\", \"type\": \"unstake_validator_v1\", \"owner\": \"13P73axPhjTRiDvwTYzzaXKeTmPpUDzXDeX8PH2owhpRKGCGWEd\", \"address\": \"112hexri3xqAXb347Sk2aN3Hkr4DLs4vZnZ69QwvPCTytZ4CAsy5\", \"stake_amount\": 1000000000000, \"owner_signature\": \"FchcHyG4SN71r_81GeLEuBnOp0prSA4xQ8v49RpiexBGtFjIiQGbiPRTW30ePb3LdSa-tpuIhYo_5e13aFBfCA\", \"stake_release_height\": 1243298}","Time":"2021-09-02T04:32:17-04:00"}, {"Block":1005214,"Hash":"iW0ZaP5x2IkDUwfnj_0U_Bftq4oA6Oq3V3dReP0eUMs","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"iW0ZaP5x2IkDUwfnj_0U_Bftq4oA6Oq3V3dReP0eUMs\", \"type\": \"unstake_validator_v1\", \"owner\": \"141WsikcrSo8tugixuLN5QTfzzLbm757UKd556iSx16sfq127ey\", \"address\": \"112BVQNFU5JZ5oHgFTasVwDpxRkJ9FgYwKmZzYB951NhW7LS1hfK\", \"stake_amount\": 1000000000000, \"owner_signature\": \"gG4a8ALZpVrg0KMpCYgGKZ3YYKNQ_9AkrSlTCNfqKIlrzUYjlQepPPqmtXKtAGWxV58y_Hasn1Hgnj29bbCgAw\", \"stake_release_height\": 1255226}","Time":"2021-09-10T11:28:28-04:00"}, {"Block":1005229,"Hash":"s3pC-QUO15cwuMtmJPWnDbJLxr1jvUJHOvfl-sxI11Q","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"s3pC-QUO15cwuMtmJPWnDbJLxr1jvUJHOvfl-sxI11Q\", \"type\": \"unstake_validator_v1\", \"owner\": \"141WsikcrSo8tugixuLN5QTfzzLbm757UKd556iSx16sfq127ey\", \"address\": \"112rDxMhcWT1kPurJQhiWEuiMptgTPRL8swHzfM7WKNBshwJjSts\", \"stake_amount\": 1000000000000, \"owner_signature\": \"JoRDBi2sD75wsGhdI7yWS5wd49YPffDSet0Ht-TgHOPs8pKH7xPYgkmqrGOjSnSFav1RnelwAD0FX_OllDY0Cg\", \"stake_release_height\": 1255245}","Time":"2021-09-10T11:43:43-04:00"}, @@ -46,16 +58,18 @@ {"Block":1097507,"Hash":"GjjiEkU1rWrZBJuma1ww78gj_TyMOy8Bf7UGvmFb6HM","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"GjjiEkU1rWrZBJuma1ww78gj_TyMOy8Bf7UGvmFb6HM\", \"type\": \"unstake_validator_v1\", \"owner\": \"14SZx1ESJrmXtjnBwZ4zbWDLXrPhGNuGxiEVBU4smmgyBKzVFdr\", \"address\": \"11R2MxWXmgER9ifBRyjdVhLPxXaHjywEJHvqMDwmaHRoc4iRidY\", \"stake_amount\": 1000000000000, \"owner_signature\": \"D17jyr4fqQnulnHpgbNwiekExMDPEQ8Qf92NduMNPkbukpHxFjOsYpu3VUOhFkI6EakDdAasajKBHvo4yUzZCA\", \"stake_release_height\": 1347521}","Time":"2021-11-13T16:27:35-05:00"}, {"Block":1103227,"Hash":"I_iWxd14cWs6ZCEOWctJZWKvg8q-CN0ew0TjY3d8YRY","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"I_iWxd14cWs6ZCEOWctJZWKvg8q-CN0ew0TjY3d8YRY\", \"type\": \"unstake_validator_v1\", \"owner\": \"149K7qgzFAD1Yy4vJJj5WrBLxziYmwqgCGCtUozXiooMRsKDbmA\", \"address\": \"112UYszCGaYCqADp78dC1iuitsZo8yuza4nVxZJUCyAKpGowujZU\", \"stake_amount\": 1000000000000, \"owner_signature\": \"umNNwvOQGxSBBL-grhBa5jGuFlDMwk8TDlDT8yl0vw9ebOb4EhDTtmciiYMT9KUqtIlU5VMmu02C7ZMhxi5oDg\", \"stake_release_height\": 1353280}","Time":"2021-11-18T23:34:30-05:00"}, {"Block":1150630,"Hash":"MQ3dImr4y_xLmjUumknEY7dQtMTjo5rhKlAMHStgDGQ","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"MQ3dImr4y_xLmjUumknEY7dQtMTjo5rhKlAMHStgDGQ\", \"type\": \"unstake_validator_v1\", \"owner\": \"13oXYBqPVucYUz7uuBHHa3mUaxEsqNzFyyYntsaj9nLTBoUiv2W\", \"address\": \"11MV5RUwYsvErcTEbJGHiPFQwU7GhKvLQFtJrdTZ5stzuYQioQK\", \"stake_amount\": 1000000000000, \"owner_signature\": \"jV7ubEAKFRWPeJe_TJUmtuKPMFeHR25P0ZUaD8fYOlizD80Ks3rstYjjJfwJN-DxT90x1saCC1fnO8uSrZdEBQ\", \"stake_release_height\": 1400635}","Time":"2021-12-23T07:08:00-05:00"}, +{"Block":1191886,"Hash":"RfqQ1Vq6qhMLHAtcbtb0y5N0aBfZOPKqChsljbLMag4","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"RfqQ1Vq6qhMLHAtcbtb0y5N0aBfZOPKqChsljbLMag4\", \"type\": \"unstake_validator_v1\", \"owner\": \"13SoCNwjK9DEE8Fg8xvd45eKqAqZSQUDbwfVB9YGEyXZqRoFNTL\", \"address\": \"13uXhuPFvejiNKi2G3vWT23JsfuDBJNyxWUdPRxvi4mgeGFWeBj\", \"stake_amount\": 1000000000000, \"owner_signature\": \"HzUoZXE7y7SkzvwIF4fbSJPuUMgdGFH1Gc1mgbWb5ylhJwlEu29hZKi3TY2il-U49JzSQe4olF9HrMhLdWepDg\", \"stake_release_height\": 1441891}","Time":"2022-01-21T12:01:29-05:00"}, +{"Block":1215060,"Hash":"xqWOAOepgNTC6slyi4noVLXRLKxir4xVCuMzayeTavM","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"xqWOAOepgNTC6slyi4noVLXRLKxir4xVCuMzayeTavM\", \"type\": \"unstake_validator_v1\", \"owner\": \"134c74JYsfN7X4CRGixhFSWgvR6m6wV4RMJUC13J97GnN9uBCJN\", \"address\": \"13vpUfieCqBbyLHF6QtFNS6uoB6nG6d9f2Y3B6wcBWGXHbdswVJ\", \"stake_amount\": 1000000000000, \"owner_signature\": \"cBNU-xVJtmLB5qNqeAuhngRelkpxQTndVkAKbmDXfBPGDJB79-Pg0MMDo3Q1AygWWDgYpxfMr9EcH-TGasGYDA\", \"stake_release_height\": 1465080}","Time":"2022-02-06T19:57:25-05:00"}, {"Block":960313,"Hash":"fXfwqV-1lA33erj3IwiEa2vIaVNu4qq6eBi9gJm9bZg","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"fXfwqV-1lA33erj3IwiEa2vIaVNu4qq6eBi9gJm9bZg\", \"type\": \"unstake_validator_v1\", \"owner\": \"12xoVMjaduyZm1bw1GEBXoQe6YHCfU5gghcuobQ5weopZ8as3qw\", \"address\": \"11ShxanLac4CbtvbvCuvKBBs6Jq1D4g6jPMkhbkxF8sis5bMeRZ\", \"stake_amount\": 1000000000000, \"owner_signature\": \"0i7H7rFrDIwj_ChzT--OnpmAPwrPF5YLkenqtsr7cs0JyknArYmm4HFcAzNENN3qejSEwNN9IB777EPL44yFAA\", \"stake_release_height\": 1210331}","Time":"2021-08-10T23:56:53-04:00"}, {"Block":960336,"Hash":"UcGVGWx7pEGHwOXANLtQ5qeqVK-rkV9r6kIpvrZICcM","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"UcGVGWx7pEGHwOXANLtQ5qeqVK-rkV9r6kIpvrZICcM\", \"type\": \"unstake_validator_v1\", \"owner\": \"12xoVMjaduyZm1bw1GEBXoQe6YHCfU5gghcuobQ5weopZ8as3qw\", \"address\": \"11Dk1QfJUn6a4qnfu4ufF7c8KZKf2ZDwm7EsGEiDsh2WZX9Cnxk\", \"stake_amount\": 1000000000000, \"owner_signature\": \"CSz6oS9wT-U0QatpfBK6g3QdQUPMyFlAn09FegNKXjkukh90eoIfuRxwakyOg5STCd5cuVl9yMvV_gOe4WKIAA\", \"stake_release_height\": 1210350}","Time":"2021-08-11T00:23:43-04:00"}, {"Block":960366,"Hash":"3QSM2gTB7xygbZtfuzbs-YvfAQyDrHFeZw0xUtAcpGc","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"3QSM2gTB7xygbZtfuzbs-YvfAQyDrHFeZw0xUtAcpGc\", \"type\": \"unstake_validator_v1\", \"owner\": \"12xoVMjaduyZm1bw1GEBXoQe6YHCfU5gghcuobQ5weopZ8as3qw\", \"address\": \"112hLLgKmMw1CGxuALfJgWPwpdPUJPeKYfYijJT7xmVQ1SQspXDw\", \"stake_amount\": 1000000000000, \"owner_signature\": \"OoHwD6XuknhCVgtRCW3l3ay7s6ldjWrjYFZxUKWAmOssYapWXu1E-pQ2td3Vxlip4OyQYrJq0fdwrKRAyWuQCw\", \"stake_release_height\": 1210380}","Time":"2021-08-11T01:00:04-04:00"}, {"Block":960434,"Hash":"Q3rWCkulmC0R9AsCDesxIO_CVSxXnxIfxxmOD7ET0_s","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"Q3rWCkulmC0R9AsCDesxIO_CVSxXnxIfxxmOD7ET0_s\", \"type\": \"unstake_validator_v1\", \"owner\": \"12xoVMjaduyZm1bw1GEBXoQe6YHCfU5gghcuobQ5weopZ8as3qw\", \"address\": \"112CM9jgwZtzMHp7HBwTRK6nZq6YVzEJMHUQBk6hngd4GEbEvyVZ\", \"stake_amount\": 1000000000000, \"owner_signature\": \"-Co4EuhnELuiZUJRhtXmoAnYtZ_8pP_HIV2qkMo5bWdKUn_fqIl4r8zwwxNcxoLjjqLXr7-OdZuceBoBHd3HAA\", \"stake_release_height\": 1210450}","Time":"2021-08-11T02:21:25-04:00"}, +{"Block":980522,"Hash":"erg-MSe1YZNJYd_mQ1_FDUzPLCBgddT-_GNVbXxrWwE","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"erg-MSe1YZNJYd_mQ1_FDUzPLCBgddT-_GNVbXxrWwE\", \"type\": \"unstake_validator_v1\", \"owner\": \"12yMesr1QQApygG73PVZwDsd65zKB3dSgrfQNm2voiy8PD35jTE\", \"address\": \"112PvBWVx1xE1zcSagAw1wcRDBxDE71qfjezkh8iryWyxZmQSfiM\", \"stake_amount\": 1000000000000, \"owner_signature\": \"mEZAvD-vxLBEPPVtAaX5WaxutkS1H093OqBFBDIrMZfKDEE1v2HgXhmS6Rr9F7AtbGcR5CXPZ1W_JYvmNTJsDQ\", \"stake_release_height\": 1230548}","Time":"2021-08-24T17:16:43-04:00"}, {"Block":968453,"Hash":"xCbFK2O1L0Yl6eM7Ltcd55UjV_rYgsUDa5dRGquJHn0","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"xCbFK2O1L0Yl6eM7Ltcd55UjV_rYgsUDa5dRGquJHn0\", \"type\": \"unstake_validator_v1\", \"owner\": \"13RtTjMaNpqEQBQqN9K1RezaHJS1cTmX9iMJch3tnGM2XVKz7k6\", \"address\": \"13Q95MP2H8pyZePE4sYV156fePMXQUM8hcm42XSeH7rk5RbftHj\", \"stake_amount\": 1000000000000, \"owner_signature\": \"SnqLfblhBm-55dMNwou6IzXJkLpfSaWVwG5A0LXrOQUQqfyrNrlWMVKGMjK-8fumtvI2x6QBJQnvN4gXjmOeAA\", \"stake_release_height\": 1218460}","Time":"2021-08-16T18:29:38-04:00"}, {"Block":968475,"Hash":"pYs6njlEvQxdfaNT6nzRhJ1cJb7UiiKGz37rwMlDH9I","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"pYs6njlEvQxdfaNT6nzRhJ1cJb7UiiKGz37rwMlDH9I\", \"type\": \"unstake_validator_v1\", \"owner\": \"13RtTjMaNpqEQBQqN9K1RezaHJS1cTmX9iMJch3tnGM2XVKz7k6\", \"address\": \"112P4F8kLrmQ5fCscM35T4jEwb7Z2xtESx4WZXektXvu2LMGnw6D\", \"stake_amount\": 1000000000000, \"owner_signature\": \"UcAE7mpHFDdjprWQ67mzLheomwxJn7TQtHQwvK1vZfAHRJSqqMQWJdrwyNvljGrkdhUw2n-ZYF84qhTSq6XqDQ\", \"stake_release_height\": 1218500}","Time":"2021-08-16T18:57:07-04:00"}, {"Block":968478,"Hash":"gd3sUODNew9fZnQ0udqz4m4crAW3_66zfbWw1i8A7-w","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"gd3sUODNew9fZnQ0udqz4m4crAW3_66zfbWw1i8A7-w\", \"type\": \"unstake_validator_v1\", \"owner\": \"13RtTjMaNpqEQBQqN9K1RezaHJS1cTmX9iMJch3tnGM2XVKz7k6\", \"address\": \"13DXfT7oYcMWLyrAxjEPVkJSj3XD6Qfia6R8EBYyepfAKneGWrR\", \"stake_amount\": 1000000000000, \"owner_signature\": \"1-q4g-12uZ_e1c50ald2Bh-crWQBXQtogiNyKXkM1iy8Kab3wR4aZQoM-1LRDT702WnKSIQM6LqsoS1PH6CbDw\", \"stake_release_height\": 1218500}","Time":"2021-08-16T18:59:37-04:00"}, {"Block":979099,"Hash":"oT4SmRNlYP7WGGU4EU1bpayRXoPo4KSFatshQqXDbe8","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"oT4SmRNlYP7WGGU4EU1bpayRXoPo4KSFatshQqXDbe8\", \"type\": \"unstake_validator_v1\", \"owner\": \"14XpPwvTLYtH2nLpUTRwKyHuhVXLEe5cD9vXv9zTUgqCFhqTKFE\", \"address\": \"12yVMFiU1BnFfmDNr7Menko4i1tW1QB5XDvNSTuAHp7uZJpJQUN\", \"stake_amount\": 1000000000000, \"owner_signature\": \"GHX8ZBr9oArTUMkAKbB8XFx0UUjvMZevUmEaL2hTNLeQdhUqBnlLkvdUhD3Lk4Ts2nSuliylzzY_COTV0CbJBg\", \"stake_release_height\": 1229153}","Time":"2021-08-23T19:42:44-04:00"}, {"Block":979110,"Hash":"tFsCXV1blt5uSgul6fccL4VhuAzkVkEE3qWiyt8mYCk","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"tFsCXV1blt5uSgul6fccL4VhuAzkVkEE3qWiyt8mYCk\", \"type\": \"unstake_validator_v1\", \"owner\": \"14XpPwvTLYtH2nLpUTRwKyHuhVXLEe5cD9vXv9zTUgqCFhqTKFE\", \"address\": \"13qJcSXo5wrxjy93AWQ7b1TJBW8VWSVw2APxU5wqk83oUUTM9KW\", \"stake_amount\": 1000000000000, \"owner_signature\": \"htVNRe_2Z6aqm1z_GMiJmokdWl7h-cw2ZJ9FKlP9b3_du_WryGKyUBalX0hOLAyNtlYkootU3PmwMDMy3Nj9DA\", \"stake_release_height\": 1229153}","Time":"2021-08-23T19:51:49-04:00"}, -{"Block":980522,"Hash":"erg-MSe1YZNJYd_mQ1_FDUzPLCBgddT-_GNVbXxrWwE","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"erg-MSe1YZNJYd_mQ1_FDUzPLCBgddT-_GNVbXxrWwE\", \"type\": \"unstake_validator_v1\", \"owner\": \"12yMesr1QQApygG73PVZwDsd65zKB3dSgrfQNm2voiy8PD35jTE\", \"address\": \"112PvBWVx1xE1zcSagAw1wcRDBxDE71qfjezkh8iryWyxZmQSfiM\", \"stake_amount\": 1000000000000, \"owner_signature\": \"mEZAvD-vxLBEPPVtAaX5WaxutkS1H093OqBFBDIrMZfKDEE1v2HgXhmS6Rr9F7AtbGcR5CXPZ1W_JYvmNTJsDQ\", \"stake_release_height\": 1230548}","Time":"2021-08-24T17:16:43-04:00"}, {"Block":1005222,"Hash":"Oz8gUNEAIcH48cOhT9o-KATfrZUQqcEKriVj-RrXzL8","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"Oz8gUNEAIcH48cOhT9o-KATfrZUQqcEKriVj-RrXzL8\", \"type\": \"unstake_validator_v1\", \"owner\": \"141WsikcrSo8tugixuLN5QTfzzLbm757UKd556iSx16sfq127ey\", \"address\": \"1126bQkTLZGXtt3Dx4kWUs4JufeBfsdnWTgNV3fptEmAYM2YPkzo\", \"stake_amount\": 1000000000000, \"owner_signature\": \"zL9B1V5fAZK23QLRkys4NvgqWlrG-OBiAAQULMTP0y1VHelySQpCgBlBZacfYmtnHpwl9cRwoLJfBI_G1-4_BA\", \"stake_release_height\": 1255236}","Time":"2021-09-10T11:36:36-04:00"}, {"Block":1005236,"Hash":"3BgVMqp8-7q8QlnKtS26OApAy0gEcJTzyo7HgHWHqzI","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"3BgVMqp8-7q8QlnKtS26OApAy0gEcJTzyo7HgHWHqzI\", \"type\": \"unstake_validator_v1\", \"owner\": \"141WsikcrSo8tugixuLN5QTfzzLbm757UKd556iSx16sfq127ey\", \"address\": \"11uofnhAvfGg4Fi3QUeKLMmJypEs143mppvARPzRgEH7SAJAkab\", \"stake_amount\": 1000000000000, \"owner_signature\": \"RSO5gfB8G0OYYvotfHdXRsfpsYOkqbtZb0Jwm0DsVk-ZuewB5-5NmiZGFfzIEqGNHzCgwuSWKgtB_UFg7ACEAQ\", \"stake_release_height\": 1255245}","Time":"2021-09-10T11:49:55-04:00"}, {"Block":1005236,"Hash":"fGjWVZ642NbIboaaTJRvMKyDXm4nH_ABrMW8SYVZQuI","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"fGjWVZ642NbIboaaTJRvMKyDXm4nH_ABrMW8SYVZQuI\", \"type\": \"unstake_validator_v1\", \"owner\": \"141WsikcrSo8tugixuLN5QTfzzLbm757UKd556iSx16sfq127ey\", \"address\": \"11srdiZquxtHzm4uEVWvpGEAW7AWsySd3e56mfhcY8yybRPm6f3\", \"stake_amount\": 1000000000000, \"owner_signature\": \"GYcCrzX_qowPFZyTsDpWUpJmshDdclpkvw0w6IFiv2GQaE2yu0ge_0n66doEHYAxYz_DQ6vu-dIZYvOHNdv5BA\", \"stake_release_height\": 1255245}","Time":"2021-09-10T11:49:55-04:00"}, @@ -69,6 +83,12 @@ {"Block":1092999,"Hash":"5BX5_FyfAc-Eoe1ySPmRerVUviPpapDB-jwRSMot-FY","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"5BX5_FyfAc-Eoe1ySPmRerVUviPpapDB-jwRSMot-FY\", \"type\": \"unstake_validator_v1\", \"owner\": \"13Za3jGFSJkewpckqqvLe63EgVb1VV3gXRZSdhn1YhJjesv8p6t\", \"address\": \"11YaXboB3i9T1LPSf8CtFuFP7yLy1Yn1N8cJaDQUNenbYBw7MRG\", \"stake_amount\": 1000000000000, \"owner_signature\": \"FYpeo9HHmgY2NFOT_ZwRJMN2U6i9osadoZ0d-6WUF6jf5idkfbZ8kSlBBEnZFm_pS2ksFIp5EnM-MW1AFHujDQ\", \"stake_release_height\": 1343000}","Time":"2021-11-10T11:58:56-05:00"}, {"Block":1098732,"Hash":"5WeUKmTj6lgt_QCBIyZajHrpR-19J_RhFqKRh972xxs","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"5WeUKmTj6lgt_QCBIyZajHrpR-19J_RhFqKRh972xxs\", \"type\": \"unstake_validator_v1\", \"owner\": \"13PqygKMAt91uYvTxHs3R75JkEAejVj8BbxTJMBPeA8QrCtiRHD\", \"address\": \"11Kqj6M1fnsuHFxkcobskn1GgnH8iNjDFbNbME9Ex6CGrjtsxgi\", \"stake_amount\": 1000000000000, \"owner_signature\": \"IYAcQN5uMgF7IvHkIBwR6xUkws2JpB3vpE5LUQFwQ1TrMCKvEy3sDmkmVxXJTgjdXWHgFkh1MUrw_-SjKHPACg\", \"stake_release_height\": 1348745}","Time":"2021-11-14T14:03:11-05:00"}, {"Block":1131737,"Hash":"S9AzMLbEhcuiApMDZTYpDNAo_hsnex7djBkvlm2y8fI","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"S9AzMLbEhcuiApMDZTYpDNAo_hsnex7djBkvlm2y8fI\", \"type\": \"unstake_validator_v1\", \"owner\": \"14SZx1ESJrmXtjnBwZ4zbWDLXrPhGNuGxiEVBU4smmgyBKzVFdr\", \"address\": \"112EKivRJrp5eK4dm5VEDRbXVBatrtJ7SY8UhazBp51K6JNBV5Mz\", \"stake_amount\": 1000000000000, \"owner_signature\": \"aIHkdGdYxQN9TJNfzZhRogfzmjNGoYP0G3sPofRJ5hZKJ-flV79rEmR9-H5u7iD6QCvvgzcIt9EfQ4HXN8iuDg\", \"stake_release_height\": 1381748}","Time":"2021-12-09T00:19:34-05:00"}, +{"Block":1164723,"Hash":"OT_PIHMBjtsvFvrP7775eru872962EdbHKLlkng3RQs","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"OT_PIHMBjtsvFvrP7775eru872962EdbHKLlkng3RQs\", \"type\": \"unstake_validator_v1\", \"owner\": \"13JWTearAUFq42xFeanq1zWXuCvZTbh37woNZgZmGfqCayr7g1d\", \"address\": \"13Fy67rcKV35Jmo7pKfFSN5qDqQ6Ck9QmMBa5RaWn3LnX6NVKMb\", \"stake_amount\": 1000000000000, \"owner_signature\": \"OVYv7MEsiB6KHskNUlRTqiCIqREZ5_JH5e4vFVsW2FxT7z6Oe57pOO4BGaXnPYezDXjml5ngT2HnnpKXtt2ABg\", \"stake_release_height\": 1414748}","Time":"2022-01-03T15:41:19-05:00"}, +{"Block":1181267,"Hash":"CdCmaDdFWDxVNJkcpTsxzOTh9fiQZRC6Hh7XfsLKb5g","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"CdCmaDdFWDxVNJkcpTsxzOTh9fiQZRC6Hh7XfsLKb5g\", \"type\": \"unstake_validator_v1\", \"owner\": \"14J6zntifsPAbiPxHYhyK7zV5ZdtKm3DiiZUVNRCe4NS9kEbGKT\", \"address\": \"11hN5VjgoLp3qBtSPyb3s755TBDor3iqDXz5CESGXP3o5s5dHHG\", \"stake_amount\": 1000000000000, \"owner_signature\": \"B4cAVkc-tfWnJYbDXinYoVWjsIlIeRftKwAAlaSRID06m2JR0ZvKSMx1tOkfWCtbj0LE8PHQPP4qBqITCZpNBQ\", \"stake_release_height\": 1431270}","Time":"2022-01-14T15:26:29-05:00"}, +{"Block":1184629,"Hash":"fhm-7rPKVzdP4MUy4kj444_Qyi7UtqBm9OBrHjTPXsc","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"fhm-7rPKVzdP4MUy4kj444_Qyi7UtqBm9OBrHjTPXsc\", \"type\": \"unstake_validator_v1\", \"owner\": \"14eafPyta3dC19Htz3oJH1gBeVPqSyNfgmKTuG3VVyfXJFYfKDX\", \"address\": \"1358vG9BMVXPs5UAKymstGPXQGFeofRTLdSvKeTBaToZzpjyFja\", \"stake_amount\": 1000000000000, \"owner_signature\": \"u_m7F71cSnj_zHV6p7DTveyl5Z6qGhuBu6wM0haKCjpeBu59_XpaXQo3C_IK6aAB0o8uUs20GxnjH2ZW6Bn_Dg\", \"stake_release_height\": 1434629}","Time":"2022-01-16T19:52:03-05:00"}, +{"Block":1187565,"Hash":"ixvg-WyiSO7IJz5Px4f9M3bHxg49RBYQzq-iUrHZiY4","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"ixvg-WyiSO7IJz5Px4f9M3bHxg49RBYQzq-iUrHZiY4\", \"type\": \"unstake_validator_v1\", \"owner\": \"14J6zntifsPAbiPxHYhyK7zV5ZdtKm3DiiZUVNRCe4NS9kEbGKT\", \"address\": \"1125gc3nTRncRGRHf5V9i6AdaRaQavc9kUWs7srXJFtJ8TxXE2cY\", \"stake_amount\": 1000000000000, \"owner_signature\": \"zMOqJtObP2FSw346xySb7mhIHzOwBSTUzDVbSlNKHgIQI4hCRgkr-L1p0wEzn4xoJVz_Zm2YNpetG3MNrwmPBw\", \"stake_release_height\": 1437570}","Time":"2022-01-18T17:20:25-05:00"}, +{"Block":1215059,"Hash":"xW6jo03y2rGsMGCO3rhVX6v1Yr_oy3gB7NmKJZw7feI","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"xW6jo03y2rGsMGCO3rhVX6v1Yr_oy3gB7NmKJZw7feI\", \"type\": \"unstake_validator_v1\", \"owner\": \"134c74JYsfN7X4CRGixhFSWgvR6m6wV4RMJUC13J97GnN9uBCJN\", \"address\": \"14NPMmxrw6r2ijqybwUEPquSKPLs9HhsvP6qkYoo7UGLKgUVFCY\", \"stake_amount\": 1000000000000, \"owner_signature\": \"EGVbMPV0KgkVD-AMg7J_saWsvU9V4UPI6UDkoSp48Ei1fyYGhdV_A-aa9ymPSpid8YOJ0hVslN8VXFjfKwtDDw\", \"stake_release_height\": 1465080}","Time":"2022-02-06T19:56:24-05:00"}, +{"Block":1228829,"Hash":"7d2DlD3LoH1UIi4fiCrRn6FmMfGiNygrZiTl9-An30A","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"7d2DlD3LoH1UIi4fiCrRn6FmMfGiNygrZiTl9-An30A\", \"type\": \"unstake_validator_v1\", \"owner\": \"14pa5EzLaGzZLvqHhHtEnQcATd3aQ5aHs1dsgRn2HkPXx5RDjn8\", \"address\": \"11h95urmNhUkg2RPJ4TC9J2GhsewV6fwcbxPBgoNSgz722PLPSL\", \"stake_amount\": 1000000000000, \"owner_signature\": \"_dNOvQ0ROho6jibmr6ep1CX1gBxNTAATrNBiwiUqCe5vHgTpyUYbt_VWqmqz_cK2_6-_qPE6GWn9Nd1DYLNABQ\", \"stake_release_height\": 1478836}","Time":"2022-02-16T18:43:25-05:00"}, {"Block":993314,"Hash":"SKa7K_P6LdUlB8FOCkHp4BTIhSzalLdOPL1Xne-04i8","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"SKa7K_P6LdUlB8FOCkHp4BTIhSzalLdOPL1Xne-04i8\", \"type\": \"unstake_validator_v1\", \"owner\": \"14VnJJXXcfpceTmtEi9p6r2cpb7qHKGKvFAEdwrMwYz82UuB3VD\", \"address\": \"11YfdfnGVae9zbJfpDsuNs1mxpFqVHDYdoYtmBbQEqt7fLLfehK\", \"stake_amount\": 1000000000000, \"owner_signature\": \"TuWrpLaspqz-48NzHVqNeslZyedV6w45JepBv0lfdPUt0PNbS_23_d7cNY73v2r2uuSsW7UqvNT3tAyJSWxdDw\", \"stake_release_height\": 1243320}","Time":"2021-09-02T04:47:04-04:00"}, {"Block":1054676,"Hash":"EZKBBsPZjnv5wcRLcRIMas3dAkq2RuuMU1RXAO74ftI","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"EZKBBsPZjnv5wcRLcRIMas3dAkq2RuuMU1RXAO74ftI\", \"type\": \"unstake_validator_v1\", \"owner\": \"14GUU4aPGhgpcqbr2nD78asrmHqiHPuEBTcqhDuxV3j8zL7zWeK\", \"address\": \"135Rx7XmUccCV4xodmsQsoxavoJhy8R9HdThEBmWsTLEvc64op4\", \"stake_amount\": 1000000000000, \"owner_signature\": \"NtlVAoMSRVOU2cGc8oREBNyhKMpHOm7nKhfpUUahj0Kepe2D17r4O2WxDBnZp2ajTUaAuUo8NN15lzpRYSF8DA\", \"stake_release_height\": 1304676}","Time":"2021-10-14T22:03:50-04:00"}, {"Block":1078647,"Hash":"eaiDPF1pvu0Hy6Pwl3QgEWxNSpHPLdAlrwiH-oidcUs","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"eaiDPF1pvu0Hy6Pwl3QgEWxNSpHPLdAlrwiH-oidcUs\", \"type\": \"unstake_validator_v1\", \"owner\": \"14M5UoVUpphkmiiAUxcMSpcEyNsxVydi7Q6myi6FXQjHWBmjv7s\", \"address\": \"13TWA75bFpL5WYq8QLwkMaZ5BMx6aeZNcXheoL3kSsGh21WzaYr\", \"stake_amount\": 1000000000000, \"owner_signature\": \"5b52wUamuDgUFmfWmus8-_vwn04vz4yKEx14yxQKWA03I4q44Fv-EnKs60SiD_w-Vj7NlrJf3vvkMlF_RDPbBw\", \"stake_release_height\": 1328664}","Time":"2021-10-31T14:39:18-04:00"}, @@ -78,6 +98,12 @@ {"Block":1103226,"Hash":"u9Os6yOo4j6S85xVKmrVEPBd4iAmp_3qkn1lBBLS8x0","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"u9Os6yOo4j6S85xVKmrVEPBd4iAmp_3qkn1lBBLS8x0\", \"type\": \"unstake_validator_v1\", \"owner\": \"149K7qgzFAD1Yy4vJJj5WrBLxziYmwqgCGCtUozXiooMRsKDbmA\", \"address\": \"11Dm1aGMQ94fn8KCrzL7qyPcMfxrqSZ8UMNrhaEbkGp9K7MNmeo\", \"stake_amount\": 1000000000000, \"owner_signature\": \"3isjCDoZcr2E9IySyBb7TsgA5ojwvitoElkCHcA53rcptFlHpXd9_u3WLo_SiP0lWATURWr2U4EqhOAJnBhdDQ\", \"stake_release_height\": 1353280}","Time":"2021-11-18T23:33:37-05:00"}, {"Block":1103226,"Hash":"18mhcbqGTkAm9Ey2RJDg3qQ39YKQNzDf4LxPyjqdgF4","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"18mhcbqGTkAm9Ey2RJDg3qQ39YKQNzDf4LxPyjqdgF4\", \"type\": \"unstake_validator_v1\", \"owner\": \"149K7qgzFAD1Yy4vJJj5WrBLxziYmwqgCGCtUozXiooMRsKDbmA\", \"address\": \"113XvSDEw1MvAdx3EbEbaBAoN9Fa2UnfcZU1GHos16RTbWmtdnq\", \"stake_amount\": 1000000000000, \"owner_signature\": \"hB2AY2CZ-6S72Gqw3OZpe0TYzSM2-yTAYFCZOyf5TYZsBvLskiqOaoqNVhzcDURZ0SGFzymYXaKensPmB886Bg\", \"stake_release_height\": 1353280}","Time":"2021-11-18T23:33:37-05:00"}, {"Block":1148566,"Hash":"ezBMMomW6YVkUuvu8FcX92rrM9tfCdmxNAWcGE0BN4o","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"ezBMMomW6YVkUuvu8FcX92rrM9tfCdmxNAWcGE0BN4o\", \"type\": \"unstake_validator_v1\", \"owner\": \"1375s7FJnC4NasM5KLiSFPFafroaN3AUdaqoqLYez6odShTj8FR\", \"address\": \"112E7DVQKHJYzWyniHyuDNTPFWh6dLmrLznFNaDyrAxh75ZELSUM\", \"stake_amount\": 1000000000000, \"owner_signature\": \"-PHRQZg12cftZRbkEc-T7JcK3Hew9gz65Vyz2h311Qw7jgA4N48qCTUaJbY7-ZypOvIY514mnVLwCOHQqbNlDw\", \"stake_release_height\": 1398574}","Time":"2021-12-21T13:57:58-05:00"}, +{"Block":1173198,"Hash":"WmmhCp0dlWmRxU43xPmI7rp4jbXE3R2nJ57F8EpyFDQ","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"WmmhCp0dlWmRxU43xPmI7rp4jbXE3R2nJ57F8EpyFDQ\", \"type\": \"unstake_validator_v1\", \"owner\": \"14RBJV3EqZVFTk7hquK2aPFvae7fZknZ9yoRdRtu3PYxfzExFwo\", \"address\": \"112d2cbaJp6Ma71ujhFsfC9bxffLZT7mNJUJfcZiyjeWoGsLEXMj\", \"stake_amount\": 1000000000000, \"owner_signature\": \"W2qpC6Cl0A52Ht2vfTpuNcKm4ioJF-XerI3jsW-Wt1E1bOZ99LydtGSttpJEhzD3unJbdPUy-jaDD8lPkgvdCA\", \"stake_release_height\": 1423201}","Time":"2022-01-09T09:24:57-05:00"}, +{"Block":1181283,"Hash":"Pfkc29pYYm-Rh2cyJUYkoQZJk8PsOubUPcItsuyUfDs","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"Pfkc29pYYm-Rh2cyJUYkoQZJk8PsOubUPcItsuyUfDs\", \"type\": \"unstake_validator_v1\", \"owner\": \"14J6zntifsPAbiPxHYhyK7zV5ZdtKm3DiiZUVNRCe4NS9kEbGKT\", \"address\": \"119Px624etqHqsPqz3NKJ4FjhsxiYBE1zj367utzbK51cTMqp1r\", \"stake_amount\": 1000000000000, \"owner_signature\": \"YmTwrAJqUKhdYLaCDAa6cQJeCGnm1VfNrY40yqYAq3BsnIe72dEYT813kv1A8rklnkpj52LJOWeQ1UNf78fKCg\", \"stake_release_height\": 1431285}","Time":"2022-01-14T15:39:57-05:00"}, +{"Block":1184442,"Hash":"ReM_PNzTcj68tfU2jxU__NeZYl93rTU8GIzfFNZU6f8","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"ReM_PNzTcj68tfU2jxU__NeZYl93rTU8GIzfFNZU6f8\", \"type\": \"unstake_validator_v1\", \"owner\": \"13YjqdzC1tPDyVE25YnjfzoaDnTjmroaqKVzciLPSGgMuT1VWNX\", \"address\": \"13n6yreSosXa7rgTQG5nvbB5CX4sdbhqYsCMzYPWveJqZ2Co6VN\", \"stake_amount\": 1000000000000, \"owner_signature\": \"5RVOn75aro_qfC8TomdX0-OO1I5iiJKCNznvofUdQo1wYzPiRFsTx-ETKsM2-7dq99RNbn7c5kcuetwIwE-dAA\", \"stake_release_height\": 1434454}","Time":"2022-01-16T16:56:40-05:00"}, +{"Block":1187785,"Hash":"-2rZAQqpyviuQSMa3GQ6dthZBe9uKIMLrxrgR1tkieQ","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"-2rZAQqpyviuQSMa3GQ6dthZBe9uKIMLrxrgR1tkieQ\", \"type\": \"unstake_validator_v1\", \"owner\": \"14YqE1VapVhb7pahL3rJJPJBgLBkud5bpiUbpWo8VuQvscds1mB\", \"address\": \"11jmxrZ29X4ZnWY9G8E6NM9WYmyLazcuwVAj1r5pQigas7ykAm9\", \"stake_amount\": 1000000000000, \"owner_signature\": \"yypFOHW38cP4JhngVs8aGsZPkkLO221kJh1aWx5ay3j290DmYBNy7mF0qYAPE1vCr219rJ5M6CdpCdMc2EbKCA\", \"stake_release_height\": 1437785}","Time":"2022-01-18T20:41:56-05:00"}, +{"Block":1210397,"Hash":"shEEwLQjvNCx5e6NRbxGeaWJSxK_zLC66UljqigxvoI","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"shEEwLQjvNCx5e6NRbxGeaWJSxK_zLC66UljqigxvoI\", \"type\": \"unstake_validator_v1\", \"owner\": \"136Q6at4MoCEqaih29WQTZSabepvpSgcqBUW3etyNiERjs6jKCb\", \"address\": \"13UewU3WPyBtCkoh6yEyJq7hVcqCMo5FMUDqBJ2f97tG2B8gPkL\", \"stake_amount\": 1000000000000, \"owner_signature\": \"KvOwWu7bQVJrjeK7eLdn-QS9U0KP3DX2qugeOXzPYsaFzKTSXZoiyd1RSNrfqKn_cE2pqkkgrfFM7r40ZSv6BA\", \"stake_release_height\": 1460399}","Time":"2022-02-03T09:45:22-05:00"}, +{"Block":1212197,"Hash":"m2LvrwQukVDJF34vPP6AoiQg2APRtsrVXSEGpjs-Dpg","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"m2LvrwQukVDJF34vPP6AoiQg2APRtsrVXSEGpjs-Dpg\", \"type\": \"unstake_validator_v1\", \"owner\": \"14r7AGamvbgPNgDFxNdWyGRtTaucE2Mwh1Lh447Ni1jbduQxhZU\", \"address\": \"11aSfPsye3xDBCXkXJr5u9VrwGmR2m4uZfBYEi6vbkprAAvFTBQ\", \"stake_amount\": 1000000000000, \"owner_signature\": \"xPmdDmEC1tG9TDdzAYZIJdNXKRfm4aHFBB_al25EnuJyuJAEyUGYFlFiWPsa_9XnETH6-r8V6T6AYnyARU_rAg\", \"stake_release_height\": 1462210}","Time":"2022-02-04T17:36:03-05:00"}, {"Block":960343,"Hash":"-W2WqZ8nkINlWm6CAf5HBiBgszIm8JM2BmboHQHe7l8","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"-W2WqZ8nkINlWm6CAf5HBiBgszIm8JM2BmboHQHe7l8\", \"type\": \"unstake_validator_v1\", \"owner\": \"12xoVMjaduyZm1bw1GEBXoQe6YHCfU5gghcuobQ5weopZ8as3qw\", \"address\": \"11TJwzUDUktQdV12eQ3TULEkKpf24SLa3nHpPTfySFj1UdN5HeU\", \"stake_amount\": 1000000000000, \"owner_signature\": \"9VGV1x0Sr6vUbcL64iBulntGsV43OsWqw8C0cE3w3M7PXnx8f8EH4m-tKuSY0PAkwn7C81LsF91fW3UdDnlzCg\", \"stake_release_height\": 1210351}","Time":"2021-08-11T00:32:29-04:00"}, {"Block":1005202,"Hash":"Pq5JYkSWW0v4mww9yZcZlEnYlARzLk_OEPjC745CLrU","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"Pq5JYkSWW0v4mww9yZcZlEnYlARzLk_OEPjC745CLrU\", \"type\": \"unstake_validator_v1\", \"owner\": \"141WsikcrSo8tugixuLN5QTfzzLbm757UKd556iSx16sfq127ey\", \"address\": \"112JkiDg2GcrbYScTRN52jvkvgGVqp4n75sBjU6dwQeqqqK6VQR8\", \"stake_amount\": 1000000000000, \"owner_signature\": \"LHLfM3ju1Pp6MVLugHAYZtPJ-P8PbNCy7Me76fysLdthliyTGBV1I6lzWR2bUfHk0e8hzbnsweqq6Pq4HlV_DQ\", \"stake_release_height\": 1255217}","Time":"2021-09-10T11:16:16-04:00"}, {"Block":1005250,"Hash":"JFPTW7BOlV65nT78SSjmmLSMtP4ps6buHXF3MS9XsH8","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"JFPTW7BOlV65nT78SSjmmLSMtP4ps6buHXF3MS9XsH8\", \"type\": \"unstake_validator_v1\", \"owner\": \"141WsikcrSo8tugixuLN5QTfzzLbm757UKd556iSx16sfq127ey\", \"address\": \"11n7gR4vDTbitDJMVH7x3NuXVAWLh5hoYRm6MUudg2HJmSbhzrW\", \"stake_amount\": 1000000000000, \"owner_signature\": \"Jhk1GsDleenAzEmFbfVWcxJ2LuXQlPj814aDCBTOLO5qZyxQwEKSMR_jnzpwA5FhVKHf6v_uJk2Wn2ymq1lkCQ\", \"stake_release_height\": 1255255}","Time":"2021-09-10T12:04:09-04:00"}, @@ -89,5 +115,14 @@ {"Block":1123725,"Hash":"iBO9eYcuCtvWY924Xh_83a8PdzyWMlSvXWQJDB7yM3c","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"iBO9eYcuCtvWY924Xh_83a8PdzyWMlSvXWQJDB7yM3c\", \"type\": \"unstake_validator_v1\", \"owner\": \"13ofKdM16eVTqqnwPqm6ufqm1w7nRBLQHUzrvBzezMwCeDVrTUX\", \"address\": \"14e13qWNHVA2tqwZCFrSP4Yo9KeEiy8TwegoVxtvnRMQpTK1Z9p\", \"stake_amount\": 1000000000000, \"owner_signature\": \"WzL9Zf-Ly8y9CQ0K8QIShXY7wC1v8Uy1p-CyOdVnsJSHCUDj16oizl2pbpoO8mgOKuuxsBLY8eBdZ8epdDmpCQ\", \"stake_release_height\": 1373727}","Time":"2021-12-03T13:30:22-05:00"}, {"Block":1123725,"Hash":"zhgXMdy22nn4DmgGxbNwm_lyyy3BuRKw-o_gmdrjfDY","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"zhgXMdy22nn4DmgGxbNwm_lyyy3BuRKw-o_gmdrjfDY\", \"type\": \"unstake_validator_v1\", \"owner\": \"13ofKdM16eVTqqnwPqm6ufqm1w7nRBLQHUzrvBzezMwCeDVrTUX\", \"address\": \"14Ta27Y1gjcjjZkaEiSB819gNMrsqTwDXrtz8QhU1WUq8MmTcd6\", \"stake_amount\": 1000000000000, \"owner_signature\": \"kA3zhgKYAjGLCEIy2CDzdZItkrVtTNLf4SSYqV_hulxMw8ddPzLwODREkQRxmpwFf_OMDXQgcEX0ZIWmoij5AA\", \"stake_release_height\": 1373728}","Time":"2021-12-03T13:30:22-05:00"}, {"Block":1123728,"Hash":"WUS3NWcXXcp4El2kEru1OXbjTUlbgxlexhnbU6syfww","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"WUS3NWcXXcp4El2kEru1OXbjTUlbgxlexhnbU6syfww\", \"type\": \"unstake_validator_v1\", \"owner\": \"13ofKdM16eVTqqnwPqm6ufqm1w7nRBLQHUzrvBzezMwCeDVrTUX\", \"address\": \"14Bnc43z21jmtL9NDRhYWv8LtZpXQ7BckYLnhWmj4X3B4ny3sG2\", \"stake_amount\": 1000000000000, \"owner_signature\": \"iY2s2anys8zf8bmr32Nv6znOOUix5KZEguDSY13cgBeg_Afe3xyeghF2_dJ2yKej0W6f3ivNSYDKHEZlayekBg\", \"stake_release_height\": 1373730}","Time":"2021-12-03T13:33:08-05:00"}, -{"Block":1123860,"Hash":"3iSzilBIbs6VRsSHC6G23nX2OYjQxAEH7S-Gh-kTWHo","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"3iSzilBIbs6VRsSHC6G23nX2OYjQxAEH7S-Gh-kTWHo\", \"type\": \"unstake_validator_v1\", \"owner\": \"13ofKdM16eVTqqnwPqm6ufqm1w7nRBLQHUzrvBzezMwCeDVrTUX\", \"address\": \"148UxZccdHbqJsNMUwxFxTUhZeNTGvSsReaDwXRBfKFxza228ga\", \"stake_amount\": 1000000000000, \"owner_signature\": \"zXTiZfb1cXvfzvHggVSU3VXXYtjouAa_ekXnH9EF1BUBhnHHfj0gJRd8eSlV4qLh3odFvtIFdTk_5Y5ILvn9CA\", \"stake_release_height\": 1373864}","Time":"2021-12-03T15:36:44-05:00"} +{"Block":1123860,"Hash":"3iSzilBIbs6VRsSHC6G23nX2OYjQxAEH7S-Gh-kTWHo","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"3iSzilBIbs6VRsSHC6G23nX2OYjQxAEH7S-Gh-kTWHo\", \"type\": \"unstake_validator_v1\", \"owner\": \"13ofKdM16eVTqqnwPqm6ufqm1w7nRBLQHUzrvBzezMwCeDVrTUX\", \"address\": \"148UxZccdHbqJsNMUwxFxTUhZeNTGvSsReaDwXRBfKFxza228ga\", \"stake_amount\": 1000000000000, \"owner_signature\": \"zXTiZfb1cXvfzvHggVSU3VXXYtjouAa_ekXnH9EF1BUBhnHHfj0gJRd8eSlV4qLh3odFvtIFdTk_5Y5ILvn9CA\", \"stake_release_height\": 1373864}","Time":"2021-12-03T15:36:44-05:00"}, +{"Block":1158382,"Hash":"bMLLtsfT0aCjHXpU5SFA1AN1GhWFJvW2vrRnoxHzA30","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"bMLLtsfT0aCjHXpU5SFA1AN1GhWFJvW2vrRnoxHzA30\", \"type\": \"unstake_validator_v1\", \"owner\": \"14dwkKaKnMmYUuBXaGBR4xnDh3TXzKZgojThtBmyEKpadiHV7Ys\", \"address\": \"11c4G9psJu418ZicLj5kMU3g4gbfPpwWkmEujmdZCWf2vJToD6k\", \"stake_amount\": 1000000000000, \"owner_signature\": \"glXBqKwR0AqMOZHxIWj5YSbciBi9TB2kKxKCRszvdM0-HNSObGcDM1SX9tcKbe9Ji_luG8jTpKnD9lbO4UHBAA\", \"stake_release_height\": 1408396}","Time":"2021-12-29T14:11:27-05:00"}, +{"Block":1158668,"Hash":"r1qhOLkXAZjv9EMeNQfNpRbLsVlrrdOL_XXibyp6xDg","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"r1qhOLkXAZjv9EMeNQfNpRbLsVlrrdOL_XXibyp6xDg\", \"type\": \"unstake_validator_v1\", \"owner\": \"14TqG8Yg4BRJkdfA1fCWivjf2PWyCgkHQi3L5V8dHXUkmQfhnLJ\", \"address\": \"14YTg2sf7KiTAMozV39jbsYg4nZWcsHHRDWmWtxY8j3VzMUwYXj\", \"stake_amount\": 1000000000000, \"owner_signature\": \"9vs4Yv2JGFUotEEdNuTqhpS8nvrcOIqWcCL3v3fgj3mL5QQfZzvUfir3sFQDis26h50Hqcs4Uyf3AzBCDaX1CQ\", \"stake_release_height\": 1408685}","Time":"2021-12-29T19:54:47-05:00"}, +{"Block":1164839,"Hash":"muuQiSm77TPVeQXYHb22Jno_XOM0YBRAmTKXqLTkK9o","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"muuQiSm77TPVeQXYHb22Jno_XOM0YBRAmTKXqLTkK9o\", \"type\": \"unstake_validator_v1\", \"owner\": \"14iFzQ429bvb8gFuwcwjdutbxQMGU1d18q1Wu6WFMegP7P1Ycu2\", \"address\": \"14BsjJb2RVewKvN2EPXFMQWPdokBXk4AfkDZfxxUQ9h9E4JTpg3\", \"stake_amount\": 1000000000000, \"owner_signature\": \"8YELrFuxpcL2vUofWb9sxPwIGddIm8Er4A2iH90F4NSEa-SbEus19qI3eqNpq3tUcyPeNfOKTLyyGGWQY0dKAg\", \"stake_release_height\": 1414844}","Time":"2022-01-03T18:09:50-05:00"}, +{"Block":1184448,"Hash":"0IYX_JskVRF2PfR8-EoALZAR2y_zEVfM_HDZsWKDVKs","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"0IYX_JskVRF2PfR8-EoALZAR2y_zEVfM_HDZsWKDVKs\", \"type\": \"unstake_validator_v1\", \"owner\": \"13YjqdzC1tPDyVE25YnjfzoaDnTjmroaqKVzciLPSGgMuT1VWNX\", \"address\": \"13eyJRgv8pVyUThy6ocUggKv56Nu9ZDJQPU3ncWwtnJck74b7i6\", \"stake_amount\": 1000000000000, \"owner_signature\": \"qpVuU-tP8PY493KiaUwFLAsH4LczGJM_kT0G2ljPpOctExv_YxlXcbp45f2Y-p3MoVkY5HN8zOmUu-NhecTBBA\", \"stake_release_height\": 1434454}","Time":"2022-01-16T17:01:41-05:00"}, +{"Block":1186355,"Hash":"a6Xrogfh_C6asQ_cmhHCpZiij0MbEp6YPXtMhPFfT3k","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"a6Xrogfh_C6asQ_cmhHCpZiij0MbEp6YPXtMhPFfT3k\", \"type\": \"unstake_validator_v1\", \"owner\": \"13YjqdzC1tPDyVE25YnjfzoaDnTjmroaqKVzciLPSGgMuT1VWNX\", \"address\": \"13UgA2zSFHHzkfxzM45Jab29XxnK7QPvWkkXSBQdU5niWzJyfXB\", \"stake_amount\": 1000000000000, \"owner_signature\": \"hcSdxwXObBqhNUvmHJRe9Bz78gPOM4oSW3d2oQhI5dMSsNiXEr9tNauWuahTcGnKOBApCmcEopadYN_vxZjKCQ\", \"stake_release_height\": 1436371}","Time":"2022-01-17T22:29:35-05:00"}, +{"Block":1187493,"Hash":"rH9Wp1W1tSntEDRcU-sh0_ol-b5EK-PH4W06BdIXq7o","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"rH9Wp1W1tSntEDRcU-sh0_ol-b5EK-PH4W06BdIXq7o\", \"type\": \"unstake_validator_v1\", \"owner\": \"14J6zntifsPAbiPxHYhyK7zV5ZdtKm3DiiZUVNRCe4NS9kEbGKT\", \"address\": \"11NAYiMbSaqqaW4YEonn8jr9bQLqrtkKJbyDg5W54Fsmi5mMzNB\", \"stake_amount\": 1000000000000, \"owner_signature\": \"yTZug0SoNBIpeTfc1yPiICE0uMHIxGfDOvZzLQ5reXVDaEN9eU1g0y4KzxfRnV5ShxqBOKhUQHU6dMcaZPJ7Aw\", \"stake_release_height\": 1437500}","Time":"2022-01-18T16:14:30-05:00"}, +{"Block":1191890,"Hash":"ErnUqnxiy82us6gJNeufaoJy2PZMmRhh_KPEY7iw2ho","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"ErnUqnxiy82us6gJNeufaoJy2PZMmRhh_KPEY7iw2ho\", \"type\": \"unstake_validator_v1\", \"owner\": \"13SoCNwjK9DEE8Fg8xvd45eKqAqZSQUDbwfVB9YGEyXZqRoFNTL\", \"address\": \"14eNsC5imxsxx4SP6R3BBdK2MD9ADvZD4iXZiSD6VN9w5BSeU5g\", \"stake_amount\": 1000000000000, \"owner_signature\": \"lzBEyG31sFa1yWgOwTEmFqFz1ePtPgayemtC9o5IdyLxw368xOSghWjRKWxGNhpXqVj8KpyiLblI88b1N7mAAg\", \"stake_release_height\": 1441890}","Time":"2022-01-21T12:04:49-05:00"}, +{"Block":1205595,"Hash":"8OWQVI4oB8zOjDAMaKvUtTgNN4mEUhzpuJ9LaAsL46A","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"8OWQVI4oB8zOjDAMaKvUtTgNN4mEUhzpuJ9LaAsL46A\", \"type\": \"unstake_validator_v1\", \"owner\": \"14PNnDMq6EnG9kXGPeH3DiBKT5akZ89AmEGzUesTaX1SdLbNpfT\", \"address\": \"11T8jF9TKEP4i4weJTkmKRjgEcJktzDmackqjG7NDHgsrwBZXzJ\", \"stake_amount\": 1000000000000, \"owner_signature\": \"Bbz47Kk7ELbF4V0yhTVuG9EXawofZLbqcCn_N_-a2HQyQJGez3YXms0N68dt6xL1kJJeG_2yoAs-e2FeZ4ciBA\", \"stake_release_height\": 1455610}","Time":"2022-01-30T20:31:04-05:00"}, +{"Block":1222335,"Hash":"kQSUXJBEvPakpL3NQPyHAg3bgau52PzT-cXkaRE0UVo","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"kQSUXJBEvPakpL3NQPyHAg3bgau52PzT-cXkaRE0UVo\", \"type\": \"unstake_validator_v1\", \"owner\": \"14ATq3tQ7Jj3zxgXcxh5whKoLeKZJj6tF2mbRkBUSt9Wv9hEQgt\", \"address\": \"118HmJoBWf9yEsUAygGokkVhLP9o825fijmQC9PNgMJube6cYkF\", \"stake_amount\": 1000000000000, \"owner_signature\": \"TwZ_7iNdF2GjGel44f6lJb6MG7fya3XFYNcVXS-hjGUAksd6VcvaSD2g3SwkDzx6pZvE_lAPIAz2tGOkFKNlCg\", \"stake_release_height\": 1472342}","Time":"2022-02-12T13:23:54-05:00"} ] \ No newline at end of file diff --git a/rosetta-cli-config/mainnet/config.json b/rosetta-cli-config/mainnet/config.json index 8f90635..28dc96a 100644 --- a/rosetta-cli-config/mainnet/config.json +++ b/rosetta-cli-config/mainnet/config.json @@ -9,7 +9,7 @@ "tip_delay": 1200, "max_retries": 10, "data": { - "start_index": 1156322, + "start_index": 1236242, "historical_balance_enabled": true, "end_conditions": { "reconciliation_coverage": { From da686a0588dde7c5ad5a87fc2d6115872550e676 Mon Sep 17 00:00:00 2001 From: Steven Yuan Date: Thu, 24 Feb 2022 01:03:12 +0000 Subject: [PATCH 14/19] ghost txn updates to account for testnet and mainnet snaps --- ghost-transactions/{ => mainnet}/1236241.json | 0 main.go | 18 +++++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) rename ghost-transactions/{ => mainnet}/1236241.json (100%) diff --git a/ghost-transactions/1236241.json b/ghost-transactions/mainnet/1236241.json similarity index 100% rename from ghost-transactions/1236241.json rename to ghost-transactions/mainnet/1236241.json diff --git a/main.go b/main.go index 9f8e058..a5e7b4a 100644 --- a/main.go +++ b/main.go @@ -75,7 +75,14 @@ func NewBlockchainRouter( } func LoadGhostTxns(network *types.NetworkIdentifier, db *badger.DB) error { - if werr := filepath.Walk("ghost-transactions", func(path string, info os.FileInfo, err error) error { + // Assume mainnet + networkDir := "mainnet" + + if network.Network == helium.TestnetNetwork { + networkDir = "testnet" + } + + if werr := filepath.Walk("ghost-transactions/"+networkDir, func(path string, info os.FileInfo, err error) error { if err != nil { zap.S().Error(err.Error()) } @@ -83,7 +90,7 @@ func LoadGhostTxns(network *types.NetworkIdentifier, db *badger.DB) error { return nil } - jsonFile, jerr := os.Open("ghost-transactions/" + info.Name()) + jsonFile, jerr := os.Open("ghost-transactions/" + networkDir + "/" + info.Name()) if jerr != nil { return jerr } @@ -166,7 +173,7 @@ func main() { } if lerr := LoadGhostTxns(network, bdb); lerr != nil { - zap.S().Error("Cannot load ghost transactions: " + lerr.Error()) + zap.S().Error("Cannot load mainnet ghost transactions: " + lerr.Error()) os.Exit(1) } @@ -176,6 +183,11 @@ func main() { Blockchain: "Helium", Network: helium.TestnetNetwork, } + + if lerr := LoadGhostTxns(network, bdb); lerr != nil { + zap.S().Error("Cannot load testnet ghost transactions: " + lerr.Error()) + os.Exit(1) + } } helium.CurrentNetwork = network From 5c3200efd793a49f0a970658700628b130c5b226 Mon Sep 17 00:00:00 2001 From: Steven Yuan Date: Thu, 10 Mar 2022 16:42:33 +0000 Subject: [PATCH 15/19] Direct DB connector to rocksdb WIP --- .gitignore | 3 +- Dockerfile | 35 +++++- docker/mainnet.sh | 4 +- docker/testnet.sh | 2 +- go.mod | 6 +- go.sum | 9 ++ helium/middleware.go | 25 +++- helium/rocksdb.go | 166 +++++++++++++++++++++++++ helium/types.go | 10 ++ main.go | 112 ++++++++++++++++- rosetta-cli-config/mainnet/config.json | 2 +- services/account_service.go | 102 ++++++++++----- utils/utils.go | 32 +++++ 13 files changed, 464 insertions(+), 44 deletions(-) create mode 100644 helium/rocksdb.go diff --git a/.gitignore b/.gitignore index 908cc5b..e60adc0 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ rosetta-data* lbs.txt node_modules helium-constructor/public -badger \ No newline at end of file +badger +rocksdb \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index e035528..9d04e26 100644 --- a/Dockerfile +++ b/Dockerfile @@ -124,13 +124,29 @@ RUN apt update \ && curl -L https://golang.org/dl/go1.17.1.linux-amd64.tar.gz | tar xzf - ENV PATH="/src/go/bin:$PATH" \ - CGO_ENABLED=0 + CGO_ENABLED=1 + +WORKDIR /app +RUN apt install -y git +RUN git clone https://github.com/facebook/rocksdb.git + +WORKDIR /app/rocksdb +RUN git checkout tags/v6.20.3 +RUN apt install -y --no-install-recommends \ + build-essential make libgflags-dev \ + zlib1g-dev libbz2-dev liblz4-dev libsnappy-dev \ + libzstd-dev libgflags-dev + +RUN make shared_lib +RUN make install + +WORKDIR /src # TODO: git clone from url instead of direct copy COPY . rosetta-helium -RUN cd rosetta-helium && go build -o rosetta-helium - +WORKDIR /src/rosetta-helium +RUN go build -o rosetta-helium FROM node-mainnet as rosetta-helium-final @@ -141,7 +157,18 @@ EXPOSE 44158 RUN apt update \ && apt install -y --no-install-recommends \ - ca-certificates git npm + ca-certificates git npm + +WORKDIR /app +COPY --from=rosetta-builder /app/rocksdb rocksdb + +WORKDIR /app/rocksdb +RUN apt install -y --no-install-recommends \ + build-essential make libgflags-dev \ + zlib1g-dev libbz2-dev liblz4-dev libsnappy-dev \ + libzstd-dev + +RUN make install WORKDIR /app diff --git a/docker/mainnet.sh b/docker/mainnet.sh index acf6446..8fb8582 100644 --- a/docker/mainnet.sh +++ b/docker/mainnet.sh @@ -2,8 +2,8 @@ set -euo pipefail -cat /opt/blockchain_node/config/sys.config | grep -oP '(?<=\{blessed_snapshot_block_height\, ).*?(?=\})' > /app/lbs.txt & +echo '1259282' > /app/lbs.txt & /opt/blockchain_node/bin/blockchain_node foreground & -/app/rosetta-helium & +/app/rosetta-helium --data="/data" & node /app/helium-constructor/public/index.js diff --git a/docker/testnet.sh b/docker/testnet.sh index 423e164..6f53077 100644 --- a/docker/testnet.sh +++ b/docker/testnet.sh @@ -3,5 +3,5 @@ set -euo pipefail /opt/blockchain_node/bin/blockchain_node foreground & -/app/rosetta-helium --testnet & +/app/rosetta-helium --testnet --data="/data" & NETWORK=testnet node /app/helium-constructor/public/index.js diff --git a/go.mod b/go.mod index 4975903..50e2b57 100644 --- a/go.mod +++ b/go.mod @@ -3,12 +3,16 @@ module github.com/helium/rosetta-helium go 1.15 require ( + github.com/btcsuite/btcutil v1.0.2 // indirect github.com/coinbase/rosetta-sdk-go v0.6.10 github.com/dgraph-io/badger/v3 v3.2103.2 // indirect github.com/golangci/golangci-lint v1.39.0 // indirect github.com/google/go-cmp v0.5.4 // indirect github.com/google/uuid v1.3.0 // indirect - github.com/mitchellh/mapstructure v1.4.1 + github.com/linxGnu/grocksdb v1.6.36 // indirect + github.com/mitchellh/mapstructure v1.4.3 + github.com/okeuday/erlang_go v2.0.4+incompatible // indirect + github.com/okeuday/erlang_go/v2 v2.0.4 // indirect github.com/ybbus/jsonrpc v2.1.2+incompatible go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.7.0 // indirect diff --git a/go.sum b/go.sum index e2c9f20..2654d3e 100644 --- a/go.sum +++ b/go.sum @@ -110,6 +110,7 @@ github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MR github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v1.0.2 h1:9iZ1Terx9fMIOtq1VrwdqfsATL9MC2l8ZrUY6YZ2uts= github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= @@ -473,6 +474,8 @@ github.com/letsencrypt/pkcs11key/v4 v4.0.0/go.mod h1:EFUvBDay26dErnNb70Nd0/VW3tJ github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/linxGnu/grocksdb v1.6.36 h1:ZYgXhDq4WLuI0ypnZM7h6NuHLaDSdTEs9ejAN/gP+K0= +github.com/linxGnu/grocksdb v1.6.36/go.mod h1:/+iSQrn7Izt6kFhHBQvcE6FkklsKXa8hc35pFyFDrDw= github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/lucasjones/reggen v0.0.0-20180717132126-cdb49ff09d77/go.mod h1:5ELEyG+X8f+meRWHuqUOewBOhvHkl7M76pdGEansxW4= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -531,6 +534,8 @@ github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8 github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs= +github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -560,6 +565,10 @@ github.com/nishanths/predeclared v0.2.1 h1:1TXtjmy4f3YCFjTxRd8zcFHOmoUir+gp0ESzj github.com/nishanths/predeclared v0.2.1/go.mod h1:HvkGJcA3naj4lOwnFXFDkFxVtSqQMB9sbB1usJ+xjQE= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/okeuday/erlang_go v2.0.4+incompatible h1:OAZE/AWFjJH0Q02/FJwixHCHLOJ2OIGuLtzjFkYahHA= +github.com/okeuday/erlang_go v2.0.4+incompatible/go.mod h1:BBz8nWELVZr7h7INZ5SVnswLIn13iDFZxHdT/wWcy7Q= +github.com/okeuday/erlang_go/v2 v2.0.4 h1:fO2lW4/d2PO5nyJgJOKOY8XIxukyPZXoYIZR25Q0CtM= +github.com/okeuday/erlang_go/v2 v2.0.4/go.mod h1:bUnKKmkI110+DM1rV59zPPqbcXp4yv18Fp2ofRwBmk4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= diff --git a/helium/middleware.go b/helium/middleware.go index d45b215..c5172cf 100644 --- a/helium/middleware.go +++ b/helium/middleware.go @@ -73,8 +73,29 @@ type GetGatewayOwnerResponse struct { func GetCurrentHeight() (*int64, *types.Error) { var result int64 - if err := NodeClient.CallFor(&result, "block_height", nil); err != nil { - return nil, WrapErr(ErrUnclearIntent, errors.New("error getting block_height")) + if NodeBalancesDB != nil { + balancesHeight, bErr := RocksDBBalancesHeightGet() + if bErr != nil { + return nil, WrapErr(ErrUnclearIntent, bErr) + } + + transactionHeight, tErr := RocksDBTransactionsHeightGet() + if tErr != nil { + return nil, WrapErr(ErrUnclearIntent, tErr) + } + + zap.S().Info("balance height: " + fmt.Sprint(*balancesHeight) + " transaction height: " + fmt.Sprint(*transactionHeight)) + + if *balancesHeight > *transactionHeight { + result = *transactionHeight + } else { + result = *balancesHeight + } + + } else { + if err := NodeClient.CallFor(&result, "block_height", nil); err != nil { + return nil, WrapErr(ErrUnclearIntent, errors.New("error getting block_height")) + } } return &result, nil diff --git a/helium/rocksdb.go b/helium/rocksdb.go new file mode 100644 index 0000000..80fe84c --- /dev/null +++ b/helium/rocksdb.go @@ -0,0 +1,166 @@ +package helium + +import ( + "bytes" + "encoding/binary" + "errors" + "fmt" + + b64 "encoding/base64" + + "github.com/btcsuite/btcutil/base58" + "github.com/helium/rosetta-helium/utils" + rocksdb "github.com/linxGnu/grocksdb" + "github.com/okeuday/erlang_go/v2/erlang" + "go.uber.org/zap" +) + +type Entry struct { + Name string + Nonce int64 + Amount int64 +} + +type AccountEntry struct { + Entry Entry + DCEntry Entry + SecEntry Entry +} + +var heightKeyBinary []byte = []byte("height") + +func extractEntryFromAccountTuple(account interface{}, position int64) (*Entry, error) { + entryBin := account.(erlang.OtpErlangTuple)[position].(erlang.OtpErlangBinary).Value + entry, eErr := erlang.BinaryToTerm(entryBin[1:]) + if eErr != nil { + return nil, eErr + } + + entryName := fmt.Sprint(entry.(erlang.OtpErlangTuple)[0].(erlang.OtpErlangAtom)) + entryNonce := utils.Num64(entry.(erlang.OtpErlangTuple)[1]) + entryAmount := utils.Num64(entry.(erlang.OtpErlangTuple)[2]) + + return &Entry{ + entryName, + entryNonce, + entryAmount, + }, nil +} + +func addressToBinary(address string) ([]byte, error) { + addressBinary, _, err := base58.CheckDecode("14XASpMbTophdTzmEwc2hTTyv78YmWgu2ckgUmEZeXX1poXGuHZ") + if err != nil { + return nil, err + } + + return addressBinary, nil +} + +func heightToBinary(height int64) ([]byte, error) { + heightBinary := new(bytes.Buffer) + err := binary.Write(heightBinary, binary.BigEndian, height) + if err != nil { + return nil, err + } + + return heightBinary.Bytes(), nil +} + +func RocksDBBlockHashGet(height int64) (*string, error) { + heightBin, hbErr := heightToBinary(height) + if hbErr != nil { + return nil, hbErr + } + + ro := rocksdb.NewDefaultReadOptions() + hashBin, hErr := NodeBlocksDB.GetCF(ro, NodeBlockchainDBHeightsHandle, heightBin) + if hErr != nil { + return nil, hErr + } + + hash := b64.RawURLEncoding.EncodeToString(hashBin.Data()) + + return &hash, nil +} + +func RocksDBTransactionsHeightGet() (*int64, error) { + ro := rocksdb.NewDefaultReadOptions() + + heightBin, hErr := NodeTransactionsDB.GetCF(ro, NodeTransactionsDBDefaultHandle, heightKeyBinary) + if hErr != nil { + return nil, hErr + } + + height := int64(binary.LittleEndian.Uint64(heightBin.Data())) + + return &height, nil +} + +func RocksDBBalancesHeightGet() (*int64, error) { + ro := rocksdb.NewDefaultReadOptions() + + heightBin, hErr := NodeBalancesDB.GetCF(ro, NodeBalancesDBDefaultHandle, heightKeyBinary) + if hErr != nil { + return nil, hErr + } + + zap.S().Info(fmt.Sprint(heightBin)) + + height := int64(binary.LittleEndian.Uint64(heightBin.Data())) + + return &height, nil +} + +func RocksDBAccountGet(address string, height int64) (*AccountEntry, error) { + addressBin, abErr := addressToBinary(address) + if abErr != nil { + return nil, abErr + } + + heightBin, hbErr := heightToBinary(height) + if hbErr != nil { + return nil, hbErr + } + + key := append(addressBin, heightBin...) + + readOptions := rocksdb.NewDefaultReadOptions() + readOptions.SetFillCache(false) + readOptions.SetTotalOrderSeek(true) + iterator := NodeBalancesDB.NewIteratorCF(readOptions, NodeBalancesDBEntriesHandle) + defer iterator.Close() + iterator.SeekForPrev(key) + + if iterator.ValidForPrefix(addressBin) { + accountEntryBin := iterator.Value() + accountEntryTuple, bErr := erlang.BinaryToTerm(accountEntryBin.Data()) + if bErr != nil { + return nil, bErr + } + accountEntryBin.Free() + + entry, entryErr := extractEntryFromAccountTuple(accountEntryTuple, 0) + if entryErr != nil { + return nil, entryErr + } + + dcEntry, entryErr := extractEntryFromAccountTuple(accountEntryTuple, 1) + if entryErr != nil { + return nil, entryErr + } + + secEntry, entryErr := extractEntryFromAccountTuple(accountEntryTuple, 2) + if entryErr != nil { + return nil, entryErr + } + + accountEntry := &AccountEntry{ + *entry, + *dcEntry, + *secEntry, + } + return accountEntry, nil + } else { + return nil, errors.New("invalid iterator") + } +} diff --git a/helium/types.go b/helium/types.go index 4cfa00c..f835189 100644 --- a/helium/types.go +++ b/helium/types.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/coinbase/rosetta-sdk-go/types" + rocksdb "github.com/linxGnu/grocksdb" "go.uber.org/zap" ) @@ -451,6 +452,15 @@ var ( // LBS is the LastBlessedBlock height as an int64 LBS = readLBSfile() + + // Optional RocksDB vars for node db + NodeBalancesDB *rocksdb.DB + NodeBlocksDB *rocksdb.DB + NodeTransactionsDB *rocksdb.DB + NodeBalancesDBEntriesHandle *rocksdb.ColumnFamilyHandle + NodeBalancesDBDefaultHandle *rocksdb.ColumnFamilyHandle + NodeBlockchainDBHeightsHandle *rocksdb.ColumnFamilyHandle + NodeTransactionsDBDefaultHandle *rocksdb.ColumnFamilyHandle ) type Block struct { diff --git a/main.go b/main.go index a5e7b4a..21d59b3 100644 --- a/main.go +++ b/main.go @@ -24,6 +24,7 @@ import ( "net/http" "os" "path/filepath" + "time" "github.com/helium/rosetta-helium/helium" "github.com/helium/rosetta-helium/services" @@ -35,12 +36,24 @@ import ( "github.com/coinbase/rosetta-sdk-go/types" badger "github.com/dgraph-io/badger/v3" + + rocksdb "github.com/linxGnu/grocksdb" ) const ( serverPort = 8080 ) +type HeliumRocksDB struct { + BalancesDB *rocksdb.DB + TransactionsDB *rocksdb.DB + BlockchainDB *rocksdb.DB + EntriesCF *rocksdb.ColumnFamilyHandle + BalancesDefaultCF *rocksdb.ColumnFamilyHandle + HeightsCF *rocksdb.ColumnFamilyHandle + TransactionsDefaultCF *rocksdb.ColumnFamilyHandle +} + // NewBlockchainRouter creates a Mux http.Handler from a collection // of server controllers. func NewBlockchainRouter( @@ -144,27 +157,92 @@ func LoadGhostTxns(network *types.NetworkIdentifier, db *badger.DB) error { return nil } +func openRocksDB(dataDir string) (heliumDB *HeliumRocksDB, err error) { + opts := rocksdb.NewDefaultOptions() + columnOpts := rocksdb.NewDefaultOptions() + + prefixExtractor := rocksdb.NewFixedPrefixTransform(33) + columnOpts.SetPrefixExtractor(prefixExtractor) + + balancesCfNames := []string{"default", "entries"} + blockchainCfNames := []string{"default", "heights"} + transactionsCfNames := []string{"default", "transactions"} + + dbBal, balancesCfHandles, dbBalErr := rocksdb.OpenDbAsSecondaryColumnFamilies( + opts, + dataDir+"/balances.db", + "rocksdb/balances.db", + balancesCfNames, + []*rocksdb.Options{opts, columnOpts}, + ) + if dbBalErr != nil { + return nil, dbBalErr + } + + dbBlock, blockchainCfHandles, dbBlockErr := rocksdb.OpenDbAsSecondaryColumnFamilies( + opts, + dataDir+"/blockchain.db", + "rocksdb/blockchain.db", + blockchainCfNames, + []*rocksdb.Options{opts, opts}, + ) + if dbBlockErr != nil { + return nil, dbBalErr + } + + dbTxn, txnCfHandles, dbTxnErr := rocksdb.OpenDbAsSecondaryColumnFamilies( + opts, + dataDir+"/transactions.db", + "rocksdb/transactions.db", + transactionsCfNames, + []*rocksdb.Options{opts, opts}, + ) + if dbTxnErr != nil { + return nil, dbTxnErr + } + + return &HeliumRocksDB{ + BalancesDB: dbBal, + TransactionsDB: dbTxn, + BlockchainDB: dbBlock, + EntriesCF: balancesCfHandles[1], + BalancesDefaultCF: balancesCfHandles[0], + HeightsCF: blockchainCfHandles[1], + TransactionsDefaultCF: txnCfHandles[0], + }, nil +} + func main() { + // Logging tool logger, _ := zap.NewDevelopment() defer logger.Sync() // flushes buffer, if any - globalLogger := zap.ReplaceGlobals(logger) defer globalLogger() + // Ghost transaction DB setup bdb, err := badger.Open(badger.DefaultOptions("badger")) if err != nil { zap.S().Fatal(err) } defer bdb.Close() - utils.DB = bdb - var testnet bool - var network *types.NetworkIdentifier + // CLI Flag Parsing + // **************** + // + // blockchain-node data dir direct connection CLI arg + var blockchainNodeDataDir string + flag.StringVar(&blockchainNodeDataDir, "data", "", "path to blockchain-node data dir") + // Testnet CLI arg + var testnet bool flag.BoolVar(&testnet, "testnet", false, "run testnet version of rosetta-helium") + + // Parse flags flag.Parse() + // Network setup + var network *types.NetworkIdentifier if !testnet { zap.S().Info("Initilizing mainnet node...") network = &types.NetworkIdentifier{ @@ -192,6 +270,32 @@ func main() { helium.CurrentNetwork = network + // Blockchain-node rocksdb direct connection setup + if blockchainNodeDataDir != "" { + // Set total number of retries before canceling DB open + retries := 10 + + zap.S().Info("Attempting to load rocksdb directly at dir '" + blockchainNodeDataDir + "'") + + for retries > 0 { + heliumDB, dbOpenErr := openRocksDB(blockchainNodeDataDir) + if dbOpenErr != nil { + zap.S().Warn(dbOpenErr.Error() + ": Unable to open rocksdb at this time. Retrying - (" + fmt.Sprint(retries) + " attemps left)") + time.Sleep(5 * time.Second) + } else { + zap.S().Info("Loaded rocksdb directly at dir '" + blockchainNodeDataDir + "'") + helium.NodeBalancesDB = heliumDB.BalancesDB + helium.NodeBlocksDB = heliumDB.BlockchainDB + helium.NodeTransactionsDB = heliumDB.BlockchainDB + helium.NodeBalancesDBEntriesHandle = heliumDB.EntriesCF + helium.NodeBalancesDBDefaultHandle = heliumDB.BalancesDefaultCF + helium.NodeBlockchainDBHeightsHandle = heliumDB.HeightsCF + helium.NodeTransactionsDBDefaultHandle = heliumDB.TransactionsDefaultCF + break + } + } + } + // The asserter automatically rejects incorrectly formatted // requests. a, err := asserter.NewServer( diff --git a/rosetta-cli-config/mainnet/config.json b/rosetta-cli-config/mainnet/config.json index 28dc96a..8531da1 100644 --- a/rosetta-cli-config/mainnet/config.json +++ b/rosetta-cli-config/mainnet/config.json @@ -9,7 +9,7 @@ "tip_delay": 1200, "max_retries": 10, "data": { - "start_index": 1236242, + "start_index": 1259282, "historical_balance_enabled": true, "end_conditions": { "reconciliation_coverage": { diff --git a/services/account_service.go b/services/account_service.go index 40490f2..65cf9d7 100644 --- a/services/account_service.go +++ b/services/account_service.go @@ -17,10 +17,12 @@ package services import ( "context" "errors" + "fmt" "github.com/coinbase/rosetta-sdk-go/server" "github.com/coinbase/rosetta-sdk-go/types" "github.com/helium/rosetta-helium/helium" + "go.uber.org/zap" ) // AccountAPIService implements the server.AccountAPIServicer interface. @@ -45,6 +47,8 @@ func (s *AccountAPIService) AccountBalance( Address: request.AccountIdentifier.Address, } + zap.S().Info(request.AccountIdentifier.Address + " " + fmt.Sprint(*request.BlockIdentifier.Index)) + if request.BlockIdentifier != nil { if request.BlockIdentifier.Index == nil { return nil, helium.WrapErr( @@ -55,9 +59,11 @@ func (s *AccountAPIService) AccountBalance( balanceRequest.Height = *request.BlockIdentifier.Index } - accountBalances, aErr := helium.GetBalance(balanceRequest) - if aErr != nil { - if aErr.Code == 1 { + if helium.NodeBalancesDB != nil { + var accountBalances []*types.Amount + accountEntry, aeErr := helium.RocksDBAccountGet(request.AccountIdentifier.Address, balanceRequest.Height) + if aeErr != nil { + zap.S().Info("no balance found for " + balanceRequest.Address + " at height " + fmt.Sprint(balanceRequest.Height) + ". Returning balanaces of 0.") accountBalances = []*types.Amount{ { Value: "0", @@ -69,41 +75,81 @@ func (s *AccountAPIService) AccountBalance( }, } } else { - return nil, aErr + accountBalances = []*types.Amount{ + { + Value: fmt.Sprint(accountEntry.Entry.Amount), + Currency: helium.HNT, + }, + { + Value: fmt.Sprint(accountEntry.SecEntry.Amount), + Currency: helium.HST, + }, + } } - } - var blockId types.BlockIdentifier - - if request.BlockIdentifier == nil { - currentHeight, chErr := helium.GetCurrentHeight() - if chErr != nil { - return nil, chErr + blockHash, bhErr := helium.RocksDBBlockHashGet(*request.BlockIdentifier.Index) + if bhErr != nil { + return nil, helium.WrapErr(helium.ErrFailed, bhErr) } - currentBlock, cErr := helium.GetBlockIdentifier(&types.PartialBlockIdentifier{ - Index: currentHeight, - }) - if cErr != nil { - return nil, cErr + blockIdentifier := &types.BlockIdentifier{ + Index: *request.BlockIdentifier.Index, + Hash: *blockHash, } - blockId = *currentBlock + return &types.AccountBalanceResponse{ + BlockIdentifier: blockIdentifier, + Balances: accountBalances, + }, nil } else { - requestedBlock, rErr := helium.GetBlockIdentifier(&types.PartialBlockIdentifier{ - Index: request.BlockIdentifier.Index, - }) - if rErr != nil { - return nil, rErr + zap.S().Info("Old path") + accountBalances, aErr := helium.GetBalance(balanceRequest) + if aErr != nil { + zap.S().Info("no balance found for " + balanceRequest.Address + " at height " + fmt.Sprint(balanceRequest.Height) + ". Returning balanaces of 0.") + accountBalances = []*types.Amount{ + { + Value: "0", + Currency: helium.HNT, + }, + { + Value: "0", + Currency: helium.HST, + }, + } } - blockId = *requestedBlock - } + var blockId types.BlockIdentifier + + if request.BlockIdentifier == nil { + currentHeight, chErr := helium.GetCurrentHeight() + if chErr != nil { + return nil, chErr + } - return &types.AccountBalanceResponse{ - BlockIdentifier: &blockId, - Balances: accountBalances, - }, nil + currentBlock, cErr := helium.GetBlockIdentifier(&types.PartialBlockIdentifier{ + Index: currentHeight, + }) + if cErr != nil { + return nil, cErr + } + + blockId = *currentBlock + } else { + requestedBlock, rErr := helium.GetBlockIdentifier(&types.PartialBlockIdentifier{ + Index: request.BlockIdentifier.Index, + }) + if rErr != nil { + return nil, rErr + } + + blockId = *requestedBlock + } + + return &types.AccountBalanceResponse{ + BlockIdentifier: &blockId, + Balances: accountBalances, + }, nil + } } // AccountCoins implements the /account/coins endpoint. diff --git a/utils/utils.go b/utils/utils.go index 14633f0..b5f63a1 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -3,6 +3,7 @@ package utils import ( "encoding/json" "errors" + "math/big" "strings" "github.com/coinbase/rosetta-sdk-go/types" @@ -212,3 +213,34 @@ func StringInSlice(a string, list []string) bool { } return false } + +func Num64(n interface{}) int64 { + switch n := n.(type) { + case int: + return int64(n) + case int8: + return int64(n) + case int16: + return int64(n) + case int32: + return int64(n) + case int64: + return int64(n) + case uint: + return int64(n) + case uintptr: + return int64(n) + case uint8: + return int64(n) + case uint16: + return int64(n) + case uint32: + return int64(n) + case uint64: + return int64(n) + case *big.Int: + return n.Int64() + default: + return n.(int64) + } +} From 9056533ff79d4c483e3a26a7bd550ab9df4070ec Mon Sep 17 00:00:00 2001 From: Steven Yuan Date: Thu, 10 Mar 2022 16:48:59 +0000 Subject: [PATCH 16/19] take out hardcoded address... smh --- helium/rocksdb.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helium/rocksdb.go b/helium/rocksdb.go index 80fe84c..007f023 100644 --- a/helium/rocksdb.go +++ b/helium/rocksdb.go @@ -48,7 +48,7 @@ func extractEntryFromAccountTuple(account interface{}, position int64) (*Entry, } func addressToBinary(address string) ([]byte, error) { - addressBinary, _, err := base58.CheckDecode("14XASpMbTophdTzmEwc2hTTyv78YmWgu2ckgUmEZeXX1poXGuHZ") + addressBinary, _, err := base58.CheckDecode(address) if err != nil { return nil, err } From 623f40774380bbd5f8dc8d1211b34abc0b7e0461 Mon Sep 17 00:00:00 2001 From: Steven Yuan Date: Wed, 16 Mar 2022 05:06:25 +0000 Subject: [PATCH 17/19] Enabled direct rocksdb connection --- docker/mainnet.sh | 2 +- .../mainnet/{1236241.json => 1267921.json} | 14 +++- helium/middleware.go | 68 ++++++++----------- helium/op_processor.go | 2 +- helium/rocksdb.go | 20 ++---- main.go | 5 +- rosetta-cli-config/mainnet/config.json | 2 +- services/account_service.go | 62 ++++++++--------- services/network_service.go | 14 ++++ 9 files changed, 95 insertions(+), 94 deletions(-) rename ghost-transactions/mainnet/{1236241.json => 1267921.json} (91%) diff --git a/docker/mainnet.sh b/docker/mainnet.sh index 8fb8582..52c35b7 100644 --- a/docker/mainnet.sh +++ b/docker/mainnet.sh @@ -2,7 +2,7 @@ set -euo pipefail -echo '1259282' > /app/lbs.txt & +echo '1267922' > /app/lbs.txt & /opt/blockchain_node/bin/blockchain_node foreground & /app/rosetta-helium --data="/data" & diff --git a/ghost-transactions/mainnet/1236241.json b/ghost-transactions/mainnet/1267921.json similarity index 91% rename from ghost-transactions/mainnet/1236241.json rename to ghost-transactions/mainnet/1267921.json index 8146ce2..4a03b5e 100644 --- a/ghost-transactions/mainnet/1236241.json +++ b/ghost-transactions/mainnet/1267921.json @@ -36,6 +36,9 @@ {"Block":993313,"Hash":"xVvKLTs5vfffYyxY1LZO_GoSxb4gm_Xl1E7k757hgjk","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"xVvKLTs5vfffYyxY1LZO_GoSxb4gm_Xl1E7k757hgjk\", \"type\": \"unstake_validator_v1\", \"owner\": \"14a1abAcR1CYEatWzNyDYNtpvDPnr85Qqy3fPMtBRGdKjWNb2rN\", \"address\": \"11oageLfoBu9jT9xsbA8x8Eio19rftsxetk8MTz6H6EWt8ur54t\", \"stake_amount\": 1000000000000, \"owner_signature\": \"keN-YiB3QarmYg9WJVNeRnEB5BVCwbNH5r159EbM1o1MSL1ytVRTmXiZqISy6FW2VhynZqegaUDDhWJQ1tShDw\", \"stake_release_height\": 1243315}","Time":"2021-09-02T04:46:13-04:00"}, {"Block":1080759,"Hash":"fkBxpxknm2khWwCWIujkevwfPgQAKsKXGaTY1fIwQuo","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"fkBxpxknm2khWwCWIujkevwfPgQAKsKXGaTY1fIwQuo\", \"type\": \"unstake_validator_v1\", \"owner\": \"14o3qw58KbC9reDLcK29AcwP6yA5rkrsw8L2XwEGAgEkcWt61pW\", \"address\": \"112Vtnki3FL2Bn3Gg28Q8grgnnkJazN7QMbNLDJdMWnVXQP4rhEB\", \"stake_amount\": 1000000000000, \"owner_signature\": \"0vkLUsXjcld_5HpVAssbencMrCL6V5ET33A__1Fop7NRLy82rnHkAMxP-emskc7HjrOUMdOQmW4q0DS6-S-OCg\", \"stake_release_height\": 1330800}","Time":"2021-11-02T00:59:26-04:00"}, {"Block":1138346,"Hash":"C2xwJXHAjCFPlu7tzbaXZRAUVZM579xOR1IBqYRmPDQ","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"C2xwJXHAjCFPlu7tzbaXZRAUVZM579xOR1IBqYRmPDQ\", \"type\": \"unstake_validator_v1\", \"owner\": \"13HTDhdVSJsoyEHKAZYsWhyFmM76dGmPfmnU7JR6sC5MRJpH81E\", \"address\": \"11qecHAqvJd977S9VZidTAHzN7wKGMWcWhJwfMoCY5B6CKvp2fC\", \"stake_amount\": 1000000000000, \"owner_signature\": \"9Xyojj0Y4a9CQv6URAIdjtAQgsst6Ap2BzvIc2Yn0PuXDtOryqxp2O__hdKHmvMN152QT1ksGAbbh0STbL8yAw\", \"stake_release_height\": 1388400}","Time":"2021-12-13T18:12:51-05:00"}, +{"Block":1236188,"Hash":"ftJwL4G6TCeRM67_50WaldGPF4uuXev-lPS6GvpU9DI","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"ftJwL4G6TCeRM67_50WaldGPF4uuXev-lPS6GvpU9DI\", \"type\": \"unstake_validator_v1\", \"owner\": \"14CzpM7RbWjuDgfHq26b6ppwmSpy3h8e88kKVCWEyoJySyTvWd6\", \"address\": \"112Y23w8EjpQDBqqLQaegmbbprFF5GScMVXC5Ctxpo1mTnRtmXPC\", \"stake_amount\": 1000000000000, \"owner_signature\": \"thWHn1_1ziCjPG95rqZExv2RkR9h8Aqf4opRhJ9MTv-HO7v_BDVeOWmQz6ZbXiC38sLO8jnMHdYjgmMWfnB8CQ\", \"stake_release_height\": 1486188}","Time":"2022-02-21T13:21:16-05:00"}, +{"Block":1236188,"Hash":"WgHsuv_DeiXo2g0n8PQ0suQmmMwVxBiwm6HpYVNPvC4","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"WgHsuv_DeiXo2g0n8PQ0suQmmMwVxBiwm6HpYVNPvC4\", \"type\": \"unstake_validator_v1\", \"owner\": \"14HmJ1s5WLzGuDCeKt6qKz2o9ZRstQCqjUiDjcTJQxxG5xVyhY3\", \"address\": \"112sovgvtdybLuqiGDj86A2S9oGtBN6GEU78fEvkoUjQriYDiVSh\", \"stake_amount\": 1000000000000, \"owner_signature\": \"amQ5VWclF_jxFfAT_mlLCc1KaGhtuz7Qi2B_uUzWc3Geh6hVLnlrfo_HwfuRWJ19Up21TGYBIGKGRr-_3xJLAg\", \"stake_release_height\": 1486188}","Time":"2022-02-21T13:21:16-05:00"}, +{"Block":1236188,"Hash":"f5QeSJtkIIuMkMILZKzmCU6Rm3lSzklCgQvF853rDxs","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"f5QeSJtkIIuMkMILZKzmCU6Rm3lSzklCgQvF853rDxs\", \"type\": \"unstake_validator_v1\", \"owner\": \"13RuyiiMixC6KjPaxwj4AzsNqQsENMJ6jYn84fsdWZYkqNZVq9w\", \"address\": \"14pDRFfaR9ucDFovPmS5UBM6zwijvNBFWFetEZCjpXCt9a1ZiFU\", \"stake_amount\": 1000000000000, \"owner_signature\": \"GdigQNN-AALx1OLzNE8ucqs7HdvOIMkWSSAcZw3Lvo11t942TYrvE0ajzEBH7T2DZeHuwg9IOLOAWfFG1KIwAQ\", \"stake_release_height\": 1486188}","Time":"2022-02-21T13:21:16-05:00"}, {"Block":960305,"Hash":"uBQcVUQEM9bI4LYU66smLyn2BxOXJSuWzSu4kCRyNKc","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"uBQcVUQEM9bI4LYU66smLyn2BxOXJSuWzSu4kCRyNKc\", \"type\": \"unstake_validator_v1\", \"owner\": \"12xoVMjaduyZm1bw1GEBXoQe6YHCfU5gghcuobQ5weopZ8as3qw\", \"address\": \"11PEHmkn1p8us4FwZLVFjGnrCsnUrpFKGzhvccd3MXkmv6pWxBi\", \"stake_amount\": 1000000000000, \"owner_signature\": \"rQ3WoSVPGKHFJBjo7STn2Sprw-3atM2DSrw5LCgQ63_YXqv6DfsrkR0npQU_9nXK418LSwb9eDa565cktgJhBA\", \"stake_release_height\": 1210330}","Time":"2021-08-10T23:47:16-04:00"}, {"Block":982299,"Hash":"ghbZO_Mxk_DLID0HSy2oeQIrQO24uSZPh7cImWFe3SA","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"ghbZO_Mxk_DLID0HSy2oeQIrQO24uSZPh7cImWFe3SA\", \"type\": \"unstake_validator_v1\", \"owner\": \"13Q8j6wTjbZ8xMCaEBtzNEjY912WmsZM4RJfWwgeBmRoMh8F6Ur\", \"address\": \"11zgHFxUsgJAZGf9r3aEAqLbKd1QuDVBpUNkLNitwctPeaqW5QW\", \"stake_amount\": 1000000000000, \"owner_signature\": \"DgC8cLCpkKBBqZRDFA__F2y824xEeu0B2svnfbaHRb9RHUKWH34C9g3n-WFIVe6fbBqtaoaPUyeD5-1W-cCzCg\", \"stake_release_height\": 1232300}","Time":"2021-08-25T23:12:10-04:00"}, {"Block":1063908,"Hash":"62ViZW56xd6EEnd8_xvlcBBizrMu1j-9dbsGm1-FMgk","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"62ViZW56xd6EEnd8_xvlcBBizrMu1j-9dbsGm1-FMgk\", \"type\": \"unstake_validator_v1\", \"owner\": \"14NvSPHti6K32U6Lven9XMkPEusRfog8jYtUACgm3hqgaPenwyY\", \"address\": \"14SDFnzCU8s7uomCeYZETNAcg151hpjab2WxMLGRA948zwp6eNw\", \"stake_amount\": 1000000000000, \"owner_signature\": \"js5vyOxVucGUqBBJe_xFPQN0wj7YtIP4n5hw4u90GX39Y--ROz4y1NsiAyKfGtoeAB0fXwEh10ZZupTg1G4eCg\", \"stake_release_height\": 1313910}","Time":"2021-10-21T08:58:35-04:00"}, @@ -47,6 +50,8 @@ {"Block":1158384,"Hash":"x3Nhho7THmDJAPNeRiEbVVOXVOKpNJTtx_Y10-OCMbw","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"x3Nhho7THmDJAPNeRiEbVVOXVOKpNJTtx_Y10-OCMbw\", \"type\": \"unstake_validator_v1\", \"owner\": \"13PL7mqUNewGt4j5XTch2t3v8awB3YJkJJVLYtrsX7aVQcAWWy3\", \"address\": \"11LUtbdfzvEmvTxvuExubsVezsbjmkEtFHeV3gRUG4A8X12ESAZ\", \"stake_amount\": 1000000000000, \"owner_signature\": \"i6MoxnRUEbKvPgkX0FHTBMgsU4xemKIA-vtL-Y6vf-govNXU4TjDKJur7EKF_UEaCTMzjhFlCjbFforzQKcTDw\", \"stake_release_height\": 1408397}","Time":"2021-12-29T14:13:07-05:00"}, {"Block":1191129,"Hash":"9K6ZRAZ3juua6cHQuL6WfOOx252VT51cYgMwtMLE71M","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"9K6ZRAZ3juua6cHQuL6WfOOx252VT51cYgMwtMLE71M\", \"type\": \"unstake_validator_v1\", \"owner\": \"13fAhjCGycJALqbsQCJ49d6JUQjQ5wgBUEZm7ZGytfGPNM4uzn9\", \"address\": \"14ko5Gg33HoeUGypDh2W9Cr2oj18foiRVagvyhdMcQbwgvrpm2S\", \"stake_amount\": 1000000000000, \"owner_signature\": \"VM9K6Ce59KMpC7S0yOOer3kZG0tIw3R6wjzpe0HTDk2TPM5nBIYO1F_SqxVKL1JAs1_YDvWthDFUyFY0xEE8BQ\", \"stake_release_height\": 1441129}","Time":"2022-01-21T00:11:54-05:00"}, {"Block":1205599,"Hash":"bFyJt0uPq5GeJSI0os_EkS-ZZfsvOR0GnV66w4A4p34","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"bFyJt0uPq5GeJSI0os_EkS-ZZfsvOR0GnV66w4A4p34\", \"type\": \"unstake_validator_v1\", \"owner\": \"14PNnDMq6EnG9kXGPeH3DiBKT5akZ89AmEGzUesTaX1SdLbNpfT\", \"address\": \"112ssQr2qe3XLb6dBTNZVBdaiEU9bEb2XpFQkvN2wbLaB5xoshZh\", \"stake_amount\": 1000000000000, \"owner_signature\": \"D805VbtCTXHwwKBDf8ekpsg_jiHmJF76cxTmJGTqz0mou5bjFsI0q5-EygASKjlWzIiwoLOHsQ96RoRjJN-dCA\", \"stake_release_height\": 1455610}","Time":"2022-01-30T20:35:08-05:00"}, +{"Block":1236186,"Hash":"AJWkmVg35UUmfAnzuvjgfp5LJeO1uD-8wLqf51n2rzU","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"AJWkmVg35UUmfAnzuvjgfp5LJeO1uD-8wLqf51n2rzU\", \"type\": \"unstake_validator_v1\", \"owner\": \"146fnkgzwVoX6p2drN8JWDc5BvCV45v7FawSmCyuk4y6PC58ttB\", \"address\": \"14ipBKpxUEecAkrJU5rQThWmJHwHFVYRtbQF7joDr7B3uqhodfP\", \"stake_amount\": 1000000000000, \"owner_signature\": \"HJ__3un0NcvwKPPaiWi5EnXSaxo_RYHfC3UDYJYmApITr1HikzkgbYBNO5s4500L9smWzLK9JmGnJ8977gc_Cg\", \"stake_release_height\": 1486188}","Time":"2022-02-21T13:19:36-05:00"}, +{"Block":1251708,"Hash":"rQygqkChLjBUM940nqjH-SNwGjfjvdHDNm4yLCEzlec","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"rQygqkChLjBUM940nqjH-SNwGjfjvdHDNm4yLCEzlec\", \"type\": \"unstake_validator_v1\", \"owner\": \"132syp9LVXtRidwdHgXKC7DGuMkELCYmKakQTSXYZrt4LAEmCHo\", \"address\": \"112SbCvjoa2g7TjYejnhQCrxpA4jKCcaagRcNo34rr4cWFZhF8nu\", \"stake_amount\": 1000000000000, \"owner_signature\": \"UGgCiHimi6w_I2kfUL3g-ZbZTsVBX3HYQgPgGbMcPS101vp3bUreYVqyGZJzikZu2wOovZLpaRGl_mR7k-EvCQ\", \"stake_release_height\": 1501740}","Time":"2022-03-03T16:25:33-05:00"}, {"Block":993298,"Hash":"whK6XSNtJ7mFNCOG5DgZ020ZF3WNWwU0TuB8DBI6Z9U","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"whK6XSNtJ7mFNCOG5DgZ020ZF3WNWwU0TuB8DBI6Z9U\", \"type\": \"unstake_validator_v1\", \"owner\": \"13P73axPhjTRiDvwTYzzaXKeTmPpUDzXDeX8PH2owhpRKGCGWEd\", \"address\": \"112hexri3xqAXb347Sk2aN3Hkr4DLs4vZnZ69QwvPCTytZ4CAsy5\", \"stake_amount\": 1000000000000, \"owner_signature\": \"FchcHyG4SN71r_81GeLEuBnOp0prSA4xQ8v49RpiexBGtFjIiQGbiPRTW30ePb3LdSa-tpuIhYo_5e13aFBfCA\", \"stake_release_height\": 1243298}","Time":"2021-09-02T04:32:17-04:00"}, {"Block":1005214,"Hash":"iW0ZaP5x2IkDUwfnj_0U_Bftq4oA6Oq3V3dReP0eUMs","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"iW0ZaP5x2IkDUwfnj_0U_Bftq4oA6Oq3V3dReP0eUMs\", \"type\": \"unstake_validator_v1\", \"owner\": \"141WsikcrSo8tugixuLN5QTfzzLbm757UKd556iSx16sfq127ey\", \"address\": \"112BVQNFU5JZ5oHgFTasVwDpxRkJ9FgYwKmZzYB951NhW7LS1hfK\", \"stake_amount\": 1000000000000, \"owner_signature\": \"gG4a8ALZpVrg0KMpCYgGKZ3YYKNQ_9AkrSlTCNfqKIlrzUYjlQepPPqmtXKtAGWxV58y_Hasn1Hgnj29bbCgAw\", \"stake_release_height\": 1255226}","Time":"2021-09-10T11:28:28-04:00"}, {"Block":1005229,"Hash":"s3pC-QUO15cwuMtmJPWnDbJLxr1jvUJHOvfl-sxI11Q","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"s3pC-QUO15cwuMtmJPWnDbJLxr1jvUJHOvfl-sxI11Q\", \"type\": \"unstake_validator_v1\", \"owner\": \"141WsikcrSo8tugixuLN5QTfzzLbm757UKd556iSx16sfq127ey\", \"address\": \"112rDxMhcWT1kPurJQhiWEuiMptgTPRL8swHzfM7WKNBshwJjSts\", \"stake_amount\": 1000000000000, \"owner_signature\": \"JoRDBi2sD75wsGhdI7yWS5wd49YPffDSet0Ht-TgHOPs8pKH7xPYgkmqrGOjSnSFav1RnelwAD0FX_OllDY0Cg\", \"stake_release_height\": 1255245}","Time":"2021-09-10T11:43:43-04:00"}, @@ -60,6 +65,9 @@ {"Block":1150630,"Hash":"MQ3dImr4y_xLmjUumknEY7dQtMTjo5rhKlAMHStgDGQ","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"MQ3dImr4y_xLmjUumknEY7dQtMTjo5rhKlAMHStgDGQ\", \"type\": \"unstake_validator_v1\", \"owner\": \"13oXYBqPVucYUz7uuBHHa3mUaxEsqNzFyyYntsaj9nLTBoUiv2W\", \"address\": \"11MV5RUwYsvErcTEbJGHiPFQwU7GhKvLQFtJrdTZ5stzuYQioQK\", \"stake_amount\": 1000000000000, \"owner_signature\": \"jV7ubEAKFRWPeJe_TJUmtuKPMFeHR25P0ZUaD8fYOlizD80Ks3rstYjjJfwJN-DxT90x1saCC1fnO8uSrZdEBQ\", \"stake_release_height\": 1400635}","Time":"2021-12-23T07:08:00-05:00"}, {"Block":1191886,"Hash":"RfqQ1Vq6qhMLHAtcbtb0y5N0aBfZOPKqChsljbLMag4","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"RfqQ1Vq6qhMLHAtcbtb0y5N0aBfZOPKqChsljbLMag4\", \"type\": \"unstake_validator_v1\", \"owner\": \"13SoCNwjK9DEE8Fg8xvd45eKqAqZSQUDbwfVB9YGEyXZqRoFNTL\", \"address\": \"13uXhuPFvejiNKi2G3vWT23JsfuDBJNyxWUdPRxvi4mgeGFWeBj\", \"stake_amount\": 1000000000000, \"owner_signature\": \"HzUoZXE7y7SkzvwIF4fbSJPuUMgdGFH1Gc1mgbWb5ylhJwlEu29hZKi3TY2il-U49JzSQe4olF9HrMhLdWepDg\", \"stake_release_height\": 1441891}","Time":"2022-01-21T12:01:29-05:00"}, {"Block":1215060,"Hash":"xqWOAOepgNTC6slyi4noVLXRLKxir4xVCuMzayeTavM","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"xqWOAOepgNTC6slyi4noVLXRLKxir4xVCuMzayeTavM\", \"type\": \"unstake_validator_v1\", \"owner\": \"134c74JYsfN7X4CRGixhFSWgvR6m6wV4RMJUC13J97GnN9uBCJN\", \"address\": \"13vpUfieCqBbyLHF6QtFNS6uoB6nG6d9f2Y3B6wcBWGXHbdswVJ\", \"stake_amount\": 1000000000000, \"owner_signature\": \"cBNU-xVJtmLB5qNqeAuhngRelkpxQTndVkAKbmDXfBPGDJB79-Pg0MMDo3Q1AygWWDgYpxfMr9EcH-TGasGYDA\", \"stake_release_height\": 1465080}","Time":"2022-02-06T19:57:25-05:00"}, +{"Block":1236187,"Hash":"6ucFDcVJmhS1cPJtTF5LcEgy45CRcEnhYsS8tylxpaY","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"6ucFDcVJmhS1cPJtTF5LcEgy45CRcEnhYsS8tylxpaY\", \"type\": \"unstake_validator_v1\", \"owner\": \"12zesvGBAvc5H83xkGTAz5pjCCZgmZtrnB5FURr5iDwRJjAt6Gh\", \"address\": \"14F3K6nhc6keLuq4T6jKhxiGpXZRJPM7MCskW81cr58uR3JpF5w\", \"stake_amount\": 1000000000000, \"owner_signature\": \"eeeFyGi_0DbWGJ3iBnLQLDq5zeYAI5t_KyVYYpen-Ut7fsd8dHYhy3eUjtbfRDVrtJ1iZxeq5T5q_DaM-IPnCA\", \"stake_release_height\": 1486188}","Time":"2022-02-21T13:20:26-05:00"}, +{"Block":1236187,"Hash":"egus-ihTR7MoUzPsfp4IiX85UwVpEtT5UK9DpIL6UwI","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"egus-ihTR7MoUzPsfp4IiX85UwVpEtT5UK9DpIL6UwI\", \"type\": \"unstake_validator_v1\", \"owner\": \"13ShGEBJs9U5Sogsiy5QVoW5M9V3PU6Pu6mHDtfpj2NixWZcC3H\", \"address\": \"14YSQGx57GwT8Be8r3mjEmFDCQhsnWH86z1XVKw2vC499CxsQ2W\", \"stake_amount\": 1000000000000, \"owner_signature\": \"wl1-EokAOrlUUWYFGqVqmNlLbETsB6Pp01KKMoWxyJNH_j0moBcnrQk3El_pa8qwXUSj-BrMff03LaHhunARAg\", \"stake_release_height\": 1486188}","Time":"2022-02-21T13:20:26-05:00"}, +{"Block":1252004,"Hash":"1v8obLMaIfOj-ZWIeN6EjN_IeoPqLzU3AKihiQ4w0Rw","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"1v8obLMaIfOj-ZWIeN6EjN_IeoPqLzU3AKihiQ4w0Rw\", \"type\": \"unstake_validator_v1\", \"owner\": \"13csfUCAqyV4qqBbn2YDzregdE26g37FtL3YfaZJHnZvDEdDuWg\", \"address\": \"13MG8CvYE8c2fpRwKNCzFwwGFHGtGJJ2nHnGLNBZ6pTfw41rAPB\", \"stake_amount\": 1000000000000, \"owner_signature\": \"j544QAuLt31klDBMnzCjqGFnWLutU557YB3jN1Cs4jwuLnN8lJXWcJATkBYWJdEywaAEG-Z4SdlczNO59SScBQ\", \"stake_release_height\": 1502024}","Time":"2022-03-03T21:28:28-05:00"}, {"Block":960313,"Hash":"fXfwqV-1lA33erj3IwiEa2vIaVNu4qq6eBi9gJm9bZg","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"fXfwqV-1lA33erj3IwiEa2vIaVNu4qq6eBi9gJm9bZg\", \"type\": \"unstake_validator_v1\", \"owner\": \"12xoVMjaduyZm1bw1GEBXoQe6YHCfU5gghcuobQ5weopZ8as3qw\", \"address\": \"11ShxanLac4CbtvbvCuvKBBs6Jq1D4g6jPMkhbkxF8sis5bMeRZ\", \"stake_amount\": 1000000000000, \"owner_signature\": \"0i7H7rFrDIwj_ChzT--OnpmAPwrPF5YLkenqtsr7cs0JyknArYmm4HFcAzNENN3qejSEwNN9IB777EPL44yFAA\", \"stake_release_height\": 1210331}","Time":"2021-08-10T23:56:53-04:00"}, {"Block":960336,"Hash":"UcGVGWx7pEGHwOXANLtQ5qeqVK-rkV9r6kIpvrZICcM","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"UcGVGWx7pEGHwOXANLtQ5qeqVK-rkV9r6kIpvrZICcM\", \"type\": \"unstake_validator_v1\", \"owner\": \"12xoVMjaduyZm1bw1GEBXoQe6YHCfU5gghcuobQ5weopZ8as3qw\", \"address\": \"11Dk1QfJUn6a4qnfu4ufF7c8KZKf2ZDwm7EsGEiDsh2WZX9Cnxk\", \"stake_amount\": 1000000000000, \"owner_signature\": \"CSz6oS9wT-U0QatpfBK6g3QdQUPMyFlAn09FegNKXjkukh90eoIfuRxwakyOg5STCd5cuVl9yMvV_gOe4WKIAA\", \"stake_release_height\": 1210350}","Time":"2021-08-11T00:23:43-04:00"}, {"Block":960366,"Hash":"3QSM2gTB7xygbZtfuzbs-YvfAQyDrHFeZw0xUtAcpGc","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"3QSM2gTB7xygbZtfuzbs-YvfAQyDrHFeZw0xUtAcpGc\", \"type\": \"unstake_validator_v1\", \"owner\": \"12xoVMjaduyZm1bw1GEBXoQe6YHCfU5gghcuobQ5weopZ8as3qw\", \"address\": \"112hLLgKmMw1CGxuALfJgWPwpdPUJPeKYfYijJT7xmVQ1SQspXDw\", \"stake_amount\": 1000000000000, \"owner_signature\": \"OoHwD6XuknhCVgtRCW3l3ay7s6ldjWrjYFZxUKWAmOssYapWXu1E-pQ2td3Vxlip4OyQYrJq0fdwrKRAyWuQCw\", \"stake_release_height\": 1210380}","Time":"2021-08-11T01:00:04-04:00"}, @@ -104,6 +112,7 @@ {"Block":1187785,"Hash":"-2rZAQqpyviuQSMa3GQ6dthZBe9uKIMLrxrgR1tkieQ","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"-2rZAQqpyviuQSMa3GQ6dthZBe9uKIMLrxrgR1tkieQ\", \"type\": \"unstake_validator_v1\", \"owner\": \"14YqE1VapVhb7pahL3rJJPJBgLBkud5bpiUbpWo8VuQvscds1mB\", \"address\": \"11jmxrZ29X4ZnWY9G8E6NM9WYmyLazcuwVAj1r5pQigas7ykAm9\", \"stake_amount\": 1000000000000, \"owner_signature\": \"yypFOHW38cP4JhngVs8aGsZPkkLO221kJh1aWx5ay3j290DmYBNy7mF0qYAPE1vCr219rJ5M6CdpCdMc2EbKCA\", \"stake_release_height\": 1437785}","Time":"2022-01-18T20:41:56-05:00"}, {"Block":1210397,"Hash":"shEEwLQjvNCx5e6NRbxGeaWJSxK_zLC66UljqigxvoI","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"shEEwLQjvNCx5e6NRbxGeaWJSxK_zLC66UljqigxvoI\", \"type\": \"unstake_validator_v1\", \"owner\": \"136Q6at4MoCEqaih29WQTZSabepvpSgcqBUW3etyNiERjs6jKCb\", \"address\": \"13UewU3WPyBtCkoh6yEyJq7hVcqCMo5FMUDqBJ2f97tG2B8gPkL\", \"stake_amount\": 1000000000000, \"owner_signature\": \"KvOwWu7bQVJrjeK7eLdn-QS9U0KP3DX2qugeOXzPYsaFzKTSXZoiyd1RSNrfqKn_cE2pqkkgrfFM7r40ZSv6BA\", \"stake_release_height\": 1460399}","Time":"2022-02-03T09:45:22-05:00"}, {"Block":1212197,"Hash":"m2LvrwQukVDJF34vPP6AoiQg2APRtsrVXSEGpjs-Dpg","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"m2LvrwQukVDJF34vPP6AoiQg2APRtsrVXSEGpjs-Dpg\", \"type\": \"unstake_validator_v1\", \"owner\": \"14r7AGamvbgPNgDFxNdWyGRtTaucE2Mwh1Lh447Ni1jbduQxhZU\", \"address\": \"11aSfPsye3xDBCXkXJr5u9VrwGmR2m4uZfBYEi6vbkprAAvFTBQ\", \"stake_amount\": 1000000000000, \"owner_signature\": \"xPmdDmEC1tG9TDdzAYZIJdNXKRfm4aHFBB_al25EnuJyuJAEyUGYFlFiWPsa_9XnETH6-r8V6T6AYnyARU_rAg\", \"stake_release_height\": 1462210}","Time":"2022-02-04T17:36:03-05:00"}, +{"Block":1236200,"Hash":"ooflaHWnaREmq9tGPG8U6PVW9ZOvHOKPD8kFmhzIQds","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"ooflaHWnaREmq9tGPG8U6PVW9ZOvHOKPD8kFmhzIQds\", \"type\": \"unstake_validator_v1\", \"owner\": \"14kDLseUELFQKXCJ5bjUWiUZitZ6pTFyuWB6kXcQ5kYzwyDnzfW\", \"address\": \"14ekfz7FsJqbHroGmVU7ahNH2EKHSwEJ7SoSXMpryTRKk1aCcTh\", \"stake_amount\": 1000000000000, \"owner_signature\": \"wHxdiNK5412rUajdsjEUlfHBhz5b8L6nHzzsKQiX8N1Uhy_dgMHiyFqYey1Z_vBWPXyxUVUX9KE-J5Wqzr8UCQ\", \"stake_release_height\": 1486220}","Time":"2022-02-21T13:31:48-05:00"}, {"Block":960343,"Hash":"-W2WqZ8nkINlWm6CAf5HBiBgszIm8JM2BmboHQHe7l8","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"-W2WqZ8nkINlWm6CAf5HBiBgszIm8JM2BmboHQHe7l8\", \"type\": \"unstake_validator_v1\", \"owner\": \"12xoVMjaduyZm1bw1GEBXoQe6YHCfU5gghcuobQ5weopZ8as3qw\", \"address\": \"11TJwzUDUktQdV12eQ3TULEkKpf24SLa3nHpPTfySFj1UdN5HeU\", \"stake_amount\": 1000000000000, \"owner_signature\": \"9VGV1x0Sr6vUbcL64iBulntGsV43OsWqw8C0cE3w3M7PXnx8f8EH4m-tKuSY0PAkwn7C81LsF91fW3UdDnlzCg\", \"stake_release_height\": 1210351}","Time":"2021-08-11T00:32:29-04:00"}, {"Block":1005202,"Hash":"Pq5JYkSWW0v4mww9yZcZlEnYlARzLk_OEPjC745CLrU","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"Pq5JYkSWW0v4mww9yZcZlEnYlARzLk_OEPjC745CLrU\", \"type\": \"unstake_validator_v1\", \"owner\": \"141WsikcrSo8tugixuLN5QTfzzLbm757UKd556iSx16sfq127ey\", \"address\": \"112JkiDg2GcrbYScTRN52jvkvgGVqp4n75sBjU6dwQeqqqK6VQR8\", \"stake_amount\": 1000000000000, \"owner_signature\": \"LHLfM3ju1Pp6MVLugHAYZtPJ-P8PbNCy7Me76fysLdthliyTGBV1I6lzWR2bUfHk0e8hzbnsweqq6Pq4HlV_DQ\", \"stake_release_height\": 1255217}","Time":"2021-09-10T11:16:16-04:00"}, {"Block":1005250,"Hash":"JFPTW7BOlV65nT78SSjmmLSMtP4ps6buHXF3MS9XsH8","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"JFPTW7BOlV65nT78SSjmmLSMtP4ps6buHXF3MS9XsH8\", \"type\": \"unstake_validator_v1\", \"owner\": \"141WsikcrSo8tugixuLN5QTfzzLbm757UKd556iSx16sfq127ey\", \"address\": \"11n7gR4vDTbitDJMVH7x3NuXVAWLh5hoYRm6MUudg2HJmSbhzrW\", \"stake_amount\": 1000000000000, \"owner_signature\": \"Jhk1GsDleenAzEmFbfVWcxJ2LuXQlPj814aDCBTOLO5qZyxQwEKSMR_jnzpwA5FhVKHf6v_uJk2Wn2ymq1lkCQ\", \"stake_release_height\": 1255255}","Time":"2021-09-10T12:04:09-04:00"}, @@ -124,5 +133,8 @@ {"Block":1187493,"Hash":"rH9Wp1W1tSntEDRcU-sh0_ol-b5EK-PH4W06BdIXq7o","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"rH9Wp1W1tSntEDRcU-sh0_ol-b5EK-PH4W06BdIXq7o\", \"type\": \"unstake_validator_v1\", \"owner\": \"14J6zntifsPAbiPxHYhyK7zV5ZdtKm3DiiZUVNRCe4NS9kEbGKT\", \"address\": \"11NAYiMbSaqqaW4YEonn8jr9bQLqrtkKJbyDg5W54Fsmi5mMzNB\", \"stake_amount\": 1000000000000, \"owner_signature\": \"yTZug0SoNBIpeTfc1yPiICE0uMHIxGfDOvZzLQ5reXVDaEN9eU1g0y4KzxfRnV5ShxqBOKhUQHU6dMcaZPJ7Aw\", \"stake_release_height\": 1437500}","Time":"2022-01-18T16:14:30-05:00"}, {"Block":1191890,"Hash":"ErnUqnxiy82us6gJNeufaoJy2PZMmRhh_KPEY7iw2ho","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"ErnUqnxiy82us6gJNeufaoJy2PZMmRhh_KPEY7iw2ho\", \"type\": \"unstake_validator_v1\", \"owner\": \"13SoCNwjK9DEE8Fg8xvd45eKqAqZSQUDbwfVB9YGEyXZqRoFNTL\", \"address\": \"14eNsC5imxsxx4SP6R3BBdK2MD9ADvZD4iXZiSD6VN9w5BSeU5g\", \"stake_amount\": 1000000000000, \"owner_signature\": \"lzBEyG31sFa1yWgOwTEmFqFz1ePtPgayemtC9o5IdyLxw368xOSghWjRKWxGNhpXqVj8KpyiLblI88b1N7mAAg\", \"stake_release_height\": 1441890}","Time":"2022-01-21T12:04:49-05:00"}, {"Block":1205595,"Hash":"8OWQVI4oB8zOjDAMaKvUtTgNN4mEUhzpuJ9LaAsL46A","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"8OWQVI4oB8zOjDAMaKvUtTgNN4mEUhzpuJ9LaAsL46A\", \"type\": \"unstake_validator_v1\", \"owner\": \"14PNnDMq6EnG9kXGPeH3DiBKT5akZ89AmEGzUesTaX1SdLbNpfT\", \"address\": \"11T8jF9TKEP4i4weJTkmKRjgEcJktzDmackqjG7NDHgsrwBZXzJ\", \"stake_amount\": 1000000000000, \"owner_signature\": \"Bbz47Kk7ELbF4V0yhTVuG9EXawofZLbqcCn_N_-a2HQyQJGez3YXms0N68dt6xL1kJJeG_2yoAs-e2FeZ4ciBA\", \"stake_release_height\": 1455610}","Time":"2022-01-30T20:31:04-05:00"}, -{"Block":1222335,"Hash":"kQSUXJBEvPakpL3NQPyHAg3bgau52PzT-cXkaRE0UVo","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"kQSUXJBEvPakpL3NQPyHAg3bgau52PzT-cXkaRE0UVo\", \"type\": \"unstake_validator_v1\", \"owner\": \"14ATq3tQ7Jj3zxgXcxh5whKoLeKZJj6tF2mbRkBUSt9Wv9hEQgt\", \"address\": \"118HmJoBWf9yEsUAygGokkVhLP9o825fijmQC9PNgMJube6cYkF\", \"stake_amount\": 1000000000000, \"owner_signature\": \"TwZ_7iNdF2GjGel44f6lJb6MG7fya3XFYNcVXS-hjGUAksd6VcvaSD2g3SwkDzx6pZvE_lAPIAz2tGOkFKNlCg\", \"stake_release_height\": 1472342}","Time":"2022-02-12T13:23:54-05:00"} +{"Block":1222335,"Hash":"kQSUXJBEvPakpL3NQPyHAg3bgau52PzT-cXkaRE0UVo","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"kQSUXJBEvPakpL3NQPyHAg3bgau52PzT-cXkaRE0UVo\", \"type\": \"unstake_validator_v1\", \"owner\": \"14ATq3tQ7Jj3zxgXcxh5whKoLeKZJj6tF2mbRkBUSt9Wv9hEQgt\", \"address\": \"118HmJoBWf9yEsUAygGokkVhLP9o825fijmQC9PNgMJube6cYkF\", \"stake_amount\": 1000000000000, \"owner_signature\": \"TwZ_7iNdF2GjGel44f6lJb6MG7fya3XFYNcVXS-hjGUAksd6VcvaSD2g3SwkDzx6pZvE_lAPIAz2tGOkFKNlCg\", \"stake_release_height\": 1472342}","Time":"2022-02-12T13:23:54-05:00"}, +{"Block":1242120,"Hash":"XQXmOmZmCXrPTSwyee0xnrlhN-iE3Yx0cok28q9P0kk","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"XQXmOmZmCXrPTSwyee0xnrlhN-iE3Yx0cok28q9P0kk\", \"type\": \"unstake_validator_v1\", \"owner\": \"13mksMX1JTutHNZgA9zVH8yA4bZKBgRW9rwPrhzspRGX2zNZbw1\", \"address\": \"112hiMD27kd5vT7QpVHLit1C1DjN2yrGvMN1srcNQgyyuWNjDWZN\", \"stake_amount\": 1000000000000, \"owner_signature\": \"mLLH-22Cq33sey8ByQ9UCyXOmRtIAt0OKGT1nXy2yHpsKkoUi60npzexzw4rvqaR8ffs9jLaskx1cxtenP7FCg\", \"stake_release_height\": 1492156}","Time":"2022-02-25T09:16:33-05:00"}, +{"Block":1248888,"Hash":"ySXXsHtZHLo15khyfkEhvVOYGxXb_fT_odQRz3XsLq0","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"ySXXsHtZHLo15khyfkEhvVOYGxXb_fT_odQRz3XsLq0\", \"type\": \"unstake_validator_v1\", \"owner\": \"14NvSPHti6K32U6Lven9XMkPEusRfog8jYtUACgm3hqgaPenwyY\", \"address\": \"11wX5Kp7Qskg7gbFDzmVrnNTuNhEXkFqEXKdHWGstfhAW6fEYXs\", \"stake_amount\": 1000000000000, \"owner_signature\": \"1qKDaoX-zSXe-cMBjZX5rty2dJg6mLJdzpAucpJt5gDFupfmqXgMigWBKM1_6EQgLAWHkKFn4M_eVH5XQp6xDw\", \"stake_release_height\": 1498909}","Time":"2022-03-01T19:18:29-05:00"}, +{"Block":1253015,"Hash":"LmEWy_z3yHFfmtxXohCystYGi8Fs90is94R--JQBUzk","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"LmEWy_z3yHFfmtxXohCystYGi8Fs90is94R--JQBUzk\", \"type\": \"unstake_validator_v1\", \"owner\": \"14MFM9WzVg5V7a5PUDcUq6ZfxGPiQRHtBpjwiqKoov54hJCUE9v\", \"address\": \"112o1rf3pB8qxCM5EHun3yc3UCqRrqcEKNaXDc6YH1VvCYaTZgHU\", \"stake_amount\": 1000000000000, \"owner_signature\": \"9u_I4uYlB9cjc1AurCtFxCTIx_lvs2aRuv3z41RQ8pxRxZD6zpvCQLh0phPDMrwQvsxqfJw3wpHfNm-Kgp8tDg\", \"stake_release_height\": 1503041}","Time":"2022-03-04T16:08:53-05:00"} ] \ No newline at end of file diff --git a/helium/middleware.go b/helium/middleware.go index c5172cf..ec3a071 100644 --- a/helium/middleware.go +++ b/helium/middleware.go @@ -72,30 +72,8 @@ type GetGatewayOwnerResponse struct { func GetCurrentHeight() (*int64, *types.Error) { var result int64 - - if NodeBalancesDB != nil { - balancesHeight, bErr := RocksDBBalancesHeightGet() - if bErr != nil { - return nil, WrapErr(ErrUnclearIntent, bErr) - } - - transactionHeight, tErr := RocksDBTransactionsHeightGet() - if tErr != nil { - return nil, WrapErr(ErrUnclearIntent, tErr) - } - - zap.S().Info("balance height: " + fmt.Sprint(*balancesHeight) + " transaction height: " + fmt.Sprint(*transactionHeight)) - - if *balancesHeight > *transactionHeight { - result = *transactionHeight - } else { - result = *balancesHeight - } - - } else { - if err := NodeClient.CallFor(&result, "block_height", nil); err != nil { - return nil, WrapErr(ErrUnclearIntent, errors.New("error getting block_height")) - } + if err := NodeClient.CallFor(&result, "block_height", nil); err != nil { + return nil, WrapErr(ErrUnclearIntent, errors.New("error getting block_height")) } return &result, nil @@ -176,23 +154,37 @@ func GetBlockIdentifier(blockIdentifier *types.PartialBlockIdentifier) (*types.B } } - callResult, err := utils.DecodeCallAsNumber(NodeClient.Call("block_get", req)) - jsonResult, _ := json.Marshal(callResult) - json.Unmarshal(jsonResult, &result) + if NodeBlocksDB != nil { + blockHash, bhErr := RocksDBBlockHashGet(*blockIdentifier.Index) + if bhErr != nil { + return nil, WrapErr(ErrFailed, bhErr) + } - if err != nil { - return nil, WrapErr( - ErrFailed, - err, - ) - } + identifier := &types.BlockIdentifier{ + Index: *blockIdentifier.Index, + Hash: *blockHash, + } - identifier := &types.BlockIdentifier{ - Index: result.Height, - Hash: result.Hash, - } + return identifier, nil + } else { + callResult, err := utils.DecodeCallAsNumber(NodeClient.Call("block_get", req)) + jsonResult, _ := json.Marshal(callResult) + json.Unmarshal(jsonResult, &result) + + if err != nil { + return nil, WrapErr( + ErrFailed, + err, + ) + } - return identifier, nil + identifier := &types.BlockIdentifier{ + Index: result.Height, + Hash: result.Hash, + } + + return identifier, nil + } } func GetBlockMeta(blockIdentifier *types.PartialBlockIdentifier) (*Block, *types.Error) { diff --git a/helium/op_processor.go b/helium/op_processor.go index 435e0d6..8660348 100644 --- a/helium/op_processor.go +++ b/helium/op_processor.go @@ -207,7 +207,7 @@ func TransactionToOps(txn map[string]interface{}, status string, block *types.Bl } return FeeOnlyTxn( TransferHotspotOp, - fmt.Sprint(txn["new_owner"]), + fmt.Sprint(txn["owner"]), fmt.Sprint(txn["new_owner"]), feeDetails, txn, diff --git a/helium/rocksdb.go b/helium/rocksdb.go index 007f023..c5b947a 100644 --- a/helium/rocksdb.go +++ b/helium/rocksdb.go @@ -12,7 +12,6 @@ import ( "github.com/helium/rosetta-helium/utils" rocksdb "github.com/linxGnu/grocksdb" "github.com/okeuday/erlang_go/v2/erlang" - "go.uber.org/zap" ) type Entry struct { @@ -96,21 +95,6 @@ func RocksDBTransactionsHeightGet() (*int64, error) { return &height, nil } -func RocksDBBalancesHeightGet() (*int64, error) { - ro := rocksdb.NewDefaultReadOptions() - - heightBin, hErr := NodeBalancesDB.GetCF(ro, NodeBalancesDBDefaultHandle, heightKeyBinary) - if hErr != nil { - return nil, hErr - } - - zap.S().Info(fmt.Sprint(heightBin)) - - height := int64(binary.LittleEndian.Uint64(heightBin.Data())) - - return &height, nil -} - func RocksDBAccountGet(address string, height int64) (*AccountEntry, error) { addressBin, abErr := addressToBinary(address) if abErr != nil { @@ -124,6 +108,8 @@ func RocksDBAccountGet(address string, height int64) (*AccountEntry, error) { key := append(addressBin, heightBin...) + // zap.S().Info("key searched: " + fmt.Sprint(key)) + readOptions := rocksdb.NewDefaultReadOptions() readOptions.SetFillCache(false) readOptions.SetTotalOrderSeek(true) @@ -132,6 +118,8 @@ func RocksDBAccountGet(address string, height int64) (*AccountEntry, error) { iterator.SeekForPrev(key) if iterator.ValidForPrefix(addressBin) { + // zap.S().Info("key retrieved: " + fmt.Sprint(int64(binary.BigEndian.Uint64(iterator.Key().Data()[33:41])))) + accountEntryBin := iterator.Value() accountEntryTuple, bErr := erlang.BinaryToTerm(accountEntryBin.Data()) if bErr != nil { diff --git a/main.go b/main.go index 21d59b3..c5c468b 100644 --- a/main.go +++ b/main.go @@ -49,7 +49,6 @@ type HeliumRocksDB struct { TransactionsDB *rocksdb.DB BlockchainDB *rocksdb.DB EntriesCF *rocksdb.ColumnFamilyHandle - BalancesDefaultCF *rocksdb.ColumnFamilyHandle HeightsCF *rocksdb.ColumnFamilyHandle TransactionsDefaultCF *rocksdb.ColumnFamilyHandle } @@ -206,7 +205,6 @@ func openRocksDB(dataDir string) (heliumDB *HeliumRocksDB, err error) { TransactionsDB: dbTxn, BlockchainDB: dbBlock, EntriesCF: balancesCfHandles[1], - BalancesDefaultCF: balancesCfHandles[0], HeightsCF: blockchainCfHandles[1], TransactionsDefaultCF: txnCfHandles[0], }, nil @@ -286,9 +284,8 @@ func main() { zap.S().Info("Loaded rocksdb directly at dir '" + blockchainNodeDataDir + "'") helium.NodeBalancesDB = heliumDB.BalancesDB helium.NodeBlocksDB = heliumDB.BlockchainDB - helium.NodeTransactionsDB = heliumDB.BlockchainDB + helium.NodeTransactionsDB = heliumDB.TransactionsDB helium.NodeBalancesDBEntriesHandle = heliumDB.EntriesCF - helium.NodeBalancesDBDefaultHandle = heliumDB.BalancesDefaultCF helium.NodeBlockchainDBHeightsHandle = heliumDB.HeightsCF helium.NodeTransactionsDBDefaultHandle = heliumDB.TransactionsDefaultCF break diff --git a/rosetta-cli-config/mainnet/config.json b/rosetta-cli-config/mainnet/config.json index 8531da1..3667e9b 100644 --- a/rosetta-cli-config/mainnet/config.json +++ b/rosetta-cli-config/mainnet/config.json @@ -9,7 +9,7 @@ "tip_delay": 1200, "max_retries": 10, "data": { - "start_index": 1259282, + "start_index": 1267922, "historical_balance_enabled": true, "end_conditions": { "reconciliation_coverage": { diff --git a/services/account_service.go b/services/account_service.go index 65cf9d7..af7ee8c 100644 --- a/services/account_service.go +++ b/services/account_service.go @@ -47,8 +47,6 @@ func (s *AccountAPIService) AccountBalance( Address: request.AccountIdentifier.Address, } - zap.S().Info(request.AccountIdentifier.Address + " " + fmt.Sprint(*request.BlockIdentifier.Index)) - if request.BlockIdentifier != nil { if request.BlockIdentifier.Index == nil { return nil, helium.WrapErr( @@ -59,9 +57,36 @@ func (s *AccountAPIService) AccountBalance( balanceRequest.Height = *request.BlockIdentifier.Index } + var blockId types.BlockIdentifier + + if request.BlockIdentifier == nil { + currentHeight, chErr := helium.GetCurrentHeight() + if chErr != nil { + return nil, chErr + } + + currentBlock, cErr := helium.GetBlockIdentifier(&types.PartialBlockIdentifier{ + Index: currentHeight, + }) + if cErr != nil { + return nil, cErr + } + + blockId = *currentBlock + } else { + requestedBlock, rErr := helium.GetBlockIdentifier(&types.PartialBlockIdentifier{ + Index: request.BlockIdentifier.Index, + }) + if rErr != nil { + return nil, rErr + } + + blockId = *requestedBlock + } + if helium.NodeBalancesDB != nil { var accountBalances []*types.Amount - accountEntry, aeErr := helium.RocksDBAccountGet(request.AccountIdentifier.Address, balanceRequest.Height) + accountEntry, aeErr := helium.RocksDBAccountGet(request.AccountIdentifier.Address, blockId.Index) if aeErr != nil { zap.S().Info("no balance found for " + balanceRequest.Address + " at height " + fmt.Sprint(balanceRequest.Height) + ". Returning balanaces of 0.") accountBalances = []*types.Amount{ @@ -87,13 +112,13 @@ func (s *AccountAPIService) AccountBalance( } } - blockHash, bhErr := helium.RocksDBBlockHashGet(*request.BlockIdentifier.Index) + blockHash, bhErr := helium.RocksDBBlockHashGet(blockId.Index) if bhErr != nil { return nil, helium.WrapErr(helium.ErrFailed, bhErr) } blockIdentifier := &types.BlockIdentifier{ - Index: *request.BlockIdentifier.Index, + Index: blockId.Index, Hash: *blockHash, } @@ -118,33 +143,6 @@ func (s *AccountAPIService) AccountBalance( } } - var blockId types.BlockIdentifier - - if request.BlockIdentifier == nil { - currentHeight, chErr := helium.GetCurrentHeight() - if chErr != nil { - return nil, chErr - } - - currentBlock, cErr := helium.GetBlockIdentifier(&types.PartialBlockIdentifier{ - Index: currentHeight, - }) - if cErr != nil { - return nil, cErr - } - - blockId = *currentBlock - } else { - requestedBlock, rErr := helium.GetBlockIdentifier(&types.PartialBlockIdentifier{ - Index: request.BlockIdentifier.Index, - }) - if rErr != nil { - return nil, rErr - } - - blockId = *requestedBlock - } - return &types.AccountBalanceResponse{ BlockIdentifier: &blockId, Balances: accountBalances, diff --git a/services/network_service.go b/services/network_service.go index 7eb652d..1e0cb82 100644 --- a/services/network_service.go +++ b/services/network_service.go @@ -53,6 +53,20 @@ func (s *NetworkAPIService) NetworkStatus( ctx context.Context, request *types.NetworkRequest, ) (*types.NetworkStatusResponse, *types.Error) { + + // Update all secondary rocksdb references during network status updates + if tErr := helium.NodeBalancesDB.TryCatchUpWithPrimary(); tErr != nil { + return nil, helium.WrapErr(helium.ErrFailed, tErr) + } + + if tErr := helium.NodeBlocksDB.TryCatchUpWithPrimary(); tErr != nil { + return nil, helium.WrapErr(helium.ErrFailed, tErr) + } + + if tErr := helium.NodeTransactionsDB.TryCatchUpWithPrimary(); tErr != nil { + return nil, helium.WrapErr(helium.ErrFailed, tErr) + } + currentHeight, chErr := helium.GetCurrentHeight() if chErr != nil { return nil, chErr From 547de9d6857039b9094c6719d85bb9d21d04d580 Mon Sep 17 00:00:00 2001 From: Steven Yuan Date: Wed, 16 Mar 2022 05:07:03 +0000 Subject: [PATCH 18/19] config --- rosetta-cli-config/mainnet/config_easy.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rosetta-cli-config/mainnet/config_easy.json b/rosetta-cli-config/mainnet/config_easy.json index 9c87c70..13c4c6f 100644 --- a/rosetta-cli-config/mainnet/config_easy.json +++ b/rosetta-cli-config/mainnet/config_easy.json @@ -18,7 +18,7 @@ } }, "data": { - "start_index": 1108082, + "start_index": 1267922, "reconciliation_disabled": true, "inactive_discrepency_search_disabled": true, "balance_tracking_disabled": true, From 150fad16d7339a1c0f6de5a7aacb64b0452d913b Mon Sep 17 00:00:00 2001 From: Steven Yuan Date: Thu, 28 Apr 2022 15:50:03 +0000 Subject: [PATCH 19/19] WIP optimizations --- docker/mainnet.sh | 2 +- .../mainnet/{1267921.json => 1329841.json} | 65 ++++++++++++++++++- helium/errors.go | 11 +++- helium/middleware.go | 18 +++-- helium/rocksdb.go | 42 +++++++++++- helium/types.go | 4 ++ main.go | 9 ++- rosetta-cli-config/mainnet/config.json | 7 +- services/account_service.go | 20 ++++++ services/block_service.go | 18 +++++ services/network_service.go | 2 +- 11 files changed, 182 insertions(+), 16 deletions(-) rename ghost-transactions/mainnet/{1267921.json => 1329841.json} (68%) diff --git a/docker/mainnet.sh b/docker/mainnet.sh index 52c35b7..8fb8582 100644 --- a/docker/mainnet.sh +++ b/docker/mainnet.sh @@ -2,7 +2,7 @@ set -euo pipefail -echo '1267922' > /app/lbs.txt & +echo '1259282' > /app/lbs.txt & /opt/blockchain_node/bin/blockchain_node foreground & /app/rosetta-helium --data="/data" & diff --git a/ghost-transactions/mainnet/1267921.json b/ghost-transactions/mainnet/1329841.json similarity index 68% rename from ghost-transactions/mainnet/1267921.json rename to ghost-transactions/mainnet/1329841.json index 4a03b5e..d3714f4 100644 --- a/ghost-transactions/mainnet/1267921.json +++ b/ghost-transactions/mainnet/1329841.json @@ -12,7 +12,16 @@ {"Block":1150629,"Hash":"G4VCOOzIJffBn3_ecEj5QzqWXSpmKzvPWVg5rob43oc","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"G4VCOOzIJffBn3_ecEj5QzqWXSpmKzvPWVg5rob43oc\", \"type\": \"unstake_validator_v1\", \"owner\": \"13vAncddhhsEgeHznUtfM5zYiGQozS11rMvp1ad3WsUYEyU7KoU\", \"address\": \"112eoqVMVuYRTFrT9yZyjw67eTWR8o1mdKxYvo9qn57uWx55kAin\", \"stake_amount\": 1000000000000, \"owner_signature\": \"BcI7MQxUhHv4XpfD4qgPhhFh2Oy05AWxrqLNh2DbDplMmpchv9R6DS7hPKupVJrlTYeYN2jDW4RscGtKdto0AA\", \"stake_release_height\": 1400635}","Time":"2021-12-23T07:07:10-05:00"}, {"Block":1184435,"Hash":"RMXovClP05Jnb4iurKek78HMNsoO8Bj2f1ycFf_S6tw","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"RMXovClP05Jnb4iurKek78HMNsoO8Bj2f1ycFf_S6tw\", \"type\": \"unstake_validator_v1\", \"owner\": \"13YjqdzC1tPDyVE25YnjfzoaDnTjmroaqKVzciLPSGgMuT1VWNX\", \"address\": \"14X7JsJkH2pxntupHtap2SUyFBqw2R7JLNzqpNkkKXjmNft9ti5\", \"stake_amount\": 1000000000000, \"owner_signature\": \"YbPzqxeMEg_3dDYtCTwHe3BrFma66MV996hSo9rluinJSFuFpmH9qwkc-s-6hyjYxDCzNoipTJBywJraWPSKCw\", \"stake_release_height\": 1434454}","Time":"2022-01-16T16:50:46-05:00"}, {"Block":1184436,"Hash":"fIVEuqz1JbQ1Bsfz2H-Lob0q4QzXvxq3Nj-LXxhCgKI","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"fIVEuqz1JbQ1Bsfz2H-Lob0q4QzXvxq3Nj-LXxhCgKI\", \"type\": \"unstake_validator_v1\", \"owner\": \"13YjqdzC1tPDyVE25YnjfzoaDnTjmroaqKVzciLPSGgMuT1VWNX\", \"address\": \"13EXp7rNBEWNnuXMt1LkZ8j8U4SQofT4vccuTnUDbW87XND5tRt\", \"stake_amount\": 1000000000000, \"owner_signature\": \"-i7OpsT3w06_ornclAF06Gjhig9gLDWo39tic99LjbjHCvQ65GJWSRpcMxVarr_iQ27WH7SLNF7ogur2KVCuBA\", \"stake_release_height\": 1434454}","Time":"2022-01-16T16:51:36-05:00"}, +{"Block":1279801,"Hash":"MiJYRbhCc0-_rtQumHAQN12GKrR_g76mlViREw9zbu8","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"MiJYRbhCc0-_rtQumHAQN12GKrR_g76mlViREw9zbu8\", \"type\": \"unstake_validator_v1\", \"owner\": \"14dgGv2ZSYzGGFRi8f5PNV3uehCrsqzwdGJR1qpmwrLPQFp2UWW\", \"address\": \"14963G2Z4ZNL8ujrpR2ytkXqq4AM3vzeHQkbHERDKKWWbsLbYyM\", \"stake_amount\": 1000000000000, \"owner_signature\": \"AxKDAZgkKdXDCXQjl3gjXhBLCWgidJM3zczvxbiGSGvsl6P2ChKb9o5q2aLqcisXi4Q9shxAAEuxaiubHVk6Dg\", \"stake_release_height\": 1529814}","Time":"2022-03-24T04:51:49-04:00"}, {"Block":1228768,"Hash":"jZYijpnCgzivwoimAI2T-VN6O2yQEsInAJ3AbkPPAH8","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"jZYijpnCgzivwoimAI2T-VN6O2yQEsInAJ3AbkPPAH8\", \"type\": \"unstake_validator_v1\", \"owner\": \"14iFzQ429bvb8gFuwcwjdutbxQMGU1d18q1Wu6WFMegP7P1Ycu2\", \"address\": \"13Qx7G1dyvqp9ZoSFgSNmQCooTKzwt9hQVN4TST24fGW7PP4c6q\", \"stake_amount\": 1000000000000, \"owner_signature\": \"QFkXRCUrvsjgi8X4Df_q31zOh1RL8dBX2wqFBDEL-HTARy7ggeLAe-4a21L1WAt6HzNHyor8VhNWvfJKomIzAw\", \"stake_release_height\": 1478782}","Time":"2022-02-16T17:47:34-05:00"}, +{"Block":1275306,"Hash":"OBCxkvHOUQJyu9cpuyrXUK70mL0_YLh5x8TYTa6vMDA","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"OBCxkvHOUQJyu9cpuyrXUK70mL0_YLh5x8TYTa6vMDA\", \"type\": \"unstake_validator_v1\", \"owner\": \"14StHhMRZ2bMB3BNbnrQGP4PjQzybiBrwy9PAcH5orq3JjAWRWi\", \"address\": \"13n2mjrf6gLEMpRaokvuShhqUYGk9cWVWfVkA63ZbogkmX44ccY\", \"stake_amount\": 1000000000000, \"owner_signature\": \"vCqigX5sUxPPtUS8cL6shZwNvhQpBPc-mizJb2CECx-KOaz20tlnQ1O6xzsHyNmbcw9Tpt9ETNi43ZkiDV_tAA\", \"stake_release_height\": 1525326}","Time":"2022-03-21T06:10:14-04:00"}, +{"Block":1275318,"Hash":"Pf0iciQp2hP_j49NqGXbN9uveovOrUUA-o7f_M19QRs","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"Pf0iciQp2hP_j49NqGXbN9uveovOrUUA-o7f_M19QRs\", \"type\": \"unstake_validator_v1\", \"owner\": \"14qbcDkA9uWY9xk1evvwH2MdfZ9YzF5jtQziHBjyVsf2GnRUJNb\", \"address\": \"13QbYt6hW1X99DV9eSBeHk3JCArqvX8DAqVQCwERxUpEkEH7m36\", \"stake_amount\": 1000000000000, \"owner_signature\": \"4LiobjLQCvLpPZOSi9bW0PMaH4eAWKYgdOpr9x7mkaR9cX-nOmiLQ9U0l6SjAPUcT0pDP0MNwWOhg5ddyj5CCA\", \"stake_release_height\": 1525326}","Time":"2022-03-21T06:23:09-04:00"}, +{"Block":1279767,"Hash":"1GYyFxY2GAa2CykWBMvHpveAd_0rgxHLJpzDVl-p61M","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"1GYyFxY2GAa2CykWBMvHpveAd_0rgxHLJpzDVl-p61M\", \"type\": \"unstake_validator_v1\", \"owner\": \"14StHhMRZ2bMB3BNbnrQGP4PjQzybiBrwy9PAcH5orq3JjAWRWi\", \"address\": \"1497fviDPAmBSck3UaF9vRaUx8iGGGnEuowpxR2erHbjqBANk38\", \"stake_amount\": 1000000000000, \"owner_signature\": \"Ic6vWe91VuyzNvxpcILUJTCWgAi1WRV6wyUj9SDn_G8AlWfZFZe8SZPKPSOlXLx1wzaSVeInA1o2dopfeIeIDQ\", \"stake_release_height\": 1529777}","Time":"2022-03-24T04:20:48-04:00"}, +{"Block":1289609,"Hash":"bsnB13dK9gOdcjyg16yYlcbCH27rEhsPXwn21-efiZk","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"bsnB13dK9gOdcjyg16yYlcbCH27rEhsPXwn21-efiZk\", \"type\": \"unstake_validator_v1\", \"owner\": \"13YozYcGpJNK2gPTRd5PnMk1BnFskHHgHM9rb5ayQi5tBPE9eCm\", \"address\": \"12xsBbGjW1UovqzmTVGMYFqpZ7JzCoWBFwysUyvezPzbPuDwWZ1\", \"stake_amount\": 1000000000000, \"owner_signature\": \"mQg6ELekIaidOKzpHjtr6H18fsZuthOWKGJR95qOXs0drXdpeTedSLBr5YstcfZ9jco9eZp98_51QMSMe8nrCQ\", \"stake_release_height\": 1539630}","Time":"2022-03-30T11:45:09-04:00"}, +{"Block":1289614,"Hash":"NeDxzFGqr5qD-AM3ZDfkfmOAb37Qpur8P1ncKXCqb7c","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"NeDxzFGqr5qD-AM3ZDfkfmOAb37Qpur8P1ncKXCqb7c\", \"type\": \"unstake_validator_v1\", \"owner\": \"14iKMEN15SRA7p1xCEjhcVTERozMVPTaWAUFtVhUnZDnXJE8unc\", \"address\": \"14NsgT8szQcdMCyqqq61xGrdheSBA5cevuTTVKsEVc52otn2jLN\", \"stake_amount\": 1000000000000, \"owner_signature\": \"PMaqm-iaMsDovvuJLyutm5QkQFS7nAmg3WP0DPnZ3xK3nh4LSq7uUlKQXtfVRttJyePw1zr_gmeN08cb42Q1Dg\", \"stake_release_height\": 1539630}","Time":"2022-03-30T11:49:19-04:00"}, +{"Block":1289616,"Hash":"7kyl4lIddl8EsJ6TMUnKAczQ5eJoaS0TgwM6grXxxR8","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"7kyl4lIddl8EsJ6TMUnKAczQ5eJoaS0TgwM6grXxxR8\", \"type\": \"unstake_validator_v1\", \"owner\": \"14iKMEN15SRA7p1xCEjhcVTERozMVPTaWAUFtVhUnZDnXJE8unc\", \"address\": \"13LVJz2qbvttuZkVHwZPXFUtz2njDyRDcgmUPzDrtMrSyw6opSJ\", \"stake_amount\": 1000000000000, \"owner_signature\": \"A8heLajawmmaF2SjbfKp7VGIoyrAhI1VqN2GkScPH_YTqdBZFh5EMQEj1dxr_cEPQYsF4q6C3iAvM4_zl-pJAg\", \"stake_release_height\": 1539630}","Time":"2022-03-30T11:51:00-04:00"}, +{"Block":1304651,"Hash":"6b2oGajR_uoUMghKbylJ9YuR89jLPTPzMd_TEkQJx1M","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"6b2oGajR_uoUMghKbylJ9YuR89jLPTPzMd_TEkQJx1M\", \"type\": \"unstake_validator_v1\", \"owner\": \"14pa5EzLaGzZLvqHhHtEnQcATd3aQ5aHs1dsgRn2HkPXx5RDjn8\", \"address\": \"11ZxVnSyzwVNkcNxPzmnJYBygirZFrknmtgL9qRjoqyNMSFpTe3\", \"stake_amount\": 1000000000000, \"owner_signature\": \"4xQEQuCiHQqGLCFDwaU1c7YZXe-HQSVPMyV1aI4sQs4uB-WkG2jqmS3vRkdiUgxsAkGQ_o0jqFHZpIf5zjC6CA\", \"stake_release_height\": 1554704}","Time":"2022-04-09T13:35:57-04:00"}, +{"Block":1310996,"Hash":"N-9vqKDe2ZyYnOEejieE3BEtC9dHyN7uabJT8zqn8H4","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"N-9vqKDe2ZyYnOEejieE3BEtC9dHyN7uabJT8zqn8H4\", \"type\": \"unstake_validator_v1\", \"owner\": \"14qbcDkA9uWY9xk1evvwH2MdfZ9YzF5jtQziHBjyVsf2GnRUJNb\", \"address\": \"13Q2yaeYRKNRP6SYxHv13u7jQqdK5BNxPPuh68mGRgDrbn1fMsb\", \"stake_amount\": 1000000000000, \"owner_signature\": \"FNvwwAdKh2zunH5jmN1vuG9Sq_cPGZP1pTJqdqYW_d2dd7wvSNtyjVcGGoy9KPjzH_feuQ_24SgAT-yPfd2nBQ\", \"stake_release_height\": 1561014}","Time":"2022-04-14T03:04:58-04:00"}, {"Block":960405,"Hash":"P4vjS7HDbBWQ1dUWDB36htTgBk9GmxPOH8SiqYvDxnQ","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"P4vjS7HDbBWQ1dUWDB36htTgBk9GmxPOH8SiqYvDxnQ\", \"type\": \"unstake_validator_v1\", \"owner\": \"12xoVMjaduyZm1bw1GEBXoQe6YHCfU5gghcuobQ5weopZ8as3qw\", \"address\": \"112LWrY91t5xEZ4ChoehMQBTVBZk8QKrnhZatKQbPTLM3c67R3CZ\", \"stake_amount\": 1000000000000, \"owner_signature\": \"blk_dAVf8XX_JcrvNXJ8Jjm_WqlU58ccrjZ431PMZIucq7jv76tlJbjzpJJ2qoEabXdYOqp2wHhKcGT9AhzRDQ\", \"stake_release_height\": 1210420}","Time":"2021-08-11T01:46:59-04:00"}, {"Block":980401,"Hash":"1MLDABvC7R_jyNUrDEmaB7U1pdyvQyUL9XQTERlSNg0","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"1MLDABvC7R_jyNUrDEmaB7U1pdyvQyUL9XQTERlSNg0\", \"type\": \"unstake_validator_v1\", \"owner\": \"13z7iDxBz6NuCDXBJm573kBqS7vDcKMzN3NscQndrvDLCCJKNMd\", \"address\": \"112cMXhHGQfyrc3mkfPvczg5qfSgGod2EgQCwEzMSxRDjouVQp3A\", \"stake_amount\": 1000000000000, \"owner_signature\": \"fJQbWBx8FE0jUfHN4pvQKvPDJe9YN_gI25Ox6pwWLdS8HGhMx8lbIkoBpkdp1qELSaZmLctVXe2L5LO9j0w5Dw\", \"stake_release_height\": 1230420}","Time":"2021-08-24T15:33:00-04:00"}, {"Block":1005224,"Hash":"nKn8B-2pHiLtL-EadB1niqd5gCQsQk5C0BUc4StXciI","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"nKn8B-2pHiLtL-EadB1niqd5gCQsQk5C0BUc4StXciI\", \"type\": \"unstake_validator_v1\", \"owner\": \"141WsikcrSo8tugixuLN5QTfzzLbm757UKd556iSx16sfq127ey\", \"address\": \"112E2kYMHdw6jqWFZ4Hc1CfJBx765B441ByLWAe7hQKDvzKwkV13\", \"stake_amount\": 1000000000000, \"owner_signature\": \"WKL3M-MDCLXLTduVN1wpWtGvFRImi16NXMmgmBue5r_3NOyD95RiPGytu6SUglZEChsaz1ey1vFyPVYTyo6oDA\", \"stake_release_height\": 1255236}","Time":"2021-09-10T11:38:38-04:00"}, @@ -28,6 +37,11 @@ {"Block":1187448,"Hash":"83Q8h-ERMwrhHRmlQc3GTftdB-I5lMuIkxoYKIANCUw","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"83Q8h-ERMwrhHRmlQc3GTftdB-I5lMuIkxoYKIANCUw\", \"type\": \"unstake_validator_v1\", \"owner\": \"14J6zntifsPAbiPxHYhyK7zV5ZdtKm3DiiZUVNRCe4NS9kEbGKT\", \"address\": \"116tGvUzhrF4de99R4WtSjEzC4KUYhmoDB3d3LBP1KWh4ywN8jr\", \"stake_amount\": 1000000000000, \"owner_signature\": \"QqzaLK0I6hgFAv-gR-hoq_002qCsizdOf8Bzzy1cVdogPVpaEr_q8MJ9GsqepTn99TQLkwOpKwXKdswSmR9-Aw\", \"stake_release_height\": 1437461}","Time":"2022-01-18T15:32:29-05:00"}, {"Block":1204193,"Hash":"MMNRcZ6Cwz6i9JxzAt-3S-Muox6avUK2LhXPAVXq5Tk","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"MMNRcZ6Cwz6i9JxzAt-3S-Muox6avUK2LhXPAVXq5Tk\", \"type\": \"unstake_validator_v1\", \"owner\": \"13XwyG3nRs7u8BHjFHpfquNNmQi4EpuyhbMVTBP2yNzUvLKJNYi\", \"address\": \"112uXKVQwo2fxmcmp6zBMYiKHXyevUuBnjXjwFAZVYWofpLcBiza\", \"stake_amount\": 1000000000000, \"owner_signature\": \"0D1UphyulqwMYt4iKozLl_EsXm9YZY9W7YBllXqV8SheIuob34RO40RYXLPM84PJSqdcESyVlh3AAFF4X9gGCw\", \"stake_release_height\": 1454195}","Time":"2022-01-29T19:41:26-05:00"}, {"Block":1205593,"Hash":"dDaHd1YJUUtyHhdea7Yp7b6zXQ0gEVIecnT_kpbkARw","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"dDaHd1YJUUtyHhdea7Yp7b6zXQ0gEVIecnT_kpbkARw\", \"type\": \"unstake_validator_v1\", \"owner\": \"14PNnDMq6EnG9kXGPeH3DiBKT5akZ89AmEGzUesTaX1SdLbNpfT\", \"address\": \"11CLUNS5fqLkFvbWHuxk1oRZx5o6xh68PcFjfTADkh3zWTmD2Ah\", \"stake_amount\": 1000000000000, \"owner_signature\": \"7WQHoMa3SJOUmcFnvcPii6rlelRcR3Ge7QXIRRLu57ceGJAdokE8Gm5zYUpu8kwkwblCeOtowCJ-8qvvbZPOCA\", \"stake_release_height\": 1455610}","Time":"2022-01-30T20:29:02-05:00"}, +{"Block":1280769,"Hash":"v4BaNNKEziyzyta0AhTSs-qIJCv-5PJV0Pnt1u6A2Rk","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"v4BaNNKEziyzyta0AhTSs-qIJCv-5PJV0Pnt1u6A2Rk\", \"type\": \"unstake_validator_v1\", \"owner\": \"14o8tvMzXHLvdokf7iS9L6sx67eEjkHrj9xEGiMVhZLQEpYxqny\", \"address\": \"13xhTvtw9bFKgN6zbzKXVptuXzs1cb1bJFjaLP3oWLULviAjktM\", \"stake_amount\": 1000000000000, \"owner_signature\": \"Ih2PHMF6tsUfKf4mSLfnb1VcG5RQmtYM5X9uRNCxQTSSaAOW7n4r609W6zny6Z5l8SBLfSqCn9wvJG6BxEAKCg\", \"stake_release_height\": 1530779}","Time":"2022-03-24T20:07:19-04:00"}, +{"Block":1286927,"Hash":"XKTF2MiGNZHjOgeeevvpWcuFcbCnEcfCC7gBFyDKlX4","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"XKTF2MiGNZHjOgeeevvpWcuFcbCnEcfCC7gBFyDKlX4\", \"type\": \"unstake_validator_v1\", \"owner\": \"13LBsi3N9m1um5d3xqrd6AU3AJxbkyCX47HRTgzKET6TRSHzCcn\", \"address\": \"134gWTg4UxGScmPhHu1ccJNEP4rKaChuAAUwSm8pFXgVTq8hpbx\", \"stake_amount\": 1000000000000, \"owner_signature\": \"2kV4e3SaXYwDcw7MKjV63wjaJZZ8s6_LxVLLBhjL-qXtuiWweCtI2ofd8gCd8E9-32CTCKdjoU8T1C7TosvJBA\", \"stake_release_height\": 1536928}","Time":"2022-03-28T19:10:19-04:00"}, +{"Block":1291394,"Hash":"qAJKrzbRwb27_NlIeNHEMlhhnzhWToU3a4yac44Wc_A","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"qAJKrzbRwb27_NlIeNHEMlhhnzhWToU3a4yac44Wc_A\", \"type\": \"unstake_validator_v1\", \"owner\": \"136nSZ4niPtQNLqgVKi2uj5KVBw363vnjTciBYkv1LcVvda7fgP\", \"address\": \"118uHWzqZLN5Q4WL8AFank9Gzoo7xwdb9fKVDVVGRF9hEAQJXuC\", \"stake_amount\": 1000000000000, \"owner_signature\": \"cEQFG34m3JR7oVjBH7w4eiVovw1FeTmSi2L1bpjKFCck2MJBYVsJJOLMGHxaEZX4xDWJXZzNEM_XgfYGscT8CQ\", \"stake_release_height\": 1541400}","Time":"2022-03-31T14:46:23-04:00"}, +{"Block":1292633,"Hash":"NoBIwCUZuAgSzRmqbssvi6VySwcZAIIPa_GDA1sXbTk","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"NoBIwCUZuAgSzRmqbssvi6VySwcZAIIPa_GDA1sXbTk\", \"type\": \"unstake_validator_v1\", \"owner\": \"14eHET8js1X7oCL1GpcMr5A1Hwkkhd4v9nc4yE4eyVusmvAtwYo\", \"address\": \"112nxiJrFFAPrH2TUq9b62sLsE86MJwfoPFSG7fULHMihiKbRY94\", \"stake_amount\": 1000000000000, \"owner_signature\": \"otMhlLnv2fns-8CsGlnAFnru3UBD1kSQv7wWCw8hKJQBDuQ1RJ330_B52rEpiOSX8RYF3gEvRk8LliSmU1TsCA\", \"stake_release_height\": 1542682}","Time":"2022-04-01T10:10:46-04:00"}, +{"Block":1327657,"Hash":"C1Xzpq84ha3Dv1T1_shuOXDAe-RXUNIQ52nScHSONlM","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"C1Xzpq84ha3Dv1T1_shuOXDAe-RXUNIQ52nScHSONlM\", \"type\": \"unstake_validator_v1\", \"owner\": \"13DR9qoGAw7yDvhQpBEzsnwEWXsM2h7NDP7ZGTaJaceCC4zJDpv\", \"address\": \"112Dp9ihQX5bS3jV3KhN3orDv4H1YhbxnYXh8PfP9dPNr2Kg7mDE\", \"stake_amount\": 1000000000000, \"owner_signature\": \"JaBRlhq-H-bNHJGV7cDbQBfTuLR7wWE3xIGRY5S2lWZNOFINH8N84R_oMM9bmUMA1RSdwRsrX7xmDQjlLpQYBw\", \"stake_release_height\": 1577711}","Time":"2022-04-25T20:15:25-04:00"}, {"Block":912024,"Hash":"fMT-7_f2WQNKAYIQWX2-V258KsoI61HYbt_zAbN3A1I","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"fMT-7_f2WQNKAYIQWX2-V258KsoI61HYbt_zAbN3A1I\", \"type\": \"unstake_validator_v1\", \"owner\": \"13Yet3BKcwpanUMFE4botQp4ZQwkDJeNzKdCMMoMot4fsQLEN4n\", \"address\": \"11cY9Ly5H3hU4Ai2k7G9niHLAxsKb1ragQYGLJ7E9vh4Vnx6Efb\", \"stake_amount\": 1000000000000, \"owner_signature\": \"M17f8dT1YkLjZwZwayasX3wsZg8wPXoR3a7sGja0Ds6zEVBiRxfsTFE6Qo7gL7bbAizHDZC6N2s1rF5eO_mWCg\", \"stake_release_height\": 1162029}","Time":"2021-07-08T16:45:34-04:00"}, {"Block":968474,"Hash":"GtbPkm_o8CfXYRKHR3RbMdhi3QgqTTMC5eNcg0dpLy0","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"GtbPkm_o8CfXYRKHR3RbMdhi3QgqTTMC5eNcg0dpLy0\", \"type\": \"unstake_validator_v1\", \"owner\": \"13RtTjMaNpqEQBQqN9K1RezaHJS1cTmX9iMJch3tnGM2XVKz7k6\", \"address\": \"14rZ2HDVZpwbwKwr6XicHvEAZG1TupPGUBWmD6dCNPwma4ojVVE\", \"stake_amount\": 1000000000000, \"owner_signature\": \"Td86kJjiO5RZCAppJ7USl_B9wNkagHckeXJNz7mx25wAPfuN7X4CNNUjHI-1CJMf43QijXfgEo_ounAr0VFuDQ\", \"stake_release_height\": 1218500}","Time":"2021-08-16T18:56:17-04:00"}, {"Block":968474,"Hash":"KB6m3qpOJb603jlfONUj4lglHDP5fHpbCPjYX7DM8KU","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"KB6m3qpOJb603jlfONUj4lglHDP5fHpbCPjYX7DM8KU\", \"type\": \"unstake_validator_v1\", \"owner\": \"13RtTjMaNpqEQBQqN9K1RezaHJS1cTmX9iMJch3tnGM2XVKz7k6\", \"address\": \"13cvwDwy9uzPQhMDzLToXrSpANDBKEFvu6s45LbescLfqF92PPC\", \"stake_amount\": 1000000000000, \"owner_signature\": \"aB_aFkezJZ0CZfMKi-1G6ZQA9JEltA4Ij3N3Ao4-1yweH76PYAwyCVXmvqa0Ni028IduOPeuZPqViL8Dw87sAA\", \"stake_release_height\": 1218500}","Time":"2021-08-16T18:56:17-04:00"}, @@ -36,9 +50,15 @@ {"Block":993313,"Hash":"xVvKLTs5vfffYyxY1LZO_GoSxb4gm_Xl1E7k757hgjk","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"xVvKLTs5vfffYyxY1LZO_GoSxb4gm_Xl1E7k757hgjk\", \"type\": \"unstake_validator_v1\", \"owner\": \"14a1abAcR1CYEatWzNyDYNtpvDPnr85Qqy3fPMtBRGdKjWNb2rN\", \"address\": \"11oageLfoBu9jT9xsbA8x8Eio19rftsxetk8MTz6H6EWt8ur54t\", \"stake_amount\": 1000000000000, \"owner_signature\": \"keN-YiB3QarmYg9WJVNeRnEB5BVCwbNH5r159EbM1o1MSL1ytVRTmXiZqISy6FW2VhynZqegaUDDhWJQ1tShDw\", \"stake_release_height\": 1243315}","Time":"2021-09-02T04:46:13-04:00"}, {"Block":1080759,"Hash":"fkBxpxknm2khWwCWIujkevwfPgQAKsKXGaTY1fIwQuo","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"fkBxpxknm2khWwCWIujkevwfPgQAKsKXGaTY1fIwQuo\", \"type\": \"unstake_validator_v1\", \"owner\": \"14o3qw58KbC9reDLcK29AcwP6yA5rkrsw8L2XwEGAgEkcWt61pW\", \"address\": \"112Vtnki3FL2Bn3Gg28Q8grgnnkJazN7QMbNLDJdMWnVXQP4rhEB\", \"stake_amount\": 1000000000000, \"owner_signature\": \"0vkLUsXjcld_5HpVAssbencMrCL6V5ET33A__1Fop7NRLy82rnHkAMxP-emskc7HjrOUMdOQmW4q0DS6-S-OCg\", \"stake_release_height\": 1330800}","Time":"2021-11-02T00:59:26-04:00"}, {"Block":1138346,"Hash":"C2xwJXHAjCFPlu7tzbaXZRAUVZM579xOR1IBqYRmPDQ","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"C2xwJXHAjCFPlu7tzbaXZRAUVZM579xOR1IBqYRmPDQ\", \"type\": \"unstake_validator_v1\", \"owner\": \"13HTDhdVSJsoyEHKAZYsWhyFmM76dGmPfmnU7JR6sC5MRJpH81E\", \"address\": \"11qecHAqvJd977S9VZidTAHzN7wKGMWcWhJwfMoCY5B6CKvp2fC\", \"stake_amount\": 1000000000000, \"owner_signature\": \"9Xyojj0Y4a9CQv6URAIdjtAQgsst6Ap2BzvIc2Yn0PuXDtOryqxp2O__hdKHmvMN152QT1ksGAbbh0STbL8yAw\", \"stake_release_height\": 1388400}","Time":"2021-12-13T18:12:51-05:00"}, +{"Block":1279776,"Hash":"ZYxBTsRkbDZjwHZnqeLpdBLKIbfyMHjN5YeuYT4VO2A","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"ZYxBTsRkbDZjwHZnqeLpdBLKIbfyMHjN5YeuYT4VO2A\", \"type\": \"unstake_validator_v1\", \"owner\": \"14iKMEN15SRA7p1xCEjhcVTERozMVPTaWAUFtVhUnZDnXJE8unc\", \"address\": \"14YuDQAz4fF4jbGJ7UgrT8wvLBw1HqnXXsDpC7MghnqD9dMX2Gn\", \"stake_amount\": 1000000000000, \"owner_signature\": \"eKDxaxHUXtrQUKeL7gKmqSOFqroIdExzQmEupSL93ijjrSgtlD8315CAh1ov1qPDZsDUA0zNA7kB0A2j75hoDg\", \"stake_release_height\": 1529777}","Time":"2022-03-24T04:28:19-04:00"}, +{"Block":1279776,"Hash":"UmzvyvYHmn9h4m2w_NUS71izAMjCCm1hq3mNh0xDaus","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"UmzvyvYHmn9h4m2w_NUS71izAMjCCm1hq3mNh0xDaus\", \"type\": \"unstake_validator_v1\", \"owner\": \"13YozYcGpJNK2gPTRd5PnMk1BnFskHHgHM9rb5ayQi5tBPE9eCm\", \"address\": \"14L5qqGzphh2uBQs4xcZ9x4UYiBXJ2zDxU8g7BtoQVJSk4427BL\", \"stake_amount\": 1000000000000, \"owner_signature\": \"T2_xCHbciLuRYDLHy1Qde6010CO5RIveB0blxw_IZz0Aj6qurWfVPMf8C_dtU-xIGVa5vrRKdqUr55LbR5sUDQ\", \"stake_release_height\": 1529777}","Time":"2022-03-24T04:28:19-04:00"}, {"Block":1236188,"Hash":"ftJwL4G6TCeRM67_50WaldGPF4uuXev-lPS6GvpU9DI","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"ftJwL4G6TCeRM67_50WaldGPF4uuXev-lPS6GvpU9DI\", \"type\": \"unstake_validator_v1\", \"owner\": \"14CzpM7RbWjuDgfHq26b6ppwmSpy3h8e88kKVCWEyoJySyTvWd6\", \"address\": \"112Y23w8EjpQDBqqLQaegmbbprFF5GScMVXC5Ctxpo1mTnRtmXPC\", \"stake_amount\": 1000000000000, \"owner_signature\": \"thWHn1_1ziCjPG95rqZExv2RkR9h8Aqf4opRhJ9MTv-HO7v_BDVeOWmQz6ZbXiC38sLO8jnMHdYjgmMWfnB8CQ\", \"stake_release_height\": 1486188}","Time":"2022-02-21T13:21:16-05:00"}, {"Block":1236188,"Hash":"WgHsuv_DeiXo2g0n8PQ0suQmmMwVxBiwm6HpYVNPvC4","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"WgHsuv_DeiXo2g0n8PQ0suQmmMwVxBiwm6HpYVNPvC4\", \"type\": \"unstake_validator_v1\", \"owner\": \"14HmJ1s5WLzGuDCeKt6qKz2o9ZRstQCqjUiDjcTJQxxG5xVyhY3\", \"address\": \"112sovgvtdybLuqiGDj86A2S9oGtBN6GEU78fEvkoUjQriYDiVSh\", \"stake_amount\": 1000000000000, \"owner_signature\": \"amQ5VWclF_jxFfAT_mlLCc1KaGhtuz7Qi2B_uUzWc3Geh6hVLnlrfo_HwfuRWJ19Up21TGYBIGKGRr-_3xJLAg\", \"stake_release_height\": 1486188}","Time":"2022-02-21T13:21:16-05:00"}, {"Block":1236188,"Hash":"f5QeSJtkIIuMkMILZKzmCU6Rm3lSzklCgQvF853rDxs","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"f5QeSJtkIIuMkMILZKzmCU6Rm3lSzklCgQvF853rDxs\", \"type\": \"unstake_validator_v1\", \"owner\": \"13RuyiiMixC6KjPaxwj4AzsNqQsENMJ6jYn84fsdWZYkqNZVq9w\", \"address\": \"14pDRFfaR9ucDFovPmS5UBM6zwijvNBFWFetEZCjpXCt9a1ZiFU\", \"stake_amount\": 1000000000000, \"owner_signature\": \"GdigQNN-AALx1OLzNE8ucqs7HdvOIMkWSSAcZw3Lvo11t942TYrvE0ajzEBH7T2DZeHuwg9IOLOAWfFG1KIwAQ\", \"stake_release_height\": 1486188}","Time":"2022-02-21T13:21:16-05:00"}, +{"Block":1275315,"Hash":"fw3ZH2XeKWeyhWmT9DtfgQV0m8YOIPu_D7T_6JzxRzM","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"fw3ZH2XeKWeyhWmT9DtfgQV0m8YOIPu_D7T_6JzxRzM\", \"type\": \"unstake_validator_v1\", \"owner\": \"14dgGv2ZSYzGGFRi8f5PNV3uehCrsqzwdGJR1qpmwrLPQFp2UWW\", \"address\": \"13BP4t46F1eKstf8tZapWaKozJeXe4HMnMMbC3rTsbkotWJr2Gf\", \"stake_amount\": 1000000000000, \"owner_signature\": \"nokSg1jqikbExAU3xBLxYe5-cgb_FA_WSacL-5FE0BouxfF0mAAZjjE0gjJgmB9YCGiqW1lGjJCkr9zUaJIGCg\", \"stake_release_height\": 1525326}","Time":"2022-03-21T06:17:49-04:00"}, +{"Block":1292897,"Hash":"FPaK0NZev-npXwcE3r0z47LhoV7L-VLou8ONoYXJqTE","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"FPaK0NZev-npXwcE3r0z47LhoV7L-VLou8ONoYXJqTE\", \"type\": \"unstake_validator_v1\", \"owner\": \"14eHET8js1X7oCL1GpcMr5A1Hwkkhd4v9nc4yE4eyVusmvAtwYo\", \"address\": \"1122BqWcTPnky5P8hbfWqCVuijfhXGcjCcfKxTsokEUF1pmmEBBW\", \"stake_amount\": 1000000000000, \"owner_signature\": \"BN__WNKAzsRvpWBzGSBd_1ai94WwNgq7ZNifl6L_hdgrkF7gHMV7vr9H3onvN_0YCv6zYrkbiIp5dLevM1D-Ag\", \"stake_release_height\": 1542917}","Time":"2022-04-01T13:59:30-04:00"}, +{"Block":1303924,"Hash":"blDCsodWeBbUo4K2zNcqv5DNxCdd0Itb-2EKzB_yTss","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"blDCsodWeBbUo4K2zNcqv5DNxCdd0Itb-2EKzB_yTss\", \"type\": \"unstake_validator_v1\", \"owner\": \"13TdHa13JCeNq3thraaAgcXKwedJaMaR1VHbsuRJ3CCqTrNJegF\", \"address\": \"112hvBfDuzzLeGq1zNCVTXBJCCcWmZxQE9JCGRA4DRXoTNCDUu9r\", \"stake_amount\": 1000000000000, \"owner_signature\": \"2q0BzTeFjJpn-eRMpnpSVFgyPjpuasqYPGGQMDSB0dM6hhpZ27EkpR9vXIeMDtan0gRl27ZOdRmAm3Xt0jAhDg\", \"stake_release_height\": 1553931}","Time":"2022-04-09T01:08:36-04:00"}, +{"Block":1327295,"Hash":"dZ57S9EdKCvTU3aYFyDuJ5Ga9ZjCoZD3CUYyGYv8s8U","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"dZ57S9EdKCvTU3aYFyDuJ5Ga9ZjCoZD3CUYyGYv8s8U\", \"type\": \"unstake_validator_v1\", \"owner\": \"12zTFq7j7utJMUawWxsQn4LWq7QAhvR4pvAVaTmgXzH5GhjRUBD\", \"address\": \"112sKVcEQNTzW2JsZn4srvDp4gVptYdtLszexSta9zhrMnQcYJGt\", \"stake_amount\": 1000000000000, \"owner_signature\": \"iou_f0p2Gki5BQmeW37QfoVBnzM7v_iwIG2fLwBFhaAF1ZM253n0_gsCWHXP9wcEIUTPHcLR_ucwviN3FNpJDQ\", \"stake_release_height\": 1577327}","Time":"2022-04-25T14:15:40-04:00"}, {"Block":960305,"Hash":"uBQcVUQEM9bI4LYU66smLyn2BxOXJSuWzSu4kCRyNKc","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"uBQcVUQEM9bI4LYU66smLyn2BxOXJSuWzSu4kCRyNKc\", \"type\": \"unstake_validator_v1\", \"owner\": \"12xoVMjaduyZm1bw1GEBXoQe6YHCfU5gghcuobQ5weopZ8as3qw\", \"address\": \"11PEHmkn1p8us4FwZLVFjGnrCsnUrpFKGzhvccd3MXkmv6pWxBi\", \"stake_amount\": 1000000000000, \"owner_signature\": \"rQ3WoSVPGKHFJBjo7STn2Sprw-3atM2DSrw5LCgQ63_YXqv6DfsrkR0npQU_9nXK418LSwb9eDa565cktgJhBA\", \"stake_release_height\": 1210330}","Time":"2021-08-10T23:47:16-04:00"}, {"Block":982299,"Hash":"ghbZO_Mxk_DLID0HSy2oeQIrQO24uSZPh7cImWFe3SA","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"ghbZO_Mxk_DLID0HSy2oeQIrQO24uSZPh7cImWFe3SA\", \"type\": \"unstake_validator_v1\", \"owner\": \"13Q8j6wTjbZ8xMCaEBtzNEjY912WmsZM4RJfWwgeBmRoMh8F6Ur\", \"address\": \"11zgHFxUsgJAZGf9r3aEAqLbKd1QuDVBpUNkLNitwctPeaqW5QW\", \"stake_amount\": 1000000000000, \"owner_signature\": \"DgC8cLCpkKBBqZRDFA__F2y824xEeu0B2svnfbaHRb9RHUKWH34C9g3n-WFIVe6fbBqtaoaPUyeD5-1W-cCzCg\", \"stake_release_height\": 1232300}","Time":"2021-08-25T23:12:10-04:00"}, {"Block":1063908,"Hash":"62ViZW56xd6EEnd8_xvlcBBizrMu1j-9dbsGm1-FMgk","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"62ViZW56xd6EEnd8_xvlcBBizrMu1j-9dbsGm1-FMgk\", \"type\": \"unstake_validator_v1\", \"owner\": \"14NvSPHti6K32U6Lven9XMkPEusRfog8jYtUACgm3hqgaPenwyY\", \"address\": \"14SDFnzCU8s7uomCeYZETNAcg151hpjab2WxMLGRA948zwp6eNw\", \"stake_amount\": 1000000000000, \"owner_signature\": \"js5vyOxVucGUqBBJe_xFPQN0wj7YtIP4n5hw4u90GX39Y--ROz4y1NsiAyKfGtoeAB0fXwEh10ZZupTg1G4eCg\", \"stake_release_height\": 1313910}","Time":"2021-10-21T08:58:35-04:00"}, @@ -52,6 +72,12 @@ {"Block":1205599,"Hash":"bFyJt0uPq5GeJSI0os_EkS-ZZfsvOR0GnV66w4A4p34","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"bFyJt0uPq5GeJSI0os_EkS-ZZfsvOR0GnV66w4A4p34\", \"type\": \"unstake_validator_v1\", \"owner\": \"14PNnDMq6EnG9kXGPeH3DiBKT5akZ89AmEGzUesTaX1SdLbNpfT\", \"address\": \"112ssQr2qe3XLb6dBTNZVBdaiEU9bEb2XpFQkvN2wbLaB5xoshZh\", \"stake_amount\": 1000000000000, \"owner_signature\": \"D805VbtCTXHwwKBDf8ekpsg_jiHmJF76cxTmJGTqz0mou5bjFsI0q5-EygASKjlWzIiwoLOHsQ96RoRjJN-dCA\", \"stake_release_height\": 1455610}","Time":"2022-01-30T20:35:08-05:00"}, {"Block":1236186,"Hash":"AJWkmVg35UUmfAnzuvjgfp5LJeO1uD-8wLqf51n2rzU","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"AJWkmVg35UUmfAnzuvjgfp5LJeO1uD-8wLqf51n2rzU\", \"type\": \"unstake_validator_v1\", \"owner\": \"146fnkgzwVoX6p2drN8JWDc5BvCV45v7FawSmCyuk4y6PC58ttB\", \"address\": \"14ipBKpxUEecAkrJU5rQThWmJHwHFVYRtbQF7joDr7B3uqhodfP\", \"stake_amount\": 1000000000000, \"owner_signature\": \"HJ__3un0NcvwKPPaiWi5EnXSaxo_RYHfC3UDYJYmApITr1HikzkgbYBNO5s4500L9smWzLK9JmGnJ8977gc_Cg\", \"stake_release_height\": 1486188}","Time":"2022-02-21T13:19:36-05:00"}, {"Block":1251708,"Hash":"rQygqkChLjBUM940nqjH-SNwGjfjvdHDNm4yLCEzlec","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"rQygqkChLjBUM940nqjH-SNwGjfjvdHDNm4yLCEzlec\", \"type\": \"unstake_validator_v1\", \"owner\": \"132syp9LVXtRidwdHgXKC7DGuMkELCYmKakQTSXYZrt4LAEmCHo\", \"address\": \"112SbCvjoa2g7TjYejnhQCrxpA4jKCcaagRcNo34rr4cWFZhF8nu\", \"stake_amount\": 1000000000000, \"owner_signature\": \"UGgCiHimi6w_I2kfUL3g-ZbZTsVBX3HYQgPgGbMcPS101vp3bUreYVqyGZJzikZu2wOovZLpaRGl_mR7k-EvCQ\", \"stake_release_height\": 1501740}","Time":"2022-03-03T16:25:33-05:00"}, +{"Block":1276817,"Hash":"LsJOfawvsiFtYSmd6oG-3ArIUlr3Of3YtlsDdHYiAtc","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"LsJOfawvsiFtYSmd6oG-3ArIUlr3Of3YtlsDdHYiAtc\", \"type\": \"unstake_validator_v1\", \"owner\": \"143PkHdBbNevgDESNGQyVjUEpK7NjPnd4myZhDsrCB3eaxHXUTL\", \"address\": \"11tYC8zr1a1oJ4i3BkuoJLnsJGWkrwi2mxmnM6XxLmNfkDTQCYt\", \"stake_amount\": 1000000000000, \"owner_signature\": \"CQNIO8duSwSuCWzWZUIdzoKqAFgDEDj4kF-bpnbf3QX262d68E3ac9UybwIuc2-dI1ZAHSJx1TwrTqUdsWyrAw\", \"stake_release_height\": 1526840}","Time":"2022-03-22T06:17:31-04:00"}, +{"Block":1284755,"Hash":"wRr7E30C3klwkfeMCIWLPwLa37u0VJzkmYJ5vl_Vm8o","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"wRr7E30C3klwkfeMCIWLPwLa37u0VJzkmYJ5vl_Vm8o\", \"type\": \"unstake_validator_v1\", \"owner\": \"14dgGv2ZSYzGGFRi8f5PNV3uehCrsqzwdGJR1qpmwrLPQFp2UWW\", \"address\": \"133KBUx3X37ak2X1D8a5YwCSrTzUtVLd1UrZUgLWvduvUBNKGh4\", \"stake_amount\": 1000000000000, \"owner_signature\": \"NmuH9-owihJsuZnIyPCJaqdkfypCDNad7EoDuki0QZC2dY7xQHGsl0XczXwmK9zdqWxtXd7OLTxQXcfrvl8oBw\", \"stake_release_height\": 1534773}","Time":"2022-03-27T09:48:16-04:00"}, +{"Block":1284760,"Hash":"4JPEfPW0qZjpA64PO6s6CBHlvNyQ1-cRcXWoSJZZqvk","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"4JPEfPW0qZjpA64PO6s6CBHlvNyQ1-cRcXWoSJZZqvk\", \"type\": \"unstake_validator_v1\", \"owner\": \"14iKMEN15SRA7p1xCEjhcVTERozMVPTaWAUFtVhUnZDnXJE8unc\", \"address\": \"14TGAvccv7Rp1ii44FUnzjupJ3Uai54Nr8mfPpWuwe5TxFgHn3M\", \"stake_amount\": 1000000000000, \"owner_signature\": \"dzMLbVUfXU0WJn1bM7Lk6LqI_ILAZxJn852KowgJ5lsvv-Xeu_NZEdpJXdOm7ttO0cyLHs3--lEtaQw6X9CcDg\", \"stake_release_height\": 1534773}","Time":"2022-03-27T09:53:11-04:00"}, +{"Block":1292892,"Hash":"4YcyHANkf481yyCSvKP0BXt_W6pk1yFRnbm_96-avfk","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"4YcyHANkf481yyCSvKP0BXt_W6pk1yFRnbm_96-avfk\", \"type\": \"unstake_validator_v1\", \"owner\": \"14eHET8js1X7oCL1GpcMr5A1Hwkkhd4v9nc4yE4eyVusmvAtwYo\", \"address\": \"112qsvSxqjET4rbmv4as63rRPAXayzeWTjGQJkWBFCV3cphs3x4y\", \"stake_amount\": 1000000000000, \"owner_signature\": \"Rejp9Fl386wFHZmHhfMXFfat0VK1v6oqw5AjjmIexjwRujQ9hJqgpUbEmAjWp96NWcRWK8oY-exKF_1__ze8BA\", \"stake_release_height\": 1542915}","Time":"2022-04-01T13:54:08-04:00"}, +{"Block":1300599,"Hash":"ZiC5g2cyKH4jIELsxr8wYv8ijSwhYcdWjdsapnPQ2AE","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"ZiC5g2cyKH4jIELsxr8wYv8ijSwhYcdWjdsapnPQ2AE\", \"type\": \"unstake_validator_v1\", \"owner\": \"14J5GZ9f9px1qDVpGJvdwzKifytBt8VFvAMmPAHLyuoU27hhBtE\", \"address\": \"14E3PkvjU5sF57vnHG3K3MfBWEAUxqFnQJu1mGhuHac7NQT6VHp\", \"stake_amount\": 1000000000000, \"owner_signature\": \"FKiyqofWRKGjaI-HXdgwoqdON2u98c0MduT7tBrHe8QwsC4hZ3_nB7urw83uimgabiOnYuDtfmQEyJHFHo9zAw\", \"stake_release_height\": 1550626}","Time":"2022-04-06T17:10:25-04:00"}, +{"Block":1303546,"Hash":"LOg-RqOVaHP_kF5yP_TWccYUM3JFpzWRyYd4sOmpK0U","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"LOg-RqOVaHP_kF5yP_TWccYUM3JFpzWRyYd4sOmpK0U\", \"type\": \"unstake_validator_v1\", \"owner\": \"143AANfuAXdtjnvvsSpePFnFsSKvn7uLHEwL3Puz5VkfokWfHmq\", \"address\": \"112oD8r4TUPVRpVzAyXdU5Tuf2BBvs9mxQgPFrBDbafqCQJvWkMT\", \"stake_amount\": 1000000000000, \"owner_signature\": \"BgziJun3Ue1cFOAOVPyhAal8-FiX6EcpqhYrfcoNMt1n7pM-gcIyehdLoKVB0buXVCtv4Id8cjlhyOqoCi0VBQ\", \"stake_release_height\": 1553587}","Time":"2022-04-08T18:37:08-04:00"}, {"Block":993298,"Hash":"whK6XSNtJ7mFNCOG5DgZ020ZF3WNWwU0TuB8DBI6Z9U","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"whK6XSNtJ7mFNCOG5DgZ020ZF3WNWwU0TuB8DBI6Z9U\", \"type\": \"unstake_validator_v1\", \"owner\": \"13P73axPhjTRiDvwTYzzaXKeTmPpUDzXDeX8PH2owhpRKGCGWEd\", \"address\": \"112hexri3xqAXb347Sk2aN3Hkr4DLs4vZnZ69QwvPCTytZ4CAsy5\", \"stake_amount\": 1000000000000, \"owner_signature\": \"FchcHyG4SN71r_81GeLEuBnOp0prSA4xQ8v49RpiexBGtFjIiQGbiPRTW30ePb3LdSa-tpuIhYo_5e13aFBfCA\", \"stake_release_height\": 1243298}","Time":"2021-09-02T04:32:17-04:00"}, {"Block":1005214,"Hash":"iW0ZaP5x2IkDUwfnj_0U_Bftq4oA6Oq3V3dReP0eUMs","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"iW0ZaP5x2IkDUwfnj_0U_Bftq4oA6Oq3V3dReP0eUMs\", \"type\": \"unstake_validator_v1\", \"owner\": \"141WsikcrSo8tugixuLN5QTfzzLbm757UKd556iSx16sfq127ey\", \"address\": \"112BVQNFU5JZ5oHgFTasVwDpxRkJ9FgYwKmZzYB951NhW7LS1hfK\", \"stake_amount\": 1000000000000, \"owner_signature\": \"gG4a8ALZpVrg0KMpCYgGKZ3YYKNQ_9AkrSlTCNfqKIlrzUYjlQepPPqmtXKtAGWxV58y_Hasn1Hgnj29bbCgAw\", \"stake_release_height\": 1255226}","Time":"2021-09-10T11:28:28-04:00"}, {"Block":1005229,"Hash":"s3pC-QUO15cwuMtmJPWnDbJLxr1jvUJHOvfl-sxI11Q","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"s3pC-QUO15cwuMtmJPWnDbJLxr1jvUJHOvfl-sxI11Q\", \"type\": \"unstake_validator_v1\", \"owner\": \"141WsikcrSo8tugixuLN5QTfzzLbm757UKd556iSx16sfq127ey\", \"address\": \"112rDxMhcWT1kPurJQhiWEuiMptgTPRL8swHzfM7WKNBshwJjSts\", \"stake_amount\": 1000000000000, \"owner_signature\": \"JoRDBi2sD75wsGhdI7yWS5wd49YPffDSet0Ht-TgHOPs8pKH7xPYgkmqrGOjSnSFav1RnelwAD0FX_OllDY0Cg\", \"stake_release_height\": 1255245}","Time":"2021-09-10T11:43:43-04:00"}, @@ -68,6 +94,15 @@ {"Block":1236187,"Hash":"6ucFDcVJmhS1cPJtTF5LcEgy45CRcEnhYsS8tylxpaY","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"6ucFDcVJmhS1cPJtTF5LcEgy45CRcEnhYsS8tylxpaY\", \"type\": \"unstake_validator_v1\", \"owner\": \"12zesvGBAvc5H83xkGTAz5pjCCZgmZtrnB5FURr5iDwRJjAt6Gh\", \"address\": \"14F3K6nhc6keLuq4T6jKhxiGpXZRJPM7MCskW81cr58uR3JpF5w\", \"stake_amount\": 1000000000000, \"owner_signature\": \"eeeFyGi_0DbWGJ3iBnLQLDq5zeYAI5t_KyVYYpen-Ut7fsd8dHYhy3eUjtbfRDVrtJ1iZxeq5T5q_DaM-IPnCA\", \"stake_release_height\": 1486188}","Time":"2022-02-21T13:20:26-05:00"}, {"Block":1236187,"Hash":"egus-ihTR7MoUzPsfp4IiX85UwVpEtT5UK9DpIL6UwI","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"egus-ihTR7MoUzPsfp4IiX85UwVpEtT5UK9DpIL6UwI\", \"type\": \"unstake_validator_v1\", \"owner\": \"13ShGEBJs9U5Sogsiy5QVoW5M9V3PU6Pu6mHDtfpj2NixWZcC3H\", \"address\": \"14YSQGx57GwT8Be8r3mjEmFDCQhsnWH86z1XVKw2vC499CxsQ2W\", \"stake_amount\": 1000000000000, \"owner_signature\": \"wl1-EokAOrlUUWYFGqVqmNlLbETsB6Pp01KKMoWxyJNH_j0moBcnrQk3El_pa8qwXUSj-BrMff03LaHhunARAg\", \"stake_release_height\": 1486188}","Time":"2022-02-21T13:20:26-05:00"}, {"Block":1252004,"Hash":"1v8obLMaIfOj-ZWIeN6EjN_IeoPqLzU3AKihiQ4w0Rw","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"1v8obLMaIfOj-ZWIeN6EjN_IeoPqLzU3AKihiQ4w0Rw\", \"type\": \"unstake_validator_v1\", \"owner\": \"13csfUCAqyV4qqBbn2YDzregdE26g37FtL3YfaZJHnZvDEdDuWg\", \"address\": \"13MG8CvYE8c2fpRwKNCzFwwGFHGtGJJ2nHnGLNBZ6pTfw41rAPB\", \"stake_amount\": 1000000000000, \"owner_signature\": \"j544QAuLt31klDBMnzCjqGFnWLutU557YB3jN1Cs4jwuLnN8lJXWcJATkBYWJdEywaAEG-Z4SdlczNO59SScBQ\", \"stake_release_height\": 1502024}","Time":"2022-03-03T21:28:28-05:00"}, +{"Block":1261089,"Hash":"B2E9GJtkb3nw6K0oWL5yQanR-ufhUKpcomQ5Pv0Wg44","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"B2E9GJtkb3nw6K0oWL5yQanR-ufhUKpcomQ5Pv0Wg44\", \"type\": \"unstake_validator_v1\", \"owner\": \"13chnGo475Q6zKYZBoJTmsad5d8mCtjAmmRy51kjaEtz3cZgbWF\", \"address\": \"11Bryk58FvAMcox7Suia6d1ocNU9odg5QmNHwMxHRRnCLpybjrx\", \"stake_amount\": 1000000000000, \"owner_signature\": \"OFygIQ01FrX_YOfHqOiuHm4RhH31ZDE5t_EU0dVDg3THNEeu4qytqv5nQ7rzU6OXIcdfh3tgF_J4052aYs98Ag\", \"stake_release_height\": 1511090}","Time":"2022-03-10T15:40:58-05:00"}, +{"Block":1268931,"Hash":"JiMLW2GHPhD_v5QlEcBYpHoVE4i4uprsu6sonP3jx0w","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"JiMLW2GHPhD_v5QlEcBYpHoVE4i4uprsu6sonP3jx0w\", \"type\": \"unstake_validator_v1\", \"owner\": \"1339wNs723XKhMjmm99iqHGiAAqKtuTpD8qjs8faru6joCPMzVc\", \"address\": \"11rxtSj8cVDJJtZYgCkxKDXFfvrRvf8vrxAbE6s85rWbscz5bv3\", \"stake_amount\": 1000000000000, \"owner_signature\": \"S2CeM4Xmobnt0xTlRDa0TBDJm9CTCJcdxpgZwiJ7D10hoBQColVB9Zez_KSA1o1wQDlAV-LcTIe4qr_Zr1a7Cg\", \"stake_release_height\": 1518932}","Time":"2022-03-16T12:15:43-04:00"}, +{"Block":1283656,"Hash":"6IouS3bMT45xx8VixZA7m8wTaXB46im32GgzYRIDWOk","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"6IouS3bMT45xx8VixZA7m8wTaXB46im32GgzYRIDWOk\", \"type\": \"unstake_validator_v1\", \"owner\": \"14SJtTomiirQ4V7bH9NTYVB4Znz68E7fCoepggJDz9WYeronyNQ\", \"address\": \"13MqRn5ggpQs9yzsnCk21g274itmeTkY3kyUWDpMqzWPiX4tTpv\", \"stake_amount\": 1000000000000, \"owner_signature\": \"TC8G8DzAs8c7Vc1Xgl-9rc3Yt8ID3rdj7KFCPGDlfjp8XCi8IOALa-wjVphGPeLjd-0au7uaG8DzcOwyTdjpBQ\", \"stake_release_height\": 1533670}","Time":"2022-03-26T16:37:36-04:00"}, +{"Block":1284758,"Hash":"Ag6NhBOdt0oY1AymgD50yr36jIhVhYztHzDi8Yu-cEI","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"Ag6NhBOdt0oY1AymgD50yr36jIhVhYztHzDi8Yu-cEI\", \"type\": \"unstake_validator_v1\", \"owner\": \"14iKMEN15SRA7p1xCEjhcVTERozMVPTaWAUFtVhUnZDnXJE8unc\", \"address\": \"13utb6ynFCqt1RcV2ZhEL1JhFjfT4WLNxedZSjQA3PPekxLgdvT\", \"stake_amount\": 1000000000000, \"owner_signature\": \"2WgHxOT84wGyXKQzHMKIUwRkSCRITuerQuGdWzN7myNURab5URKkSQKvXtF00xr1ry9SKMyEKqXEpCajbUJTDA\", \"stake_release_height\": 1534773}","Time":"2022-03-27T09:51:13-04:00"}, +{"Block":1284758,"Hash":"dpzIKqg7seRkuFMMsWv3pTCV9anC3yUHlFVjY8XD1O0","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"dpzIKqg7seRkuFMMsWv3pTCV9anC3yUHlFVjY8XD1O0\", \"type\": \"unstake_validator_v1\", \"owner\": \"14StHhMRZ2bMB3BNbnrQGP4PjQzybiBrwy9PAcH5orq3JjAWRWi\", \"address\": \"14G52UeJv9dM8rQ6rmpXopgyAFqh18pndzc5ypc6S1ezdUnDkNA\", \"stake_amount\": 1000000000000, \"owner_signature\": \"6zJCAsV4juSRdVdRWcYY87FoV4xeQWArpOer_VW7YeIe8wcNNbnCxIHfteF96uxnRQNmPcN_gwR8AiJTRONBDQ\", \"stake_release_height\": 1534773}","Time":"2022-03-27T09:51:13-04:00"}, +{"Block":1285867,"Hash":"lj6dhC_NMzk81lnfhTRfIWKg0PyNmYXJlJQ32fsXEyY","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"lj6dhC_NMzk81lnfhTRfIWKg0PyNmYXJlJQ32fsXEyY\", \"type\": \"unstake_validator_v1\", \"owner\": \"14mCCTAW5QtmdoJ5TTsnTDEJjjvUAwDeYwhW7p1So7wiyWiMS4p\", \"address\": \"14McaxNYFU1JhrkJzqpZrvGUVoEwW5CrP3JgQ31dMHo8bZxMsLX\", \"stake_amount\": 1000000000000, \"owner_signature\": \"AkBFUKZKx0LOSGIwHERkQ7Z6pNJMpaO9bne_ppN2PAjQ4-HcsMiKxg5j3ab-n_drSj3NaqGjlN9aizrg9mqbDA\", \"stake_release_height\": 1535894}","Time":"2022-03-28T02:32:37-04:00"}, +{"Block":1289608,"Hash":"rKawBRkifOYByM7QW2OQfVUrym_ek2EzX8G43UYKfag","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"rKawBRkifOYByM7QW2OQfVUrym_ek2EzX8G43UYKfag\", \"type\": \"unstake_validator_v1\", \"owner\": \"14dgGv2ZSYzGGFRi8f5PNV3uehCrsqzwdGJR1qpmwrLPQFp2UWW\", \"address\": \"14hJSrc3o2ZfFockv6LUnmH9eF74EY9niP4qa1GM6bsuP4uYvb8\", \"stake_amount\": 1000000000000, \"owner_signature\": \"4lEDVSyHu-svpD6IZYyIohf0IjwzzBkFSSRskSqKUGnruETFc-Y2y3MSgS3Hwm1Xn0ZCFaTc1Ae27HFF9re7AA\", \"stake_release_height\": 1539615}","Time":"2022-03-30T11:44:19-04:00"}, +{"Block":1291574,"Hash":"jxOfHU28Bk_ZCunjYoaoirRAjUMB3fmj434hbiKQBzw","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"jxOfHU28Bk_ZCunjYoaoirRAjUMB3fmj434hbiKQBzw\", \"type\": \"unstake_validator_v1\", \"owner\": \"14iKMEN15SRA7p1xCEjhcVTERozMVPTaWAUFtVhUnZDnXJE8unc\", \"address\": \"14WtNjpX7uBFkJk1rmS71p2W6mJNbDuyaiCALF7LGVgbAijNLe8\", \"stake_amount\": 1000000000000, \"owner_signature\": \"oFvQKHw_GUlbem0l292C0Idb_Mr3qqCA8r7yRHPQH1odb6sx4Xm4e405qvU7qoZ0MUX1lczKtDy8VdUDdNE1Cg\", \"stake_release_height\": 1541596}","Time":"2022-03-31T17:40:56-04:00"}, +{"Block":1310992,"Hash":"mxiPsZ8Cs5EyHlH46lJ30liZ2shfy-Cz3YlyWQNb-C8","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"mxiPsZ8Cs5EyHlH46lJ30liZ2shfy-Cz3YlyWQNb-C8\", \"type\": \"unstake_validator_v1\", \"owner\": \"14iKMEN15SRA7p1xCEjhcVTERozMVPTaWAUFtVhUnZDnXJE8unc\", \"address\": \"14oH28hPr3Z4e6K6GW1msoNKaDnSptQfXfAYsJFhxDkGDQNqRzZ\", \"stake_amount\": 1000000000000, \"owner_signature\": \"zAqDvfzR7qIP4QIyHZybG3rDzVt_grQrCwV6IlOC1SuMqcDroM6_Ibtw1lYhect4LtTnxTZLL2OhhJiv4b-rDg\", \"stake_release_height\": 1561014}","Time":"2022-04-14T03:00:54-04:00"}, {"Block":960313,"Hash":"fXfwqV-1lA33erj3IwiEa2vIaVNu4qq6eBi9gJm9bZg","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"fXfwqV-1lA33erj3IwiEa2vIaVNu4qq6eBi9gJm9bZg\", \"type\": \"unstake_validator_v1\", \"owner\": \"12xoVMjaduyZm1bw1GEBXoQe6YHCfU5gghcuobQ5weopZ8as3qw\", \"address\": \"11ShxanLac4CbtvbvCuvKBBs6Jq1D4g6jPMkhbkxF8sis5bMeRZ\", \"stake_amount\": 1000000000000, \"owner_signature\": \"0i7H7rFrDIwj_ChzT--OnpmAPwrPF5YLkenqtsr7cs0JyknArYmm4HFcAzNENN3qejSEwNN9IB777EPL44yFAA\", \"stake_release_height\": 1210331}","Time":"2021-08-10T23:56:53-04:00"}, {"Block":960336,"Hash":"UcGVGWx7pEGHwOXANLtQ5qeqVK-rkV9r6kIpvrZICcM","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"UcGVGWx7pEGHwOXANLtQ5qeqVK-rkV9r6kIpvrZICcM\", \"type\": \"unstake_validator_v1\", \"owner\": \"12xoVMjaduyZm1bw1GEBXoQe6YHCfU5gghcuobQ5weopZ8as3qw\", \"address\": \"11Dk1QfJUn6a4qnfu4ufF7c8KZKf2ZDwm7EsGEiDsh2WZX9Cnxk\", \"stake_amount\": 1000000000000, \"owner_signature\": \"CSz6oS9wT-U0QatpfBK6g3QdQUPMyFlAn09FegNKXjkukh90eoIfuRxwakyOg5STCd5cuVl9yMvV_gOe4WKIAA\", \"stake_release_height\": 1210350}","Time":"2021-08-11T00:23:43-04:00"}, {"Block":960366,"Hash":"3QSM2gTB7xygbZtfuzbs-YvfAQyDrHFeZw0xUtAcpGc","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"3QSM2gTB7xygbZtfuzbs-YvfAQyDrHFeZw0xUtAcpGc\", \"type\": \"unstake_validator_v1\", \"owner\": \"12xoVMjaduyZm1bw1GEBXoQe6YHCfU5gghcuobQ5weopZ8as3qw\", \"address\": \"112hLLgKmMw1CGxuALfJgWPwpdPUJPeKYfYijJT7xmVQ1SQspXDw\", \"stake_amount\": 1000000000000, \"owner_signature\": \"OoHwD6XuknhCVgtRCW3l3ay7s6ldjWrjYFZxUKWAmOssYapWXu1E-pQ2td3Vxlip4OyQYrJq0fdwrKRAyWuQCw\", \"stake_release_height\": 1210380}","Time":"2021-08-11T01:00:04-04:00"}, @@ -97,6 +132,16 @@ {"Block":1187565,"Hash":"ixvg-WyiSO7IJz5Px4f9M3bHxg49RBYQzq-iUrHZiY4","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"ixvg-WyiSO7IJz5Px4f9M3bHxg49RBYQzq-iUrHZiY4\", \"type\": \"unstake_validator_v1\", \"owner\": \"14J6zntifsPAbiPxHYhyK7zV5ZdtKm3DiiZUVNRCe4NS9kEbGKT\", \"address\": \"1125gc3nTRncRGRHf5V9i6AdaRaQavc9kUWs7srXJFtJ8TxXE2cY\", \"stake_amount\": 1000000000000, \"owner_signature\": \"zMOqJtObP2FSw346xySb7mhIHzOwBSTUzDVbSlNKHgIQI4hCRgkr-L1p0wEzn4xoJVz_Zm2YNpetG3MNrwmPBw\", \"stake_release_height\": 1437570}","Time":"2022-01-18T17:20:25-05:00"}, {"Block":1215059,"Hash":"xW6jo03y2rGsMGCO3rhVX6v1Yr_oy3gB7NmKJZw7feI","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"xW6jo03y2rGsMGCO3rhVX6v1Yr_oy3gB7NmKJZw7feI\", \"type\": \"unstake_validator_v1\", \"owner\": \"134c74JYsfN7X4CRGixhFSWgvR6m6wV4RMJUC13J97GnN9uBCJN\", \"address\": \"14NPMmxrw6r2ijqybwUEPquSKPLs9HhsvP6qkYoo7UGLKgUVFCY\", \"stake_amount\": 1000000000000, \"owner_signature\": \"EGVbMPV0KgkVD-AMg7J_saWsvU9V4UPI6UDkoSp48Ei1fyYGhdV_A-aa9ymPSpid8YOJ0hVslN8VXFjfKwtDDw\", \"stake_release_height\": 1465080}","Time":"2022-02-06T19:56:24-05:00"}, {"Block":1228829,"Hash":"7d2DlD3LoH1UIi4fiCrRn6FmMfGiNygrZiTl9-An30A","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"7d2DlD3LoH1UIi4fiCrRn6FmMfGiNygrZiTl9-An30A\", \"type\": \"unstake_validator_v1\", \"owner\": \"14pa5EzLaGzZLvqHhHtEnQcATd3aQ5aHs1dsgRn2HkPXx5RDjn8\", \"address\": \"11h95urmNhUkg2RPJ4TC9J2GhsewV6fwcbxPBgoNSgz722PLPSL\", \"stake_amount\": 1000000000000, \"owner_signature\": \"_dNOvQ0ROho6jibmr6ep1CX1gBxNTAATrNBiwiUqCe5vHgTpyUYbt_VWqmqz_cK2_6-_qPE6GWn9Nd1DYLNABQ\", \"stake_release_height\": 1478836}","Time":"2022-02-16T18:43:25-05:00"}, +{"Block":1264989,"Hash":"4KYSuAGKz46msXd0vZEvM54ZyO5tKaJHzTVugUgYTfM","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"4KYSuAGKz46msXd0vZEvM54ZyO5tKaJHzTVugUgYTfM\", \"type\": \"unstake_validator_v1\", \"owner\": \"14hLSQaYa8uZjC7ojJaRnYu57A6StULU5m5NXSLXWHsNokXb5v1\", \"address\": \"14pqzSqMpXk1KJqbLCJCx3mRNfqQmQvx1XDjysHmhYGpPmEay3J\", \"stake_amount\": 1000000000000, \"owner_signature\": \"5_u-q3LHTTyyfkVd4BzAWJ11qGOYCKf6pRuqHag-S76Ged8ZSjHtN1X2iYegl4-LLacQQlAunt0xkfS_v_PXDw\", \"stake_release_height\": 1515022}","Time":"2022-03-13T13:05:42-04:00"}, +{"Block":1284756,"Hash":"hrA5m20SgkifcK0MZaiGMOAR__OvSWZQmSsf2h6d2fo","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"hrA5m20SgkifcK0MZaiGMOAR__OvSWZQmSsf2h6d2fo\", \"type\": \"unstake_validator_v1\", \"owner\": \"14StHhMRZ2bMB3BNbnrQGP4PjQzybiBrwy9PAcH5orq3JjAWRWi\", \"address\": \"142pdjqAsMpQkVvaMgroPhxGnKTRvDkosYBQYv1j91EiePwmq3V\", \"stake_amount\": 1000000000000, \"owner_signature\": \"WUO6zYChFa8cGIUJhjJxY-IAoV_NjTfpGMEbX86N2oo1kMJ9lqsdpQcFqaHzjf40M0ksmPW1-zYZjRG3A2sqDQ\", \"stake_release_height\": 1534773}","Time":"2022-03-27T09:49:15-04:00"}, +{"Block":1289605,"Hash":"59UkByJO4sUyoXo2QFrOKU-Sw_5BttWYNtxVG0y0EEQ","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"59UkByJO4sUyoXo2QFrOKU-Sw_5BttWYNtxVG0y0EEQ\", \"type\": \"unstake_validator_v1\", \"owner\": \"14qbcDkA9uWY9xk1evvwH2MdfZ9YzF5jtQziHBjyVsf2GnRUJNb\", \"address\": \"14jNhRTBejn82EG5A2pGwBChSr6mSx7eowP3i7U24CBvvsgY2fn\", \"stake_amount\": 1000000000000, \"owner_signature\": \"Ix29KmBhEoLqU2YD4qm5mb3_6JnxvGaSvCmcf0fjMTyQI20quAPMtuEcbGwNl5aNMvrl3tG8ydfro0GkZv3pBg\", \"stake_release_height\": 1539615}","Time":"2022-03-30T11:41:48-04:00"}, +{"Block":1291396,"Hash":"jaMhrVDTgwZ65xhmLMdsV170UMOObgkJFYyvUNC9fuE","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"jaMhrVDTgwZ65xhmLMdsV170UMOObgkJFYyvUNC9fuE\", \"type\": \"unstake_validator_v1\", \"owner\": \"136nSZ4niPtQNLqgVKi2uj5KVBw363vnjTciBYkv1LcVvda7fgP\", \"address\": \"112h85d7NRsMn8B99RgGUvXnBeHFYEM5Kv5bBBcbANybT5gdg3BN\", \"stake_amount\": 1000000000000, \"owner_signature\": \"zHUPm1DHkOrK1XST4ifM56qnmL6YLTCRXW_9_JS3t_zJey7LIucsq-B0B0nf8srhzCIUwTSNNp1MDvrgniOKAg\", \"stake_release_height\": 1541400}","Time":"2022-03-31T14:48:03-04:00"}, +{"Block":1299471,"Hash":"u496SLowpgr_HLOsnnjwwprbs8gUw8pJKOtMYa47MUw","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"u496SLowpgr_HLOsnnjwwprbs8gUw8pJKOtMYa47MUw\", \"type\": \"unstake_validator_v1\", \"owner\": \"13VQsTi9gd9o1kphazMSc4hvxu8uPBoMpEDqpXbhyLXtTM43QgM\", \"address\": \"112Sd8eMeMRsQDJS1UhbkjBufEGhNcE96U56zC9RfbNJ5XEumpg9\", \"stake_amount\": 1000000000000, \"owner_signature\": \"Nm20i6bTiy4J5gfFyh7w6e0gwL7tY3-ffJoodSj7cO-uIz6aX0BwlqLoWmfX32ixAiN3qsBcjbSb0OxoszstDQ\", \"stake_release_height\": 1549475}","Time":"2022-04-05T23:10:18-04:00"}, +{"Block":1300645,"Hash":"FP-mMUFlqw24qK4ZHSZsYGoLekt8Z3awlH0mVneE7UE","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"FP-mMUFlqw24qK4ZHSZsYGoLekt8Z3awlH0mVneE7UE\", \"type\": \"unstake_validator_v1\", \"owner\": \"14M582eZhtXgA99D2fXDz3EGNdFm7k4NL3AV36vMR6nmGRYe9jY\", \"address\": \"112aPqWMs7hgiGxuNJFVpuuWnzE6UJ5PxgSMxed3mfd4GSwvVe9W\", \"stake_amount\": 1000000000000, \"owner_signature\": \"GHcPOQw1HZ_-CWf-N4n_DOLInnIBXSlvYV-QTBWHZogrElavwXO5SKLK7IvBKesZ1YgII0gFUUI3NKTY6qSACA\", \"stake_release_height\": 1550651}","Time":"2022-04-06T17:53:35-04:00"}, +{"Block":1310995,"Hash":"HgjPsEGfQLf1fHZg9rolHFMkff882zAUp7H_OsoGLuE","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"HgjPsEGfQLf1fHZg9rolHFMkff882zAUp7H_OsoGLuE\", \"type\": \"unstake_validator_v1\", \"owner\": \"14qbcDkA9uWY9xk1evvwH2MdfZ9YzF5jtQziHBjyVsf2GnRUJNb\", \"address\": \"14WQWnnCQSUi7gtnP9Ea2AxpugLxRTVX1KkWeX9zMV4De5duFSo\", \"stake_amount\": 1000000000000, \"owner_signature\": \"_z-Dkg-WO37pkCf0yqjASHLAmZdcQgVf7nENw3YTSL_ff-NL5K1uFVF_0OVTWCFjYlWJVxy1Ju2dGEdRvMIkBQ\", \"stake_release_height\": 1561014}","Time":"2022-04-14T03:03:57-04:00"}, +{"Block":1315810,"Hash":"gRf4M9SOayhLTXNZNq_dTjONA6v59C5KNEHaoy4gY1k","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"gRf4M9SOayhLTXNZNq_dTjONA6v59C5KNEHaoy4gY1k\", \"type\": \"unstake_validator_v1\", \"owner\": \"14iKMEN15SRA7p1xCEjhcVTERozMVPTaWAUFtVhUnZDnXJE8unc\", \"address\": \"13LMjX6v7nmajZZzbBXasbjN326kv2qRfiPjgyVx8UdFWp2kft6\", \"stake_amount\": 1000000000000, \"owner_signature\": \"BPML2KFdDARL0lvozCROdDBqCd75w6TqGCbdstLPPGTjLuq8YjUTXrgyXvtmYznTp7O0hBJaqwdm9hZc51E-BQ\", \"stake_release_height\": 1565832}","Time":"2022-04-17T13:00:33-04:00"}, +{"Block":1315813,"Hash":"f2sBJaBY3cCtKwPAbjdQzz2yOsaISq7vY9aIpzoWhKc","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"f2sBJaBY3cCtKwPAbjdQzz2yOsaISq7vY9aIpzoWhKc\", \"type\": \"unstake_validator_v1\", \"owner\": \"14dgGv2ZSYzGGFRi8f5PNV3uehCrsqzwdGJR1qpmwrLPQFp2UWW\", \"address\": \"133vAtk3dvhhVwLjEUXEr7npyw3LTW8Qn4FGF5GsihPjecxZfym\", \"stake_amount\": 1000000000000, \"owner_signature\": \"J4Hd6iIdu48kM0SuG6oglezxMqP_ZTWYiHr77g-2kP5vCrWbNlRlOK6ShJg9C-txDZyyyZ1Pv9SDLycW_6SZBA\", \"stake_release_height\": 1565832}","Time":"2022-04-17T13:03:36-04:00"}, +{"Block":1315813,"Hash":"PUUtlRkHWI60de2gqHASqhv5j7ia0_GvGPEd1hFXZi0","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"PUUtlRkHWI60de2gqHASqhv5j7ia0_GvGPEd1hFXZi0\", \"type\": \"unstake_validator_v1\", \"owner\": \"14dgGv2ZSYzGGFRi8f5PNV3uehCrsqzwdGJR1qpmwrLPQFp2UWW\", \"address\": \"13e6k6gqXg76UF6BcK3CbUf1MCVR2LvPyMdT7noYZ5HSnNL6dLU\", \"stake_amount\": 1000000000000, \"owner_signature\": \"OFlKEtiVuxS2B9AKXZImFxJhCb0UmWikru-QcbT3pABmO3e4p0qL86ILulIVJ97JOATrJbsbRsU1eaP4PeBtCQ\", \"stake_release_height\": 1565832}","Time":"2022-04-17T13:03:36-04:00"}, {"Block":993314,"Hash":"SKa7K_P6LdUlB8FOCkHp4BTIhSzalLdOPL1Xne-04i8","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"SKa7K_P6LdUlB8FOCkHp4BTIhSzalLdOPL1Xne-04i8\", \"type\": \"unstake_validator_v1\", \"owner\": \"14VnJJXXcfpceTmtEi9p6r2cpb7qHKGKvFAEdwrMwYz82UuB3VD\", \"address\": \"11YfdfnGVae9zbJfpDsuNs1mxpFqVHDYdoYtmBbQEqt7fLLfehK\", \"stake_amount\": 1000000000000, \"owner_signature\": \"TuWrpLaspqz-48NzHVqNeslZyedV6w45JepBv0lfdPUt0PNbS_23_d7cNY73v2r2uuSsW7UqvNT3tAyJSWxdDw\", \"stake_release_height\": 1243320}","Time":"2021-09-02T04:47:04-04:00"}, {"Block":1054676,"Hash":"EZKBBsPZjnv5wcRLcRIMas3dAkq2RuuMU1RXAO74ftI","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"EZKBBsPZjnv5wcRLcRIMas3dAkq2RuuMU1RXAO74ftI\", \"type\": \"unstake_validator_v1\", \"owner\": \"14GUU4aPGhgpcqbr2nD78asrmHqiHPuEBTcqhDuxV3j8zL7zWeK\", \"address\": \"135Rx7XmUccCV4xodmsQsoxavoJhy8R9HdThEBmWsTLEvc64op4\", \"stake_amount\": 1000000000000, \"owner_signature\": \"NtlVAoMSRVOU2cGc8oREBNyhKMpHOm7nKhfpUUahj0Kepe2D17r4O2WxDBnZp2ajTUaAuUo8NN15lzpRYSF8DA\", \"stake_release_height\": 1304676}","Time":"2021-10-14T22:03:50-04:00"}, {"Block":1078647,"Hash":"eaiDPF1pvu0Hy6Pwl3QgEWxNSpHPLdAlrwiH-oidcUs","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"eaiDPF1pvu0Hy6Pwl3QgEWxNSpHPLdAlrwiH-oidcUs\", \"type\": \"unstake_validator_v1\", \"owner\": \"14M5UoVUpphkmiiAUxcMSpcEyNsxVydi7Q6myi6FXQjHWBmjv7s\", \"address\": \"13TWA75bFpL5WYq8QLwkMaZ5BMx6aeZNcXheoL3kSsGh21WzaYr\", \"stake_amount\": 1000000000000, \"owner_signature\": \"5b52wUamuDgUFmfWmus8-_vwn04vz4yKEx14yxQKWA03I4q44Fv-EnKs60SiD_w-Vj7NlrJf3vvkMlF_RDPbBw\", \"stake_release_height\": 1328664}","Time":"2021-10-31T14:39:18-04:00"}, @@ -113,6 +158,16 @@ {"Block":1210397,"Hash":"shEEwLQjvNCx5e6NRbxGeaWJSxK_zLC66UljqigxvoI","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"shEEwLQjvNCx5e6NRbxGeaWJSxK_zLC66UljqigxvoI\", \"type\": \"unstake_validator_v1\", \"owner\": \"136Q6at4MoCEqaih29WQTZSabepvpSgcqBUW3etyNiERjs6jKCb\", \"address\": \"13UewU3WPyBtCkoh6yEyJq7hVcqCMo5FMUDqBJ2f97tG2B8gPkL\", \"stake_amount\": 1000000000000, \"owner_signature\": \"KvOwWu7bQVJrjeK7eLdn-QS9U0KP3DX2qugeOXzPYsaFzKTSXZoiyd1RSNrfqKn_cE2pqkkgrfFM7r40ZSv6BA\", \"stake_release_height\": 1460399}","Time":"2022-02-03T09:45:22-05:00"}, {"Block":1212197,"Hash":"m2LvrwQukVDJF34vPP6AoiQg2APRtsrVXSEGpjs-Dpg","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"m2LvrwQukVDJF34vPP6AoiQg2APRtsrVXSEGpjs-Dpg\", \"type\": \"unstake_validator_v1\", \"owner\": \"14r7AGamvbgPNgDFxNdWyGRtTaucE2Mwh1Lh447Ni1jbduQxhZU\", \"address\": \"11aSfPsye3xDBCXkXJr5u9VrwGmR2m4uZfBYEi6vbkprAAvFTBQ\", \"stake_amount\": 1000000000000, \"owner_signature\": \"xPmdDmEC1tG9TDdzAYZIJdNXKRfm4aHFBB_al25EnuJyuJAEyUGYFlFiWPsa_9XnETH6-r8V6T6AYnyARU_rAg\", \"stake_release_height\": 1462210}","Time":"2022-02-04T17:36:03-05:00"}, {"Block":1236200,"Hash":"ooflaHWnaREmq9tGPG8U6PVW9ZOvHOKPD8kFmhzIQds","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"ooflaHWnaREmq9tGPG8U6PVW9ZOvHOKPD8kFmhzIQds\", \"type\": \"unstake_validator_v1\", \"owner\": \"14kDLseUELFQKXCJ5bjUWiUZitZ6pTFyuWB6kXcQ5kYzwyDnzfW\", \"address\": \"14ekfz7FsJqbHroGmVU7ahNH2EKHSwEJ7SoSXMpryTRKk1aCcTh\", \"stake_amount\": 1000000000000, \"owner_signature\": \"wHxdiNK5412rUajdsjEUlfHBhz5b8L6nHzzsKQiX8N1Uhy_dgMHiyFqYey1Z_vBWPXyxUVUX9KE-J5Wqzr8UCQ\", \"stake_release_height\": 1486220}","Time":"2022-02-21T13:31:48-05:00"}, +{"Block":1258299,"Hash":"_ccyo7_-Tme5Jih_cELUc7_mFSm7e8ZbhZNvoCP3LUU","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"_ccyo7_-Tme5Jih_cELUc7_mFSm7e8ZbhZNvoCP3LUU\", \"type\": \"unstake_validator_v1\", \"owner\": \"134c74JYsfN7X4CRGixhFSWgvR6m6wV4RMJUC13J97GnN9uBCJN\", \"address\": \"14E9ZWagvwbC1HMgqC3uDfwZtLR1PKvdyQvbsM39cqarmkepr4L\", \"stake_amount\": 1000000000000, \"owner_signature\": \"pkhalgj5j_uSuzRNU_oQcuvf_uMa-ykaFo0K6xkwcU9Wq0rSMm31yQ_RVpyDLHyZSlUjRF57qTrNCVSoWHW9Dg\", \"stake_release_height\": 1508325}","Time":"2022-03-08T12:31:04-05:00"}, +{"Block":1279764,"Hash":"mFvoKmX8KkVEY9Lk5ASvxpKAwfMASSk0Ghog27jyTzk","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"mFvoKmX8KkVEY9Lk5ASvxpKAwfMASSk0Ghog27jyTzk\", \"type\": \"unstake_validator_v1\", \"owner\": \"13YozYcGpJNK2gPTRd5PnMk1BnFskHHgHM9rb5ayQi5tBPE9eCm\", \"address\": \"14ZX4T4bvkP96B1ARAEGPCb9tAN4LoCPBCpTmsrJos4H1jr4P9p\", \"stake_amount\": 1000000000000, \"owner_signature\": \"kFspgC6syRWYUClIHhxmLL4FBoeP6QoVs3jXoeC9DbX4Wn2tE7UXqsaVAY3Qx_Un8ADtaMgwlVTUQ60wgfScBw\", \"stake_release_height\": 1529777}","Time":"2022-03-24T04:18:18-04:00"}, +{"Block":1289611,"Hash":"GIJ2WD7S7eUyguvOIL-a4EZizOVFhgHZdTipQTbXjlI","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"GIJ2WD7S7eUyguvOIL-a4EZizOVFhgHZdTipQTbXjlI\", \"type\": \"unstake_validator_v1\", \"owner\": \"14StHhMRZ2bMB3BNbnrQGP4PjQzybiBrwy9PAcH5orq3JjAWRWi\", \"address\": \"14AJX4GHd1oq1TrDtSFh5Z3TQabNoznGQES4yWw8kDM9kD7ehHU\", \"stake_amount\": 1000000000000, \"owner_signature\": \"tFs0XAzDiJDpwM7dDsDB0oymDip-W8HxlV8y8Cfl5ipgVuldyJOQcUqO13U57WYd5Z4Ovup3ufJdDnXGwNOIAg\", \"stake_release_height\": 1539630}","Time":"2022-03-30T11:46:49-04:00"}, +{"Block":1292644,"Hash":"u1OA5rlqGCgvBr03PojRkhtS7K_TkJAOs-XxDNPuYew","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"u1OA5rlqGCgvBr03PojRkhtS7K_TkJAOs-XxDNPuYew\", \"type\": \"unstake_validator_v1\", \"owner\": \"14eHET8js1X7oCL1GpcMr5A1Hwkkhd4v9nc4yE4eyVusmvAtwYo\", \"address\": \"11R3YG9VTRtkvpvfDJ1nP2MZAdHXC2xR5pnrNKRNRdvQZaCaUjY\", \"stake_amount\": 1000000000000, \"owner_signature\": \"WTHlhELCBa6bwYThurKEHkhgGzMr0gFOwJ8sgqdw4KoodyDEuvGvKq73sar7FjgX3blYnzOoX5pJzUgsUW9tCg\", \"stake_release_height\": 1542668}","Time":"2022-04-01T10:19:57-04:00"}, +{"Block":1308045,"Hash":"yKj0LZRwPg1yM_eOolgHgQLygc1t0H29btP3wKPBMxI","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"yKj0LZRwPg1yM_eOolgHgQLygc1t0H29btP3wKPBMxI\", \"type\": \"unstake_validator_v1\", \"owner\": \"14nLZ1v52THwpGy2GVCRqm3HJKGa8HZGyA135MJikBSHyKcWiyr\", \"address\": \"112WiVjvnmGqTZrKLHLrzbYqZmsH8qsWPLdgmk685DTmHNUvDFxe\", \"stake_amount\": 1000000000000, \"owner_signature\": \"4MsAIR_ZEhaBcuOU5dTrZXPZjfDyKmvzUQ3W8qfSI_aJb7HqsIJYWg79uRiJVs3bLAec9UmnyKgvM1eeXl8PAQ\", \"stake_release_height\": 1558098}","Time":"2022-04-11T23:59:31-04:00"}, +{"Block":1310993,"Hash":"A-vPyfbwbQFuXN1vpYraE4f89fw8OYA_uZifHPHVUUk","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"A-vPyfbwbQFuXN1vpYraE4f89fw8OYA_uZifHPHVUUk\", \"type\": \"unstake_validator_v1\", \"owner\": \"13YozYcGpJNK2gPTRd5PnMk1BnFskHHgHM9rb5ayQi5tBPE9eCm\", \"address\": \"133CjMZ2nQvmLgquAfs9A3jveaGJRdeLvinDQrG6y7c2MhBjdFx\", \"stake_amount\": 1000000000000, \"owner_signature\": \"DVr_vVu5R7rkhvZfu9h1gkIde4MJ6sssje_lp8ryVbiTfax4dPU0xNQ9iM2jCUFQ-kR4VX7MUiC1w0zT1LFEDw\", \"stake_release_height\": 1561014}","Time":"2022-04-14T03:01:55-04:00"}, +{"Block":1310994,"Hash":"KbBDpT0QBfnm1BwxiPYHsC72HKv5GC0w7Jr2qzDO6oI","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"KbBDpT0QBfnm1BwxiPYHsC72HKv5GC0w7Jr2qzDO6oI\", \"type\": \"unstake_validator_v1\", \"owner\": \"13YozYcGpJNK2gPTRd5PnMk1BnFskHHgHM9rb5ayQi5tBPE9eCm\", \"address\": \"13A1Vcoez8jcVM3EUzT6fyxcpiNNrqwMXsL1DnbPbfWQg4WMUZa\", \"stake_amount\": 1000000000000, \"owner_signature\": \"fYlmGObEMQqY05PmX1_qutPfjFERPZ3Tt5_Z2YY95CcwAU8rSKmmiJReDdAqNDCWFrMmKKTLEuwITjTW8m7VDQ\", \"stake_release_height\": 1561014}","Time":"2022-04-14T03:02:56-04:00"}, +{"Block":1315811,"Hash":"EwDG3mtTFCUkFoYyDPCuvXR2FeTOXfvIyhYNA1h6vxQ","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"EwDG3mtTFCUkFoYyDPCuvXR2FeTOXfvIyhYNA1h6vxQ\", \"type\": \"unstake_validator_v1\", \"owner\": \"14iKMEN15SRA7p1xCEjhcVTERozMVPTaWAUFtVhUnZDnXJE8unc\", \"address\": \"13PNnBjr44QZHi21SBAe78NwCLCsb6nfTAVRgWe3a716bYMHDT9\", \"stake_amount\": 1000000000000, \"owner_signature\": \"0F5d_fgTyc7yKel2iWGBPpilu46JFPcHmTgMUQD2ALQi8CjRrhS9Vqqb2HsONDJLyf_XAoV3bgW1AsVPfdiuBA\", \"stake_release_height\": 1565832}","Time":"2022-04-17T13:01:34-04:00"}, +{"Block":1315811,"Hash":"EgxXiDGCT6WY_Do0PmsJjsQTMzMWrrI-LGSnIJVjyhI","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"EgxXiDGCT6WY_Do0PmsJjsQTMzMWrrI-LGSnIJVjyhI\", \"type\": \"unstake_validator_v1\", \"owner\": \"14dgGv2ZSYzGGFRi8f5PNV3uehCrsqzwdGJR1qpmwrLPQFp2UWW\", \"address\": \"14T9cbTBJsamFuoC9LVc57rGcDMGkNuikCaDZ9JzisutpXVobFe\", \"stake_amount\": 1000000000000, \"owner_signature\": \"XmrBaLKVSI0GXbBVqOTlerBg_TaKJtE8Tw4cfrKJm9bsGPTlvlnzSNzr7rfxCDswBMItRsux6hDuIRknyZ1VBw\", \"stake_release_height\": 1565832}","Time":"2022-04-17T13:01:34-04:00"}, +{"Block":1319247,"Hash":"6iiPf-_loCL0GmtSv7DzY4NpTrof_YJkGe5xHnM6ZOs","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"6iiPf-_loCL0GmtSv7DzY4NpTrof_YJkGe5xHnM6ZOs\", \"type\": \"unstake_validator_v1\", \"owner\": \"131RZmEa6oq9mSuYCCFPovLp2qAsnuQmBwrFK3RM8YQ4rEeXTSM\", \"address\": \"11fz334HCaFi4reNc2SZEyZQynBXYc4QzK2UFxWUy7WKnTWQj2i\", \"stake_amount\": 1000000000000, \"owner_signature\": \"v6jB5edfnNX-z5Y11VFWuK56rJGF1w3zoA-RQF6h42dMrOURNZPQAqTBcsiheTeH6jD0BWIYCkg4OFh7MaNHBQ\", \"stake_release_height\": 1569295}","Time":"2022-04-20T00:33:47-04:00"}, {"Block":960343,"Hash":"-W2WqZ8nkINlWm6CAf5HBiBgszIm8JM2BmboHQHe7l8","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"-W2WqZ8nkINlWm6CAf5HBiBgszIm8JM2BmboHQHe7l8\", \"type\": \"unstake_validator_v1\", \"owner\": \"12xoVMjaduyZm1bw1GEBXoQe6YHCfU5gghcuobQ5weopZ8as3qw\", \"address\": \"11TJwzUDUktQdV12eQ3TULEkKpf24SLa3nHpPTfySFj1UdN5HeU\", \"stake_amount\": 1000000000000, \"owner_signature\": \"9VGV1x0Sr6vUbcL64iBulntGsV43OsWqw8C0cE3w3M7PXnx8f8EH4m-tKuSY0PAkwn7C81LsF91fW3UdDnlzCg\", \"stake_release_height\": 1210351}","Time":"2021-08-11T00:32:29-04:00"}, {"Block":1005202,"Hash":"Pq5JYkSWW0v4mww9yZcZlEnYlARzLk_OEPjC745CLrU","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"Pq5JYkSWW0v4mww9yZcZlEnYlARzLk_OEPjC745CLrU\", \"type\": \"unstake_validator_v1\", \"owner\": \"141WsikcrSo8tugixuLN5QTfzzLbm757UKd556iSx16sfq127ey\", \"address\": \"112JkiDg2GcrbYScTRN52jvkvgGVqp4n75sBjU6dwQeqqqK6VQR8\", \"stake_amount\": 1000000000000, \"owner_signature\": \"LHLfM3ju1Pp6MVLugHAYZtPJ-P8PbNCy7Me76fysLdthliyTGBV1I6lzWR2bUfHk0e8hzbnsweqq6Pq4HlV_DQ\", \"stake_release_height\": 1255217}","Time":"2021-09-10T11:16:16-04:00"}, {"Block":1005250,"Hash":"JFPTW7BOlV65nT78SSjmmLSMtP4ps6buHXF3MS9XsH8","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"JFPTW7BOlV65nT78SSjmmLSMtP4ps6buHXF3MS9XsH8\", \"type\": \"unstake_validator_v1\", \"owner\": \"141WsikcrSo8tugixuLN5QTfzzLbm757UKd556iSx16sfq127ey\", \"address\": \"11n7gR4vDTbitDJMVH7x3NuXVAWLh5hoYRm6MUudg2HJmSbhzrW\", \"stake_amount\": 1000000000000, \"owner_signature\": \"Jhk1GsDleenAzEmFbfVWcxJ2LuXQlPj814aDCBTOLO5qZyxQwEKSMR_jnzpwA5FhVKHf6v_uJk2Wn2ymq1lkCQ\", \"stake_release_height\": 1255255}","Time":"2021-09-10T12:04:09-04:00"}, @@ -136,5 +191,13 @@ {"Block":1222335,"Hash":"kQSUXJBEvPakpL3NQPyHAg3bgau52PzT-cXkaRE0UVo","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"kQSUXJBEvPakpL3NQPyHAg3bgau52PzT-cXkaRE0UVo\", \"type\": \"unstake_validator_v1\", \"owner\": \"14ATq3tQ7Jj3zxgXcxh5whKoLeKZJj6tF2mbRkBUSt9Wv9hEQgt\", \"address\": \"118HmJoBWf9yEsUAygGokkVhLP9o825fijmQC9PNgMJube6cYkF\", \"stake_amount\": 1000000000000, \"owner_signature\": \"TwZ_7iNdF2GjGel44f6lJb6MG7fya3XFYNcVXS-hjGUAksd6VcvaSD2g3SwkDzx6pZvE_lAPIAz2tGOkFKNlCg\", \"stake_release_height\": 1472342}","Time":"2022-02-12T13:23:54-05:00"}, {"Block":1242120,"Hash":"XQXmOmZmCXrPTSwyee0xnrlhN-iE3Yx0cok28q9P0kk","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"XQXmOmZmCXrPTSwyee0xnrlhN-iE3Yx0cok28q9P0kk\", \"type\": \"unstake_validator_v1\", \"owner\": \"13mksMX1JTutHNZgA9zVH8yA4bZKBgRW9rwPrhzspRGX2zNZbw1\", \"address\": \"112hiMD27kd5vT7QpVHLit1C1DjN2yrGvMN1srcNQgyyuWNjDWZN\", \"stake_amount\": 1000000000000, \"owner_signature\": \"mLLH-22Cq33sey8ByQ9UCyXOmRtIAt0OKGT1nXy2yHpsKkoUi60npzexzw4rvqaR8ffs9jLaskx1cxtenP7FCg\", \"stake_release_height\": 1492156}","Time":"2022-02-25T09:16:33-05:00"}, {"Block":1248888,"Hash":"ySXXsHtZHLo15khyfkEhvVOYGxXb_fT_odQRz3XsLq0","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"ySXXsHtZHLo15khyfkEhvVOYGxXb_fT_odQRz3XsLq0\", \"type\": \"unstake_validator_v1\", \"owner\": \"14NvSPHti6K32U6Lven9XMkPEusRfog8jYtUACgm3hqgaPenwyY\", \"address\": \"11wX5Kp7Qskg7gbFDzmVrnNTuNhEXkFqEXKdHWGstfhAW6fEYXs\", \"stake_amount\": 1000000000000, \"owner_signature\": \"1qKDaoX-zSXe-cMBjZX5rty2dJg6mLJdzpAucpJt5gDFupfmqXgMigWBKM1_6EQgLAWHkKFn4M_eVH5XQp6xDw\", \"stake_release_height\": 1498909}","Time":"2022-03-01T19:18:29-05:00"}, -{"Block":1253015,"Hash":"LmEWy_z3yHFfmtxXohCystYGi8Fs90is94R--JQBUzk","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"LmEWy_z3yHFfmtxXohCystYGi8Fs90is94R--JQBUzk\", \"type\": \"unstake_validator_v1\", \"owner\": \"14MFM9WzVg5V7a5PUDcUq6ZfxGPiQRHtBpjwiqKoov54hJCUE9v\", \"address\": \"112o1rf3pB8qxCM5EHun3yc3UCqRrqcEKNaXDc6YH1VvCYaTZgHU\", \"stake_amount\": 1000000000000, \"owner_signature\": \"9u_I4uYlB9cjc1AurCtFxCTIx_lvs2aRuv3z41RQ8pxRxZD6zpvCQLh0phPDMrwQvsxqfJw3wpHfNm-Kgp8tDg\", \"stake_release_height\": 1503041}","Time":"2022-03-04T16:08:53-05:00"} +{"Block":1253015,"Hash":"LmEWy_z3yHFfmtxXohCystYGi8Fs90is94R--JQBUzk","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"LmEWy_z3yHFfmtxXohCystYGi8Fs90is94R--JQBUzk\", \"type\": \"unstake_validator_v1\", \"owner\": \"14MFM9WzVg5V7a5PUDcUq6ZfxGPiQRHtBpjwiqKoov54hJCUE9v\", \"address\": \"112o1rf3pB8qxCM5EHun3yc3UCqRrqcEKNaXDc6YH1VvCYaTZgHU\", \"stake_amount\": 1000000000000, \"owner_signature\": \"9u_I4uYlB9cjc1AurCtFxCTIx_lvs2aRuv3z41RQ8pxRxZD6zpvCQLh0phPDMrwQvsxqfJw3wpHfNm-Kgp8tDg\", \"stake_release_height\": 1503041}","Time":"2022-03-04T16:08:53-05:00"}, +{"Block":1280244,"Hash":"24_oJNtyjKmlXpoWQpZFfOlNtUgFJ8BPgTl3taUHNtQ","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"24_oJNtyjKmlXpoWQpZFfOlNtUgFJ8BPgTl3taUHNtQ\", \"type\": \"unstake_validator_v1\", \"owner\": \"14mCCTAW5QtmdoJ5TTsnTDEJjjvUAwDeYwhW7p1So7wiyWiMS4p\", \"address\": \"13duPPcD468FeSR4oS45LLWwq53EjnDQ6rorEf12RVwjcPe1brw\", \"stake_amount\": 1000000000000, \"owner_signature\": \"bk16-eTSXP7p_Cv7nvVJdPrZZXV08AfwlbqFK5vno9woHRJI0RTJuwGj2uwkaocUwSbVY0SQN6Zuf_8Tlhg2Dg\", \"stake_release_height\": 1530285}","Time":"2022-03-24T11:51:30-04:00"}, +{"Block":1280775,"Hash":"V_FVn_jjcMDV8VYuXVI1ANZ-LRrbngueWKuPqudZAJM","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"V_FVn_jjcMDV8VYuXVI1ANZ-LRrbngueWKuPqudZAJM\", \"type\": \"unstake_validator_v1\", \"owner\": \"14o8tvMzXHLvdokf7iS9L6sx67eEjkHrj9xEGiMVhZLQEpYxqny\", \"address\": \"14VRCoRki35CtifB2WYZTqH98ixoKGrgdGeZZyET83VCKkbqnmB\", \"stake_amount\": 1000000000000, \"owner_signature\": \"rUcoJi77MMOhLQU2xTdaOFXyLwPivIW1iKnKybknN3Ckpcnuzpw50DWpng9cy5wNs-0S_up1WIFEXuIcBFL2Cg\", \"stake_release_height\": 1530779}","Time":"2022-03-24T20:12:21-04:00"}, +{"Block":1291576,"Hash":"j-8qOLHQgP2Dl__va-OJTd7V3d8wkq6RVt8TZFKEZxk","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"j-8qOLHQgP2Dl__va-OJTd7V3d8wkq6RVt8TZFKEZxk\", \"type\": \"unstake_validator_v1\", \"owner\": \"14StHhMRZ2bMB3BNbnrQGP4PjQzybiBrwy9PAcH5orq3JjAWRWi\", \"address\": \"13L8fzzmQ2ZJwgoznP9vF7bpzm2Mmkv9FcB6d3Jhm4o88S8FpzG\", \"stake_amount\": 1000000000000, \"owner_signature\": \"pr2qjLfmxH6qlmDxB_tzMsjDxN7FZewHV36RD5Aj7DpJhm3CaNcYrPPmj0aVsrjapgzXgbi5a2DX7rFIyzKkAg\", \"stake_release_height\": 1541596}","Time":"2022-03-31T17:42:58-04:00"}, +{"Block":1291576,"Hash":"oPQwEXqltCRTMUvbotY-HmLZGZ8Bs3-zHkvaTsDd-Uo","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"oPQwEXqltCRTMUvbotY-HmLZGZ8Bs3-zHkvaTsDd-Uo\", \"type\": \"unstake_validator_v1\", \"owner\": \"14StHhMRZ2bMB3BNbnrQGP4PjQzybiBrwy9PAcH5orq3JjAWRWi\", \"address\": \"13WUger7QZdPpncHxaTKinZV71H8SMUfwnG86xHWhDBCu2qbjxj\", \"stake_amount\": 1000000000000, \"owner_signature\": \"k3GaNY_-6FUQFs4IW0eUKBf66f53NDoqA8cSnPVImIhNM7iGXSGH8W0R45MlYgHHiUT_IOfFdxU_z8yqxtdGAw\", \"stake_release_height\": 1541596}","Time":"2022-03-31T17:42:58-04:00"}, +{"Block":1291576,"Hash":"p5Fc5MIH2f6EUJtyWYPraq-EMsfnCumrhLTuCCdMhr4","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"p5Fc5MIH2f6EUJtyWYPraq-EMsfnCumrhLTuCCdMhr4\", \"type\": \"unstake_validator_v1\", \"owner\": \"14StHhMRZ2bMB3BNbnrQGP4PjQzybiBrwy9PAcH5orq3JjAWRWi\", \"address\": \"14XxVd4441VB9KoiTdv9YjJ4fuWfKb71RsqnnqNEgnttA3EX8jn\", \"stake_amount\": 1000000000000, \"owner_signature\": \"EKDRJWy54BNBXK9h0unUYyEK2I3FugojbTjGmJzjjt_vbwnN8gil-U027pHEaauNdsy4LQd6qxRySX3A0Z7GBw\", \"stake_release_height\": 1541596}","Time":"2022-03-31T17:42:58-04:00"}, +{"Block":1292898,"Hash":"vbmt_MQwu-IYeQveA8Jek6KACKz1dihXNwtNI9JpyWM","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"vbmt_MQwu-IYeQveA8Jek6KACKz1dihXNwtNI9JpyWM\", \"type\": \"unstake_validator_v1\", \"owner\": \"14eHET8js1X7oCL1GpcMr5A1Hwkkhd4v9nc4yE4eyVusmvAtwYo\", \"address\": \"11nzDJHCYKcoiwTEULUFW5pKit3RApYSA2RoUFznY8nSbwiFcF9\", \"stake_amount\": 1000000000000, \"owner_signature\": \"SGoc3RyyxC2FVy1vgHk9Xud1qgXztoWIgkd5_LFFF_y3ZdChYapiqnMCpvPE3XUQuHodVcgrcwdY4EXcIUB7Ag\", \"stake_release_height\": 1542921}","Time":"2022-04-01T14:00:23-04:00"}, +{"Block":1298965,"Hash":"vzvPZdEWfTbZAy6a9LUpu4ailjmEWFoglcZnuuI69YM","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"vzvPZdEWfTbZAy6a9LUpu4ailjmEWFoglcZnuuI69YM\", \"type\": \"unstake_validator_v1\", \"owner\": \"14cFFfHBtpXNwEfFcfBkCpnC4Dw2nq24r5mpv8CqZXeUU3RfNcu\", \"address\": \"11PhQ3gLCUMhSmEepdzVZWmaWWUkWH2fERbF3GcYRn6tEuSS2v4\", \"stake_amount\": 1000000000000, \"owner_signature\": \"e0Cv5I83myJFUH84Pvmw8lOqx0hzClIhQLS2ZvNMii-2i7gHCewNKgpn7CL_qsKeTLws9_mxIPIODu7omMRsCQ\", \"stake_release_height\": 1548968}","Time":"2022-04-05T15:01:15-04:00"}, +{"Block":1323064,"Hash":"HMKhaOUbLxm1WGNYLuGE3IToUvLKpLeO2U4skAOV_xg","Type":"unstake_validator_v1","Fields":"{\"fee\": 35000, \"hash\": \"HMKhaOUbLxm1WGNYLuGE3IToUvLKpLeO2U4skAOV_xg\", \"type\": \"unstake_validator_v1\", \"owner\": \"133CD2RtX7J2T1eUBXMjP2MoBHEp734dsquVB55CjTnw6fUuQnR\", \"address\": \"11XNtf6tDk8HiqstHWBaLhFCioU31wnmT9SQ2eTB1Rtwxct7RUQ\", \"stake_amount\": 1000000000000, \"owner_signature\": \"ML3WsWQwO3DAnRxN1piwJsTTl0s0uLS2sgefOH3WU96EcW1LhMEecLj_50IijI3eyN4b0_W7U7EkkJDTZtKeBg\", \"stake_release_height\": 1573092}","Time":"2022-04-22T16:20:33-04:00"} ] \ No newline at end of file diff --git a/helium/errors.go b/helium/errors.go index 0097472..faf1ee1 100644 --- a/helium/errors.go +++ b/helium/errors.go @@ -35,6 +35,7 @@ var ( ErrSignatureInvalid, ErrEnvVariableMissing, ErrNodeSync, + ErrDBCatchup, } // ErrUnimplemented is returned when an endpoint @@ -124,8 +125,14 @@ var ( } ErrNodeSync = &types.Error{ - Code: 12, - Message: "Node is not ready", + Code: 12, + Message: "Node is not ready", + Retriable: true, + } + ErrDBCatchup = &types.Error{ + Code: 13, + Message: "RocksDB secondary needs to catchup", + Retriable: true, } ) diff --git a/helium/middleware.go b/helium/middleware.go index ec3a071..6272dde 100644 --- a/helium/middleware.go +++ b/helium/middleware.go @@ -71,12 +71,20 @@ type GetGatewayOwnerResponse struct { } func GetCurrentHeight() (*int64, *types.Error) { - var result int64 - if err := NodeClient.CallFor(&result, "block_height", nil); err != nil { - return nil, WrapErr(ErrUnclearIntent, errors.New("error getting block_height")) + if NodeBalancesDB != nil { + txnHeight, tErr := RocksDBTransactionsHeightGet() + if tErr != nil { + return nil, WrapErr(ErrFailed, tErr) + } + zap.S().Info("txn height: " + fmt.Sprint(*txnHeight)) + return txnHeight, nil + } else { + var result int64 + if err := NodeClient.CallFor(&result, "block_height", nil); err != nil { + return nil, WrapErr(ErrUnclearIntent, errors.New("error getting block_height")) + } + return &result, nil } - - return &result, nil } func GetBlockTimestamp(blockIdentifier *types.PartialBlockIdentifier) (*int64, *types.Error) { diff --git a/helium/rocksdb.go b/helium/rocksdb.go index c5b947a..0bae360 100644 --- a/helium/rocksdb.go +++ b/helium/rocksdb.go @@ -12,6 +12,7 @@ import ( "github.com/helium/rosetta-helium/utils" rocksdb "github.com/linxGnu/grocksdb" "github.com/okeuday/erlang_go/v2/erlang" + "go.uber.org/zap" ) type Entry struct { @@ -84,12 +85,33 @@ func RocksDBBlockHashGet(height int64) (*string, error) { func RocksDBTransactionsHeightGet() (*int64, error) { ro := rocksdb.NewDefaultReadOptions() + ro.SetFillCache(false) + ro.SetTotalOrderSeek(true) heightBin, hErr := NodeTransactionsDB.GetCF(ro, NodeTransactionsDBDefaultHandle, heightKeyBinary) if hErr != nil { return nil, hErr } + if heightBin.Data() == nil { + return nil, hErr + } + + height := int64(binary.LittleEndian.Uint64(heightBin.Data())) + + return &height, nil +} + +func RocksDBBalancesHeightGet() (*int64, error) { + ro := rocksdb.NewDefaultReadOptions() + ro.SetFillCache(false) + ro.SetTotalOrderSeek(true) + + heightBin, hErr := NodeBalancesDB.GetCF(ro, NodeBalancesDBDefaultHandle, heightKeyBinary) + if hErr != nil { + return nil, hErr + } + height := int64(binary.LittleEndian.Uint64(heightBin.Data())) return &height, nil @@ -108,6 +130,24 @@ func RocksDBAccountGet(address string, height int64) (*AccountEntry, error) { key := append(addressBin, heightBin...) + balancesHeight, _ := RocksDBBalancesHeightGet() + zap.S().Info("AccountGet current balances height: " + fmt.Sprint(*balancesHeight)) + + // txnsHeight, _ := RocksDBTransactionsHeightGet() + // zap.S().Info("AccountGet current txns height: " + fmt.Sprint(*txnsHeight)) + zap.S().Info("AccountGet requested height: " + fmt.Sprint(height)) + + if *balancesHeight < height { + zap.S().Info("BALANCES IS NOT READY. RETRY.") + if tErr := NodeBalancesDB.TryCatchUpWithPrimary(); tErr != nil { + return nil, tErr + } + if tErr := NodeTransactionsDB.TryCatchUpWithPrimary(); tErr != nil { + return nil, tErr + } + return nil, errors.New("dbcatchup") + } + // zap.S().Info("key searched: " + fmt.Sprint(key)) readOptions := rocksdb.NewDefaultReadOptions() @@ -118,7 +158,7 @@ func RocksDBAccountGet(address string, height int64) (*AccountEntry, error) { iterator.SeekForPrev(key) if iterator.ValidForPrefix(addressBin) { - // zap.S().Info("key retrieved: " + fmt.Sprint(int64(binary.BigEndian.Uint64(iterator.Key().Data()[33:41])))) + zap.S().Info("key retrieved: " + fmt.Sprint(int64(binary.BigEndian.Uint64(iterator.Key().Data()[33:41])))) accountEntryBin := iterator.Value() accountEntryTuple, bErr := erlang.BinaryToTerm(accountEntryBin.Data()) diff --git a/helium/types.go b/helium/types.go index f835189..adfb895 100644 --- a/helium/types.go +++ b/helium/types.go @@ -333,6 +333,10 @@ var ( // testnet network in bytes TestnetNetworkBytes = []byte{1} + // SyncedRocksDBHeight is the height of the + // latest iterator + SyncedRocksDBHeight = int64(0) + // SuccessStatus is the status of any // Helium operation considered successful. SuccessStatus = "SUCCESS" diff --git a/main.go b/main.go index c5c468b..e6ee0f4 100644 --- a/main.go +++ b/main.go @@ -49,6 +49,7 @@ type HeliumRocksDB struct { TransactionsDB *rocksdb.DB BlockchainDB *rocksdb.DB EntriesCF *rocksdb.ColumnFamilyHandle + BalancesDefaultCF *rocksdb.ColumnFamilyHandle HeightsCF *rocksdb.ColumnFamilyHandle TransactionsDefaultCF *rocksdb.ColumnFamilyHandle } @@ -170,7 +171,7 @@ func openRocksDB(dataDir string) (heliumDB *HeliumRocksDB, err error) { dbBal, balancesCfHandles, dbBalErr := rocksdb.OpenDbAsSecondaryColumnFamilies( opts, dataDir+"/balances.db", - "rocksdb/balances.db", + "./rocksdb/balances.db", balancesCfNames, []*rocksdb.Options{opts, columnOpts}, ) @@ -181,7 +182,7 @@ func openRocksDB(dataDir string) (heliumDB *HeliumRocksDB, err error) { dbBlock, blockchainCfHandles, dbBlockErr := rocksdb.OpenDbAsSecondaryColumnFamilies( opts, dataDir+"/blockchain.db", - "rocksdb/blockchain.db", + "./rocksdb/blockchain.db", blockchainCfNames, []*rocksdb.Options{opts, opts}, ) @@ -192,7 +193,7 @@ func openRocksDB(dataDir string) (heliumDB *HeliumRocksDB, err error) { dbTxn, txnCfHandles, dbTxnErr := rocksdb.OpenDbAsSecondaryColumnFamilies( opts, dataDir+"/transactions.db", - "rocksdb/transactions.db", + "./rocksdb/transactions.db", transactionsCfNames, []*rocksdb.Options{opts, opts}, ) @@ -204,6 +205,7 @@ func openRocksDB(dataDir string) (heliumDB *HeliumRocksDB, err error) { BalancesDB: dbBal, TransactionsDB: dbTxn, BlockchainDB: dbBlock, + BalancesDefaultCF: balancesCfHandles[0], EntriesCF: balancesCfHandles[1], HeightsCF: blockchainCfHandles[1], TransactionsDefaultCF: txnCfHandles[0], @@ -286,6 +288,7 @@ func main() { helium.NodeBlocksDB = heliumDB.BlockchainDB helium.NodeTransactionsDB = heliumDB.TransactionsDB helium.NodeBalancesDBEntriesHandle = heliumDB.EntriesCF + helium.NodeBalancesDBDefaultHandle = heliumDB.BalancesDefaultCF helium.NodeBlockchainDBHeightsHandle = heliumDB.HeightsCF helium.NodeTransactionsDBDefaultHandle = heliumDB.TransactionsDefaultCF break diff --git a/rosetta-cli-config/mainnet/config.json b/rosetta-cli-config/mainnet/config.json index 3667e9b..0816f0b 100644 --- a/rosetta-cli-config/mainnet/config.json +++ b/rosetta-cli-config/mainnet/config.json @@ -7,9 +7,12 @@ "data_directory": "rosetta-data", "http_timeout": 2000, "tip_delay": 1200, - "max_retries": 10, + "max_retries": 20, + "max_sync_concurrency":1, "data": { - "start_index": 1267922, + "active_reconciliation_concurrency":1, + "inactive_reconciliation_concurrency":1, + "start_index": 1329842, "historical_balance_enabled": true, "end_conditions": { "reconciliation_coverage": { diff --git a/services/account_service.go b/services/account_service.go index af7ee8c..d097266 100644 --- a/services/account_service.go +++ b/services/account_service.go @@ -85,9 +85,29 @@ func (s *AccountAPIService) AccountBalance( } if helium.NodeBalancesDB != nil { + // zap.S().Info("/account/balance request: " + fmt.Sprint(request.AccountIdentifier.Address) + " at block " + fmt.Sprint(*request.BlockIdentifier.Index)) + // zap.S().Info("SYNCED HEIGHT: " + fmt.Sprint(helium.SyncedRocksDBHeight)) + // zap.S().Info("SHOULD I SYNC? " + fmt.Sprint((*request.BlockIdentifier.Index > helium.SyncedRocksDBHeight))) + + // if (request.BlockIdentifier.Index == nil) || (*request.BlockIdentifier.Index > helium.SyncedRocksDBHeight) { + // zap.S().Info("DEBUG Block Index Requested: " + fmt.Sprint(*request.BlockIdentifier.Index)) + // zap.S().Info("DEBUG Inadequate height: " + fmt.Sprint(helium.SyncedRocksDBHeight)) + + // // Update all secondary rocksdb references if there are no block identifiers + // if tErr := helium.NodeBalancesDB.TryCatchUpWithPrimary(); tErr != nil { + // return nil, helium.WrapErr(helium.ErrFailed, tErr) + // } + + // helium.SyncedRocksDBHeight = *request.BlockIdentifier.Index + // zap.S().Info("DEBUG db synced at: " + fmt.Sprint(helium.SyncedRocksDBHeight)) + // } + var accountBalances []*types.Amount accountEntry, aeErr := helium.RocksDBAccountGet(request.AccountIdentifier.Address, blockId.Index) if aeErr != nil { + if aeErr.Error() == "dbcatchup" { + return nil, helium.ErrDBCatchup + } zap.S().Info("no balance found for " + balanceRequest.Address + " at height " + fmt.Sprint(balanceRequest.Height) + ". Returning balanaces of 0.") accountBalances = []*types.Amount{ { diff --git a/services/block_service.go b/services/block_service.go index d8b383a..2b579db 100644 --- a/services/block_service.go +++ b/services/block_service.go @@ -17,11 +17,13 @@ package services import ( "context" "errors" + "fmt" "strconv" "github.com/coinbase/rosetta-sdk-go/server" "github.com/coinbase/rosetta-sdk-go/types" "github.com/helium/rosetta-helium/helium" + "go.uber.org/zap" ) // BlockAPIService implements the server.BlockAPIServicer interface. @@ -41,6 +43,22 @@ func (s *BlockAPIService) Block( ctx context.Context, request *types.BlockRequest, ) (*types.BlockResponse, *types.Error) { + + zap.S().Info("/block request: " + fmt.Sprint(*request.BlockIdentifier.Index)) + + // Update all secondary rocksdb references + if tErr := helium.NodeBalancesDB.TryCatchUpWithPrimary(); tErr != nil { + return nil, helium.WrapErr(helium.ErrFailed, tErr) + } + + if tErr := helium.NodeBlocksDB.TryCatchUpWithPrimary(); tErr != nil { + return nil, helium.WrapErr(helium.ErrFailed, tErr) + } + + if tErr := helium.NodeTransactionsDB.TryCatchUpWithPrimary(); tErr != nil { + return nil, helium.WrapErr(helium.ErrFailed, tErr) + } + previousBlockIndex := *request.BlockIdentifier.Index - 1 if previousBlockIndex == 0 { previousBlockIndex = 1 diff --git a/services/network_service.go b/services/network_service.go index 1e0cb82..bf615d4 100644 --- a/services/network_service.go +++ b/services/network_service.go @@ -54,7 +54,7 @@ func (s *NetworkAPIService) NetworkStatus( request *types.NetworkRequest, ) (*types.NetworkStatusResponse, *types.Error) { - // Update all secondary rocksdb references during network status updates + // Update all secondary rocksdb references if tErr := helium.NodeBalancesDB.TryCatchUpWithPrimary(); tErr != nil { return nil, helium.WrapErr(helium.ErrFailed, tErr) }