Cleaned up naming of seed->commit
This commit is contained in:
parent
e635a8ff53
commit
9442e7e04a
|
@ -29,7 +29,7 @@ var (
|
|||
|
||||
//nolint
|
||||
const (
|
||||
SeedFlag = "seed"
|
||||
CommitFlag = "commit"
|
||||
HashFlag = "valhash"
|
||||
GenesisFlag = "genesis"
|
||||
FlagTrustNode = "trust-node"
|
||||
|
@ -52,7 +52,7 @@ var ResetCmd = &cobra.Command{
|
|||
|
||||
func init() {
|
||||
InitCmd.Flags().Bool("force-reset", false, "Wipe clean an existing client store, except for keys")
|
||||
InitCmd.Flags().String(SeedFlag, "", "Seed file to import (optional)")
|
||||
InitCmd.Flags().String(CommitFlag, "", "Commit file to import (optional)")
|
||||
InitCmd.Flags().String(HashFlag, "", "Trusted validator hash (must match to accept)")
|
||||
InitCmd.Flags().String(GenesisFlag, "", "Genesis file with chainid and validators (optional)")
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ func doInit(cmd *cobra.Command, root string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = initSeed()
|
||||
err = initTrust()
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -275,27 +275,27 @@ func initConfigFile(cmd *cobra.Command) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func initSeed() (err error) {
|
||||
func initTrust() (err error) {
|
||||
// create a provider....
|
||||
trust, source := GetProviders()
|
||||
|
||||
// load a seed file, or get data from the provider
|
||||
var seed certifiers.FullCommit
|
||||
seedFile := viper.GetString(SeedFlag)
|
||||
if seedFile == "" {
|
||||
// load a commit file, or get data from the provider
|
||||
var fc certifiers.FullCommit
|
||||
commitFile := viper.GetString(CommitFlag)
|
||||
if commitFile == "" {
|
||||
fmt.Println("Loading validator set from tendermint rpc...")
|
||||
seed, err = source.LatestCommit()
|
||||
fc, err = source.LatestCommit()
|
||||
} else {
|
||||
fmt.Printf("Loading validators from file %s\n", seedFile)
|
||||
seed, err = files.LoadFullCommit(seedFile)
|
||||
fmt.Printf("Loading validators from file %s\n", commitFile)
|
||||
fc, err = files.LoadFullCommit(commitFile)
|
||||
}
|
||||
// can't load the seed? abort!
|
||||
// can't load the commit? abort!
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// make sure it is a proper seed
|
||||
err = seed.ValidateBasic(viper.GetString(ChainFlag))
|
||||
// make sure it is a proper commit
|
||||
err = fc.ValidateBasic(viper.GetString(ChainFlag))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -305,30 +305,30 @@ func initSeed() (err error) {
|
|||
if hash != "" {
|
||||
var hashb []byte
|
||||
hashb, err = hex.DecodeString(hash)
|
||||
if err == nil && !bytes.Equal(hashb, seed.ValidatorsHash()) {
|
||||
err = errors.Errorf("Seed hash doesn't match expectation: %X", seed.ValidatorsHash())
|
||||
if err == nil && !bytes.Equal(hashb, fc.ValidatorsHash()) {
|
||||
err = errors.Errorf("Validator hash doesn't match expectation: %X", fc.ValidatorsHash())
|
||||
}
|
||||
} else {
|
||||
err = validateHash(seed)
|
||||
err = validateHash(fc)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// if accepted, store seed as current state
|
||||
trust.StoreCommit(seed)
|
||||
// if accepted, store commit as current state
|
||||
trust.StoreCommit(fc)
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateHash(seed certifiers.FullCommit) error {
|
||||
func validateHash(fc certifiers.FullCommit) error {
|
||||
// ask the user to verify the validator hash
|
||||
fmt.Println("\nImportant: if this is incorrect, all interaction with the chain will be insecure!")
|
||||
fmt.Printf(" Given validator hash valid: %X\n", seed.ValidatorsHash())
|
||||
fmt.Printf(" Given validator hash valid: %X\n", fc.ValidatorsHash())
|
||||
fmt.Println("Is this valid (y/n)?")
|
||||
valid := askForConfirmation()
|
||||
if !valid {
|
||||
return errors.New("Invalid validator hash, try init with proper seed later")
|
||||
return errors.New("Invalid validator hash, try init with proper commit later")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ func txQueryCmd(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
check, err := client.GetCertifiedCheckpoint(res.Height, node, cert)
|
||||
check, err := client.GetCertifiedCommit(res.Height, node, cert)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -38,15 +38,15 @@ func GetLocalProvider(dir string) certifiers.Provider {
|
|||
func GetCertifier(chainID string, trust certifiers.Provider,
|
||||
source certifiers.Provider) (*certifiers.Inquiring, error) {
|
||||
|
||||
// this gets the most recent verified seed
|
||||
seed, err := trust.LatestCommit()
|
||||
// this gets the most recent verified commit
|
||||
fc, err := trust.LatestCommit()
|
||||
if certerr.IsCommitNotFoundErr(err) {
|
||||
return nil, errors.New("Please run init first to establish a root of trust")
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cert := certifiers.NewInquiring(chainID, seed, trust, source)
|
||||
cert := certifiers.NewInquiring(chainID, fc, trust, source)
|
||||
return cert, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -47,8 +47,8 @@ func GetWithProof(key []byte, reqHeight int, node client.Client,
|
|||
}
|
||||
|
||||
// AppHash for height H is in header H+1
|
||||
var check *certifiers.Commit
|
||||
check, err = GetCertifiedCheckpoint(int(resp.Height+1), node, cert)
|
||||
var commit *certifiers.Commit
|
||||
commit, err = GetCertifiedCommit(int(resp.Height+1), node, cert)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ func GetWithProof(key []byte, reqHeight int, node client.Client,
|
|||
}
|
||||
|
||||
// Validate the proof against the certified header to ensure data integrity.
|
||||
err = eproof.Verify(resp.Key, resp.Value, check.Header.AppHash)
|
||||
err = eproof.Verify(resp.Key, resp.Value, commit.Header.AppHash)
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "Couldn't verify proof")
|
||||
return
|
||||
|
@ -79,7 +79,7 @@ func GetWithProof(key []byte, reqHeight int, node client.Client,
|
|||
return
|
||||
}
|
||||
// Validate the proof against the certified header to ensure data integrity.
|
||||
err = aproof.Verify(resp.Key, nil, check.Header.AppHash)
|
||||
err = aproof.Verify(resp.Key, nil, commit.Header.AppHash)
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "Couldn't verify proof")
|
||||
return
|
||||
|
@ -92,9 +92,9 @@ func GetWithProof(key []byte, reqHeight int, node client.Client,
|
|||
return
|
||||
}
|
||||
|
||||
// GetCertifiedCheckpoint gets the signed header for a given height
|
||||
// GetCertifiedCommit gets the signed header for a given height
|
||||
// and certifies it. Returns error if unable to get a proven header.
|
||||
func GetCertifiedCheckpoint(h int, node client.Client,
|
||||
func GetCertifiedCommit(h int, node client.Client,
|
||||
cert certifiers.Certifier) (empty *certifiers.Commit, err error) {
|
||||
|
||||
// FIXME: cannot use cert.GetByHeight for now, as it also requires
|
||||
|
|
|
@ -141,8 +141,8 @@ func TestTxProofs(t *testing.T) {
|
|||
err = res.Proof.Validate(key)
|
||||
assert.NoError(err, "%+v", err)
|
||||
|
||||
check, err := GetCertifiedCheckpoint(int(br.Height), cl, cert)
|
||||
commit, err := GetCertifiedCommit(int(br.Height), cl, cert)
|
||||
require.Nil(err, "%+v", err)
|
||||
require.Equal(res.Proof.RootHash, check.Header.DataHash)
|
||||
require.Equal(res.Proof.RootHash, commit.Header.DataHash)
|
||||
|
||||
}
|
||||
|
|
|
@ -39,36 +39,36 @@ var PostPacketTxCmd = &cobra.Command{
|
|||
|
||||
//nolint
|
||||
const (
|
||||
FlagSeed = "seed"
|
||||
FlagCommit = "commit"
|
||||
FlagPacket = "packet"
|
||||
)
|
||||
|
||||
func init() {
|
||||
fs1 := RegisterChainTxCmd.Flags()
|
||||
fs1.String(FlagSeed, "", "Filename with a seed file")
|
||||
fs1.String(FlagCommit, "", "Filename with a commit file")
|
||||
|
||||
fs2 := UpdateChainTxCmd.Flags()
|
||||
fs2.String(FlagSeed, "", "Filename with a seed file")
|
||||
fs2.String(FlagCommit, "", "Filename with a commit file")
|
||||
|
||||
fs3 := PostPacketTxCmd.Flags()
|
||||
fs3.String(FlagPacket, "", "Filename with a packet to post")
|
||||
}
|
||||
|
||||
func registerChainTxCmd(cmd *cobra.Command, args []string) error {
|
||||
seed, err := readSeed()
|
||||
fc, err := readCommit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tx := ibc.RegisterChainTx{seed}.Wrap()
|
||||
tx := ibc.RegisterChainTx{fc}.Wrap()
|
||||
return txcmd.DoTx(tx)
|
||||
}
|
||||
|
||||
func updateChainTxCmd(cmd *cobra.Command, args []string) error {
|
||||
seed, err := readSeed()
|
||||
fc, err := readCommit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tx := ibc.UpdateChainTx{seed}.Wrap()
|
||||
tx := ibc.UpdateChainTx{fc}.Wrap()
|
||||
return txcmd.DoTx(tx)
|
||||
}
|
||||
|
||||
|
@ -80,8 +80,8 @@ func postPacketTxCmd(cmd *cobra.Command, args []string) error {
|
|||
return txcmd.DoTx(post.Wrap())
|
||||
}
|
||||
|
||||
func readSeed() (fc certifiers.FullCommit, err error) {
|
||||
name := viper.GetString(FlagSeed)
|
||||
func readCommit() (fc certifiers.FullCommit, err error) {
|
||||
name := viper.GetString(FlagCommit)
|
||||
if name == "" {
|
||||
return fc, errors.New("You must specify a commit file")
|
||||
}
|
||||
|
|
|
@ -100,20 +100,20 @@ func (h Handler) DeliverTx(ctx sdk.Context, store state.SimpleDB, tx sdk.Tx) (re
|
|||
|
||||
switch t := tx.Unwrap().(type) {
|
||||
case RegisterChainTx:
|
||||
return h.initSeed(ctx, store, t)
|
||||
return h.registerChain(ctx, store, t)
|
||||
case UpdateChainTx:
|
||||
return h.updateSeed(ctx, store, t)
|
||||
return h.updateChain(ctx, store, t)
|
||||
case CreatePacketTx:
|
||||
return h.createPacket(ctx, store, t)
|
||||
}
|
||||
return res, errors.ErrUnknownTxType(tx.Unwrap())
|
||||
}
|
||||
|
||||
// initSeed imports the first seed for this chain and
|
||||
// registerChain imports the first seed for this chain and
|
||||
// accepts it as the root of trust.
|
||||
//
|
||||
// only the registrar, if set, is allowed to do this
|
||||
func (h Handler) initSeed(ctx sdk.Context, store state.SimpleDB,
|
||||
func (h Handler) registerChain(ctx sdk.Context, store state.SimpleDB,
|
||||
t RegisterChainTx) (res sdk.DeliverResult, err error) {
|
||||
|
||||
info := LoadInfo(store)
|
||||
|
@ -135,9 +135,9 @@ func (h Handler) initSeed(ctx sdk.Context, store state.SimpleDB,
|
|||
return res, err
|
||||
}
|
||||
|
||||
// updateSeed checks the seed against the existing chain data and rejects it if it
|
||||
// updateChain checks the seed against the existing chain data and rejects it if it
|
||||
// doesn't fit (or no chain data)
|
||||
func (h Handler) updateSeed(ctx sdk.Context, store state.SimpleDB,
|
||||
func (h Handler) updateChain(ctx sdk.Context, store state.SimpleDB,
|
||||
t UpdateChainTx) (res sdk.DeliverResult, err error) {
|
||||
|
||||
chainID := t.ChainID()
|
||||
|
|
|
@ -27,12 +27,12 @@ func TestIBCRegister(t *testing.T) {
|
|||
appHash := []byte{0, 4, 7, 23}
|
||||
appHash2 := []byte{12, 34, 56, 78}
|
||||
|
||||
// badSeed doesn't validate
|
||||
badSeed := genEmptyCommit(keys2, "chain-2", 123, appHash, len(keys2))
|
||||
badSeed.Header.AppHash = appHash2
|
||||
// badCommit doesn't validate
|
||||
badCommit := genEmptyCommit(keys2, "chain-2", 123, appHash, len(keys2))
|
||||
badCommit.Header.AppHash = appHash2
|
||||
|
||||
cases := []struct {
|
||||
seed certifiers.FullCommit
|
||||
fc certifiers.FullCommit
|
||||
checker errors.CheckErr
|
||||
}{
|
||||
{
|
||||
|
@ -44,7 +44,7 @@ func TestIBCRegister(t *testing.T) {
|
|||
IsAlreadyRegisteredErr,
|
||||
},
|
||||
{
|
||||
badSeed,
|
||||
badCommit,
|
||||
IsInvalidCommitErr,
|
||||
},
|
||||
{
|
||||
|
@ -58,7 +58,7 @@ func TestIBCRegister(t *testing.T) {
|
|||
app := stack.New().Dispatch(stack.WrapHandler(NewHandler()))
|
||||
|
||||
for i, tc := range cases {
|
||||
tx := RegisterChainTx{tc.seed}.Wrap()
|
||||
tx := RegisterChainTx{tc.fc}.Wrap()
|
||||
_, err := app.DeliverTx(ctx, store, tx)
|
||||
assert.True(tc.checker(err), "%d: %+v", i, err)
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ func TestIBCUpdate(t *testing.T) {
|
|||
require.Nil(err, "%+v", err)
|
||||
|
||||
cases := []struct {
|
||||
seed certifiers.FullCommit
|
||||
fc certifiers.FullCommit
|
||||
checker errors.CheckErr
|
||||
}{
|
||||
// same validator, higher up
|
||||
|
@ -211,7 +211,7 @@ func TestIBCUpdate(t *testing.T) {
|
|||
}
|
||||
|
||||
for i, tc := range cases {
|
||||
tx := UpdateChainTx{tc.seed}.Wrap()
|
||||
tx := UpdateChainTx{tc.fc}.Wrap()
|
||||
_, err := app.DeliverTx(ctx, store, tx)
|
||||
assert.True(tc.checker(err), "%d: %+v", i, err)
|
||||
}
|
||||
|
|
|
@ -11,19 +11,19 @@ import (
|
|||
certerr "github.com/tendermint/light-client/certifiers/errors"
|
||||
)
|
||||
|
||||
func assertSeedEqual(t *testing.T, s, s2 certifiers.FullCommit) {
|
||||
func assertCommitsEqual(t *testing.T, fc, fc2 certifiers.FullCommit) {
|
||||
assert := assert.New(t)
|
||||
assert.Equal(s.Height(), s2.Height())
|
||||
assert.Equal(s.ValidatorsHash(), s2.ValidatorsHash())
|
||||
assert.Equal(fc.Height(), fc2.Height())
|
||||
assert.Equal(fc.ValidatorsHash(), fc2.ValidatorsHash())
|
||||
// TODO: more
|
||||
}
|
||||
|
||||
func TestProviderStore(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
|
||||
// make a few seeds
|
||||
// make a few commits
|
||||
keys := certifiers.GenValKeys(2)
|
||||
seeds := makeSeeds(keys, 4, "some-chain", "demo-store")
|
||||
commits := makeCommits(keys, 4, "some-chain", "demo-store")
|
||||
|
||||
// make a provider
|
||||
store := state.NewMemKVStore()
|
||||
|
@ -34,39 +34,39 @@ func TestProviderStore(t *testing.T) {
|
|||
require.NotNil(err)
|
||||
assert.True(certerr.IsCommitNotFoundErr(err))
|
||||
|
||||
// add a seed
|
||||
for _, s := range seeds {
|
||||
err = p.StoreCommit(s)
|
||||
// add commits
|
||||
for _, fc := range commits {
|
||||
err = p.StoreCommit(fc)
|
||||
require.Nil(err)
|
||||
}
|
||||
|
||||
// make sure we get it...
|
||||
s := seeds[0]
|
||||
val, err := p.GetByHeight(s.Height())
|
||||
fc := commits[0]
|
||||
val, err := p.GetByHeight(fc.Height())
|
||||
if assert.Nil(err) {
|
||||
assertSeedEqual(t, s, val)
|
||||
assertCommitsEqual(t, fc, val)
|
||||
}
|
||||
|
||||
// make sure we get higher
|
||||
val, err = p.GetByHeight(s.Height() + 2)
|
||||
val, err = p.GetByHeight(fc.Height() + 2)
|
||||
if assert.Nil(err) {
|
||||
assertSeedEqual(t, s, val)
|
||||
assertCommitsEqual(t, fc, val)
|
||||
}
|
||||
|
||||
// below is nothing
|
||||
_, err = p.GetByHeight(s.Height() - 2)
|
||||
_, err = p.GetByHeight(fc.Height() - 2)
|
||||
assert.True(certerr.IsCommitNotFoundErr(err))
|
||||
|
||||
// make sure we get highest
|
||||
val, err = p.LatestCommit()
|
||||
if assert.Nil(err) {
|
||||
assertSeedEqual(t, seeds[3], val)
|
||||
assertCommitsEqual(t, commits[3], val)
|
||||
}
|
||||
|
||||
// make sure by hash also (note all have same hash, so overwritten)
|
||||
val, err = p.GetByHash(seeds[1].ValidatorsHash())
|
||||
val, err = p.GetByHash(commits[1].ValidatorsHash())
|
||||
if assert.Nil(err) {
|
||||
assertSeedEqual(t, seeds[3], val)
|
||||
assertCommitsEqual(t, commits[3], val)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,17 +76,17 @@ func TestDBProvider(t *testing.T) {
|
|||
checkProvider(t, p, "test-db", "bling")
|
||||
}
|
||||
|
||||
func makeSeeds(keys certifiers.ValKeys, count int, chainID, app string) []certifiers.FullCommit {
|
||||
func makeCommits(keys certifiers.ValKeys, count int, chainID, app string) []certifiers.FullCommit {
|
||||
appHash := []byte(app)
|
||||
seeds := make([]certifiers.FullCommit, count)
|
||||
commits := make([]certifiers.FullCommit, count)
|
||||
for i := 0; i < count; i++ {
|
||||
// two seeds for each validator, to check how we handle dups
|
||||
// two commits for each validator, to check how we handle dups
|
||||
// (10, 0), (10, 1), (10, 1), (10, 2), (10, 2), ...
|
||||
vals := keys.ToValidators(10, int64(count/2))
|
||||
h := 20 + 10*i
|
||||
seeds[i] = keys.GenFullCommit(chainID, h, nil, vals, appHash, 0, len(keys))
|
||||
commits[i] = keys.GenFullCommit(chainID, h, nil, vals, appHash, 0, len(keys))
|
||||
}
|
||||
return seeds
|
||||
return commits
|
||||
}
|
||||
|
||||
func checkProvider(t *testing.T, p certifiers.Provider, chainID, app string) {
|
||||
|
@ -94,43 +94,43 @@ func checkProvider(t *testing.T, p certifiers.Provider, chainID, app string) {
|
|||
keys := certifiers.GenValKeys(5)
|
||||
count := 10
|
||||
|
||||
// make a bunch of seeds...
|
||||
seeds := makeSeeds(keys, count, chainID, app)
|
||||
// make a bunch of commits...
|
||||
commits := makeCommits(keys, count, chainID, app)
|
||||
|
||||
// check provider is empty
|
||||
seed, err := p.GetByHeight(20)
|
||||
fc, err := p.GetByHeight(20)
|
||||
require.NotNil(err)
|
||||
assert.True(certerr.IsCommitNotFoundErr(err))
|
||||
|
||||
seed, err = p.GetByHash(seeds[3].ValidatorsHash())
|
||||
fc, err = p.GetByHash(commits[3].ValidatorsHash())
|
||||
require.NotNil(err)
|
||||
assert.True(certerr.IsCommitNotFoundErr(err))
|
||||
|
||||
// now add them all to the provider
|
||||
for _, s := range seeds {
|
||||
err = p.StoreCommit(s)
|
||||
for _, fc := range commits {
|
||||
err = p.StoreCommit(fc)
|
||||
require.Nil(err)
|
||||
// and make sure we can get it back
|
||||
s2, err := p.GetByHash(s.ValidatorsHash())
|
||||
fc2, err := p.GetByHash(fc.ValidatorsHash())
|
||||
assert.Nil(err)
|
||||
assertSeedEqual(t, s, s2)
|
||||
assertCommitsEqual(t, fc, fc2)
|
||||
// by height as well
|
||||
s2, err = p.GetByHeight(s.Height())
|
||||
fc2, err = p.GetByHeight(fc.Height())
|
||||
assert.Nil(err)
|
||||
assertSeedEqual(t, s, s2)
|
||||
assertCommitsEqual(t, fc, fc2)
|
||||
}
|
||||
|
||||
// make sure we get the last hash if we overstep
|
||||
seed, err = p.GetByHeight(5000)
|
||||
fc, err = p.GetByHeight(5000)
|
||||
if assert.Nil(err) {
|
||||
assertSeedEqual(t, seeds[count-1], seed)
|
||||
assertCommitsEqual(t, commits[count-1], fc)
|
||||
}
|
||||
|
||||
// and middle ones as well
|
||||
seed, err = p.GetByHeight(47)
|
||||
fc, err = p.GetByHeight(47)
|
||||
if assert.Nil(err) {
|
||||
// we only step by 10, so 40 must be the one below this
|
||||
assert.Equal(40, seed.Height())
|
||||
assert.Equal(40, fc.Height())
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,8 +32,8 @@ func NewMockChain(chainID string, numKeys int) MockChain {
|
|||
|
||||
// GetRegistrationTx returns a valid tx to register this chain
|
||||
func (m MockChain) GetRegistrationTx(h int) RegisterChainTx {
|
||||
seed := genEmptyCommit(m.keys, m.chainID, h, m.tree.Hash(), len(m.keys))
|
||||
return RegisterChainTx{seed}
|
||||
fc := genEmptyCommit(m.keys, m.chainID, h, m.tree.Hash(), len(m.keys))
|
||||
return RegisterChainTx{fc}
|
||||
}
|
||||
|
||||
// MakePostPacket commits the packet locally and returns the proof,
|
||||
|
@ -42,8 +42,8 @@ func (m MockChain) MakePostPacket(packet Packet, h int) (
|
|||
PostPacketTx, UpdateChainTx) {
|
||||
|
||||
post := makePostPacket(m.tree, packet, m.chainID, h)
|
||||
seed := genEmptyCommit(m.keys, m.chainID, h+1, m.tree.Hash(), len(m.keys))
|
||||
update := UpdateChainTx{seed}
|
||||
fc := genEmptyCommit(m.keys, m.chainID, h+1, m.tree.Hash(), len(m.keys))
|
||||
update := UpdateChainTx{fc}
|
||||
|
||||
return post, update
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue