explorer/: Deactivated stake accounts report as delegated (#12262)

* feat: add getStakeActivation to web3.js

* feat: add activation status to delegation card

* style: pretty

* feat: add epoch to getStakeActivation call

* feat: add unit test for getStakeActivation in web3.js

* feat: add test for getStakeActivation in web3.js

* feat: add getStakeActivation

* chore: add rollup watch

* feat: use string literal for stake activation state

* fix: dont display empty () for not delegated accounts

* fix: remove optional chaining due to issue with esdoc

* chore: remove optional_chaining

* feat: add live test for getStakeActivation

* feat: add active/inactive stake to account page

* feat: extend _buildArgs to support additional options, simplify unit test

* chore: update @solana/web3.js tp 0.76.0

* style: resolve linter issues

Co-authored-by: Justin Starry <justin@solana.com>
This commit is contained in:
Bartosz Lipinski 2020-09-22 00:41:39 -05:00 committed by GitHub
parent 7dd4de80eb
commit ef60d0f5ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 7 deletions

View File

@ -11,17 +11,20 @@ import {
StakeAccountType,
} from "validators/accounts/stake";
import BN from "bn.js";
import { StakeActivationData } from "@solana/web3.js";
const MAX_EPOCH = new BN(2).pow(new BN(64)).sub(new BN(1));
export function StakeAccountSection({
account,
stakeAccount,
activation,
stakeAccountType,
}: {
account: Account;
stakeAccount: StakeAccountInfo | StakeAccountWasm;
stakeAccountType: StakeAccountType;
activation?: StakeActivationData;
}) {
return (
<>
@ -35,6 +38,7 @@ export function StakeAccountSection({
<>
<DelegationCard
stakeAccount={stakeAccount}
activation={activation}
stakeAccountType={stakeAccountType}
/>
<AuthoritiesCard meta={stakeAccount.meta} />
@ -129,17 +133,22 @@ function OverviewCard({
function DelegationCard({
stakeAccount,
stakeAccountType,
activation,
}: {
stakeAccount: StakeAccountInfo | StakeAccountWasm;
stakeAccountType: StakeAccountType;
activation?: StakeActivationData;
}) {
const displayStatus = () => {
// TODO check epoch
let status = TYPE_NAMES[stakeAccountType];
let activationState = "";
if (stakeAccountType !== "delegated") {
status = "Not delegated";
} else {
activationState = activation ? `(${activation.state})` : "";
}
return status;
return [status, activationState].join(" ");
};
let voterPubkey, activationEpoch, deactivationEpoch;
@ -190,6 +199,24 @@ function DelegationCard({
</td>
</tr>
{activation && (
<>
<tr>
<td>Active Stake (SOL)</td>
<td className="text-lg-right">
{lamportsToSolString(activation.active)}
</td>
</tr>
<tr>
<td>Inactive Stake (SOL)</td>
<td className="text-lg-right">
{lamportsToSolString(activation.inactive)}
</td>
</tr>
</>
)}
{voterPubkey && (
<tr>
<td>Delegated Vote Address</td>

View File

@ -143,6 +143,7 @@ function DetailsSections({ pubkey, tab }: { pubkey: PublicKey; tab?: string }) {
function InfoSection({ account }: { account: Account }) {
const data = account?.details?.data;
if (data && data.program === "stake") {
let stakeAccountType, stakeAccount;
if ("accountType" in data.parsed) {
@ -157,6 +158,7 @@ function InfoSection({ account }: { account: Account }) {
<StakeAccountSection
account={account}
stakeAccount={stakeAccount}
activation={data.activation}
stakeAccountType={stakeAccountType}
/>
);

View File

@ -1,6 +1,11 @@
import React from "react";
import { StakeAccount as StakeAccountWasm } from "solana-sdk-wasm";
import { PublicKey, Connection, StakeProgram } from "@solana/web3.js";
import {
PublicKey,
Connection,
StakeProgram,
StakeActivationData,
} from "@solana/web3.js";
import { useCluster, Cluster } from "../cluster";
import { HistoryProvider } from "./history";
import { TokensProvider, TOKEN_PROGRAM_ID } from "./tokens";
@ -20,6 +25,7 @@ export { useAccountHistory } from "./history";
export type StakeProgramData = {
program: "stake";
parsed: StakeAccount | StakeAccountWasm;
activation?: StakeActivationData;
};
export type TokenProgramData = {
@ -85,9 +91,8 @@ async function fetchAccountInfo(
let data;
let fetchStatus;
try {
const result = (
await new Connection(url, "single").getParsedAccountInfo(pubkey)
).value;
const connection = new Connection(url, "single");
const result = (await connection.getParsedAccountInfo(pubkey)).value;
let lamports, details;
if (result === null) {
@ -104,17 +109,26 @@ async function fetchAccountInfo(
let data: ProgramData | undefined;
if (result.owner.equals(StakeProgram.programId)) {
try {
let parsed;
let parsed: StakeAccount | StakeAccountWasm;
let isDelegated: boolean = false;
if ("parsed" in result.data) {
const info = coerce(result.data.parsed, ParsedInfo);
parsed = coerce(info, StakeAccount);
isDelegated = parsed.type === "delegated";
} else {
const wasm = await import("solana-sdk-wasm");
parsed = wasm.StakeAccount.fromAccountData(result.data);
isDelegated = (parsed.accountType as any) === "delegated";
}
const activation = isDelegated
? await connection.getStakeActivation(pubkey)
: undefined;
data = {
program: "stake",
parsed,
activation,
};
} catch (err) {
reportError(err, { url, address: pubkey.toBase58() });