|
|
|
@ -166,8 +166,16 @@ func NewPrivateAdminAPI(eth *Ethereum) *PrivateAdminAPI { |
|
|
|
|
return &PrivateAdminAPI{eth: eth} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ExportChain exports the current blockchain into a local file.
|
|
|
|
|
func (api *PrivateAdminAPI) ExportChain(file string) (bool, error) { |
|
|
|
|
// ExportChain exports the current blockchain into a local file,
|
|
|
|
|
// or a range of blocks if first and last are non-nil
|
|
|
|
|
func (api *PrivateAdminAPI) ExportChain(file string, first *uint64, last *uint64) (bool, error) { |
|
|
|
|
if first == nil && last != nil { |
|
|
|
|
return false, errors.New("last cannot be specified without first") |
|
|
|
|
} |
|
|
|
|
if first != nil && last == nil { |
|
|
|
|
head := api.eth.BlockChain().CurrentHeader().Number.Uint64() |
|
|
|
|
last = &head |
|
|
|
|
} |
|
|
|
|
if _, err := os.Stat(file); err == nil { |
|
|
|
|
// File already exists. Allowing overwrite could be a DoS vecotor,
|
|
|
|
|
// since the 'file' may point to arbitrary paths on the drive
|
|
|
|
@ -187,7 +195,11 @@ func (api *PrivateAdminAPI) ExportChain(file string) (bool, error) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Export the blockchain
|
|
|
|
|
if err := api.eth.BlockChain().Export(writer); err != nil { |
|
|
|
|
if first != nil { |
|
|
|
|
if err := api.eth.BlockChain().ExportN(writer, *first, *last); err != nil { |
|
|
|
|
return false, err |
|
|
|
|
} |
|
|
|
|
} else if err := api.eth.BlockChain().Export(writer); err != nil { |
|
|
|
|
return false, err |
|
|
|
|
} |
|
|
|
|
return true, nil |
|
|
|
|