feat(user/bkotslu):Retrieve OTS files from storage if older
[BK-2020-03.git] / user / bkotslu
index f2e1220516be82d6512932256205c1f41050c96e..b6f79e51c2104ec9b3514675974dcce6241206ca 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/bash
 # Desc: Utility for backing up and retrieving ots files
-# Version: 0.0.1
+# Version: 0.0.2
 
 OTS_FCACHE_DIR="$HOME/.cache/bkotslu/";
 MAX_FIND_DEPTH=12;
@@ -89,6 +89,15 @@ EOF
     vbm "DEBUG:showVersion function ended."
     return 0; # Function finished.
 }; # Display script version.
+checkDepends() {
+    vbm "STATUS:Starting checkDepends()";
+    if ! command -v sha256sum 1>/dev/random 2>&1; then
+        die "FATAL:sha256sum not available."; fi;
+    if ! command -v grep 1>/dev/random 2>&1; then
+        die "FATAL:grep not available."; fi;
+    if ! command -v find 1>/dev/random 2>&1; then
+        die "FATAL:grep not available."; fi;
+};
 processArgs() {
     # Desc: Processes arguments provided to script.
     # Usage: processArgs "$@"
@@ -186,14 +195,14 @@ get_ots_filehash() {
     # Input:  arg1    OTS file path
     # Output: stdout  sha256 file hash (lowercase)
     local output;
-
     vbm "DEBUG:Starting get_ots_filehash() on:$1";
+    
     if output="$( "$(which ots)" info "$1" | \
             grep -E "^File sha256 hash: " | \
             head -n1 | \
             sed -E -e 's/(^File sha256 hash: )([0-9a-f]+$)/\2/g'; )" && \
             [[ -n "$output" ]]; then
-        vbm "STATUS:Read file hash via ots from:$1";
+        vbm "STATUS:Read file digest (${output}) via ots from:$1";
         printf "%s" "$output";
         return 0;
     else
@@ -211,14 +220,14 @@ get_ots_oldestblock() {
     #          vbm()
     #          BK-2020-03: yell()
     local output;
-
-    vbm "DEBUG:Starting get_ots_oldestblock() on:$1";    
+    vbm "DEBUG:Starting get_ots_oldestblock() on:$1";
+    
     if output="$( "$(which ots)" info "$1" | \
             grep -E "verify BitcoinBlockHeaderAttestation\([0-9]+\)" | \
             sort | head -n1 | \
             sed -E -e 's/(^    verify BitcoinBlockHeaderAttestation)\(([0-9]+)(\))/\2/g'; )" && \
             [[ -n "$output" ]]; then
-        vbm "STATUS:Retrieved Bitcoin block via ots from:$1";
+        vbm "STATUS:Retrieved Bitcoin block (${output}) via ots from:$1";
         printf "%s" "$output";
         return 0;
     else
@@ -228,36 +237,99 @@ get_ots_oldestblock() {
 }; # Gets oldest Bitcoin block from ots file
 cache_ots_file() {
     # Desc: Scans and caches an OTS file for storing
-    if fhash="$(must get_ots_filehash "$line")" && \
-            block="$(must get_ots_oldestblock "$line")"; then
+    # Input: arg1  input file
+    # Output: exit code
+    local fin="$1";
+    vbm "STATUS:Starting cache_ots_file()";
+    
+    if [[ ! -f "$fin" ]]; then die "FATAL:OTS file not found:$fin"; fi; 
+    if fhash="$(must get_ots_filehash "$fin")" && \
+            block="$(must get_ots_oldestblock "$fin")"; then
         fout="${fhash}_${block}.otsu"; # file name out
         pout="${pathDirOut1}/${fout}"; # file path out
-        vbm "STATUS:Found OTS file at ${line} with hash ${fhash} and block ${block} and saving to ${pout}";
-        must cp -n "$line" "$pout";
+        vbm "STATUS:Found OTS file at ${fin} with hash ${fhash} and block ${block}.";
+        vbm "STATUS:Saving found OTS file to ${pout}";
+        must cp -n "$fin" "$pout";
+        return 0;
     else
-        yell "ERROR:Problem analyzing file with OpenTimestamps:${line}";
+        yell "ERROR:Problem analyzing file with OpenTimestamps:${fin}";
+        return 1;
     fi;
 }; # Scans a single OTS file
-
+get_sha256_digest() {
+    # Depends: GNU Coreutils 8.32 (sha256sum)
+    # Input:  arg1    path  file path
+    # Output: stdout  str   sha256 digest (lowercase hexadecimal)
+    vbm "DEBUG:Starting get_sha256_digest()";
+    sha256sum "$1" | head -n1 | sed -E -e 's/(^[0-9a-f]{64})(.+)/\1/';
+};
+get_oldest_stored_ots_path() {
+    # Desc: Lookup most recent OTS file from storage
+    # Input:  pathDirOut1  var  path to OTS storage dir
+    #         arg1         str  sha256 digest (lowercase hexadecimal)
+    # Output: stdout       path OTS file with matching sha256 digest
+    vbm "DEBUG:Starting get_oldest_stored_ots_path()";
+    
+    digest="$1";
+    if output="$( find "$pathDirOut1" -type f -name "${digest}*" | \
+            sort | \
+            head -n1 )" && \
+            [[ -n "$output" ]]; then
+        output="$(readlink -f "$output")";
+        vbm "STATUS:Found matching OTS file with digest ${digest} at:$output";
+        printf "%s" "$output";
+        return 0;
+    else
+        yell "ERROR:Could not find matching OTS file with digest ${digest} in ${pathDirOut1}";
+        return 1;
+    fi;
+};
 main() {
+    checkDepends;
     processArgs "$@";
-
+    vbm "DEBUG:Starting rest of main()";
 
     # Scan provided dir for OTS files to cache.
     if [[ -n "$pathDirIn1" ]]; then
         while read -r line; do
             line="$(readlink -f "$line")";
-            cache_ots_file;
+            cache_ots_file "$line";
         done < <(find "$pathDirIn1" -maxdepth "$MAX_FIND_DEPTH" -type f -name "*.ots");
     fi;
 
     # Lookup OTS file from archive for provided file.
     if [[ -n "$pathFileIn1" ]]; then
-        :
+        # Check for and store any OTS file attached to provided file
+        if [[ -f "${pathFileIn1}.ots" ]]; then
+            vbm "STATUS:OTS file accompanying provided file found:${pathFileIn1}.ots";
+            cache_ots_file "${pathFileIn1}.ots" && vbm "STATUS:Stored provided file's OTS file.";
+        fi;
+        
+        # Get file hash
+        fhash="$(get_sha256_digest "$pathFileIn1"; )";
+        if path_stored_ots="$(get_oldest_stored_ots_path "$fhash"; )"; then
+            vbm "STATUS:Stored OTS found with matching hash.";
+            blk_stored="$(get_ots_oldestblock "$path_stored_ots"; )";
+            vbm "STATUS:Stored OTS file has block number ${blk_stored}.";
+            if [[ -f "${pathFileIn1}.ots" ]]; then
+                vbm "STATUS:An OTS file is next to provided file.";
+                blk_provid="$(get_ots_oldestblock "${pathFileIn1}.ots"; )";
+                vbm "STATUS:Provided file's OTS file has block number ${blk_provid}";
+                if [[ "$blk_stored" -lt "$blk_provid" ]]; then
+                    vbm "STATUS:Older timestamp in OTS store found. Replacing ${pathFileIn1} (block ${blk_provid}) with ${path_stored_ots} (block ${blk_stored}).";
+                    #must mv "$pathFileIn1" "${pathFileIn1}.baku";
+                    #must cp "$path_stored_ots" "$pathFileIn1";
+                else
+                    yell "STATUS:Stored OTS file (block ${blk_stored}) is not older than provided file's OTS file (block ${blk_provid}). No action taken for:${pathFileIn1}";
+                fi;
+            else
+                vbm "STATUS:Stored OTS file found with digest matching provided file. Copying ${path_stored_ots} to ${pathFileIn1}.ots";
+                must cp "$path_stored_ots" "${pathFileIn1}.ots";
+            fi;
+        else
+            vbm "STATUS:No stored OTS found. No action taken for:${pathFileIn1}";
+        fi;
     fi;
-    
-    
-
 
 }; # main program